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     default:
67       break;
68     }
69   }
70 
71   void handleDeclarator(const DeclaratorDecl *D,
72                         const NamedDecl *Parent = nullptr,
73                         bool isIBType = false) {
74     if (!Parent) Parent = D;
75 
76     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
77                                  Parent->getLexicalDeclContext(),
78                                  /*isBase=*/false, isIBType);
79     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
80     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
81       // Only index parameters in definitions, parameters in declarations are
82       // not useful.
83       if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
84         auto *DC = Parm->getDeclContext();
85         if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
86           if (FD->isThisDeclarationADefinition())
87             IndexCtx.handleDecl(Parm);
88         } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
89           if (MD->isThisDeclarationADefinition())
90             IndexCtx.handleDecl(Parm);
91         } else {
92           IndexCtx.handleDecl(Parm);
93         }
94       } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95         if (FD->isThisDeclarationADefinition()) {
96           for (auto PI : FD->parameters()) {
97             IndexCtx.handleDecl(PI);
98           }
99         }
100       }
101     }
102   }
103 
104   bool handleObjCMethod(const ObjCMethodDecl *D,
105                         const ObjCPropertyDecl *AssociatedProp = nullptr) {
106     SmallVector<SymbolRelation, 4> Relations;
107     SmallVector<const ObjCMethodDecl*, 4> Overriden;
108 
109     D->getOverriddenMethods(Overriden);
110     for(auto overridden: Overriden) {
111       Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
112                              overridden);
113     }
114     if (AssociatedProp)
115       Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
116                              AssociatedProp);
117 
118     // getLocation() returns beginning token of a method declaration, but for
119     // indexing purposes we want to point to the base name.
120     SourceLocation MethodLoc = D->getSelectorStartLoc();
121     if (MethodLoc.isInvalid())
122       MethodLoc = D->getLocation();
123 
124     SourceLocation AttrLoc;
125 
126     // check for (getter=/setter=)
127     if (AssociatedProp) {
128       bool isGetter = !D->param_size();
129       AttrLoc = isGetter ?
130         AssociatedProp->getGetterNameLoc():
131         AssociatedProp->getSetterNameLoc();
132     }
133 
134     SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
135     if (D->isImplicit()) {
136       if (AttrLoc.isValid()) {
137         MethodLoc = AttrLoc;
138       } else {
139         Roles |= (SymbolRoleSet)SymbolRole::Implicit;
140       }
141     } else if (AttrLoc.isValid()) {
142       IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
143                                D->getDeclContext(), 0);
144     }
145 
146     TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
147     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
148     bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
149     for (const auto *I : D->parameters()) {
150       handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
151       hasIBActionAndFirst = false;
152     }
153 
154     if (D->isThisDeclarationADefinition()) {
155       const Stmt *Body = D->getBody();
156       if (Body) {
157         IndexCtx.indexBody(Body, D, D);
158       }
159     }
160     return true;
161   }
162 
163   /// Gather the declarations which the given declaration \D overrides in a
164   /// pseudo-override manner.
165   ///
166   /// Pseudo-overrides occur when a class template specialization declares
167   /// a declaration that has the same name as a similar declaration in the
168   /// non-specialized template.
169   void
170   gatherTemplatePseudoOverrides(const NamedDecl *D,
171                                 SmallVectorImpl<SymbolRelation> &Relations) {
172     if (!IndexCtx.getLangOpts().CPlusPlus)
173       return;
174     const auto *CTSD =
175         dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
176     if (!CTSD)
177       return;
178     llvm::PointerUnion<ClassTemplateDecl *,
179                        ClassTemplatePartialSpecializationDecl *>
180         Template = CTSD->getSpecializedTemplateOrPartial();
181     if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
182       const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
183       bool TypeOverride = isa<TypeDecl>(D);
184       for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
185         if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
186           ND = CTD->getTemplatedDecl();
187         if (ND->isImplicit())
188           continue;
189         // Types can override other types.
190         if (!TypeOverride) {
191           if (ND->getKind() != D->getKind())
192             continue;
193         } else if (!isa<TypeDecl>(ND))
194           continue;
195         if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
196           const auto *DFD = cast<FunctionDecl>(D);
197           // Function overrides are approximated using the number of parameters.
198           if (FD->getStorageClass() != DFD->getStorageClass() ||
199               FD->getNumParams() != DFD->getNumParams())
200             continue;
201         }
202         Relations.emplace_back(
203             SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
204       }
205     }
206   }
207 
208   bool VisitFunctionDecl(const FunctionDecl *D) {
209     if (D->isDeleted())
210       return true;
211 
212     SymbolRoleSet Roles{};
213     SmallVector<SymbolRelation, 4> Relations;
214     if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
215       if (CXXMD->isVirtual())
216         Roles |= (unsigned)SymbolRole::Dynamic;
217       for (auto I = CXXMD->begin_overridden_methods(),
218            E = CXXMD->end_overridden_methods(); I != E; ++I) {
219         Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
220       }
221     }
222     gatherTemplatePseudoOverrides(D, Relations);
223     if (const auto *Base = D->getPrimaryTemplate())
224       Relations.push_back(
225           SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
226                          Base->getTemplatedDecl()));
227 
228     TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
229     handleDeclarator(D);
230 
231     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
232       IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
233                                Ctor->getParent(), Ctor->getDeclContext());
234 
235       // Constructor initializers.
236       for (const auto *Init : Ctor->inits()) {
237         if (Init->isWritten()) {
238           IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
239           if (const FieldDecl *Member = Init->getAnyMember())
240             IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
241                                      (unsigned)SymbolRole::Write);
242           IndexCtx.indexBody(Init->getInit(), D, D);
243         }
244       }
245     } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
246       if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
247         IndexCtx.handleReference(Dtor->getParent(),
248                                  TypeNameInfo->getTypeLoc().getLocStart(),
249                                  Dtor->getParent(), Dtor->getDeclContext());
250       }
251     }
252     // Template specialization arguments.
253     if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
254             D->getTemplateSpecializationArgsAsWritten()) {
255       for (const auto &Arg : TemplateArgInfo->arguments())
256         handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
257     }
258 
259     if (D->isThisDeclarationADefinition()) {
260       const Stmt *Body = D->getBody();
261       if (Body) {
262         IndexCtx.indexBody(Body, D, D);
263       }
264     }
265     return true;
266   }
267 
268   bool VisitVarDecl(const VarDecl *D) {
269     SmallVector<SymbolRelation, 4> Relations;
270     gatherTemplatePseudoOverrides(D, Relations);
271     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
272     handleDeclarator(D);
273     IndexCtx.indexBody(D->getInit(), D);
274     return true;
275   }
276 
277   bool VisitFieldDecl(const FieldDecl *D) {
278     SmallVector<SymbolRelation, 4> Relations;
279     gatherTemplatePseudoOverrides(D, Relations);
280     TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
281     handleDeclarator(D);
282     if (D->isBitField())
283       IndexCtx.indexBody(D->getBitWidth(), D);
284     else if (D->hasInClassInitializer())
285       IndexCtx.indexBody(D->getInClassInitializer(), D);
286     return true;
287   }
288 
289   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
290     if (D->getSynthesize()) {
291       // handled in VisitObjCPropertyImplDecl
292       return true;
293     }
294     TRY_DECL(D, IndexCtx.handleDecl(D));
295     handleDeclarator(D);
296     return true;
297   }
298 
299   bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
300     handleDeclarator(D);
301     return true;
302   }
303 
304   bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
305     TRY_DECL(D, IndexCtx.handleDecl(D));
306     IndexCtx.indexBody(D->getInitExpr(), D);
307     return true;
308   }
309 
310   bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
311     if (!D->isTransparentTag()) {
312       SmallVector<SymbolRelation, 4> Relations;
313       gatherTemplatePseudoOverrides(D, Relations);
314       TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
315       IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
316     }
317     return true;
318   }
319 
320   bool VisitTagDecl(const TagDecl *D) {
321     // Non-free standing tags are handled in indexTypeSourceInfo.
322     if (D->isFreeStanding()) {
323       if (D->isThisDeclarationADefinition()) {
324         SmallVector<SymbolRelation, 4> Relations;
325         gatherTemplatePseudoOverrides(D, Relations);
326         IndexCtx.indexTagDecl(D, Relations);
327       } else {
328         auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
329         return IndexCtx.handleReference(D, D->getLocation(), Parent,
330                                         D->getLexicalDeclContext(),
331                                         SymbolRoleSet());
332       }
333     }
334     return true;
335   }
336 
337   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
338                                  const ObjCContainerDecl *ContD,
339                                  SourceLocation SuperLoc) {
340     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
341     for (ObjCInterfaceDecl::protocol_iterator
342          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
343       SourceLocation Loc = *LI;
344       ObjCProtocolDecl *PD = *I;
345       SymbolRoleSet roles{};
346       if (Loc == SuperLoc)
347         roles |= (SymbolRoleSet)SymbolRole::Implicit;
348       TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
349           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
350     }
351     return true;
352   }
353 
354   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
355     if (D->isThisDeclarationADefinition()) {
356       TRY_DECL(D, IndexCtx.handleDecl(D));
357       SourceLocation SuperLoc = D->getSuperClassLoc();
358       if (auto *SuperD = D->getSuperClass()) {
359         bool hasSuperTypedef = false;
360         if (auto *TInfo = D->getSuperClassTInfo()) {
361           if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
362             if (auto *TD = TT->getDecl()) {
363               hasSuperTypedef = true;
364               TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
365                                               SymbolRoleSet()));
366             }
367           }
368         }
369         SymbolRoleSet superRoles{};
370         if (hasSuperTypedef)
371           superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
372         TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
373             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
374       }
375       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
376                                        SuperLoc));
377       TRY_TO(IndexCtx.indexDeclContext(D));
378     } else {
379       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
380                                       D->getDeclContext(), SymbolRoleSet());
381     }
382     return true;
383   }
384 
385   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
386     if (D->isThisDeclarationADefinition()) {
387       TRY_DECL(D, IndexCtx.handleDecl(D));
388       TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
389                                        /*superLoc=*/SourceLocation()));
390       TRY_TO(IndexCtx.indexDeclContext(D));
391     } else {
392       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
393                                       D->getDeclContext(), SymbolRoleSet());
394     }
395     return true;
396   }
397 
398   bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
399     const ObjCInterfaceDecl *Class = D->getClassInterface();
400     if (!Class)
401       return true;
402 
403     if (Class->isImplicitInterfaceDecl())
404       IndexCtx.handleDecl(Class);
405 
406     TRY_DECL(D, IndexCtx.handleDecl(D));
407 
408     // Visit implicit @synthesize property implementations first as their
409     // location is reported at the name of the @implementation block. This
410     // serves no purpose other than to simplify the FileCheck-based tests.
411     for (const auto *I : D->property_impls()) {
412       if (I->getLocation().isInvalid())
413         IndexCtx.indexDecl(I);
414     }
415     for (const auto *I : D->decls()) {
416       if (!isa<ObjCPropertyImplDecl>(I) ||
417           cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
418         IndexCtx.indexDecl(I);
419     }
420 
421     return true;
422   }
423 
424   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
425     if (!IndexCtx.shouldIndex(D))
426       return true;
427     const ObjCInterfaceDecl *C = D->getClassInterface();
428     if (!C)
429       return true;
430     TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
431                                    SymbolRelation{
432                                      (unsigned)SymbolRole::RelationExtendedBy, D
433                                    }));
434     SourceLocation CategoryLoc = D->getCategoryNameLoc();
435     if (!CategoryLoc.isValid())
436       CategoryLoc = D->getLocation();
437     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
438     TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
439                                      /*superLoc=*/SourceLocation()));
440     TRY_TO(IndexCtx.indexDeclContext(D));
441     return true;
442   }
443 
444   bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
445     const ObjCCategoryDecl *Cat = D->getCategoryDecl();
446     if (!Cat)
447       return true;
448     const ObjCInterfaceDecl *C = D->getClassInterface();
449     if (C)
450       TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
451                                       SymbolRoleSet()));
452     SourceLocation CategoryLoc = D->getCategoryNameLoc();
453     if (!CategoryLoc.isValid())
454       CategoryLoc = D->getLocation();
455     TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
456     IndexCtx.indexDeclContext(D);
457     return true;
458   }
459 
460   bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
461     // Methods associated with a property, even user-declared ones, are
462     // handled when we handle the property.
463     if (D->isPropertyAccessor())
464       return true;
465 
466     handleObjCMethod(D);
467     return true;
468   }
469 
470   bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
471     if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
472       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
473         handleObjCMethod(MD, D);
474     if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
475       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
476         handleObjCMethod(MD, D);
477     TRY_DECL(D, IndexCtx.handleDecl(D));
478     if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
479       IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
480                                    D->getLexicalDeclContext(), false, true);
481     IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
482     return true;
483   }
484 
485   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
486     ObjCPropertyDecl *PD = D->getPropertyDecl();
487     auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
488     SourceLocation Loc = D->getLocation();
489     SymbolRoleSet Roles = 0;
490     SmallVector<SymbolRelation, 1> Relations;
491 
492     if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
493       Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
494     if (Loc.isInvalid()) {
495       Loc = Container->getLocation();
496       Roles |= (SymbolRoleSet)SymbolRole::Implicit;
497     }
498     TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
499 
500     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
501       return true;
502 
503     assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
504     SymbolRoleSet AccessorMethodRoles =
505       SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
506     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
507       if (MD->isPropertyAccessor() &&
508           !hasUserDefined(MD, Container))
509         IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
510     }
511     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
512       if (MD->isPropertyAccessor() &&
513           !hasUserDefined(MD, Container))
514         IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
515     }
516     if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
517       if (IvarD->getSynthesize()) {
518         // For synthesized ivars, use the location of its name in the
519         // corresponding @synthesize. If there isn't one, use the containing
520         // @implementation's location, rather than the property's location,
521         // otherwise the header file containing the @interface will have different
522         // indexing contents based on whether the @implementation was present or
523         // not in the translation unit.
524         SymbolRoleSet IvarRoles = 0;
525         SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
526         if (D->getLocation().isInvalid()) {
527           IvarLoc = Container->getLocation();
528           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
529         } else if (D->getLocation() == IvarLoc) {
530           IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
531         }
532         TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
533       } else {
534         IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
535                                  D->getDeclContext(), SymbolRoleSet());
536       }
537     }
538     return true;
539   }
540 
541   bool VisitNamespaceDecl(const NamespaceDecl *D) {
542     TRY_DECL(D, IndexCtx.handleDecl(D));
543     IndexCtx.indexDeclContext(D);
544     return true;
545   }
546 
547   bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
548     TRY_DECL(D, IndexCtx.handleDecl(D));
549     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
550     IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
551                              D->getLexicalDeclContext());
552     return true;
553   }
554 
555   bool VisitUsingDecl(const UsingDecl *D) {
556     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
557     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
558 
559     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
560                                          D->getLexicalDeclContext());
561     for (const auto *I : D->shadows())
562       IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
563                                D->getLexicalDeclContext(), SymbolRoleSet());
564     return true;
565   }
566 
567   bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
568     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
569     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
570 
571     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
572                                          D->getLexicalDeclContext());
573     return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
574                                     D->getLocation(), Parent,
575                                     D->getLexicalDeclContext(),
576                                     SymbolRoleSet());
577   }
578 
579   bool VisitClassTemplateSpecializationDecl(const
580                                            ClassTemplateSpecializationDecl *D) {
581     // FIXME: Notify subsequent callbacks if info comes from implicit
582     // instantiation.
583     if (D->isThisDeclarationADefinition()) {
584       llvm::PointerUnion<ClassTemplateDecl *,
585                          ClassTemplatePartialSpecializationDecl *>
586           Template = D->getSpecializedTemplateOrPartial();
587       const Decl *SpecializationOf =
588           Template.is<ClassTemplateDecl *>()
589               ? (Decl *)Template.get<ClassTemplateDecl *>()
590               : Template.get<ClassTemplatePartialSpecializationDecl *>();
591       IndexCtx.indexTagDecl(
592           D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
593                             SpecializationOf));
594     }
595     if (TypeSourceInfo *TSI = D->getTypeAsWritten())
596       IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
597                                    D->getLexicalDeclContext());
598     return true;
599   }
600 
601   bool VisitTemplateDecl(const TemplateDecl *D) {
602     // FIXME: Template parameters.
603     return Visit(D->getTemplatedDecl());
604   }
605 
606   bool VisitFriendDecl(const FriendDecl *D) {
607     if (auto ND = D->getFriendDecl()) {
608       // FIXME: Ignore a class template in a dependent context, these are not
609       // linked properly with their redeclarations, ending up with duplicate
610       // USRs.
611       // See comment "Friend templates are visible in fairly strange ways." in
612       // SemaTemplate.cpp which precedes code that prevents the friend template
613       // from becoming visible from the enclosing context.
614       if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
615         return true;
616       return Visit(ND);
617     }
618     if (auto Ty = D->getFriendType()) {
619       IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
620     }
621     return true;
622   }
623 
624   bool VisitImportDecl(const ImportDecl *D) {
625     return IndexCtx.importedModule(D);
626   }
627 };
628 
629 } // anonymous namespace
630 
631 bool IndexingContext::indexDecl(const Decl *D) {
632   if (D->isImplicit() && shouldIgnoreIfImplicit(D))
633     return true;
634 
635   if (isTemplateImplicitInstantiation(D))
636     return true;
637 
638   IndexingDeclVisitor Visitor(*this);
639   bool ShouldContinue = Visitor.Visit(D);
640   if (!ShouldContinue)
641     return false;
642 
643   if (!Visitor.Handled && isa<DeclContext>(D))
644     return indexDeclContext(cast<DeclContext>(D));
645 
646   return true;
647 }
648 
649 bool IndexingContext::indexDeclContext(const DeclContext *DC) {
650   for (const auto *I : DC->decls())
651     if (!indexDecl(I))
652       return false;
653   return true;
654 }
655 
656 bool IndexingContext::indexTopLevelDecl(const Decl *D) {
657   if (D->getLocation().isInvalid())
658     return true;
659 
660   if (isa<ObjCMethodDecl>(D))
661     return true; // Wait for the objc container.
662 
663   return indexDecl(D);
664 }
665 
666 bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
667   for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
668     if (!indexTopLevelDecl(*I))
669       return false;
670   return true;
671 }
672