update Server.

This commit is contained in:
ykiko
2024-09-03 20:09:53 +08:00
parent 74a6e8992a
commit b7b4090f10
5 changed files with 74 additions and 138 deletions

22
include/Server/Command.h Normal file
View File

@@ -0,0 +1,22 @@
#include <clang/Tooling/CompilationDatabase.h>
namespace clice {
class CompilationDatabase {
public:
void load(clang::StringRef path);
std::vector<const char*> lookup(clang::StringRef path);
private:
std::unique_ptr<clang::tooling::CompilationDatabase> CDB;
};
namespace global {
extern CompilationDatabase CDB;
};
} // namespace clice

View File

@@ -1,15 +1,18 @@
#pragma once
#include <string>
#include <string_view>
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

32
src/Server/Command.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include <Server/Command.h>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
namespace clice {
std::vector<const char*> CompilationDatabase::lookup(clang::StringRef path) {
auto& command = CDB->getCompileCommands(path).front();
std::vector<const char*> 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

View File

@@ -1,16 +1,19 @@
#include "toml++/toml.hpp"
#include "Server/Option.h"
#include <Support/FileSystem.h>
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

View File

@@ -1,133 +1,9 @@
#include <clang/AST/Decl.h>
#include <cassert>
#include <AST/Diagnostic.h>
#include <AST/ParsedAST.h>
#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<clang::ClassTemplatePartialSpecializationDecl*> partials;
// decl->getPartialSpecializations(partials);
// for(auto partial: partials) {
// if(auto specialization =
// decl->findPartialSpecialization(arguments, partial->getTemplateParameters(), pos)) {
// specialization->dump();
// }
// }
const char* source = R"(
#include <vector>
template <typename _Tp, typename _Up, typename>
struct rebind : std::__replace_first_arg<_Tp, _Up> {};
template <typename _Tp, typename _Up>
struct rebind<_Tp, _Up, std::void_t<typename _Tp::other>> {
using type = int;
};
template <typename T>
struct test {
using result = typename rebind<std::allocator<T>, T, void>::type;
};
)";
using namespace llvm;
using namespace clang;
class Visitor : public clang::RecursiveASTVisitor<Visitor> {
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<TemplateArgument> TemplateArgs) {
void* InsertPos = nullptr;
if(auto* Spec = CTD->findSpecialization(TemplateArgs, InsertPos)) {
// return Spec;
}
ClassTemplatePartialSpecializationDecl* BestPartialSpec = nullptr;
clang::sema::TemplateDeductionInfo Info(CTD->getLocation());
llvm::SmallVector<clang::ClassTemplatePartialSpecializationDecl*> 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<ClassTemplateSpecializationDecl>(CTD->getTemplatedDecl());
}
bool VisitTemplateSpecializationType(const clang::TemplateSpecializationType* type) {
if(auto CTD = llvm::dyn_cast<clang::ClassTemplateDecl>(type->getTemplateName().getAsTemplateDecl())) {
if(CTD->getName() == "rebind") {
llvm::SmallVector<clang::TemplateArgument> 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 <Server/Option.h>
#include <Server/Command.h>
int main(int argc, const char** argv) {
// clice::execute_path = argv[0];
auto args = std::vector<const char*>{
"/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);
}