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