clang  11.0.0git
IndexDecl.cpp
Go to the documentation of this file.
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"
13 
14 using namespace clang;
15 using namespace index;
16 
17 #define TRY_DECL(D,CALL_EXPR) \
18  do { \
19  if (!IndexCtx.shouldIndex(D)) return true; \
20  if (!CALL_EXPR) \
21  return false; \
22  } while (0)
23 
24 #define TRY_TO(CALL_EXPR) \
25  do { \
26  if (!CALL_EXPR) \
27  return false; \
28  } while (0)
29 
30 namespace {
31 
32 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
33  IndexingContext &IndexCtx;
34 
35 public:
36  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
37  : IndexCtx(indexCtx) { }
38 
39  bool Handled = true;
40 
41  bool VisitDecl(const Decl *D) {
42  Handled = false;
43  return true;
44  }
45 
46  void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
47  const NamedDecl *Parent,
48  const DeclContext *DC) {
49  const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
50  switch (TALoc.getArgument().getKind()) {
52  IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
53  break;
55  IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
56  break;
60  Parent, DC);
61  if (const TemplateDecl *TD = TALoc.getArgument()
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() &&
81  }
82 
83 
84  void handleDeclarator(const DeclaratorDecl *D,
85  const NamedDecl *Parent = nullptr,
86  bool isIBType = false) {
87  if (!Parent) Parent = D;
88 
90  Parent->getLexicalDeclContext(),
91  /*isBase=*/false, isIBType);
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) {
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 
164  if (D->isImplicit()) {
165  if (AttrLoc.isValid()) {
166  MethodLoc = AttrLoc;
167  } else {
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));
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 =
205  if (!CTSD)
206  return;
207  llvm::PointerUnion<ClassTemplateDecl *,
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(
233  }
234  }
235  }
236 
237  bool VisitFunctionDecl(const FunctionDecl *D) {
238  SymbolRoleSet Roles{};
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(
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 =
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) {
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) {
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()) {
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()) {
363  gatherTemplatePseudoOverrides(D, Relations);
364  IndexCtx.indexTagDecl(D, Relations);
365  } else {
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) {
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)
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) {
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(),
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) {
525  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
526  SourceLocation Loc = D->getLocation();
527  SymbolRoleSet Roles = 0;
529 
530  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
531  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
532  if (Loc.isInvalid()) {
533  Loc = Container->getLocation();
535  }
536  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
537 
539  return true;
540 
542  SymbolRoleSet AccessorMethodRoles =
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));
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);
597  D->getLexicalDeclContext());
598  for (const auto *I : D->shadows())
599  IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
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())
612  D->getLexicalDeclContext());
613 
614  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
615  D->getLocation(), Parent,
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);
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);
634  D->getLexicalDeclContext());
635  return true;
636  }
637 
638  bool VisitClassTemplateSpecializationDecl(const
640  // FIXME: Notify subsequent callbacks if info comes from implicit
641  // instantiation.
642  llvm::PointerUnion<ClassTemplateDecl *,
644  Template = D->getSpecializedTemplateOrPartial();
645  const Decl *SpecializationOf =
646  Template.is<ClassTemplateDecl *>()
647  ? (Decl *)Template.get<ClassTemplateDecl *>()
648  : Template.get<ClassTemplatePartialSpecializationDecl *>();
651  IndexCtx.indexTagDecl(
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 
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 
755  for (const auto *I : DC->decls())
756  if (!indexDecl(I))
757  return false;
758  return true;
759 }
760 
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 
775  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
776  if (!indexTopLevelDecl(*I))
777  return false;
778  return true;
779 }
Represents a function declaration or definition.
Definition: Decl.h:1783
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:528
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:133
unsigned param_size() const
Definition: DeclObjC.h:343
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2316
iterator begin() const
Definition: DeclObjC.h:91
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1521
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2821
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:533
Stmt - This represents one statement.
Definition: Stmt.h:68
Expr * getBitWidth() const
Definition: Decl.h:2829
#define TRY_DECL(D, CALL_EXPR)
Definition: IndexDecl.cpp:17
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:3693
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:2955
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:358
The template argument is an expression, and we&#39;ve not resolved it to one of the other forms yet...
Definition: TemplateBase.h:86
iterator end()
Definition: DeclGroup.h:105
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:434
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:761
Represent a C++ namespace.
Definition: Decl.h:497
A container of type source information.
Definition: Type.h:6373
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2413
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Definition: DeclBase.cpp:286
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
Definition: Decl.h:2880
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:3088
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Definition: DeclFriend.h:53
TRY_TO(TraverseType(T->getPointeeType()))
Represents a variable declaration or definition.
Definition: Decl.h:820
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
Definition: Decl.cpp:2745
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2061
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:605
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:69
Represents a parameter to a function.
Definition: Decl.h:1595
iterator end() const
Definition: DeclObjC.h:92
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:272
Represents a class template specialization, which refers to a class template with a given set of temp...
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:123
const LangOptions & getLangOpts() const
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2112
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
Represents a member of a struct/union/class.
Definition: Decl.h:2740
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:916
NamedDecl * getFriendDecl() const
If this friend declaration doesn&#39;t name a type, return the inner declaration.
Definition: DeclFriend.h:138
loc_iterator loc_begin() const
Definition: DeclObjC.h:112
bool shouldIndexParametersInDeclarations() const
Represents a C++ using-declaration.
Definition: DeclCXX.h:3398
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:3932
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:2818
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:2881
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:960
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:2945
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:737
iterator begin()
Definition: DeclGroup.h:99
bool shouldIndexFunctionLocalSymbols() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl *> &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1297
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
Definition: Decl.h:1709
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:736
const Expr * getInitExpr() const
Definition: Decl.h:2974
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2824
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2055
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
Definition: DeclBase.h:843
Represents an ObjC class declaration.
Definition: DeclObjC.h:1163
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1659
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3667
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2748
NodeId Parent
Definition: ASTDiff.cpp:192
unsigned SymbolRoleSet
Definition: IndexSymbol.h:130
bool hasAttr() const
Definition: DeclBase.h:547
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:671
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3135
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
Definition: Decl.h:3169
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:421
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3438
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1564
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:812
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:754
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2679
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2071
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2212
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:563
SourceLocation getSelectorStartLoc() const
Definition: DeclObjC.h:291
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2373
DeclContext * getDeclContext()
Definition: DeclBase.h:439
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:338
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:774
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this...
propimpl_range property_impls() const
Definition: DeclObjC.h:2458
bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=None, const Expr *RefE=nullptr, const Decl *RefD=nullptr)
bool isInstanceMethod() const
Definition: DeclObjC.h:424
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1138
Selector getSelector() const
Definition: DeclObjC.h:323
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1354
TypeSourceInfo * getAsTypeSourceInfo() const
Definition: TemplateBase.h:427
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:339
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:442
Encodes a location in the source.
bool getSynthesize() const
Definition: DeclObjC.h:1982
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3233
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2088
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3617
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3659
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set...
Definition: Decl.h:2887
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:856
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1960
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2937
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2271
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:742
bool hasUninstantiatedDefaultArg() const
Definition: Decl.h:1713
TypeSourceInfo * getTypeAsWritten() const
Gets the type of this specialization as it was written by the user, if it was so written.
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
Definition: DeclObjC.h:1884
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:3792
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:4352
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:3460
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3085
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2431
bool shouldIndex(const Decl *D)
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:500
bool handleDecl(const Decl *D, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=None)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1299
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:402
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2817
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:80
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1332
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3060
const Expr * getInit() const
Definition: Decl.h:1229
A decomposition declaration.
Definition: DeclCXX.h:3898
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3713
Expr * getDefaultArg()
Definition: Decl.cpp:2697
Kind getKind() const
Definition: DeclBase.h:433
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3749
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2543
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false, bool isIBType=false)
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:451
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
T * getAttr() const
Definition: DeclBase.h:543
void indexTagDecl(const TagDecl *D, ArrayRef< SymbolRelation > Relations=None)
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:700
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1794
bool importedModule(const ImportDecl *ImportD)
A list of Objective-C protocols, along with the source locations at which they were referenced...
Definition: DeclObjC.h:102
The template argument is a type.
Definition: TemplateBase.h:60
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:234
shadow_range shadows() const
Definition: DeclCXX.h:3498
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3333
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
The template argument is a template name that was provided for a template template parameter...
Definition: TemplateBase.h:76
TemplateArgumentLocInfo getLocInfo() const
Definition: TemplateBase.h:504
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1936
Location information for a TemplateArgument.
Definition: TemplateBase.h:394
Declaration of a class template.
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2812
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:540
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
Definition: IndexBody.cpp:471
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:3969
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:91
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:913
This represents a decl that may have a name.
Definition: Decl.h:223
Represents a C++ namespace alias.
Definition: DeclCXX.h:2996
bool isPropertyAccessor() const
Definition: DeclObjC.h:434
Represents C++ using-directive.
Definition: DeclCXX.h:2892
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:73
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
Definition: TemplateBase.h:289
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition: Decl.h:3373
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2490
SourceLocation getLocation() const
Definition: DeclBase.h:430
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:369
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3092