diff --git a/.vscode/launch.json b/.vscode/launch.json index b853bc52..e9c38937 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "name": "clice_socket", "program": "${workspaceFolder}/build/bin/clice", "args": [ - "--config={workspaceFolder}/docs/clice.toml" + "--config=${workspaceFolder}/docs/clice.toml" ] }, { @@ -19,7 +19,7 @@ "name": "clice_test", "program": "${workspaceFolder}/build/bin/clice-tests", "args": [ - "--test-dir={workspaceFolder}/tests", + "--test-dir=${workspaceFolder}/tests", "${input:filter}" ], } diff --git a/deps/llvm b/deps/llvm index cf991be6..668c8f77 160000 --- a/deps/llvm +++ b/deps/llvm @@ -1 +1 @@ -Subproject commit cf991be623559ae58f6d1740cda67095cdeb75ba +Subproject commit 668c8f77161b29717c63a9e5bc322429ef0aa0ea diff --git a/include/Basic/Basic.h b/include/Basic/Basic.h index 64d8a780..f7461325 100644 --- a/include/Basic/Basic.h +++ b/include/Basic/Basic.h @@ -3,6 +3,12 @@ #include #include +namespace clice { + +class Compiler; + +} + namespace clice::proto { /// range in [-2^31, 2^31- 1] diff --git a/include/Compiler/Resolver.h b/include/Compiler/Resolver.h index c2a46c0b..005645e3 100644 --- a/include/Compiler/Resolver.h +++ b/include/Compiler/Resolver.h @@ -43,14 +43,31 @@ public: return lookup(expr->getQualifier(), expr->getNameInfo().getName()); } - /// TODO: - clang::lookup_result lookup(clang::CXXDependentScopeMemberExpr* expr); + clang::lookup_result lookup(const clang::UnresolvedLookupExpr* expr) { + /// FIXME: + for(auto decl: expr->decls()) { + if(auto TD = llvm::dyn_cast(decl)) { + return clang::lookup_result(TD); + } + } - clang::lookup_result lookup(clang::UnresolvedUsingValueDecl* decl) { + return {}; + } + + clang::lookup_result lookup(const clang::UnresolvedMemberExpr* expr) { + return {}; + } + + /// TODO: + clang::lookup_result lookup(clang::CXXDependentScopeMemberExpr* expr) { + return {}; + } + + clang::lookup_result lookup(const clang::UnresolvedUsingValueDecl* decl) { return lookup(decl->getQualifier(), decl->getDeclName()); } - clang::lookup_result resolve(clang::UnresolvedUsingTypenameDecl* decl) { + clang::lookup_result resolve(const clang::UnresolvedUsingTypenameDecl* decl) { return lookup(decl->getQualifier(), decl->getDeclName()); } diff --git a/include/Compiler/Semantic.h b/include/Compiler/Semantic.h index a4138bfc..bb220bac 100644 --- a/include/Compiler/Semantic.h +++ b/include/Compiler/Semantic.h @@ -53,12 +53,61 @@ enum class OccurrenceKind { Instantiation, }; -class SemanticVisitor : public clang::RecursiveASTVisitor { +template +class SemanticVisitor : public clang::RecursiveASTVisitor> { public: using Base = clang::RecursiveASTVisitor; - SemanticVisitor(Compiler& compiler) : - sema(compiler.sema()), resolver(compiler.resolver()), srcMgr(compiler.srcMgr()) {} + SemanticVisitor(Compiler& compiler, bool mainFileOnly = false) : + sema(compiler.sema()), resolver(compiler.resolver()), srcMgr(compiler.srcMgr()), + tokBuf(compiler.tokBuf()), mainFileOnly(mainFileOnly) {} + +public: + +public: + consteval bool VisitImplicitInstantiation() { + return true; + } + + Derived& getDerived() { + return static_cast(*this); + } + + bool needFilter(clang::SourceLocation location) { + return location.isInvalid() || (mainFileOnly && !srcMgr.isInMainFile(location)); + } + + void dump(clang::SourceLocation loc) { + auto location = srcMgr.getPresumedLoc(loc); + llvm::SmallString<128> path; + auto err = fs::real_path(location.getFilename(), path); + llvm::outs() << path << ":" << location.getLine() << ":" << location.getColumn() << "\n"; + } + + /// An occurrence directly corresponding to a symbol in source code. + /// In most cases, a location just correspondings to unique decl. + /// So a location will be just visited once. But in some other cases, + /// a location may correspond to multiple decls. Note that we already + /// filter some nodes with invalid location. + /// + /// Always uses spelling location if the original location is a macro location. + void handleOccurrence(const clang::Decl* decl, + clang::SourceLocation location, + OccurrenceKind kind = OccurrenceKind::Source) {} + + /// Builtin type doesn't have corresponding decl. So we handle it separately. + /// And it is possible that a builtin type is composed of multiple tokens. + /// e.g. `unsigned long long`. + void handleOccurrence(const clang::BuiltinType* type, + clang::SourceRange range, + OccurrenceKind kind = OccurrenceKind::Source) {} + + void handleOccurrence(clang::Attr* attr, clang::SourceRange range) {} + + /// Always uses expansion location if the original location is a macro location. + void handleRelation(const clang::Decl* decl, RelationKind kind, clang::SourceRange range) { + /// + } public: /// ============================================================================ @@ -66,6 +115,10 @@ public: /// ============================================================================ TRAVERSE_DECL(Decl) { + if(!llvm::isa(decl) && needFilter(decl->getLocation())) { + return true; + } + decls.push_back(decl); auto result = Base::TraverseDecl(decl); decls.pop_back(); @@ -75,7 +128,7 @@ public: VISIT_DECL(NamespaceDecl) { /// `namespace Foo { }` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } @@ -83,43 +136,43 @@ public: /// `namespace Foo = Bar` /// ^ ^~~~ reference /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); - handleOccurrence(decl->getNamespace(), decl->getTargetNameLoc()); + getDerived().handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl->getNamespace(), decl->getTargetNameLoc()); return true; } VISIT_DECL(UsingDirectiveDecl) { /// `using namespace Foo` /// ^~~~~~~ reference - handleOccurrence(decl->getNominatedNamespace(), decl->getLocation()); + getDerived().handleOccurrence(decl->getNominatedNamespace(), decl->getLocation()); return true; } VISIT_DECL(LabelDecl) { /// `label:` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } VISIT_DECL(FieldDecl) { /// `int foo;` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } VISIT_DECL(EnumConstantDecl) { /// `enum Foo { bar };` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } VISIT_DECL(UsingDecl) { /// `using Foo::bar;` /// ^~~~ reference - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); /// FIXME: return true; } @@ -127,55 +180,33 @@ public: VISIT_DECL(BindingDecl) { /// `auto [a, b] = std::make_tuple(1, 2);` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } VISIT_DECL(TemplateTypeParmDecl) { /// `template ` /// ^~~~ definition - handleOccurrence(decl, decl->getLocation()); + getDerived().handleOccurrence(decl, decl->getLocation()); return true; } VISIT_DECL(TemplateTemplateParmDecl) { /// `template