1 //===- IndexDecl.cpp - Indexing declarations ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "IndexingContext.h"
11 #include "clang/Index/IndexDataConsumer.h"
12 #include "clang/AST/DeclVisitor.h"
14 using namespace clang;
15 using namespace index;
17 #define TRY_DECL(D,CALL_EXPR) \
19 if (!IndexCtx.shouldIndex(D)) return true; \
24 #define TRY_TO(CALL_EXPR) \
32 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
33 IndexingContext &IndexCtx;
36 explicit IndexingDeclVisitor(IndexingContext &indexCtx)
37 : IndexCtx(indexCtx) { }
41 bool VisitDecl(const Decl *D) {
46 /// \brief Returns true if the given method has been defined explicitly by the
48 static bool hasUserDefined(const ObjCMethodDecl *D,
49 const ObjCImplDecl *Container) {
50 const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
51 D->isInstanceMethod());
52 return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
55 void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
56 const NamedDecl *Parent,
57 const DeclContext *DC) {
58 const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
59 switch (TALoc.getArgument().getKind()) {
60 case TemplateArgument::Expression:
61 IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
63 case TemplateArgument::Type:
64 IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
66 case TemplateArgument::Template:
67 case TemplateArgument::TemplateExpansion:
68 IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
70 if (const TemplateDecl *TD = TALoc.getArgument()
71 .getAsTemplateOrTemplatePattern()
72 .getAsTemplateDecl()) {
73 if (const NamedDecl *TTD = TD->getTemplatedDecl())
74 IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
82 void handleDeclarator(const DeclaratorDecl *D,
83 const NamedDecl *Parent = nullptr,
84 bool isIBType = false) {
85 if (!Parent) Parent = D;
87 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
88 Parent->getLexicalDeclContext(),
89 /*isBase=*/false, isIBType);
90 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
91 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
92 // Only index parameters in definitions, parameters in declarations are
94 if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
95 auto *DC = Parm->getDeclContext();
96 if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
97 if (FD->isThisDeclarationADefinition())
98 IndexCtx.handleDecl(Parm);
99 } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
100 if (MD->isThisDeclarationADefinition())
101 IndexCtx.handleDecl(Parm);
103 IndexCtx.handleDecl(Parm);
105 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
106 if (FD->isThisDeclarationADefinition()) {
107 for (auto PI : FD->parameters()) {
108 IndexCtx.handleDecl(PI);
113 // Index the default parameter value for function definitions.
114 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
115 if (FD->isThisDeclarationADefinition()) {
116 for (const auto *PV : FD->parameters()) {
117 if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
118 !PV->hasUnparsedDefaultArg())
119 IndexCtx.indexBody(PV->getDefaultArg(), D);
126 bool handleObjCMethod(const ObjCMethodDecl *D,
127 const ObjCPropertyDecl *AssociatedProp = nullptr) {
128 SmallVector<SymbolRelation, 4> Relations;
129 SmallVector<const ObjCMethodDecl*, 4> Overriden;
131 D->getOverriddenMethods(Overriden);
132 for(auto overridden: Overriden) {
133 Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
137 Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
140 // getLocation() returns beginning token of a method declaration, but for
141 // indexing purposes we want to point to the base name.
142 SourceLocation MethodLoc = D->getSelectorStartLoc();
143 if (MethodLoc.isInvalid())
144 MethodLoc = D->getLocation();
146 SourceLocation AttrLoc;
148 // check for (getter=/setter=)
149 if (AssociatedProp) {
150 bool isGetter = !D->param_size();
152 AssociatedProp->getGetterNameLoc():
153 AssociatedProp->getSetterNameLoc();
156 SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
157 if (D->isImplicit()) {
158 if (AttrLoc.isValid()) {
161 Roles |= (SymbolRoleSet)SymbolRole::Implicit;
163 } else if (AttrLoc.isValid()) {
164 IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
165 D->getDeclContext(), 0);
168 TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
169 IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
170 bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
171 for (const auto *I : D->parameters()) {
172 handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
173 hasIBActionAndFirst = false;
176 if (D->isThisDeclarationADefinition()) {
177 const Stmt *Body = D->getBody();
179 IndexCtx.indexBody(Body, D, D);
185 /// Gather the declarations which the given declaration \D overrides in a
186 /// pseudo-override manner.
188 /// Pseudo-overrides occur when a class template specialization declares
189 /// a declaration that has the same name as a similar declaration in the
190 /// non-specialized template.
192 gatherTemplatePseudoOverrides(const NamedDecl *D,
193 SmallVectorImpl<SymbolRelation> &Relations) {
194 if (!IndexCtx.getLangOpts().CPlusPlus)
197 dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
200 llvm::PointerUnion<ClassTemplateDecl *,
201 ClassTemplatePartialSpecializationDecl *>
202 Template = CTSD->getSpecializedTemplateOrPartial();
203 if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
204 const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
205 bool TypeOverride = isa<TypeDecl>(D);
206 for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
207 if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
208 ND = CTD->getTemplatedDecl();
209 if (ND->isImplicit())
211 // Types can override other types.
213 if (ND->getKind() != D->getKind())
215 } else if (!isa<TypeDecl>(ND))
217 if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
218 const auto *DFD = cast<FunctionDecl>(D);
219 // Function overrides are approximated using the number of parameters.
220 if (FD->getStorageClass() != DFD->getStorageClass() ||
221 FD->getNumParams() != DFD->getNumParams())
224 Relations.emplace_back(
225 SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
230 bool VisitFunctionDecl(const FunctionDecl *D) {
231 SymbolRoleSet Roles{};
232 SmallVector<SymbolRelation, 4> Relations;
233 if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
234 if (CXXMD->isVirtual())
235 Roles |= (unsigned)SymbolRole::Dynamic;
236 for (auto I = CXXMD->begin_overridden_methods(),
237 E = CXXMD->end_overridden_methods(); I != E; ++I) {
238 Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
241 gatherTemplatePseudoOverrides(D, Relations);
242 if (const auto *Base = D->getPrimaryTemplate())
244 SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
245 Base->getTemplatedDecl()));
247 TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
250 if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
251 IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
252 Ctor->getParent(), Ctor->getDeclContext());
254 // Constructor initializers.
255 for (const auto *Init : Ctor->inits()) {
256 if (Init->isWritten()) {
257 IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
258 if (const FieldDecl *Member = Init->getAnyMember())
259 IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
260 (unsigned)SymbolRole::Write);
261 IndexCtx.indexBody(Init->getInit(), D, D);
264 } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
265 if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
266 IndexCtx.handleReference(Dtor->getParent(),
267 TypeNameInfo->getTypeLoc().getLocStart(),
268 Dtor->getParent(), Dtor->getDeclContext());
271 // Template specialization arguments.
272 if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
273 D->getTemplateSpecializationArgsAsWritten()) {
274 for (const auto &Arg : TemplateArgInfo->arguments())
275 handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
278 if (D->isThisDeclarationADefinition()) {
279 const Stmt *Body = D->getBody();
281 IndexCtx.indexBody(Body, D, D);
287 bool VisitVarDecl(const VarDecl *D) {
288 SmallVector<SymbolRelation, 4> Relations;
289 gatherTemplatePseudoOverrides(D, Relations);
290 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
292 IndexCtx.indexBody(D->getInit(), D);
296 bool VisitDecompositionDecl(const DecompositionDecl *D) {
297 for (const auto *Binding : D->bindings())
298 TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
299 return Base::VisitDecompositionDecl(D);
302 bool VisitFieldDecl(const FieldDecl *D) {
303 SmallVector<SymbolRelation, 4> Relations;
304 gatherTemplatePseudoOverrides(D, Relations);
305 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
308 IndexCtx.indexBody(D->getBitWidth(), D);
309 else if (D->hasInClassInitializer())
310 IndexCtx.indexBody(D->getInClassInitializer(), D);
314 bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
315 if (D->getSynthesize()) {
316 // handled in VisitObjCPropertyImplDecl
319 TRY_DECL(D, IndexCtx.handleDecl(D));
324 bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
329 bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
330 TRY_DECL(D, IndexCtx.handleDecl(D));
331 IndexCtx.indexBody(D->getInitExpr(), D);
335 bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
336 if (!D->isTransparentTag()) {
337 SmallVector<SymbolRelation, 4> Relations;
338 gatherTemplatePseudoOverrides(D, Relations);
339 TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
340 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
345 bool VisitTagDecl(const TagDecl *D) {
346 // Non-free standing tags are handled in indexTypeSourceInfo.
347 if (D->isFreeStanding()) {
348 if (D->isThisDeclarationADefinition()) {
349 SmallVector<SymbolRelation, 4> Relations;
350 gatherTemplatePseudoOverrides(D, Relations);
351 IndexCtx.indexTagDecl(D, Relations);
353 auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
354 SmallVector<SymbolRelation, 1> Relations;
355 gatherTemplatePseudoOverrides(D, Relations);
356 return IndexCtx.handleReference(D, D->getLocation(), Parent,
357 D->getLexicalDeclContext(),
358 SymbolRoleSet(), Relations);
364 bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
365 const ObjCContainerDecl *ContD,
366 SourceLocation SuperLoc) {
367 ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
368 for (ObjCInterfaceDecl::protocol_iterator
369 I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
370 SourceLocation Loc = *LI;
371 ObjCProtocolDecl *PD = *I;
372 SymbolRoleSet roles{};
374 roles |= (SymbolRoleSet)SymbolRole::Implicit;
375 TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
376 SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
381 bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
382 if (D->isThisDeclarationADefinition()) {
383 TRY_DECL(D, IndexCtx.handleDecl(D));
384 SourceLocation SuperLoc = D->getSuperClassLoc();
385 if (auto *SuperD = D->getSuperClass()) {
386 bool hasSuperTypedef = false;
387 if (auto *TInfo = D->getSuperClassTInfo()) {
388 if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
389 if (auto *TD = TT->getDecl()) {
390 hasSuperTypedef = true;
391 TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
396 SymbolRoleSet superRoles{};
398 superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
399 TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
400 SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
402 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
404 TRY_TO(IndexCtx.indexDeclContext(D));
406 return IndexCtx.handleReference(D, D->getLocation(), nullptr,
407 D->getDeclContext(), SymbolRoleSet());
412 bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
413 if (D->isThisDeclarationADefinition()) {
414 TRY_DECL(D, IndexCtx.handleDecl(D));
415 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
416 /*superLoc=*/SourceLocation()));
417 TRY_TO(IndexCtx.indexDeclContext(D));
419 return IndexCtx.handleReference(D, D->getLocation(), nullptr,
420 D->getDeclContext(), SymbolRoleSet());
425 bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
426 const ObjCInterfaceDecl *Class = D->getClassInterface();
430 if (Class->isImplicitInterfaceDecl())
431 IndexCtx.handleDecl(Class);
433 TRY_DECL(D, IndexCtx.handleDecl(D));
435 // Visit implicit @synthesize property implementations first as their
436 // location is reported at the name of the @implementation block. This
437 // serves no purpose other than to simplify the FileCheck-based tests.
438 for (const auto *I : D->property_impls()) {
439 if (I->getLocation().isInvalid())
440 IndexCtx.indexDecl(I);
442 for (const auto *I : D->decls()) {
443 if (!isa<ObjCPropertyImplDecl>(I) ||
444 cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
445 IndexCtx.indexDecl(I);
451 bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
452 if (!IndexCtx.shouldIndex(D))
454 const ObjCInterfaceDecl *C = D->getClassInterface();
457 TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
459 (unsigned)SymbolRole::RelationExtendedBy, D
461 SourceLocation CategoryLoc = D->getCategoryNameLoc();
462 if (!CategoryLoc.isValid())
463 CategoryLoc = D->getLocation();
464 TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
465 TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
466 /*superLoc=*/SourceLocation()));
467 TRY_TO(IndexCtx.indexDeclContext(D));
471 bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
472 const ObjCCategoryDecl *Cat = D->getCategoryDecl();
475 const ObjCInterfaceDecl *C = D->getClassInterface();
477 TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
479 SourceLocation CategoryLoc = D->getCategoryNameLoc();
480 if (!CategoryLoc.isValid())
481 CategoryLoc = D->getLocation();
482 TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
483 IndexCtx.indexDeclContext(D);
487 bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
488 // Methods associated with a property, even user-declared ones, are
489 // handled when we handle the property.
490 if (D->isPropertyAccessor())
497 bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
498 if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
499 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
500 handleObjCMethod(MD, D);
501 if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
502 if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
503 handleObjCMethod(MD, D);
504 TRY_DECL(D, IndexCtx.handleDecl(D));
505 if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
506 IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
507 D->getLexicalDeclContext(), false, true);
508 IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
512 bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
513 ObjCPropertyDecl *PD = D->getPropertyDecl();
514 auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
515 SourceLocation Loc = D->getLocation();
516 SymbolRoleSet Roles = 0;
517 SmallVector<SymbolRelation, 1> Relations;
519 if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
520 Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
521 if (Loc.isInvalid()) {
522 Loc = Container->getLocation();
523 Roles |= (SymbolRoleSet)SymbolRole::Implicit;
525 TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
527 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
530 assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
531 SymbolRoleSet AccessorMethodRoles =
532 SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
533 if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
534 if (MD->isPropertyAccessor() &&
535 !hasUserDefined(MD, Container))
536 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
538 if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
539 if (MD->isPropertyAccessor() &&
540 !hasUserDefined(MD, Container))
541 IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
543 if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
544 if (IvarD->getSynthesize()) {
545 // For synthesized ivars, use the location of its name in the
546 // corresponding @synthesize. If there isn't one, use the containing
547 // @implementation's location, rather than the property's location,
548 // otherwise the header file containing the @interface will have different
549 // indexing contents based on whether the @implementation was present or
550 // not in the translation unit.
551 SymbolRoleSet IvarRoles = 0;
552 SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
553 if (D->getLocation().isInvalid()) {
554 IvarLoc = Container->getLocation();
555 IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
556 } else if (D->getLocation() == IvarLoc) {
557 IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
559 TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
561 IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
562 D->getDeclContext(), SymbolRoleSet());
568 bool VisitNamespaceDecl(const NamespaceDecl *D) {
569 TRY_DECL(D, IndexCtx.handleDecl(D));
570 IndexCtx.indexDeclContext(D);
574 bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
575 TRY_DECL(D, IndexCtx.handleDecl(D));
576 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
577 IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
578 D->getLexicalDeclContext());
582 bool VisitUsingDecl(const UsingDecl *D) {
583 const DeclContext *DC = D->getDeclContext()->getRedeclContext();
584 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
586 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
587 D->getLexicalDeclContext());
588 for (const auto *I : D->shadows())
589 IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
590 D->getLexicalDeclContext(), SymbolRoleSet());
594 bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
595 const DeclContext *DC = D->getDeclContext()->getRedeclContext();
596 const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
598 // NNS for the local 'using namespace' directives is visited by the body
600 if (!D->getParentFunctionOrMethod())
601 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
602 D->getLexicalDeclContext());
604 return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
605 D->getLocation(), Parent,
606 D->getLexicalDeclContext(),
610 bool VisitClassTemplateSpecializationDecl(const
611 ClassTemplateSpecializationDecl *D) {
612 // FIXME: Notify subsequent callbacks if info comes from implicit
614 llvm::PointerUnion<ClassTemplateDecl *,
615 ClassTemplatePartialSpecializationDecl *>
616 Template = D->getSpecializedTemplateOrPartial();
617 const Decl *SpecializationOf =
618 Template.is<ClassTemplateDecl *>()
619 ? (Decl *)Template.get<ClassTemplateDecl *>()
620 : Template.get<ClassTemplatePartialSpecializationDecl *>();
621 if (!D->isThisDeclarationADefinition())
622 IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
623 IndexCtx.indexTagDecl(
624 D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
626 if (TypeSourceInfo *TSI = D->getTypeAsWritten())
627 IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
628 D->getLexicalDeclContext());
632 static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
635 // We want to index the template parameters only once when indexing the
636 // canonical declaration.
637 if (const auto *FD = dyn_cast<FunctionDecl>(D))
638 return FD->getCanonicalDecl() == FD;
639 else if (const auto *TD = dyn_cast<TagDecl>(D))
640 return TD->getCanonicalDecl() == TD;
641 else if (const auto *VD = dyn_cast<VarDecl>(D))
642 return VD->getCanonicalDecl() == VD;
646 bool VisitTemplateDecl(const TemplateDecl *D) {
647 // FIXME: Template parameters.
649 // Index the default values for the template parameters.
650 const NamedDecl *Parent = D->getTemplatedDecl();
651 if (D->getTemplateParameters() &&
652 shouldIndexTemplateParameterDefaultValue(Parent)) {
653 const TemplateParameterList *Params = D->getTemplateParameters();
654 for (const NamedDecl *TP : *Params) {
655 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
656 if (TTP->hasDefaultArgument())
657 IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
658 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
659 if (NTTP->hasDefaultArgument())
660 IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
661 } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
662 if (TTPD->hasDefaultArgument())
663 handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
669 return Visit(D->getTemplatedDecl());
672 bool VisitFriendDecl(const FriendDecl *D) {
673 if (auto ND = D->getFriendDecl()) {
674 // FIXME: Ignore a class template in a dependent context, these are not
675 // linked properly with their redeclarations, ending up with duplicate
677 // See comment "Friend templates are visible in fairly strange ways." in
678 // SemaTemplate.cpp which precedes code that prevents the friend template
679 // from becoming visible from the enclosing context.
680 if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
684 if (auto Ty = D->getFriendType()) {
685 IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
690 bool VisitImportDecl(const ImportDecl *D) {
691 return IndexCtx.importedModule(D);
694 bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
695 IndexCtx.indexBody(D->getAssertExpr(),
696 dyn_cast<NamedDecl>(D->getDeclContext()),
697 D->getLexicalDeclContext());
702 } // anonymous namespace
704 bool IndexingContext::indexDecl(const Decl *D) {
705 if (D->isImplicit() && shouldIgnoreIfImplicit(D))
708 if (isTemplateImplicitInstantiation(D))
711 IndexingDeclVisitor Visitor(*this);
712 bool ShouldContinue = Visitor.Visit(D);
716 if (!Visitor.Handled && isa<DeclContext>(D))
717 return indexDeclContext(cast<DeclContext>(D));
722 bool IndexingContext::indexDeclContext(const DeclContext *DC) {
723 for (const auto *I : DC->decls())
729 bool IndexingContext::indexTopLevelDecl(const Decl *D) {
730 if (D->getLocation().isInvalid())
733 if (isa<ObjCMethodDecl>(D))
734 return true; // Wait for the objc container.
739 bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
740 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
741 if (!indexTopLevelDecl(*I))