#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