1f4fb85b1SArgyrios Kyrtzidis //===- IndexTypeSourceInfo.cpp - Indexing types ---------------------------===//
2f4fb85b1SArgyrios Kyrtzidis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f4fb85b1SArgyrios Kyrtzidis //
7f4fb85b1SArgyrios Kyrtzidis //===----------------------------------------------------------------------===//
8f4fb85b1SArgyrios Kyrtzidis
9f4fb85b1SArgyrios Kyrtzidis #include "IndexingContext.h"
10*75e16fd2SIlya Biryukov #include "clang/AST/ASTConcept.h"
11*75e16fd2SIlya Biryukov #include "clang/AST/PrettyPrinter.h"
12f4fb85b1SArgyrios Kyrtzidis #include "clang/AST/RecursiveASTVisitor.h"
13*75e16fd2SIlya Biryukov #include "clang/AST/TypeLoc.h"
147cd6b0c3SNathan Ridge #include "llvm/ADT/ScopeExit.h"
15f4fb85b1SArgyrios Kyrtzidis
16f4fb85b1SArgyrios Kyrtzidis using namespace clang;
17f4fb85b1SArgyrios Kyrtzidis using namespace index;
18f4fb85b1SArgyrios Kyrtzidis
19f4fb85b1SArgyrios Kyrtzidis namespace {
20f4fb85b1SArgyrios Kyrtzidis
21f4fb85b1SArgyrios Kyrtzidis class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
22f4fb85b1SArgyrios Kyrtzidis IndexingContext &IndexCtx;
23f4fb85b1SArgyrios Kyrtzidis const NamedDecl *Parent;
24f4fb85b1SArgyrios Kyrtzidis const DeclContext *ParentDC;
25f4fb85b1SArgyrios Kyrtzidis bool IsBase;
26f4fb85b1SArgyrios Kyrtzidis SmallVector<SymbolRelation, 3> Relations;
27f4fb85b1SArgyrios Kyrtzidis
28f4fb85b1SArgyrios Kyrtzidis typedef RecursiveASTVisitor<TypeIndexer> base;
29f4fb85b1SArgyrios Kyrtzidis
30f4fb85b1SArgyrios Kyrtzidis public:
TypeIndexer(IndexingContext & indexCtx,const NamedDecl * parent,const DeclContext * DC,bool isBase,bool isIBType)31f4fb85b1SArgyrios Kyrtzidis TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
32de0f5088SArgyrios Kyrtzidis const DeclContext *DC, bool isBase, bool isIBType)
33f4fb85b1SArgyrios Kyrtzidis : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
34f4fb85b1SArgyrios Kyrtzidis if (IsBase) {
35f4fb85b1SArgyrios Kyrtzidis assert(Parent);
36f4fb85b1SArgyrios Kyrtzidis Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
37f4fb85b1SArgyrios Kyrtzidis }
38de0f5088SArgyrios Kyrtzidis if (isIBType) {
39de0f5088SArgyrios Kyrtzidis assert(Parent);
40de0f5088SArgyrios Kyrtzidis Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
41de0f5088SArgyrios Kyrtzidis }
42f4fb85b1SArgyrios Kyrtzidis }
43f4fb85b1SArgyrios Kyrtzidis
shouldWalkTypesOfTypeLocs() const44f4fb85b1SArgyrios Kyrtzidis bool shouldWalkTypesOfTypeLocs() const { return false; }
45f4fb85b1SArgyrios Kyrtzidis
46f4fb85b1SArgyrios Kyrtzidis #define TRY_TO(CALL_EXPR) \
47f4fb85b1SArgyrios Kyrtzidis do { \
48f4fb85b1SArgyrios Kyrtzidis if (!CALL_EXPR) \
49f4fb85b1SArgyrios Kyrtzidis return false; \
50f4fb85b1SArgyrios Kyrtzidis } while (0)
51f4fb85b1SArgyrios Kyrtzidis
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL)52b780517cSKadir Cetinkaya bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TTPL) {
53b780517cSKadir Cetinkaya SourceLocation Loc = TTPL.getNameLoc();
54b780517cSKadir Cetinkaya TemplateTypeParmDecl *TTPD = TTPL.getDecl();
55b780517cSKadir Cetinkaya return IndexCtx.handleReference(TTPD, Loc, Parent, ParentDC,
56b780517cSKadir Cetinkaya SymbolRoleSet());
57b780517cSKadir Cetinkaya }
58b780517cSKadir Cetinkaya
VisitTypedefTypeLoc(TypedefTypeLoc TL)59898c241bSArgyrios Kyrtzidis bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
60898c241bSArgyrios Kyrtzidis SourceLocation Loc = TL.getNameLoc();
613b25c91aSArgyrios Kyrtzidis TypedefNameDecl *ND = TL.getTypedefNameDecl();
623b25c91aSArgyrios Kyrtzidis if (ND->isTransparentTag()) {
633b25c91aSArgyrios Kyrtzidis TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl();
643b25c91aSArgyrios Kyrtzidis return IndexCtx.handleReference(Underlying, Loc, Parent,
653b25c91aSArgyrios Kyrtzidis ParentDC, SymbolRoleSet(), Relations);
663b25c91aSArgyrios Kyrtzidis }
673b25c91aSArgyrios Kyrtzidis if (IsBase) {
683b25c91aSArgyrios Kyrtzidis TRY_TO(IndexCtx.handleReference(ND, Loc,
69898c241bSArgyrios Kyrtzidis Parent, ParentDC, SymbolRoleSet()));
70898c241bSArgyrios Kyrtzidis if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
71898c241bSArgyrios Kyrtzidis TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
72898c241bSArgyrios Kyrtzidis (unsigned)SymbolRole::Implicit,
73898c241bSArgyrios Kyrtzidis Relations));
74898c241bSArgyrios Kyrtzidis }
75898c241bSArgyrios Kyrtzidis } else {
763b25c91aSArgyrios Kyrtzidis TRY_TO(IndexCtx.handleReference(ND, Loc,
77898c241bSArgyrios Kyrtzidis Parent, ParentDC, SymbolRoleSet(),
78898c241bSArgyrios Kyrtzidis Relations));
79898c241bSArgyrios Kyrtzidis }
80898c241bSArgyrios Kyrtzidis return true;
81898c241bSArgyrios Kyrtzidis }
82898c241bSArgyrios Kyrtzidis
VisitAutoTypeLoc(AutoTypeLoc TL)83*75e16fd2SIlya Biryukov bool VisitAutoTypeLoc(AutoTypeLoc TL) {
84*75e16fd2SIlya Biryukov if (auto *C = TL.getNamedConcept())
85*75e16fd2SIlya Biryukov return IndexCtx.handleReference(C, TL.getConceptNameLoc(), Parent,
86*75e16fd2SIlya Biryukov ParentDC);
87*75e16fd2SIlya Biryukov return true;
88*75e16fd2SIlya Biryukov }
89*75e16fd2SIlya Biryukov
traverseParamVarHelper(ParmVarDecl * D)90f4fb85b1SArgyrios Kyrtzidis bool traverseParamVarHelper(ParmVarDecl *D) {
91f4fb85b1SArgyrios Kyrtzidis TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
92f4fb85b1SArgyrios Kyrtzidis if (D->getTypeSourceInfo())
93f4fb85b1SArgyrios Kyrtzidis TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
94f4fb85b1SArgyrios Kyrtzidis return true;
95f4fb85b1SArgyrios Kyrtzidis }
96f4fb85b1SArgyrios Kyrtzidis
TraverseParmVarDecl(ParmVarDecl * D)97f4fb85b1SArgyrios Kyrtzidis bool TraverseParmVarDecl(ParmVarDecl *D) {
98f4fb85b1SArgyrios Kyrtzidis // Avoid visiting default arguments from the definition that were already
99f4fb85b1SArgyrios Kyrtzidis // visited in the declaration.
100f4fb85b1SArgyrios Kyrtzidis // FIXME: A free function definition can have default arguments.
101f4fb85b1SArgyrios Kyrtzidis // Avoiding double visitaiton of default arguments should be handled by the
102f4fb85b1SArgyrios Kyrtzidis // visitor probably with a bit in the AST to indicate if the attached
103f4fb85b1SArgyrios Kyrtzidis // default argument was 'inherited' or written in source.
104f4fb85b1SArgyrios Kyrtzidis if (auto FD = dyn_cast<FunctionDecl>(D->getDeclContext())) {
105f4fb85b1SArgyrios Kyrtzidis if (FD->isThisDeclarationADefinition()) {
106f4fb85b1SArgyrios Kyrtzidis return traverseParamVarHelper(D);
107f4fb85b1SArgyrios Kyrtzidis }
108f4fb85b1SArgyrios Kyrtzidis }
109f4fb85b1SArgyrios Kyrtzidis
110f4fb85b1SArgyrios Kyrtzidis return base::TraverseParmVarDecl(D);
111f4fb85b1SArgyrios Kyrtzidis }
112f4fb85b1SArgyrios Kyrtzidis
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)113f4fb85b1SArgyrios Kyrtzidis bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
114f4fb85b1SArgyrios Kyrtzidis IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
115f4fb85b1SArgyrios Kyrtzidis return true;
116f4fb85b1SArgyrios Kyrtzidis }
117f4fb85b1SArgyrios Kyrtzidis
VisitTagTypeLoc(TagTypeLoc TL)118f4fb85b1SArgyrios Kyrtzidis bool VisitTagTypeLoc(TagTypeLoc TL) {
119f4fb85b1SArgyrios Kyrtzidis TagDecl *D = TL.getDecl();
120e94c8694SHaojian Wu if (!IndexCtx.shouldIndexFunctionLocalSymbols() &&
121e94c8694SHaojian Wu D->getParentFunctionOrMethod())
122f4fb85b1SArgyrios Kyrtzidis return true;
123f4fb85b1SArgyrios Kyrtzidis
124f4fb85b1SArgyrios Kyrtzidis if (TL.isDefinition()) {
125f4fb85b1SArgyrios Kyrtzidis IndexCtx.indexTagDecl(D);
126f4fb85b1SArgyrios Kyrtzidis return true;
127f4fb85b1SArgyrios Kyrtzidis }
128f4fb85b1SArgyrios Kyrtzidis
129f4fb85b1SArgyrios Kyrtzidis return IndexCtx.handleReference(D, TL.getNameLoc(),
130f4fb85b1SArgyrios Kyrtzidis Parent, ParentDC, SymbolRoleSet(),
131f4fb85b1SArgyrios Kyrtzidis Relations);
132f4fb85b1SArgyrios Kyrtzidis }
133f4fb85b1SArgyrios Kyrtzidis
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)134f4fb85b1SArgyrios Kyrtzidis bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
135f4fb85b1SArgyrios Kyrtzidis return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
136de0f5088SArgyrios Kyrtzidis Parent, ParentDC, SymbolRoleSet(), Relations);
137f4fb85b1SArgyrios Kyrtzidis }
138f4fb85b1SArgyrios Kyrtzidis
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)139f4fb85b1SArgyrios Kyrtzidis bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
140f4fb85b1SArgyrios Kyrtzidis for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
141f4fb85b1SArgyrios Kyrtzidis IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
142de0f5088SArgyrios Kyrtzidis Parent, ParentDC, SymbolRoleSet(), Relations);
143f4fb85b1SArgyrios Kyrtzidis }
144f4fb85b1SArgyrios Kyrtzidis return true;
145f4fb85b1SArgyrios Kyrtzidis }
146f4fb85b1SArgyrios Kyrtzidis
HandleTemplateSpecializationTypeLoc(TemplateName TemplName,SourceLocation TemplNameLoc,CXXRecordDecl * ResolvedClass,bool IsTypeAlias)14734675840SIlya Biryukov void HandleTemplateSpecializationTypeLoc(TemplateName TemplName,
14834675840SIlya Biryukov SourceLocation TemplNameLoc,
14934675840SIlya Biryukov CXXRecordDecl *ResolvedClass,
15034675840SIlya Biryukov bool IsTypeAlias) {
15134675840SIlya Biryukov // In presence of type aliases, the resolved class was never written in
15234675840SIlya Biryukov // the code so don't report it.
15334675840SIlya Biryukov if (!IsTypeAlias && ResolvedClass &&
15434675840SIlya Biryukov (!ResolvedClass->isImplicit() ||
15534675840SIlya Biryukov IndexCtx.shouldIndexImplicitInstantiation())) {
15634675840SIlya Biryukov IndexCtx.handleReference(ResolvedClass, TemplNameLoc, Parent, ParentDC,
15734675840SIlya Biryukov SymbolRoleSet(), Relations);
15834675840SIlya Biryukov } else if (const TemplateDecl *D = TemplName.getAsTemplateDecl()) {
15934675840SIlya Biryukov IndexCtx.handleReference(D, TemplNameLoc, Parent, ParentDC,
160f750f7f3SFangrui Song SymbolRoleSet(), Relations);
161f750f7f3SFangrui Song }
162f4fb85b1SArgyrios Kyrtzidis }
163f4fb85b1SArgyrios Kyrtzidis
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)16447827627SArgyrios Kyrtzidis bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
16534675840SIlya Biryukov auto *T = TL.getTypePtr();
16634675840SIlya Biryukov if (!T)
16734675840SIlya Biryukov return true;
16834675840SIlya Biryukov HandleTemplateSpecializationTypeLoc(
16934675840SIlya Biryukov T->getTemplateName(), TL.getTemplateNameLoc(), T->getAsCXXRecordDecl(),
17034675840SIlya Biryukov T->isTypeAlias());
17134675840SIlya Biryukov return true;
17247827627SArgyrios Kyrtzidis }
17347827627SArgyrios Kyrtzidis
TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1747cd6b0c3SNathan Ridge bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
1757cd6b0c3SNathan Ridge if (!WalkUpFromTemplateSpecializationTypeLoc(TL))
1767cd6b0c3SNathan Ridge return false;
1777cd6b0c3SNathan Ridge if (!TraverseTemplateName(TL.getTypePtr()->getTemplateName()))
1787cd6b0c3SNathan Ridge return false;
1797cd6b0c3SNathan Ridge
1807cd6b0c3SNathan Ridge // The relations we have to `Parent` do not apply to our template arguments,
1817cd6b0c3SNathan Ridge // so clear them while visiting the args.
1827cd6b0c3SNathan Ridge SmallVector<SymbolRelation, 3> SavedRelations = Relations;
1837cd6b0c3SNathan Ridge Relations.clear();
1847cd6b0c3SNathan Ridge auto ResetSavedRelations =
1857cd6b0c3SNathan Ridge llvm::make_scope_exit([&] { this->Relations = SavedRelations; });
1867cd6b0c3SNathan Ridge for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1877cd6b0c3SNathan Ridge if (!TraverseTemplateArgumentLoc(TL.getArgLoc(I)))
1887cd6b0c3SNathan Ridge return false;
1897cd6b0c3SNathan Ridge }
1907cd6b0c3SNathan Ridge
1917cd6b0c3SNathan Ridge return true;
1927cd6b0c3SNathan Ridge }
1937cd6b0c3SNathan Ridge
VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL)19447827627SArgyrios Kyrtzidis bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) {
19534675840SIlya Biryukov auto *T = TL.getTypePtr();
19634675840SIlya Biryukov if (!T)
19734675840SIlya Biryukov return true;
19834675840SIlya Biryukov HandleTemplateSpecializationTypeLoc(
19934675840SIlya Biryukov T->getTemplateName(), TL.getTemplateNameLoc(), T->getAsCXXRecordDecl(),
20034675840SIlya Biryukov /*IsTypeAlias=*/false);
20134675840SIlya Biryukov return true;
20247827627SArgyrios Kyrtzidis }
20347827627SArgyrios Kyrtzidis
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)204a133cbaaSHaojian Wu bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
205a133cbaaSHaojian Wu return IndexCtx.handleReference(TL.getDecl(), TL.getNameLoc(), Parent,
206a133cbaaSHaojian Wu ParentDC, SymbolRoleSet(), Relations);
207a133cbaaSHaojian Wu }
208a133cbaaSHaojian Wu
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)2094e1377afSAlex Lorenz bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
2104e1377afSAlex Lorenz const DependentNameType *DNT = TL.getTypePtr();
2114e1377afSAlex Lorenz const NestedNameSpecifier *NNS = DNT->getQualifier();
2124e1377afSAlex Lorenz const Type *T = NNS->getAsType();
2134e1377afSAlex Lorenz if (!T)
2144e1377afSAlex Lorenz return true;
2154e1377afSAlex Lorenz const TemplateSpecializationType *TST =
2164e1377afSAlex Lorenz T->getAs<TemplateSpecializationType>();
2174e1377afSAlex Lorenz if (!TST)
2184e1377afSAlex Lorenz return true;
2194e1377afSAlex Lorenz TemplateName TN = TST->getTemplateName();
2204e1377afSAlex Lorenz const ClassTemplateDecl *TD =
2214e1377afSAlex Lorenz dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
2224e1377afSAlex Lorenz if (!TD)
2234e1377afSAlex Lorenz return true;
2244e1377afSAlex Lorenz CXXRecordDecl *RD = TD->getTemplatedDecl();
22509653330SAlex Lorenz if (!RD->hasDefinition())
22609653330SAlex Lorenz return true;
22709653330SAlex Lorenz RD = RD->getDefinition();
2284e1377afSAlex Lorenz DeclarationName Name(DNT->getIdentifier());
2294e1377afSAlex Lorenz std::vector<const NamedDecl *> Symbols = RD->lookupDependentName(
2304e1377afSAlex Lorenz Name, [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
2314e1377afSAlex Lorenz if (Symbols.size() != 1)
2324e1377afSAlex Lorenz return true;
2334e1377afSAlex Lorenz return IndexCtx.handleReference(Symbols[0], TL.getNameLoc(), Parent,
2344e1377afSAlex Lorenz ParentDC, SymbolRoleSet(), Relations);
2354e1377afSAlex Lorenz }
2364e1377afSAlex Lorenz
TraverseStmt(Stmt * S)237f4fb85b1SArgyrios Kyrtzidis bool TraverseStmt(Stmt *S) {
238f4fb85b1SArgyrios Kyrtzidis IndexCtx.indexBody(S, Parent, ParentDC);
239f4fb85b1SArgyrios Kyrtzidis return true;
240f4fb85b1SArgyrios Kyrtzidis }
241f4fb85b1SArgyrios Kyrtzidis };
242f4fb85b1SArgyrios Kyrtzidis
243f4fb85b1SArgyrios Kyrtzidis } // anonymous namespace
244f4fb85b1SArgyrios Kyrtzidis
indexTypeSourceInfo(TypeSourceInfo * TInfo,const NamedDecl * Parent,const DeclContext * DC,bool isBase,bool isIBType)245f4fb85b1SArgyrios Kyrtzidis void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
246f4fb85b1SArgyrios Kyrtzidis const NamedDecl *Parent,
247f4fb85b1SArgyrios Kyrtzidis const DeclContext *DC,
248de0f5088SArgyrios Kyrtzidis bool isBase,
249de0f5088SArgyrios Kyrtzidis bool isIBType) {
250f4fb85b1SArgyrios Kyrtzidis if (!TInfo || TInfo->getTypeLoc().isNull())
251f4fb85b1SArgyrios Kyrtzidis return;
252f4fb85b1SArgyrios Kyrtzidis
253de0f5088SArgyrios Kyrtzidis indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase, isIBType);
254f4fb85b1SArgyrios Kyrtzidis }
255f4fb85b1SArgyrios Kyrtzidis
indexTypeLoc(TypeLoc TL,const NamedDecl * Parent,const DeclContext * DC,bool isBase,bool isIBType)256f4fb85b1SArgyrios Kyrtzidis void IndexingContext::indexTypeLoc(TypeLoc TL,
257f4fb85b1SArgyrios Kyrtzidis const NamedDecl *Parent,
258f4fb85b1SArgyrios Kyrtzidis const DeclContext *DC,
259de0f5088SArgyrios Kyrtzidis bool isBase,
260de0f5088SArgyrios Kyrtzidis bool isIBType) {
261f4fb85b1SArgyrios Kyrtzidis if (TL.isNull())
262f4fb85b1SArgyrios Kyrtzidis return;
263f4fb85b1SArgyrios Kyrtzidis
264f4fb85b1SArgyrios Kyrtzidis if (!DC)
265f4fb85b1SArgyrios Kyrtzidis DC = Parent->getLexicalDeclContext();
266de0f5088SArgyrios Kyrtzidis TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
267f4fb85b1SArgyrios Kyrtzidis }
268f4fb85b1SArgyrios Kyrtzidis
indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,const NamedDecl * Parent,const DeclContext * DC)269f4fb85b1SArgyrios Kyrtzidis void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
270f4fb85b1SArgyrios Kyrtzidis const NamedDecl *Parent,
271f4fb85b1SArgyrios Kyrtzidis const DeclContext *DC) {
272f4fb85b1SArgyrios Kyrtzidis if (!NNS)
273f4fb85b1SArgyrios Kyrtzidis return;
274f4fb85b1SArgyrios Kyrtzidis
275f4fb85b1SArgyrios Kyrtzidis if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
276f4fb85b1SArgyrios Kyrtzidis indexNestedNameSpecifierLoc(Prefix, Parent, DC);
277f4fb85b1SArgyrios Kyrtzidis
278f4fb85b1SArgyrios Kyrtzidis if (!DC)
279f4fb85b1SArgyrios Kyrtzidis DC = Parent->getLexicalDeclContext();
28057c4f648SAlex Lorenz SourceLocation Loc = NNS.getLocalBeginLoc();
281f4fb85b1SArgyrios Kyrtzidis
282f4fb85b1SArgyrios Kyrtzidis switch (NNS.getNestedNameSpecifier()->getKind()) {
283f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::Identifier:
284f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::Global:
285f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::Super:
286f4fb85b1SArgyrios Kyrtzidis break;
287f4fb85b1SArgyrios Kyrtzidis
288f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::Namespace:
289f4fb85b1SArgyrios Kyrtzidis handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
290f4fb85b1SArgyrios Kyrtzidis Loc, Parent, DC, SymbolRoleSet());
291f4fb85b1SArgyrios Kyrtzidis break;
292f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::NamespaceAlias:
293f4fb85b1SArgyrios Kyrtzidis handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
294f4fb85b1SArgyrios Kyrtzidis Loc, Parent, DC, SymbolRoleSet());
295f4fb85b1SArgyrios Kyrtzidis break;
296f4fb85b1SArgyrios Kyrtzidis
297f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::TypeSpec:
298f4fb85b1SArgyrios Kyrtzidis case NestedNameSpecifier::TypeSpecWithTemplate:
299f4fb85b1SArgyrios Kyrtzidis indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
300f4fb85b1SArgyrios Kyrtzidis break;
301f4fb85b1SArgyrios Kyrtzidis }
302f4fb85b1SArgyrios Kyrtzidis }
303f4fb85b1SArgyrios Kyrtzidis
indexTagDecl(const TagDecl * D,ArrayRef<SymbolRelation> Relations)304f6071c34SAlex Lorenz void IndexingContext::indexTagDecl(const TagDecl *D,
305f6071c34SAlex Lorenz ArrayRef<SymbolRelation> Relations) {
3066e5ca5beSArgyrios Kyrtzidis if (!shouldIndex(D))
3076e5ca5beSArgyrios Kyrtzidis return;
3086d1a15b2SArgyrios Kyrtzidis if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
309f4fb85b1SArgyrios Kyrtzidis return;
310f4fb85b1SArgyrios Kyrtzidis
311f6071c34SAlex Lorenz if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
312f4fb85b1SArgyrios Kyrtzidis if (D->isThisDeclarationADefinition()) {
313f4fb85b1SArgyrios Kyrtzidis indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
314f4fb85b1SArgyrios Kyrtzidis if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
315f4fb85b1SArgyrios Kyrtzidis for (const auto &I : CXXRD->bases()) {
316f4fb85b1SArgyrios Kyrtzidis indexTypeSourceInfo(I.getTypeSourceInfo(), CXXRD, CXXRD, /*isBase=*/true);
317f4fb85b1SArgyrios Kyrtzidis }
318f4fb85b1SArgyrios Kyrtzidis }
319f4fb85b1SArgyrios Kyrtzidis indexDeclContext(D);
320f4fb85b1SArgyrios Kyrtzidis }
321f4fb85b1SArgyrios Kyrtzidis }
322f4fb85b1SArgyrios Kyrtzidis }
323