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