update Server.
This commit is contained in:
22
include/Server/Command.h
Normal file
22
include/Server/Command.h
Normal 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
|
||||
@@ -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
32
src/Server/Command.cpp
Normal 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
|
||||
@@ -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
|
||||
|
||||
134
src/main.cpp
134
src/main.cpp
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user