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