diff --git a/.vscode/launch.json b/.vscode/launch.json index b57adec8..fa238403 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,8 @@ "type": "lldb", "request": "launch", "name": "clice_socket", - "program": "${workspaceFolder}/build/bin/clice" + "program": "${workspaceFolder}/build/bin/clice", + "args": ["--config=/home/ykiko/C++/clice2/docs/clice.toml"] }, { "type": "lldb", @@ -34,7 +35,7 @@ "program": "${workspaceFolder}/build/bin/clice-tests", "args": [ "--test-dir=/home/ykiko/C++/clice2/tests", - "--gtest_filter=clice.TemplateResolver" + "--gtest_filter=TemplateResolver.DefaultArgument" ], "cwd": "${workspaceFolder}" }, diff --git a/docs/clice.toml b/docs/clice.toml index 57657ba3..360b9cfc 100644 --- a/docs/clice.toml +++ b/docs/clice.toml @@ -1,6 +1,6 @@ [server] # "pipe" or "socket" -mode = "pipe" +mode = "socket" port = 50051 address = "127.0.0.1" diff --git a/include/Basic/URI.h b/include/Basic/URI.h new file mode 100644 index 00000000..2a030a58 --- /dev/null +++ b/include/Basic/URI.h @@ -0,0 +1,5 @@ +namespace clice { + + + +} \ No newline at end of file diff --git a/include/Compiler/Clang.h b/include/Compiler/Clang.h index 5a964e5c..61153468 100644 --- a/include/Compiler/Clang.h +++ b/include/Compiler/Clang.h @@ -42,6 +42,8 @@ clang::SourceLocation get(clang::SourceRange range) { #define VISIT_TYPE(type) bool Visit##type(const clang::type* type) #define VISIT_TYPELOC(type) bool Visit##type(clang::type loc) +#define TRAVERSE_DECL(type) bool Traverse##type(clang::type* decl) + using lookup_result = clang::DeclContext::lookup_result; } // namespace clang diff --git a/include/Compiler/Semantic.h b/include/Compiler/Semantic.h new file mode 100644 index 00000000..a4138bfc --- /dev/null +++ b/include/Compiler/Semantic.h @@ -0,0 +1,513 @@ +#include "Compiler.h" +#include "Resolver.h" + +#include "Support/Enum.h" +#include "Support/FileSystem.h" +#include "Utility.h" + +namespace clice { + +enum class RelationKinds : uint32_t { + Invalid, + Declaration, + Definition, + Reference, + // Write Relation. + Read, + Write, + Interface, + Implementation, + /// When target is a type definition of source, source is possible type or constructor. + TypeDefinition, + + /// When target is a base class of source. + Base, + /// When target is a derived class of source. + Derived, + + /// When target is a constructor of source. + Constructor, + /// When target is a destructor of source. + Destructor, + + // When target is a caller of source. + Caller, + // When target is a callee of source. + Callee, +}; + +struct RelationKind : enum_type { + using enum RelationKinds; + using enum_type::enum_type; + using enum_type::operator=; +}; + +enum class OccurrenceKind { + /// This occurrence directly corresponds to a unique source symbol. + Source, + /// This occurrence is a macro expansion. + MacroExpansion, + /// This occurrence is from `PseudoInstantiation` and may be not correct. + PseudoInstantiation, + /// This occurrence is from `ImplicitInstantiation` or `ExplicitInstantiation` of a template. + Instantiation, +}; + +class SemanticVisitor : public clang::RecursiveASTVisitor { +public: + using Base = clang::RecursiveASTVisitor; + + SemanticVisitor(Compiler& compiler) : + sema(compiler.sema()), resolver(compiler.resolver()), srcMgr(compiler.srcMgr()) {} + +public: + /// ============================================================================ + /// Declaration + /// ============================================================================ + + TRAVERSE_DECL(Decl) { + decls.push_back(decl); + auto result = Base::TraverseDecl(decl); + decls.pop_back(); + return result; + } + + VISIT_DECL(NamespaceDecl) { + /// `namespace Foo { }` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(NamespaceAliasDecl) { + /// `namespace Foo = Bar` + /// ^ ^~~~ reference + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + handleOccurrence(decl->getNamespace(), decl->getTargetNameLoc()); + return true; + } + + VISIT_DECL(UsingDirectiveDecl) { + /// `using namespace Foo` + /// ^~~~~~~ reference + handleOccurrence(decl->getNominatedNamespace(), decl->getLocation()); + return true; + } + + VISIT_DECL(LabelDecl) { + /// `label:` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(FieldDecl) { + /// `int foo;` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(EnumConstantDecl) { + /// `enum Foo { bar };` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(UsingDecl) { + /// `using Foo::bar;` + /// ^~~~ reference + handleOccurrence(decl, decl->getLocation()); + /// FIXME: + return true; + } + + VISIT_DECL(BindingDecl) { + /// `auto [a, b] = std::make_tuple(1, 2);` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(TemplateTypeParmDecl) { + /// `template ` + /// ^~~~ definition + handleOccurrence(decl, decl->getLocation()); + return true; + } + + VISIT_DECL(TemplateTemplateParmDecl) { + /// `template