From b7b4090f10fde6b991646f6c06508e6c5669b128 Mon Sep 17 00:00:00 2001 From: ykiko Date: Tue, 3 Sep 2024 20:09:53 +0800 Subject: [PATCH] update Server. --- include/Server/Command.h | 22 +++++++ include/Server/Option.h | 11 ++-- src/Server/Command.cpp | 32 ++++++++++ src/Server/Option.cpp | 13 ++-- src/main.cpp | 134 ++------------------------------------- 5 files changed, 74 insertions(+), 138 deletions(-) create mode 100644 include/Server/Command.h create mode 100644 src/Server/Command.cpp diff --git a/include/Server/Command.h b/include/Server/Command.h new file mode 100644 index 00000000..47e7288d --- /dev/null +++ b/include/Server/Command.h @@ -0,0 +1,22 @@ +#include + +namespace clice { + +class CompilationDatabase { + +public: + void load(clang::StringRef path); + + std::vector lookup(clang::StringRef path); + +private: + std::unique_ptr CDB; +}; + +namespace global { + +extern CompilationDatabase CDB; + +}; + +} // namespace clice diff --git a/include/Server/Option.h b/include/Server/Option.h index 85f795de..fcc2f0f4 100644 --- a/include/Server/Option.h +++ b/include/Server/Option.h @@ -1,15 +1,18 @@ #pragma once #include -#include namespace clice { struct Option { - std::string resource_dir; - static Option parse(std::string_view execpath, std::string_view filepath); + std::string compile_commands_directory; + std::string resource_dictionary; + + void parse(int argc, const char** argv); }; -extern Option option; +namespace global { +extern struct Option option; +}; } // namespace clice diff --git a/src/Server/Command.cpp b/src/Server/Command.cpp new file mode 100644 index 00000000..0ff0da5a --- /dev/null +++ b/src/Server/Command.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +namespace clice { + +std::vector CompilationDatabase::lookup(clang::StringRef path) { + auto& command = CDB->getCompileCommands(path).front(); + std::vector args; + for(auto& arg: command.CommandLine) { + // TODO: + // some modification + args.push_back(arg.c_str()); + } + return args; +} + +void CompilationDatabase::load(clang::StringRef path) { + std::string error; + CDB = clang::tooling::CompilationDatabase::loadFromDirectory(path, error); + if(!CDB) { + spdlog::error("Failed to load compilation database: {}", error); + spdlog::default_logger()->flush(); + std::terminate(); + } +} + +namespace global { +CompilationDatabase CDB; +} + +} // namespace clice diff --git a/src/Server/Option.cpp b/src/Server/Option.cpp index ee545aa8..117d8227 100644 --- a/src/Server/Option.cpp +++ b/src/Server/Option.cpp @@ -1,16 +1,19 @@ #include "toml++/toml.hpp" #include "Server/Option.h" +#include namespace clice { // TODO: replace builtin variable in Setting // e.g `{execute}` -> `execpath` -Option Option::parse(std::string_view execpath, std::string_view filepath) { - auto config = toml::parse_file(filepath); - auto clang = config["clang"]; - auto resource_dir = clang["resource_dir"].as_string()->get(); - return Option{resource_dir}; +void Option::parse(int argc, const char** argv) { + auto execute = argv[0]; + // compile_commands_directory = path::parent_path(execute); } +namespace global { +Option option; +}; + } // namespace clice diff --git a/src/main.cpp b/src/main.cpp index eef72139..6c29efcf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,133 +1,9 @@ -#include -#include -#include #include -#include "llvm/Support/InitLLVM.h" -#include "llvm/Support/TargetSelect.h" -#include "clang/Sema/TemplateDeduction.h" - -// llvm::FoldingSetNodeID id; -// clang::ClassTemplateSpecializationDecl::Profile(id, arguments, context); -// for(auto spec: decl->specializations()) { -// llvm::FoldingSetNodeID id2; -// spec->Profile(id2); -// llvm::outs() << "spec profile: " << (id == id2) << "\n"; -// llvm::outs() << "---------------------------------------------------------------\n"; -// for(std::size_t i = 0; i < arguments.size(); i++) { -// llvm::FoldingSetNodeID id3; -// arguments[i].Profile(id3, context); -// llvm::FoldingSetNodeID id4; -// spec->getTemplateArgs().asArray()[i].Profile(id4, context); -// llvm::outs() << "argument profile: " << (id3 == id4) << "\n"; -// arguments[i].dump(); -// spec->getTemplateArgs().asArray()[i].dump(); -// llvm::outs() << "---------------------------------------------------------------\n"; -// } -// } - -// if(auto specialization = decl->findSpecialization(arguments, pos)) { -// specialization->dump(); -// } - -// llvm::SmallVector partials; -// decl->getPartialSpecializations(partials); -// for(auto partial: partials) { -// if(auto specialization = -// decl->findPartialSpecialization(arguments, partial->getTemplateParameters(), pos)) { -// specialization->dump(); -// } -// } - -const char* source = R"( -#include - -template -struct rebind : std::__replace_first_arg<_Tp, _Up> {}; - -template -struct rebind<_Tp, _Up, std::void_t> { - using type = int; -}; - -template -struct test { - using result = typename rebind, T, void>::type; -}; - -)"; - -using namespace llvm; -using namespace clang; - -class Visitor : public clang::RecursiveASTVisitor { -public: - clang::Sema& sema; - clang::ASTContext& context; - - Visitor(clang::Sema& sema, clang::ASTContext& context) : sema(sema), context(context) {} - - void instantiateTemplate(clang::ClassTemplateDecl* CTD, llvm::ArrayRef TemplateArgs) { - void* InsertPos = nullptr; - - if(auto* Spec = CTD->findSpecialization(TemplateArgs, InsertPos)) { - // return Spec; - } - - ClassTemplatePartialSpecializationDecl* BestPartialSpec = nullptr; - - clang::sema::TemplateDeductionInfo Info(CTD->getLocation()); - - llvm::SmallVector partials; - CTD->getPartialSpecializations(partials); - - for(auto partial: partials) { - auto result = sema.DeduceTemplateArguments(partial, TemplateArgs, Info); - if(result == clang::TemplateDeductionResult::Success) { - llvm::outs() << "success\n"; - partial->dump(); - for(auto& arg: Info.takeSugared()->asArray()) { - llvm::outs() << "---------------------------------------\n"; - arg.dump(); - } - } - } - - // return cast(CTD->getTemplatedDecl()); - } - - bool VisitTemplateSpecializationType(const clang::TemplateSpecializationType* type) { - - if(auto CTD = llvm::dyn_cast(type->getTemplateName().getAsTemplateDecl())) { - if(CTD->getName() == "rebind") { - llvm::SmallVector arguments; - llvm::outs() << "count: " << type->template_arguments().size() << "\n"; - for(auto arg: type->template_arguments()) { - if(arg.getKind() == clang::TemplateArgument::ArgKind::Type) { - arguments.emplace_back(arg.getAsType().getCanonicalType()); - } else { - arguments.emplace_back(arg); - } - } - instantiateTemplate(CTD, arguments); - } - } - - return true; - } -}; +#include +#include int main(int argc, const char** argv) { - // clice::execute_path = argv[0]; - auto args = std::vector{ - "/usr/bin/c++", - "main.cpp", - "-resource-dir", - "/home/ykiko/C++/clice2/build/lib/clang/20", - }; - auto preamble = clice::Preamble::build("main.cpp", source, args); - auto parsedAST = clice::ParsedAST::build("main.cpp", source, args, preamble.get()); - Visitor visitor(parsedAST->sema, parsedAST->context); - auto tu = parsedAST->context.getTranslationUnitDecl(); - // tu->dump(); - visitor.TraverseDecl(parsedAST->context.getTranslationUnitDecl()); + using namespace clice; + global::option.parse(argc, argv); + global::CDB.load(global::option.compile_commands_directory); }