xref: /llvm-project/clang/lib/Index/IndexTypeSourceInfo.cpp (revision 75e16fd2c656fb7d27e6edc46dc1a63ff8323999)
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