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    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
731bool 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
749bool IndexingContext::indexDeclContext(const DeclContext *DC) {
750  for (const auto *I : DC->decls())
751    if (!indexDecl(I))
752      return false;
753  return true;
754}
755
756bool 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
766bool 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