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