clang  19.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/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"
17 
18 using namespace clang;
19 using 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 
34 namespace {
35 
36 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
37  IndexingContext &IndexCtx;
38 
39 public:
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()) {
56  IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
57  break;
59  IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
60  break;
64  Parent, DC);
65  if (const TemplateDecl *TD = TALoc.getArgument()
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() &&
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) {
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 
170  if (D->isImplicit()) {
171  if (AttrLoc.isValid()) {
172  MethodLoc = AttrLoc;
173  } else {
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 *,
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(
239  }
240  }
241  }
242 
243  bool VisitFunctionDecl(const FunctionDecl *D) {
244  SymbolRoleSet Roles{};
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(
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 =
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) {
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) {
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()) {
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()) {
369  gatherTemplatePseudoOverrides(D, Relations);
370  IndexCtx.indexTagDecl(D, Relations);
371  } else {
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) {
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)
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) {
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(),
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) {
540  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
542  SymbolRoleSet Roles = 0;
544 
545  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
546  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
547  if (Loc.isInvalid()) {
548  Loc = Container->getLocation();
550  }
551  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
552 
554  return true;
555 
557  SymbolRoleSet AccessorMethodRoles =
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));
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);
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,
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())
634  D->getLexicalDeclContext());
635 
636  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
637  D->getLocation(), Parent,
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);
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);
656  D->getLexicalDeclContext());
657  return true;
658  }
659 
660  bool VisitClassTemplateSpecializationDecl(const
662  // FIXME: Notify subsequent callbacks if info comes from implicit
663  // instantiation.
664  llvm::PointerUnion<ClassTemplateDecl *,
666  Template = D->getSpecializedTemplateOrPartial();
667  const Decl *SpecializationOf =
668  Template.is<ClassTemplateDecl *>()
669  ? (Decl *)Template.get<ClassTemplateDecl *>()
670  : Template.get<ClassTemplatePartialSpecializationDecl *>();
673  IndexCtx.indexTagDecl(
675  SpecializationOf));
676  // Template specialization arguments.
677  if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
679  for (const auto &Arg : TemplateArgInfo->arguments())
680  handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
681  }
682  return true;
683  }
684 
685  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
686  // We want to index the template parameters only once when indexing the
687  // canonical declaration.
688  if (!D)
689  return false;
690  if (const auto *FD = dyn_cast<FunctionDecl>(D))
691  return FD->getCanonicalDecl() == FD;
692  else if (const auto *TD = dyn_cast<TagDecl>(D))
693  return TD->getCanonicalDecl() == TD;
694  else if (const auto *VD = dyn_cast<VarDecl>(D))
695  return VD->getCanonicalDecl() == VD;
696  return true;
697  }
698 
699  void indexTemplateParameters(TemplateParameterList *Params,
700  const NamedDecl *Parent) {
701  for (const NamedDecl *TP : *Params) {
702  if (IndexCtx.shouldIndexTemplateParameters())
703  IndexCtx.handleDecl(TP);
704  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
705  if (TTP->hasDefaultArgument())
706  handleTemplateArgumentLoc(TTP->getDefaultArgument(), Parent,
707  TP->getLexicalDeclContext());
708  if (auto *C = TTP->getTypeConstraint())
709  IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
710  Parent, TTP->getLexicalDeclContext());
711  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
712  IndexCtx.indexTypeSourceInfo(NTTP->getTypeSourceInfo(), Parent);
713  if (NTTP->hasDefaultArgument())
714  handleTemplateArgumentLoc(NTTP->getDefaultArgument(), Parent,
715  TP->getLexicalDeclContext());
716  } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
717  if (TTPD->hasDefaultArgument())
718  handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
719  TP->getLexicalDeclContext());
720  }
721  }
722  if (auto *R = Params->getRequiresClause())
723  IndexCtx.indexBody(R, Parent);
724  }
725 
726  bool VisitTemplateDecl(const TemplateDecl *D) {
727  const NamedDecl *Parent = D->getTemplatedDecl();
728  if (!Parent)
729  return true;
730 
731  // Index the default values for the template parameters.
732  auto *Params = D->getTemplateParameters();
733  if (Params && shouldIndexTemplateParameterDefaultValue(Parent)) {
734  indexTemplateParameters(Params, Parent);
735  }
736 
737  return Visit(Parent);
738  }
739 
740  bool VisitConceptDecl(const ConceptDecl *D) {
741  if (auto *Params = D->getTemplateParameters())
742  indexTemplateParameters(Params, D);
743  if (auto *E = D->getConstraintExpr())
744  IndexCtx.indexBody(E, D);
745  return IndexCtx.handleDecl(D);
746  }
747 
748  bool VisitFriendDecl(const FriendDecl *D) {
749  if (auto ND = D->getFriendDecl()) {
750  // FIXME: Ignore a class template in a dependent context, these are not
751  // linked properly with their redeclarations, ending up with duplicate
752  // USRs.
753  // See comment "Friend templates are visible in fairly strange ways." in
754  // SemaTemplate.cpp which precedes code that prevents the friend template
755  // from becoming visible from the enclosing context.
756  if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
757  return true;
758  return Visit(ND);
759  }
760  if (auto Ty = D->getFriendType()) {
761  IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
762  }
763  return true;
764  }
765 
766  bool VisitImportDecl(const ImportDecl *D) {
767  return IndexCtx.importedModule(D);
768  }
769 
770  bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
771  IndexCtx.indexBody(D->getAssertExpr(),
772  dyn_cast<NamedDecl>(D->getDeclContext()),
773  D->getLexicalDeclContext());
774  return true;
775  }
776 };
777 
778 } // anonymous namespace
779 
781  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
782  return true;
783 
785  return true;
786 
787  IndexingDeclVisitor Visitor(*this);
788  bool ShouldContinue = Visitor.Visit(D);
789  if (!ShouldContinue)
790  return false;
791 
792  if (!Visitor.Handled && isa<DeclContext>(D))
793  return indexDeclContext(cast<DeclContext>(D));
794 
795  return true;
796 }
797 
799  for (const auto *I : DC->decls())
800  if (!indexDecl(I))
801  return false;
802  return true;
803 }
804 
806  if (!D || D->getLocation().isInvalid())
807  return true;
808 
809  if (isa<ObjCMethodDecl>(D))
810  return true; // Wait for the objc container.
811 
812  if (IndexOpts.ShouldTraverseDecl && !IndexOpts.ShouldTraverseDecl(D))
813  return true; // skip
814 
815  return indexDecl(D);
816 }
817 
819  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
820  if (!indexTopLevelDecl(*I))
821  return false;
822  return true;
823 }
This file provides AST data structures related to concepts.
NodeId Parent
Definition: ASTDiff.cpp:191
static char ID
Definition: Arena.cpp:183
Defines the C++ template declaration subclasses.
#define TRY_DECL(D, CALL_EXPR)
Definition: IndexDecl.cpp:21
SourceLocation Loc
Definition: SemaObjC.cpp:755
shadow_range shadows() const
Definition: DeclCXX.h:3483
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2534
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
Represents a class template specialization, which refers to a class template with a given set of temp...
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this.
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Declaration of a C++20 concept.
Expr * getConstraintExpr() const
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:74
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1282
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1802
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1938
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2322
iterator begin()
Definition: DeclGroup.h:99
iterator end()
Definition: DeclGroup.h:105
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
Definition: DeclBase.cpp:295
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:1077
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition: DeclBase.h:908
bool hasAttr() const
Definition: DeclBase.h:583
Kind getKind() const
Definition: DeclBase.h:448
T * getAttr() const
Definition: DeclBase.h:579
DeclContext * getDeclContext()
Definition: DeclBase.h:454
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:771
A decomposition declaration.
Definition: DeclCXX.h:4166
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:4198
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3300
const Expr * getInitExpr() const
Definition: Decl.h:3318
Represents an enum.
Definition: Decl.h:3870
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
Definition: Decl.h:4046
Represents a member of a struct/union/class.
Definition: Decl.h:3060
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition: Decl.cpp:4574
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3151
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
Definition: Decl.h:3221
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Definition: Decl.h:3164
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:54
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:137
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:122
Represents a function declaration or definition.
Definition: Decl.h:1972
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:3240
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2286
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:4166
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:4192
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:4802
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:4235
This represents a decl that may have a name.
Definition: Decl.h:249
Represents a C++ namespace alias.
Definition: DeclCXX.h:3120
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3215
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3183
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:3211
Represent a C++ namespace.
Definition: Decl.h:548
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2326
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2393
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2369
SourceLocation getCategoryNameLoc() const
Definition: DeclObjC.h:2457
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
SourceLocation getCategoryNameLoc() const
Definition: DeclObjC.h:2569
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2199
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
propimpl_range property_impls() const
Definition: DeclObjC.h:2510
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2483
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2594
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:372
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1522
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1572
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1355
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:352
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1332
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1950
bool getSynthesize() const
Definition: DeclObjC.h:2005
iterator end() const
Definition: DeclObjC.h:91
iterator begin() const
Definition: DeclObjC.h:90
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
bool isPropertyAccessor() const
Definition: DeclObjC.h:436
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:444
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:534
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:900
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:801
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:903
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2802
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2879
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2876
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2867
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2872
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2258
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2150
A list of Objective-C protocols, along with the source locations at which they were referenced.
Definition: DeclObjC.h:101
loc_iterator loc_begin() const
Definition: DeclObjC.h:111
Represents a parameter to a function.
Definition: Decl.h:1762
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
Definition: Decl.h:1891
bool hasUninstantiatedDefaultArg() const
Definition: Decl.h:1895
Expr * getDefaultArg()
Definition: Decl.cpp:2972
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
Definition: Decl.cpp:3020
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4058
Stmt - This represents one statement.
Definition: Stmt.h:84
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3587
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3685
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:3832
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition: Decl.h:3725
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
TemplateArgumentLocInfo getLocInfo() const
Definition: TemplateBase.h:576
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:616
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:609
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:350
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3435
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3485
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type,...
Definition: Decl.h:3519
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3959
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3993
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3862
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3903
Represents a C++ using-declaration.
Definition: DeclCXX.h:3512
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3546
Represents C++ using-directive.
Definition: DeclCXX.h:3015
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:3068
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3060
Represents a variable declaration or definition.
Definition: Decl.h:919
const Expr * getInit() const
Definition: Decl.h:1356
bool shouldIndexImplicitInstantiation() const
bool importedModule(const ImportDecl *ImportD)
bool shouldIndex(const Decl *D)
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:798
bool shouldIndexFunctionLocalSymbols() const
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:805
bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=std::nullopt, const Expr *RefE=nullptr)
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
Definition: IndexBody.cpp:512
bool shouldIndexParametersInDeclarations() const
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:818
static bool isTemplateImplicitInstantiation(const Decl *D)
void indexTagDecl(const TagDecl *D, ArrayRef< SymbolRelation > Relations=std::nullopt)
const LangOptions & getLangOpts() const
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:780
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false, bool isIBType=false)
bool handleDecl(const Decl *D, SymbolRoleSet Roles=SymbolRoleSet(), ArrayRef< SymbolRelation > Relations=std::nullopt)
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
unsigned SymbolRoleSet
Definition: IndexSymbol.h:133
The JSON file list parser is used to communicate input to InstallAPI.
TRY_TO(TraverseType(T->getPointeeType()))
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
Location information for a TemplateArgument.
Definition: TemplateBase.h:472
TypeSourceInfo * getAsTypeSourceInfo() const
Definition: TemplateBase.h:501
std::function< bool(const Decl *)> ShouldTraverseDecl
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:136