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