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