xref: /freebsd/contrib/llvm-project/clang/lib/Index/IndexDecl.cpp (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1 //===- IndexDecl.cpp - Indexing declarations ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "IndexingContext.h"
10 #include "clang/AST/Attr.h"
11 #include "clang/AST/Decl.h"
12 #include "clang/AST/DeclVisitor.h"
13 #include "clang/Index/IndexDataConsumer.h"
14 
15 using namespace clang;
16 using namespace index;
17 
18 #define TRY_DECL(D,CALL_EXPR)                                                  \
19   do {                                                                         \
20     if (!IndexCtx.shouldIndex(D)) return true;                                 \
21     if (!CALL_EXPR)                                                            \
22       return false;                                                            \
23   } while (0)
24 
25 #define TRY_TO(CALL_EXPR)                                                      \
26   do {                                                                         \
27     if (!CALL_EXPR)                                                            \
28       return false;                                                            \
29   } while (0)
30 
31 namespace {
32 
33 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
34   IndexingContext &IndexCtx;
35 
36 public:
37   explicit IndexingDeclVisitor(IndexingContext &indexCtx)
38     : IndexCtx(indexCtx) { }
39 
40   bool Handled = true;
41 
42   bool VisitDecl(const Decl *D) {
43     Handled = false;
44     return true;
45   }
46 
47   void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
48                                  const NamedDecl *Parent,
49                                  const DeclContext *DC) {
50     const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
51     switch (TALoc.getArgument().getKind()) {
52     case TemplateArgument::Expression:
53       IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
54       break;
55     case TemplateArgument::Type:
56       IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
57       break;
58     case TemplateArgument::Template:
59     case TemplateArgument::TemplateExpansion:
60       IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
61                                            Parent, DC);
62       if (const TemplateDecl *TD = TALoc.getArgument()
63                                        .getAsTemplateOrTemplatePattern()
64                                        .getAsTemplateDecl()) {
65         if (const NamedDecl *TTD = TD->getTemplatedDecl())
66           IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
67       }
68       break;
69     default:
70       break;
71     }
72   }
73 
74   /// Returns true if the given method has been defined explicitly by the
75   /// user.
76   static bool hasUserDefined(const ObjCMethodDecl *D,
77                              const ObjCImplDecl *Container) {
78     const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
79                                                     D->isInstanceMethod());
80     return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition() &&
81            !MD->isSynthesizedAccessorStub();
82   }
83 
84 
85   void handleDeclarator(const DeclaratorDecl *D,
86                         const NamedDecl *Parent = nullptr,
87                         bool isIBType = false) {
88     if (!Parent) Parent = D;
89 
90     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
91                                  Parent->getLexicalDeclContext(),
92                                  /*isBase=*/false, isIBType);
93     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
94     auto IndexDefaultParmeterArgument = [&](const ParmVarDecl *Parm,
95                                             const NamedDecl *Parent) {
96       if (Parm->hasDefaultArg() && !Parm->hasUninstantiatedDefaultArg() &&
97           !Parm->hasUnparsedDefaultArg())
98         IndexCtx.indexBody(Parm->getDefaultArg(), Parent);
99     };
100     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
101       if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
102         auto *DC = Parm->getDeclContext();
103         if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
104           if (IndexCtx.shouldIndexParametersInDeclarations() ||
105               FD->isThisDeclarationADefinition())
106             IndexCtx.handleDecl(Parm);
107         } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
108           if (MD->isThisDeclarationADefinition())
109             IndexCtx.handleDecl(Parm);
110         } else {
111           IndexCtx.handleDecl(Parm);
112         }
113       } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
114         if (IndexCtx.shouldIndexParametersInDeclarations() ||
115             FD->isThisDeclarationADefinition()) {
116           for (const auto *PI : FD->parameters()) {
117             IndexDefaultParmeterArgument(PI, D);
118             IndexCtx.handleDecl(PI);
119           }
120         }
121       }
122     } else {
123       // Index the default parameter value for function definitions.
124       if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
125         if (FD->isThisDeclarationADefinition()) {
126           for (const auto *PV : FD->parameters()) {
127             IndexDefaultParmeterArgument(PV, D);
128           }
129         }
130       }
131     }
132   }
133 
134   bool handleObjCMethod(const ObjCMethodDecl *D,
135                         const ObjCPropertyDecl *AssociatedProp = nullptr) {
136     SmallVector<SymbolRelation, 4> Relations;
137     SmallVector<const ObjCMethodDecl*, 4> Overriden;
138 
139     D->getOverriddenMethods(Overriden);
140     for(auto overridden: Overriden) {
141       Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
142                              overridden);
143     }
144     if (AssociatedProp)
145       Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
146                              AssociatedProp);
147 
148     // getLocation() returns beginning token of a method declaration, but for
149     // indexing purposes we want to point to the base name.
150     SourceLocation MethodLoc = D->getSelectorStartLoc();
151     if (MethodLoc.isInvalid())
152       MethodLoc = D->getLocation();
153 
154     SourceLocation AttrLoc;
155 
156     // check for (getter=/setter=)
157     if (AssociatedProp) {
158       bool isGetter = !D->param_size();
159       AttrLoc = isGetter ?
160         AssociatedProp->getGetterNameLoc():
161         AssociatedProp->getSetterNameLoc();
162     }
163 
164     SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
165     if (D->isImplicit()) {
166       if (AttrLoc.isValid()) {
167         MethodLoc = AttrLoc;
168       } else {
169         Roles |= (SymbolRoleSet)SymbolRole::Implicit;
170       }
171     } else if (AttrLoc.isValid()) {
172       IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
173                                D->getDeclContext(), 0);
174     }
175 
176     TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
177     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
178     bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
179     for (const auto *I : D->parameters()) {
180       handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
181       hasIBActionAndFirst = false;
182     }
183 
184     if (D->isThisDeclarationADefinition()) {
185       const Stmt *Body = D->getBody();
186       if (Body) {
187         IndexCtx.indexBody(Body, D, D);
188       }
189     }
190     return true;
191   }
192 
193   /// Gather the declarations which the given declaration \D overrides in a
194   /// pseudo-override manner.
195   ///
196   /// Pseudo-overrides occur when a class template specialization declares
197   /// a declaration that has the same name as a similar declaration in the
198   /// non-specialized template.
199   void
200   gatherTemplatePseudoOverrides(const NamedDecl *D,
201                                 SmallVectorImpl<SymbolRelation> &Relations) {
202     if (!IndexCtx.getLangOpts().CPlusPlus)
203       return;
204     const auto *CTSD =
205         dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
206     if (!CTSD)
207       return;
208     llvm::PointerUnion<ClassTemplateDecl *,
209                        ClassTemplatePartialSpecializationDecl *>
210         Template = CTSD->getSpecializedTemplateOrPartial();
211     if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
212       const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
213       bool TypeOverride = isa<TypeDecl>(D);
214       for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
215         if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
216           ND = CTD->getTemplatedDecl();
217         if (ND->isImplicit())
218           continue;
219         // Types can override other types.
220         if (!TypeOverride) {
221           if (ND->getKind() != D->getKind())
222             continue;
223         } else if (!isa<TypeDecl>(ND))
224           continue;
225         if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
226           const auto *DFD = cast<FunctionDecl>(D);
227           // Function overrides are approximated using the number of parameters.
228           if (FD->getStorageClass() != DFD->getStorageClass() ||
229               FD->getNumParams() != DFD->getNumParams())
230             continue;
231         }
232         Relations.emplace_back(
233             SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
234       }
235     }
236   }
237 
238   bool VisitFunctionDecl(const FunctionDecl *D) {
239     SymbolRoleSet Roles{};
240     SmallVector<SymbolRelation, 4> Relations;
241     if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
242       if (CXXMD->isVirtual())
243         Roles |= (unsigned)SymbolRole::Dynamic;
244       for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
245         Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
246       }
247     }
248     gatherTemplatePseudoOverrides(D, Relations);
249     if (const auto *Base = D->getPrimaryTemplate())
250       Relations.push_back(
251           SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
252                          Base->getTemplatedDecl()));
253 
254     TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
255     handleDeclarator(D);
256 
257     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
258       IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
259                                Ctor->getParent(), Ctor->getDeclContext(),
260                                (unsigned)SymbolRole::NameReference);
261 
262       // Constructor initializers.
263       for (const auto *Init : Ctor->inits()) {
264         if (Init->isWritten()) {
265           IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
266           if (const FieldDecl *Member = Init->getAnyMember())
267             IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
268                                      (unsigned)SymbolRole::Write);
269           IndexCtx.indexBody(Init->getInit(), D, D);
270         }
271       }
272     } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
273       if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
274         IndexCtx.handleReference(Dtor->getParent(),
275                                  TypeNameInfo->getTypeLoc().getBeginLoc(),
276                                  Dtor->getParent(), Dtor->getDeclContext(),
277                                  (unsigned)SymbolRole::NameReference);
278       }
279     } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
280       IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
281                                Guide->getLocation(), Guide,
282                                Guide->getDeclContext());
283     }
284     // Template specialization arguments.
285     if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
286             D->getTemplateSpecializationArgsAsWritten()) {
287       for (const auto &Arg : TemplateArgInfo->arguments())
288         handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
289     }
290 
291     if (D->isThisDeclarationADefinition()) {
292       const Stmt *Body = D->getBody();
293       if (Body) {
294         IndexCtx.indexBody(Body, D, D);
295       }
296     }
297     return true;
298   }
299 
300   bool VisitVarDecl(const VarDecl *D) {
301     SmallVector<SymbolRelation, 4> Relations;
302     gatherTemplatePseudoOverrides(D, Relations);
303     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
304     handleDeclarator(D);
305     IndexCtx.indexBody(D->getInit(), D);
306     return true;
307   }
308 
309   bool VisitDecompositionDecl(const DecompositionDecl *D) {
310     for (const auto *Binding : D->bindings())
311       TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
312     return Base::VisitDecompositionDecl(D);
313   }
314 
315   bool VisitFieldDecl(const FieldDecl *D) {
316     SmallVector<SymbolRelation, 4> Relations;
317     gatherTemplatePseudoOverrides(D, Relations);
318     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
319     handleDeclarator(D);
320     if (D->isBitField())
321       IndexCtx.indexBody(D->getBitWidth(), D);
322     else if (D->hasInClassInitializer())
323       IndexCtx.indexBody(D->getInClassInitializer(), D);
324     return true;
325   }
326 
327   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
328     if (D->getSynthesize()) {
329       // handled in VisitObjCPropertyImplDecl
330       return true;
331     }
332     TRY_DECL(D, IndexCtx.handleDecl(D));
333     handleDeclarator(D);
334     return true;
335   }
336 
337   bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
338     TRY_DECL(D, IndexCtx.handleDecl(D));
339     handleDeclarator(D);
340     return true;
341   }
342 
343   bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
344     TRY_DECL(D, IndexCtx.handleDecl(D));
345     IndexCtx.indexBody(D->getInitExpr(), D);
346     return true;
347   }
348 
349   bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
350     if (!D->isTransparentTag()) {
351       SmallVector<SymbolRelation, 4> Relations;
352       gatherTemplatePseudoOverrides(D, Relations);
353       TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
354       IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
355     }
356     return true;
357   }
358 
359   bool VisitTagDecl(const TagDecl *D) {
360     // Non-free standing tags are handled in indexTypeSourceInfo.
361     if (D->isFreeStanding()) {
362       if (D->isThisDeclarationADefinition()) {
363         SmallVector<SymbolRelation, 4> Relations;
364         gatherTemplatePseudoOverrides(D, Relations);
365         IndexCtx.indexTagDecl(D, Relations);
366       } else {
367         SmallVector<SymbolRelation, 1> Relations;
368         gatherTemplatePseudoOverrides(D, Relations);
369         return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
370                                    Relations, D->getLexicalDeclContext());
371       }
372     }
373     return true;
374   }
375 
376   bool VisitEnumDecl(const EnumDecl *ED) {
377     TRY_TO(VisitTagDecl(ED));
378     // Indexing for enumdecl itself is handled inside TagDecl, we just want to
379     // visit integer-base here, which is different than other TagDecl bases.
380     if (auto *TSI = ED->getIntegerTypeSourceInfo())
381       IndexCtx.indexTypeSourceInfo(TSI, ED, ED, /*isBase=*/true);
382     return true;
383   }
384 
385   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
386                                  const ObjCContainerDecl *ContD,
387                                  SourceLocation SuperLoc) {
388     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
389     for (ObjCInterfaceDecl::protocol_iterator
390          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
391       SourceLocation Loc = *LI;
392       ObjCProtocolDecl *PD = *I;
393       SymbolRoleSet roles{};
394       if (Loc == SuperLoc)
395         roles |= (SymbolRoleSet)SymbolRole::Implicit;
396       TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
397           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
398     }
399     return true;
400   }
401 
402   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
403     if (D->isThisDeclarationADefinition()) {
404       TRY_DECL(D, IndexCtx.handleDecl(D));
405       SourceLocation SuperLoc = D->getSuperClassLoc();
406       if (auto *SuperD = D->getSuperClass()) {
407         bool hasSuperTypedef = false;
408         if (auto *TInfo = D->getSuperClassTInfo()) {
409           if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
410             if (auto *TD = TT->getDecl()) {
411               hasSuperTypedef = true;
412               TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
413                                               SymbolRoleSet()));
414             }
415           }
416         }
417         SymbolRoleSet superRoles{};
418         if (hasSuperTypedef)
419           superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
420         TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
421             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
422       }
423       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
424                                        SuperLoc));
425       TRY_TO(IndexCtx.indexDeclContext(D));
426     } else {
427       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
428                                       D->getDeclContext(), SymbolRoleSet());
429     }
430     return true;
431   }
432 
433   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
434     if (D->isThisDeclarationADefinition()) {
435       TRY_DECL(D, IndexCtx.handleDecl(D));
436       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
437                                        /*SuperLoc=*/SourceLocation()));
438       TRY_TO(IndexCtx.indexDeclContext(D));
439     } else {
440       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
441                                       D->getDeclContext(), SymbolRoleSet());
442     }
443     return true;
444   }
445 
446   bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
447     const ObjCInterfaceDecl *Class = D->getClassInterface();
448     if (!Class)
449       return true;
450 
451     if (Class->isImplicitInterfaceDecl())
452       IndexCtx.handleDecl(Class);
453 
454     TRY_DECL(D, IndexCtx.handleDecl(D));
455 
456     // Visit implicit @synthesize property implementations first as their
457     // location is reported at the name of the @implementation block. This
458     // serves no purpose other than to simplify the FileCheck-based tests.
459     for (const auto *I : D->property_impls()) {
460       if (I->getLocation().isInvalid())
461         IndexCtx.indexDecl(I);
462     }
463     for (const auto *I : D->decls()) {
464       if (!isa<ObjCPropertyImplDecl>(I) ||
465           cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
466         IndexCtx.indexDecl(I);
467     }
468 
469     return true;
470   }
471 
472   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
473     if (!IndexCtx.shouldIndex(D))
474       return true;
475     const ObjCInterfaceDecl *C = D->getClassInterface();
476     if (!C)
477       return true;
478     TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
479                                    SymbolRelation{
480                                      (unsigned)SymbolRole::RelationExtendedBy, D
481                                    }));
482     SourceLocation CategoryLoc = D->getCategoryNameLoc();
483     if (!CategoryLoc.isValid())
484       CategoryLoc = D->getLocation();
485     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
486     TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
487                                      /*SuperLoc=*/SourceLocation()));
488     TRY_TO(IndexCtx.indexDeclContext(D));
489     return true;
490   }
491 
492   bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
493     const ObjCCategoryDecl *Cat = D->getCategoryDecl();
494     if (!Cat)
495       return true;
496     const ObjCInterfaceDecl *C = D->getClassInterface();
497     if (C)
498       TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
499                                       SymbolRoleSet()));
500     SourceLocation CategoryLoc = D->getCategoryNameLoc();
501     if (!CategoryLoc.isValid())
502       CategoryLoc = D->getLocation();
503     TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
504     IndexCtx.indexDeclContext(D);
505     return true;
506   }
507 
508   bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
509     // Methods associated with a property, even user-declared ones, are
510     // handled when we handle the property.
511     if (D->isPropertyAccessor())
512       return true;
513 
514     handleObjCMethod(D);
515     return true;
516   }
517 
518   bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
519     if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
520       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
521         handleObjCMethod(MD, D);
522     if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
523       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
524         handleObjCMethod(MD, D);
525     TRY_DECL(D, IndexCtx.handleDecl(D));
526     if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
527       IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
528                                    D->getLexicalDeclContext(), false, true);
529     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
530     return true;
531   }
532 
533   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
534     ObjCPropertyDecl *PD = D->getPropertyDecl();
535     auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
536     SourceLocation Loc = D->getLocation();
537     SymbolRoleSet Roles = 0;
538     SmallVector<SymbolRelation, 1> Relations;
539 
540     if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
541       Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
542     if (Loc.isInvalid()) {
543       Loc = Container->getLocation();
544       Roles |= (SymbolRoleSet)SymbolRole::Implicit;
545     }
546     TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
547 
548     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
549       return true;
550 
551     assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
552     SymbolRoleSet AccessorMethodRoles =
553       SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
554     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
555       if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container))
556         IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
557     }
558     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
559       if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container))
560         IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
561     }
562     if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
563       if (IvarD->getSynthesize()) {
564         // For synthesized ivars, use the location of its name in the
565         // corresponding @synthesize. If there isn't one, use the containing
566         // @implementation's location, rather than the property's location,
567         // otherwise the header file containing the @interface will have different
568         // indexing contents based on whether the @implementation was present or
569         // not in the translation unit.
570         SymbolRoleSet IvarRoles = 0;
571         SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
572         if (D->getLocation().isInvalid()) {
573           IvarLoc = Container->getLocation();
574           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
575         } else if (D->getLocation() == IvarLoc) {
576           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
577         }
578         TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
579       } else {
580         IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
581                                  D->getDeclContext(), SymbolRoleSet());
582       }
583     }
584     return true;
585   }
586 
587   bool VisitNamespaceDecl(const NamespaceDecl *D) {
588     TRY_DECL(D, IndexCtx.handleDecl(D));
589     IndexCtx.indexDeclContext(D);
590     return true;
591   }
592 
593   bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
594     TRY_DECL(D, IndexCtx.handleDecl(D));
595     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
596     IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
597                              D->getLexicalDeclContext());
598     return true;
599   }
600 
601   bool VisitUsingDecl(const UsingDecl *D) {
602     IndexCtx.handleDecl(D);
603 
604     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
605     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
606     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
607                                          D->getLexicalDeclContext());
608     for (const auto *I : D->shadows())
609       IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
610                                D->getLexicalDeclContext(), SymbolRoleSet());
611     return true;
612   }
613 
614   bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
615     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
616     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
617 
618     // NNS for the local 'using namespace' directives is visited by the body
619     // visitor.
620     if (!D->getParentFunctionOrMethod())
621       IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
622                                            D->getLexicalDeclContext());
623 
624     return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
625                                     D->getLocation(), Parent,
626                                     D->getLexicalDeclContext(),
627                                     SymbolRoleSet());
628   }
629 
630   bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
631     TRY_DECL(D, IndexCtx.handleDecl(D));
632     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
633     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
634     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
635                                          D->getLexicalDeclContext());
636     return true;
637   }
638 
639   bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
640     TRY_DECL(D, IndexCtx.handleDecl(D));
641     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
642     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
643     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
644                                          D->getLexicalDeclContext());
645     return true;
646   }
647 
648   bool VisitClassTemplateSpecializationDecl(const
649                                            ClassTemplateSpecializationDecl *D) {
650     // FIXME: Notify subsequent callbacks if info comes from implicit
651     // instantiation.
652     llvm::PointerUnion<ClassTemplateDecl *,
653                        ClassTemplatePartialSpecializationDecl *>
654         Template = D->getSpecializedTemplateOrPartial();
655     const Decl *SpecializationOf =
656         Template.is<ClassTemplateDecl *>()
657             ? (Decl *)Template.get<ClassTemplateDecl *>()
658             : Template.get<ClassTemplatePartialSpecializationDecl *>();
659     if (!D->isThisDeclarationADefinition())
660       IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
661     IndexCtx.indexTagDecl(
662         D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
663                           SpecializationOf));
664     if (TypeSourceInfo *TSI = D->getTypeAsWritten())
665       IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
666                                    D->getLexicalDeclContext());
667     return true;
668   }
669 
670   static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
671     // We want to index the template parameters only once when indexing the
672     // canonical declaration.
673     if (!D)
674       return false;
675     if (const auto *FD = dyn_cast<FunctionDecl>(D))
676       return FD->getCanonicalDecl() == FD;
677     else if (const auto *TD = dyn_cast<TagDecl>(D))
678       return TD->getCanonicalDecl() == TD;
679     else if (const auto *VD = dyn_cast<VarDecl>(D))
680       return VD->getCanonicalDecl() == VD;
681     return true;
682   }
683 
684   bool VisitTemplateDecl(const TemplateDecl *D) {
685 
686     const NamedDecl *Parent = D->getTemplatedDecl();
687     if (!Parent)
688       return true;
689 
690     // Index the default values for the template parameters.
691     if (D->getTemplateParameters() &&
692         shouldIndexTemplateParameterDefaultValue(Parent)) {
693       const TemplateParameterList *Params = D->getTemplateParameters();
694       for (const NamedDecl *TP : *Params) {
695         if (IndexCtx.shouldIndexTemplateParameters())
696           IndexCtx.handleDecl(TP);
697         if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
698           if (TTP->hasDefaultArgument())
699             IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
700         } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
701           if (NTTP->hasDefaultArgument())
702             IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
703         } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
704           if (TTPD->hasDefaultArgument())
705             handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
706                                       TP->getLexicalDeclContext());
707         }
708       }
709     }
710 
711     return Visit(Parent);
712   }
713 
714   bool VisitFriendDecl(const FriendDecl *D) {
715     if (auto ND = D->getFriendDecl()) {
716       // FIXME: Ignore a class template in a dependent context, these are not
717       // linked properly with their redeclarations, ending up with duplicate
718       // USRs.
719       // See comment "Friend templates are visible in fairly strange ways." in
720       // SemaTemplate.cpp which precedes code that prevents the friend template
721       // from becoming visible from the enclosing context.
722       if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
723         return true;
724       return Visit(ND);
725     }
726     if (auto Ty = D->getFriendType()) {
727       IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
728     }
729     return true;
730   }
731 
732   bool VisitImportDecl(const ImportDecl *D) {
733     return IndexCtx.importedModule(D);
734   }
735 
736   bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
737     IndexCtx.indexBody(D->getAssertExpr(),
738                        dyn_cast<NamedDecl>(D->getDeclContext()),
739                        D->getLexicalDeclContext());
740     return true;
741   }
742 };
743 
744 } // anonymous namespace
745 
746 bool IndexingContext::indexDecl(const Decl *D) {
747   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
748     return true;
749 
750   if (isTemplateImplicitInstantiation(D) && !shouldIndexImplicitInstantiation())
751     return true;
752 
753   IndexingDeclVisitor Visitor(*this);
754   bool ShouldContinue = Visitor.Visit(D);
755   if (!ShouldContinue)
756     return false;
757 
758   if (!Visitor.Handled && isa<DeclContext>(D))
759     return indexDeclContext(cast<DeclContext>(D));
760 
761   return true;
762 }
763 
764 bool IndexingContext::indexDeclContext(const DeclContext *DC) {
765   for (const auto *I : DC->decls())
766     if (!indexDecl(I))
767       return false;
768   return true;
769 }
770 
771 bool IndexingContext::indexTopLevelDecl(const Decl *D) {
772   if (!D || D->getLocation().isInvalid())
773     return true;
774 
775   if (isa<ObjCMethodDecl>(D))
776     return true; // Wait for the objc container.
777 
778   if (IndexOpts.ShouldTraverseDecl && !IndexOpts.ShouldTraverseDecl(D))
779     return true; // skip
780 
781   return indexDecl(D);
782 }
783 
784 bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
785   for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
786     if (!indexTopLevelDecl(*I))
787       return false;
788   return true;
789 }
790