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   void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
46                                  const NamedDecl *Parent,
47                                  const DeclContext *DC) {
48     const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
49     switch (TALoc.getArgument().getKind()) {
50     case TemplateArgument::Expression:
51       IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
52       break;
53     case TemplateArgument::Type:
54       IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
55       break;
56     case TemplateArgument::Template:
57     case TemplateArgument::TemplateExpansion:
58       IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
59                                            Parent, DC);
60       if (const TemplateDecl *TD = TALoc.getArgument()
61                                        .getAsTemplateOrTemplatePattern()
62                                        .getAsTemplateDecl()) {
63         if (const NamedDecl *TTD = TD->getTemplatedDecl())
64           IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
65       }
66       break;
67     default:
68       break;
69     }
70   }
71 
72   /// Returns true if the given method has been defined explicitly by the
73   /// user.
74   static bool hasUserDefined(const ObjCMethodDecl *D,
75                              const ObjCImplDecl *Container) {
76     const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
77                                                     D->isInstanceMethod());
78     return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition() &&
79            !MD->isSynthesizedAccessorStub();
80   }
81 
82 
83   void handleDeclarator(const DeclaratorDecl *D,
84                         const NamedDecl *Parent = nullptr,
85                         bool isIBType = false) {
86     if (!Parent) Parent = D;
87 
88     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
89                                  Parent->getLexicalDeclContext(),
90                                  /*isBase=*/false, isIBType);
91     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
92     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
93       if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
94         auto *DC = Parm->getDeclContext();
95         if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
96           if (IndexCtx.shouldIndexParametersInDeclarations() ||
97               FD->isThisDeclarationADefinition())
98             IndexCtx.handleDecl(Parm);
99         } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
100           if (MD->isThisDeclarationADefinition())
101             IndexCtx.handleDecl(Parm);
102         } else {
103           IndexCtx.handleDecl(Parm);
104         }
105       } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
106         if (IndexCtx.shouldIndexParametersInDeclarations() ||
107             FD->isThisDeclarationADefinition()) {
108           for (auto PI : FD->parameters()) {
109             IndexCtx.handleDecl(PI);
110           }
111         }
112       }
113     } else {
114       // Index the default parameter value for function definitions.
115       if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
116         if (FD->isThisDeclarationADefinition()) {
117           for (const auto *PV : FD->parameters()) {
118             if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
119                 !PV->hasUnparsedDefaultArg())
120               IndexCtx.indexBody(PV->getDefaultArg(), D);
121           }
122         }
123       }
124     }
125   }
126 
127   bool handleObjCMethod(const ObjCMethodDecl *D,
128                         const ObjCPropertyDecl *AssociatedProp = nullptr) {
129     SmallVector<SymbolRelation, 4> Relations;
130     SmallVector<const ObjCMethodDecl*, 4> Overriden;
131 
132     D->getOverriddenMethods(Overriden);
133     for(auto overridden: Overriden) {
134       Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
135                              overridden);
136     }
137     if (AssociatedProp)
138       Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
139                              AssociatedProp);
140 
141     // getLocation() returns beginning token of a method declaration, but for
142     // indexing purposes we want to point to the base name.
143     SourceLocation MethodLoc = D->getSelectorStartLoc();
144     if (MethodLoc.isInvalid())
145       MethodLoc = D->getLocation();
146 
147     SourceLocation AttrLoc;
148 
149     // check for (getter=/setter=)
150     if (AssociatedProp) {
151       bool isGetter = !D->param_size();
152       AttrLoc = isGetter ?
153         AssociatedProp->getGetterNameLoc():
154         AssociatedProp->getSetterNameLoc();
155     }
156 
157     SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
158     if (D->isImplicit()) {
159       if (AttrLoc.isValid()) {
160         MethodLoc = AttrLoc;
161       } else {
162         Roles |= (SymbolRoleSet)SymbolRole::Implicit;
163       }
164     } else if (AttrLoc.isValid()) {
165       IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
166                                D->getDeclContext(), 0);
167     }
168 
169     TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
170     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
171     bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
172     for (const auto *I : D->parameters()) {
173       handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
174       hasIBActionAndFirst = false;
175     }
176 
177     if (D->isThisDeclarationADefinition()) {
178       const Stmt *Body = D->getBody();
179       if (Body) {
180         IndexCtx.indexBody(Body, D, D);
181       }
182     }
183     return true;
184   }
185 
186   /// Gather the declarations which the given declaration \D overrides in a
187   /// pseudo-override manner.
188   ///
189   /// Pseudo-overrides occur when a class template specialization declares
190   /// a declaration that has the same name as a similar declaration in the
191   /// non-specialized template.
192   void
193   gatherTemplatePseudoOverrides(const NamedDecl *D,
194                                 SmallVectorImpl<SymbolRelation> &Relations) {
195     if (!IndexCtx.getLangOpts().CPlusPlus)
196       return;
197     const auto *CTSD =
198         dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
199     if (!CTSD)
200       return;
201     llvm::PointerUnion<ClassTemplateDecl *,
202                        ClassTemplatePartialSpecializationDecl *>
203         Template = CTSD->getSpecializedTemplateOrPartial();
204     if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
205       const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
206       bool TypeOverride = isa<TypeDecl>(D);
207       for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
208         if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
209           ND = CTD->getTemplatedDecl();
210         if (ND->isImplicit())
211           continue;
212         // Types can override other types.
213         if (!TypeOverride) {
214           if (ND->getKind() != D->getKind())
215             continue;
216         } else if (!isa<TypeDecl>(ND))
217           continue;
218         if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
219           const auto *DFD = cast<FunctionDecl>(D);
220           // Function overrides are approximated using the number of parameters.
221           if (FD->getStorageClass() != DFD->getStorageClass() ||
222               FD->getNumParams() != DFD->getNumParams())
223             continue;
224         }
225         Relations.emplace_back(
226             SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
227       }
228     }
229   }
230 
231   bool VisitFunctionDecl(const FunctionDecl *D) {
232     SymbolRoleSet Roles{};
233     SmallVector<SymbolRelation, 4> Relations;
234     if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
235       if (CXXMD->isVirtual())
236         Roles |= (unsigned)SymbolRole::Dynamic;
237       for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
238         Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
239       }
240     }
241     gatherTemplatePseudoOverrides(D, Relations);
242     if (const auto *Base = D->getPrimaryTemplate())
243       Relations.push_back(
244           SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
245                          Base->getTemplatedDecl()));
246 
247     TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
248     handleDeclarator(D);
249 
250     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
251       IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
252                                Ctor->getParent(), Ctor->getDeclContext(),
253                                (unsigned)SymbolRole::NameReference);
254 
255       // Constructor initializers.
256       for (const auto *Init : Ctor->inits()) {
257         if (Init->isWritten()) {
258           IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
259           if (const FieldDecl *Member = Init->getAnyMember())
260             IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
261                                      (unsigned)SymbolRole::Write);
262           IndexCtx.indexBody(Init->getInit(), D, D);
263         }
264       }
265     } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
266       if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
267         IndexCtx.handleReference(Dtor->getParent(),
268                                  TypeNameInfo->getTypeLoc().getBeginLoc(),
269                                  Dtor->getParent(), Dtor->getDeclContext(),
270                                  (unsigned)SymbolRole::NameReference);
271       }
272     } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
273       IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
274                                Guide->getLocation(), Guide,
275                                Guide->getDeclContext());
276     }
277     // Template specialization arguments.
278     if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
279             D->getTemplateSpecializationArgsAsWritten()) {
280       for (const auto &Arg : TemplateArgInfo->arguments())
281         handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
282     }
283 
284     if (D->isThisDeclarationADefinition()) {
285       const Stmt *Body = D->getBody();
286       if (Body) {
287         IndexCtx.indexBody(Body, D, D);
288       }
289     }
290     return true;
291   }
292 
293   bool VisitVarDecl(const VarDecl *D) {
294     SmallVector<SymbolRelation, 4> Relations;
295     gatherTemplatePseudoOverrides(D, Relations);
296     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
297     handleDeclarator(D);
298     IndexCtx.indexBody(D->getInit(), D);
299     return true;
300   }
301 
302   bool VisitDecompositionDecl(const DecompositionDecl *D) {
303     for (const auto *Binding : D->bindings())
304       TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
305     return Base::VisitDecompositionDecl(D);
306   }
307 
308   bool VisitFieldDecl(const FieldDecl *D) {
309     SmallVector<SymbolRelation, 4> Relations;
310     gatherTemplatePseudoOverrides(D, Relations);
311     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
312     handleDeclarator(D);
313     if (D->isBitField())
314       IndexCtx.indexBody(D->getBitWidth(), D);
315     else if (D->hasInClassInitializer())
316       IndexCtx.indexBody(D->getInClassInitializer(), D);
317     return true;
318   }
319 
320   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
321     if (D->getSynthesize()) {
322       // handled in VisitObjCPropertyImplDecl
323       return true;
324     }
325     TRY_DECL(D, IndexCtx.handleDecl(D));
326     handleDeclarator(D);
327     return true;
328   }
329 
330   bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
331     TRY_DECL(D, IndexCtx.handleDecl(D));
332     handleDeclarator(D);
333     return true;
334   }
335 
336   bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
337     TRY_DECL(D, IndexCtx.handleDecl(D));
338     IndexCtx.indexBody(D->getInitExpr(), D);
339     return true;
340   }
341 
342   bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
343     if (!D->isTransparentTag()) {
344       SmallVector<SymbolRelation, 4> Relations;
345       gatherTemplatePseudoOverrides(D, Relations);
346       TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
347       IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
348     }
349     return true;
350   }
351 
352   bool VisitTagDecl(const TagDecl *D) {
353     // Non-free standing tags are handled in indexTypeSourceInfo.
354     if (D->isFreeStanding()) {
355       if (D->isThisDeclarationADefinition()) {
356         SmallVector<SymbolRelation, 4> Relations;
357         gatherTemplatePseudoOverrides(D, Relations);
358         IndexCtx.indexTagDecl(D, Relations);
359       } else {
360         SmallVector<SymbolRelation, 1> Relations;
361         gatherTemplatePseudoOverrides(D, Relations);
362         return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
363                                    Relations, D->getLexicalDeclContext());
364       }
365     }
366     return true;
367   }
368 
369   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
370                                  const ObjCContainerDecl *ContD,
371                                  SourceLocation SuperLoc) {
372     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
373     for (ObjCInterfaceDecl::protocol_iterator
374          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
375       SourceLocation Loc = *LI;
376       ObjCProtocolDecl *PD = *I;
377       SymbolRoleSet roles{};
378       if (Loc == SuperLoc)
379         roles |= (SymbolRoleSet)SymbolRole::Implicit;
380       TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
381           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
382     }
383     return true;
384   }
385 
386   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
387     if (D->isThisDeclarationADefinition()) {
388       TRY_DECL(D, IndexCtx.handleDecl(D));
389       SourceLocation SuperLoc = D->getSuperClassLoc();
390       if (auto *SuperD = D->getSuperClass()) {
391         bool hasSuperTypedef = false;
392         if (auto *TInfo = D->getSuperClassTInfo()) {
393           if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
394             if (auto *TD = TT->getDecl()) {
395               hasSuperTypedef = true;
396               TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
397                                               SymbolRoleSet()));
398             }
399           }
400         }
401         SymbolRoleSet superRoles{};
402         if (hasSuperTypedef)
403           superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
404         TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
405             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
406       }
407       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
408                                        SuperLoc));
409       TRY_TO(IndexCtx.indexDeclContext(D));
410     } else {
411       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
412                                       D->getDeclContext(), SymbolRoleSet());
413     }
414     return true;
415   }
416 
417   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
418     if (D->isThisDeclarationADefinition()) {
419       TRY_DECL(D, IndexCtx.handleDecl(D));
420       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
421                                        /*SuperLoc=*/SourceLocation()));
422       TRY_TO(IndexCtx.indexDeclContext(D));
423     } else {
424       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
425                                       D->getDeclContext(), SymbolRoleSet());
426     }
427     return true;
428   }
429 
430   bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
431     const ObjCInterfaceDecl *Class = D->getClassInterface();
432     if (!Class)
433       return true;
434 
435     if (Class->isImplicitInterfaceDecl())
436       IndexCtx.handleDecl(Class);
437 
438     TRY_DECL(D, IndexCtx.handleDecl(D));
439 
440     // Visit implicit @synthesize property implementations first as their
441     // location is reported at the name of the @implementation block. This
442     // serves no purpose other than to simplify the FileCheck-based tests.
443     for (const auto *I : D->property_impls()) {
444       if (I->getLocation().isInvalid())
445         IndexCtx.indexDecl(I);
446     }
447     for (const auto *I : D->decls()) {
448       if (!isa<ObjCPropertyImplDecl>(I) ||
449           cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
450         IndexCtx.indexDecl(I);
451     }
452 
453     return true;
454   }
455 
456   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
457     if (!IndexCtx.shouldIndex(D))
458       return true;
459     const ObjCInterfaceDecl *C = D->getClassInterface();
460     if (!C)
461       return true;
462     TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
463                                    SymbolRelation{
464                                      (unsigned)SymbolRole::RelationExtendedBy, D
465                                    }));
466     SourceLocation CategoryLoc = D->getCategoryNameLoc();
467     if (!CategoryLoc.isValid())
468       CategoryLoc = D->getLocation();
469     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
470     TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
471                                      /*SuperLoc=*/SourceLocation()));
472     TRY_TO(IndexCtx.indexDeclContext(D));
473     return true;
474   }
475 
476   bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
477     const ObjCCategoryDecl *Cat = D->getCategoryDecl();
478     if (!Cat)
479       return true;
480     const ObjCInterfaceDecl *C = D->getClassInterface();
481     if (C)
482       TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
483                                       SymbolRoleSet()));
484     SourceLocation CategoryLoc = D->getCategoryNameLoc();
485     if (!CategoryLoc.isValid())
486       CategoryLoc = D->getLocation();
487     TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
488     IndexCtx.indexDeclContext(D);
489     return true;
490   }
491 
492   bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
493     // Methods associated with a property, even user-declared ones, are
494     // handled when we handle the property.
495     if (D->isPropertyAccessor())
496       return true;
497 
498     handleObjCMethod(D);
499     return true;
500   }
501 
502   bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
503     if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
504       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
505         handleObjCMethod(MD, D);
506     if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
507       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
508         handleObjCMethod(MD, D);
509     TRY_DECL(D, IndexCtx.handleDecl(D));
510     if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
511       IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
512                                    D->getLexicalDeclContext(), false, true);
513     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
514     return true;
515   }
516 
517   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
518     ObjCPropertyDecl *PD = D->getPropertyDecl();
519     auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
520     SourceLocation Loc = D->getLocation();
521     SymbolRoleSet Roles = 0;
522     SmallVector<SymbolRelation, 1> Relations;
523 
524     if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
525       Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
526     if (Loc.isInvalid()) {
527       Loc = Container->getLocation();
528       Roles |= (SymbolRoleSet)SymbolRole::Implicit;
529     }
530     TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
531 
532     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
533       return true;
534 
535     assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
536     SymbolRoleSet AccessorMethodRoles =
537       SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
538     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
539       if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container))
540         IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
541     }
542     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
543       if (MD->isPropertyAccessor() && !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