diff --git a/.gitignore b/.gitignore index 1794a3c3..e8b8594c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ *.out *.app +.txt .cache/ build* temp* diff --git a/CMakeLists.txt b/CMakeLists.txt index eb90f5ff..98c8cc4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,6 @@ project(CLICE) set(CMAKE_CXX_STANDARD 20) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -fno-rtti -g -O0") set(LLVM_INSTALL_PATH "${CMAKE_SOURCE_DIR}/deps/llvm/build-install") @@ -47,6 +46,7 @@ function(target_clang target) ) target_link_libraries(${target} PRIVATE LLVMSupport + LLVMFrontendOpenMP clangAST clangASTMatchers clangBasic diff --git a/deps/llvm b/deps/llvm index d9c64134..585bc0a4 160000 --- a/deps/llvm +++ b/deps/llvm @@ -1 +1 @@ -Subproject commit d9c641342db0b714604281681309233ee321f877 +Subproject commit 585bc0a4669f41c898ccb65f63de8b3e2313c278 diff --git a/include/Index/Pack.h b/include/Index/Pack.h index 3e502861..0b0d193e 100644 --- a/include/Index/Pack.h +++ b/include/Index/Pack.h @@ -22,7 +22,7 @@ namespace clice { // - `string data`: Contains all string characters, stored sequentially. /// Pack the CSIF into a binary buffer. -std::unique_ptr pack(const CSIF& csif); +std::unique_ptr pack(CSIF csif); /// Unpack the binary buffer into a CSIF. /// NOTE: the data should be mutable. when the first load it, diff --git a/scripts/build-dev-test.sh b/scripts/build-dev-test.sh index 70b8a4fa..2c219785 100755 --- a/scripts/build-dev-test.sh +++ b/scripts/build-dev-test.sh @@ -1 +1 @@ -cmake -B build -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug -DCLICE_ENABLE_TEST=ON \ No newline at end of file +cmake -B build -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug -DCLICE_ENABLE_TEST=ON -DCMAKE_CXX_FLAGS="-fno-rtti -g -O0" \ No newline at end of file diff --git a/src/AST/Resolver.cpp b/src/AST/Resolver.cpp index 0f73a0c4..bc29d795 100644 --- a/src/AST/Resolver.cpp +++ b/src/AST/Resolver.cpp @@ -1,5 +1,4 @@ #include "AST/Resolver.h" -#include "clang-extra/TreeTransform.h" namespace clice { diff --git a/src/Index/Pack.cpp b/src/Index/Pack.cpp index 37830874..0fc8b187 100644 --- a/src/Index/Pack.cpp +++ b/src/Index/Pack.cpp @@ -5,6 +5,9 @@ namespace clice { namespace { +// FIXME: figure out the influence of alignment, padding and endianness. +// Add some tests to verify the correctness of the implementation. + template constexpr bool is_array_ref_v = false; diff --git a/src/Index/SymbolCollector.cpp b/src/Index/SymbolCollector.cpp index d440bc3b..eea61a78 100644 --- a/src/Index/SymbolCollector.cpp +++ b/src/Index/SymbolCollector.cpp @@ -1,3 +1,6 @@ +#include + +#include #include namespace clice { diff --git a/tests/AST/TreeTransform.cpp b/tests/AST/TreeTransform.cpp new file mode 100644 index 00000000..1540f5de --- /dev/null +++ b/tests/AST/TreeTransform.cpp @@ -0,0 +1,139 @@ +#include +#include +#include + +namespace { + +using namespace clice; + +std::vector compileArgs = { + "clang++", + "-std=c++20", + "main.cpp", + "-resource-dir", + "/home/ykiko/C++/clice2/build/lib/clang/20", +}; + +class TemplateResolver : public clang::TreeTransform { + using Base = clang::TreeTransform; + + struct Frame { + clang::NamedDecl* decl; + std::vector arguments; + }; + +public: + TemplateResolver(clang::Sema& sema, clang::ASTContext& context) : TreeTransform(sema), context(context) {} + +private: + std::vector frames; + clang::ASTContext& context; +}; + +class Replacer : public clang::TreeTransform { + clang::ASTContext& context; + + using Base = clang::TreeTransform; + +public: + Replacer(clang::Sema& sema, clang::ASTContext& context) : TreeTransform{sema}, context(context) {} + +public: + bool TransformTemplateArguments(const clang::TemplateArgumentLoc* Inputs, + unsigned NumInputs, + clang::TemplateArgumentListInfo& Outputs, + bool Uneval = false) { + return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs, Uneval); + } + + template + bool TransformTemplateArguments(InputIterator First, + InputIterator Last, + clang::TemplateArgumentListInfo& Outputs, + bool Uneval = false) { + llvm::outs() << "template\n"; + for(auto it = First; it != Last; ++it) { + it->getArgument().dump(); + } + return Base::TransformTemplateArguments(First, Last, Outputs, Uneval); + } + + clang::NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc NNS, + clang::QualType ObjectType = clang::QualType(), + clang::NamedDecl* FirstQualifierInScope = nullptr) { + llvm::outs() << "nested\n"; + return Base::TransformNestedNameSpecifierLoc(NNS, ObjectType, FirstQualifierInScope); + } + + clang::QualType TransformDependentNameType(clang::TypeLocBuilder& TLB, + clang::DependentNameTypeLoc TL, + bool DeducedTSTContext = false) { + + DependentNameResolver resolver{getSema(), context}; + auto NNS = TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); + auto DNT = context.getDependentNameType(TL.getTypePtr()->getKeyword(), + NNS.getNestedNameSpecifier(), + TL.getTypePtr()->getIdentifier()); + auto result = resolver.resolve(DNT); + result->dump(); + llvm::outs() << "--------------------------------------------\n"; + + switch(clang::TypeLoc(result, nullptr).getTypeLocClass()) { +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + case clang::TypeLoc::CLASS: TLB.push(result); break; +#include "clang/AST/TypeLocNodes.def" + } + + return result; + } +}; + +struct Visitor : public clang::RecursiveASTVisitor { + clang::QualType result; + std::unique_ptr parsedAST; + + Visitor(const char* code) : parsedAST(ParsedAST::build("main.cpp", code, compileArgs)) {} + + bool VisitTypeAliasDecl(clang::TypeAliasDecl* decl) { + if(decl->getName() == "result") { + Replacer replacer(parsedAST->sema, parsedAST->context); + // decl->getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getType().dump(); + auto result = replacer.TransformType(decl->getTypeSourceInfo()); + // result->getType().dump(); + } + return true; + } + + clang::QualType test() { + clang::TypeLocBuilder builder; + auto decl = parsedAST->context.getTranslationUnitDecl(); + TraverseDecl(decl); + return result; + } +}; + +TEST(Transform, test) { + + const char* code = R"( +template +struct type_list {}; + +template +struct A { + using type = type_list; +}; + +template +struct test { + using result = typename A::type>::type&; +}; + +)"; + + Visitor visitor(code); + auto result = visitor.test(); +} + +} // namespace + diff --git a/tests/Index/Index.cpp b/tests/Index/Index.cpp index aa24ba23..0373d3b7 100644 --- a/tests/Index/Index.cpp +++ b/tests/Index/Index.cpp @@ -19,8 +19,8 @@ template struct X {}; template struct X {}; void f() { - X x; X y; + X x; } )"; auto invocation = createInvocation("main.cpp", code, compileArgs); @@ -44,7 +44,7 @@ void f() { std::terminate(); } - instance->getASTContext().getTranslationUnitDecl()->dump(); + // instance->getASTContext().getTranslationUnitDecl()->dump(); action->EndSourceFile(); } diff --git a/tests/Index/Pack.cpp b/tests/Index/Pack.cpp new file mode 100644 index 00000000..8e925925 --- /dev/null +++ b/tests/Index/Pack.cpp @@ -0,0 +1,20 @@ +#include +#include + +namespace { + +using namespace clice; + +TEST(clice, pack) { + CSIF csif; + csif.version = "0.0.1"; + auto data = pack(csif); + + auto result = unpack(data.get()); + EXPECT_EQ(csif.version, result.version); + + std::vector x; + x.emplace_back(1); +} + +} // namespace