clang  5.0.0
IndexDecl.cpp
Go to the documentation of this file.
1 //===- IndexDecl.cpp - Indexing declarations ------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "IndexingContext.h"
12 #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  /// \brief Returns true if the given method has been defined explicitly by the
47  /// user.
48  static bool hasUserDefined(const ObjCMethodDecl *D,
49  const ObjCImplDecl *Container) {
50  const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
51  D->isInstanceMethod());
52  return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
53  }
54 
55  void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
56  const NamedDecl *Parent,
57  const DeclContext *DC) {
58  const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
59  switch (TALoc.getArgument().getKind()) {
61  IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
62  break;
64  IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
65  break;
68  IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
69  Parent, DC);
70  if (const TemplateDecl *TD = TALoc.getArgument()
72  .getAsTemplateDecl()) {
73  if (const NamedDecl *TTD = TD->getTemplatedDecl())
74  IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
75  }
76  break;
77  default:
78  break;
79  }
80  }
81 
82  void handleDeclarator(const DeclaratorDecl *D,
83  const NamedDecl *Parent = nullptr,
84  bool isIBType = false) {
85  if (!Parent) Parent = D;
86 
87  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
88  Parent->getLexicalDeclContext(),
89  /*isBase=*/false, isIBType);
90  IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
91  if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
92  // Only index parameters in definitions, parameters in declarations are
93  // not useful.
94  if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
95  auto *DC = Parm->getDeclContext();
96  if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
97  if (FD->isThisDeclarationADefinition())
98  IndexCtx.handleDecl(Parm);
99  } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
100  if (MD->isThisDeclarationADefinition())
101  IndexCtx.handleDecl(Parm);
102  } else {
103  IndexCtx.handleDecl(Parm);
104  }
105  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
106  if (FD->isThisDeclarationADefinition()) {
107  for (auto PI : FD->parameters()) {
108  IndexCtx.handleDecl(PI);
109  }
110  }
111  }
112  } else {
113  // Index the default parameter value for function definitions.
114  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
115  if (FD->isThisDeclarationADefinition()) {
116  for (const auto *PV : FD->parameters()) {
117  if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
118  !PV->hasUnparsedDefaultArg())
119  IndexCtx.indexBody(PV->getDefaultArg(), D);
120  }
121  }
122  }
123  }
124  }
125 
126  bool handleObjCMethod(const ObjCMethodDecl *D,
127  const ObjCPropertyDecl *AssociatedProp = nullptr) {
130 
131  D->getOverriddenMethods(Overriden);
132  for(auto overridden: Overriden) {
133  Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
134  overridden);
135  }
136  if (AssociatedProp)
137  Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
138  AssociatedProp);
139 
140  // getLocation() returns beginning token of a method declaration, but for
141  // indexing purposes we want to point to the base name.
142  SourceLocation MethodLoc = D->getSelectorStartLoc();
143  if (MethodLoc.isInvalid())
144  MethodLoc = D->getLocation();
145 
146  SourceLocation AttrLoc;
147 
148  // check for (getter=/setter=)
149  if (AssociatedProp) {
150  bool isGetter = !D->param_size();
151  AttrLoc = isGetter ?
152  AssociatedProp->getGetterNameLoc():
153  AssociatedProp->getSetterNameLoc();
154  }
155 
157  if (D->isImplicit()) {
158  if (AttrLoc.isValid()) {
159  MethodLoc = AttrLoc;
160  } else {
162  }
163  } else if (AttrLoc.isValid()) {
164  IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
165  D->getDeclContext(), 0);
166  }
167 
168  TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
169  IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
170  bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
171  for (const auto *I : D->parameters()) {
172  handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
173  hasIBActionAndFirst = false;
174  }
175 
176  if (D->isThisDeclarationADefinition()) {
177  const Stmt *Body = D->getBody();
178  if (Body) {
179  IndexCtx.indexBody(Body, D, D);
180  }
181  }
182  return true;
183  }
184 
185  /// Gather the declarations which the given declaration \D overrides in a
186  /// pseudo-override manner.
187  ///
188  /// Pseudo-overrides occur when a class template specialization declares
189  /// a declaration that has the same name as a similar declaration in the
190  /// non-specialized template.
191  void
192  gatherTemplatePseudoOverrides(const NamedDecl *D,
193  SmallVectorImpl<SymbolRelation> &Relations) {
194  if (!IndexCtx.getLangOpts().CPlusPlus)
195  return;
196  const auto *CTSD =
198  if (!CTSD)
199  return;
200  llvm::PointerUnion<ClassTemplateDecl *,
202  Template = CTSD->getSpecializedTemplateOrPartial();
203  if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
204  const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
205  bool TypeOverride = isa<TypeDecl>(D);
206  for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
207  if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
208  ND = CTD->getTemplatedDecl();
209  if (ND->isImplicit())
210  continue;
211  // Types can override other types.
212  if (!TypeOverride) {
213  if (ND->getKind() != D->getKind())
214  continue;
215  } else if (!isa<TypeDecl>(ND))
216  continue;
217  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
218  const auto *DFD = cast<FunctionDecl>(D);
219  // Function overrides are approximated using the number of parameters.
220  if (FD->getStorageClass() != DFD->getStorageClass() ||
221  FD->getNumParams() != DFD->getNumParams())
222  continue;
223  }
224  Relations.emplace_back(
226  }
227  }
228  }
229 
230  bool VisitFunctionDecl(const FunctionDecl *D) {
231  SymbolRoleSet Roles{};
233  if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
234  if (CXXMD->isVirtual())
235  Roles |= (unsigned)SymbolRole::Dynamic;
236  for (auto I = CXXMD->begin_overridden_methods(),
237  E = CXXMD->end_overridden_methods(); I != E; ++I) {
238  Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
239  }
240  }
241  gatherTemplatePseudoOverrides(D, Relations);
242  if (const auto *Base = D->getPrimaryTemplate())
243  Relations.push_back(
245  Base->getTemplatedDecl()));
246 
247  TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
248  handleDeclarator(D);
249 
250  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
251  IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
252  Ctor->getParent(), Ctor->getDeclContext());
253 
254  // Constructor initializers.
255  for (const auto *Init : Ctor->inits()) {
256  if (Init->isWritten()) {
257  IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
258  if (const FieldDecl *Member = Init->getAnyMember())
259  IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
261  IndexCtx.indexBody(Init->getInit(), D, D);
262  }
263  }
264  } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
265  if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
266  IndexCtx.handleReference(Dtor->getParent(),
267  TypeNameInfo->getTypeLoc().getLocStart(),
268  Dtor->getParent(), Dtor->getDeclContext());
269  }
270  }
271  // Template specialization arguments.
272  if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
274  for (const auto &Arg : TemplateArgInfo->arguments())
275  handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
276  }
277 
278  if (D->isThisDeclarationADefinition()) {
279  const Stmt *Body = D->getBody();
280  if (Body) {
281  IndexCtx.indexBody(Body, D, D);
282  }
283  }
284  return true;
285  }
286 
287  bool VisitVarDecl(const VarDecl *D) {
289  gatherTemplatePseudoOverrides(D, Relations);
290  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
291  handleDeclarator(D);
292  IndexCtx.indexBody(D->getInit(), D);
293  return true;
294  }
295 
296  bool VisitDecompositionDecl(const DecompositionDecl *D) {
297  for (const auto *Binding : D->bindings())
298  TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
299  return Base::VisitDecompositionDecl(D);
300  }
301 
302  bool VisitFieldDecl(const FieldDecl *D) {
304  gatherTemplatePseudoOverrides(D, Relations);
305  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
306  handleDeclarator(D);
307  if (D->isBitField())
308  IndexCtx.indexBody(D->getBitWidth(), D);
309  else if (D->hasInClassInitializer())
310  IndexCtx.indexBody(D->getInClassInitializer(), D);
311  return true;
312  }
313 
314  bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
315  if (D->getSynthesize()) {
316  // handled in VisitObjCPropertyImplDecl
317  return true;
318  }
319  TRY_DECL(D, IndexCtx.handleDecl(D));
320  handleDeclarator(D);
321  return true;
322  }
323 
324  bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
325  handleDeclarator(D);
326  return true;
327  }
328 
329  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
330  TRY_DECL(D, IndexCtx.handleDecl(D));
331  IndexCtx.indexBody(D->getInitExpr(), D);
332  return true;
333  }
334 
335  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
336  if (!D->isTransparentTag()) {
338  gatherTemplatePseudoOverrides(D, Relations);
339  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
340  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
341  }
342  return true;
343  }
344 
345  bool VisitTagDecl(const TagDecl *D) {
346  // Non-free standing tags are handled in indexTypeSourceInfo.
347  if (D->isFreeStanding()) {
348  if (D->isThisDeclarationADefinition()) {
350  gatherTemplatePseudoOverrides(D, Relations);
351  IndexCtx.indexTagDecl(D, Relations);
352  } else {
353  auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
355  gatherTemplatePseudoOverrides(D, Relations);
356  return IndexCtx.handleReference(D, D->getLocation(), Parent,
358  SymbolRoleSet(), Relations);
359  }
360  }
361  return true;
362  }
363 
364  bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
365  const ObjCContainerDecl *ContD,
366  SourceLocation SuperLoc) {
369  I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
370  SourceLocation Loc = *LI;
371  ObjCProtocolDecl *PD = *I;
372  SymbolRoleSet roles{};
373  if (Loc == SuperLoc)
375  TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
376  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
377  }
378  return true;
379  }
380 
381  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
382  if (D->isThisDeclarationADefinition()) {
383  TRY_DECL(D, IndexCtx.handleDecl(D));
384  SourceLocation SuperLoc = D->getSuperClassLoc();
385  if (auto *SuperD = D->getSuperClass()) {
386  bool hasSuperTypedef = false;
387  if (auto *TInfo = D->getSuperClassTInfo()) {
388  if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
389  if (auto *TD = TT->getDecl()) {
390  hasSuperTypedef = true;
391  TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
392  SymbolRoleSet()));
393  }
394  }
395  }
396  SymbolRoleSet superRoles{};
397  if (hasSuperTypedef)
398  superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
399  TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
401  }
402  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
403  SuperLoc));
404  TRY_TO(IndexCtx.indexDeclContext(D));
405  } else {
406  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
407  D->getDeclContext(), SymbolRoleSet());
408  }
409  return true;
410  }
411 
412  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
413  if (D->isThisDeclarationADefinition()) {
414  TRY_DECL(D, IndexCtx.handleDecl(D));
415  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
416  /*superLoc=*/SourceLocation()));
417  TRY_TO(IndexCtx.indexDeclContext(D));
418  } else {
419  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
420  D->getDeclContext(), SymbolRoleSet());
421  }
422  return true;
423  }
424 
425  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
427  if (!Class)
428  return true;
429 
430  if (Class->isImplicitInterfaceDecl())
431  IndexCtx.handleDecl(Class);
432 
433  TRY_DECL(D, IndexCtx.handleDecl(D));
434 
435  // Visit implicit @synthesize property implementations first as their
436  // location is reported at the name of the @implementation block. This
437  // serves no purpose other than to simplify the FileCheck-based tests.
438  for (const auto *I : D->property_impls()) {
439  if (I->getLocation().isInvalid())
440  IndexCtx.indexDecl(I);
441  }
442  for (const auto *I : D->decls()) {
443  if (!isa<ObjCPropertyImplDecl>(I) ||
444  cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
445  IndexCtx.indexDecl(I);
446  }
447 
448  return true;
449  }
450 
451  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
452  if (!IndexCtx.shouldIndex(D))
453  return true;
454  const ObjCInterfaceDecl *C = D->getClassInterface();
455  if (!C)
456  return true;
457  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
460  }));
461  SourceLocation CategoryLoc = D->getCategoryNameLoc();
462  if (!CategoryLoc.isValid())
463  CategoryLoc = D->getLocation();
464  TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
465  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
466  /*superLoc=*/SourceLocation()));
467  TRY_TO(IndexCtx.indexDeclContext(D));
468  return true;
469  }
470 
471  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
472  const ObjCCategoryDecl *Cat = D->getCategoryDecl();
473  if (!Cat)
474  return true;
475  const ObjCInterfaceDecl *C = D->getClassInterface();
476  if (C)
477  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
478  SymbolRoleSet()));
479  SourceLocation CategoryLoc = D->getCategoryNameLoc();
480  if (!CategoryLoc.isValid())
481  CategoryLoc = D->getLocation();
482  TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
483  IndexCtx.indexDeclContext(D);
484  return true;
485  }
486 
487  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
488  // Methods associated with a property, even user-declared ones, are
489  // handled when we handle the property.
490  if (D->isPropertyAccessor())
491  return true;
492 
493  handleObjCMethod(D);
494  return true;
495  }
496 
497  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
498  if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
499  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
500  handleObjCMethod(MD, D);
501  if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
502  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
503  handleObjCMethod(MD, D);
504  TRY_DECL(D, IndexCtx.handleDecl(D));
505  if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
506  IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
507  D->getLexicalDeclContext(), false, true);
508  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
509  return true;
510  }
511 
512  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
514  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
515  SourceLocation Loc = D->getLocation();
516  SymbolRoleSet Roles = 0;
518 
519  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
520  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
521  if (Loc.isInvalid()) {
522  Loc = Container->getLocation();
524  }
525  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
526 
528  return true;
529 
531  SymbolRoleSet AccessorMethodRoles =
533  if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
534  if (MD->isPropertyAccessor() &&
535  !hasUserDefined(MD, Container))
536  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
537  }
538  if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
539  if (MD->isPropertyAccessor() &&
540  !hasUserDefined(MD, Container))
541  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
542  }
543  if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
544  if (IvarD->getSynthesize()) {
545  // For synthesized ivars, use the location of its name in the
546  // corresponding @synthesize. If there isn't one, use the containing
547  // @implementation's location, rather than the property's location,
548  // otherwise the header file containing the @interface will have different
549  // indexing contents based on whether the @implementation was present or
550  // not in the translation unit.
551  SymbolRoleSet IvarRoles = 0;
552  SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
553  if (D->getLocation().isInvalid()) {
554  IvarLoc = Container->getLocation();
555  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
556  } else if (D->getLocation() == IvarLoc) {
557  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
558  }
559  TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
560  } else {
561  IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
562  D->getDeclContext(), SymbolRoleSet());
563  }
564  }
565  return true;
566  }
567 
568  bool VisitNamespaceDecl(const NamespaceDecl *D) {
569  TRY_DECL(D, IndexCtx.handleDecl(D));
570  IndexCtx.indexDeclContext(D);
571  return true;
572  }
573 
574  bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
575  TRY_DECL(D, IndexCtx.handleDecl(D));
576  IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
577  IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
578  D->getLexicalDeclContext());
579  return true;
580  }
581 
582  bool VisitUsingDecl(const UsingDecl *D) {
583  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
584  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
585 
586  IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
587  D->getLexicalDeclContext());
588  for (const auto *I : D->shadows())
589  IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
591  return true;
592  }
593 
594  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
595  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
596  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
597 
598  // NNS for the local 'using namespace' directives is visited by the body
599  // visitor.
600  if (!D->getParentFunctionOrMethod())
601  IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
602  D->getLexicalDeclContext());
603 
604  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
605  D->getLocation(), Parent,
607  SymbolRoleSet());
608  }
609 
610  bool VisitClassTemplateSpecializationDecl(const
612  // FIXME: Notify subsequent callbacks if info comes from implicit
613  // instantiation.
614  llvm::PointerUnion<ClassTemplateDecl *,
616  Template = D->getSpecializedTemplateOrPartial();
617  const Decl *SpecializationOf =
618  Template.is<ClassTemplateDecl *>()
619  ? (Decl *)Template.get<ClassTemplateDecl *>()
620  : Template.get<ClassTemplatePartialSpecializationDecl *>();
621  if (!D->isThisDeclarationADefinition())
622  IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
623  IndexCtx.indexTagDecl(
624  D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
625  SpecializationOf));
626  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
627  IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
628  D->getLexicalDeclContext());
629  return true;
630  }
631 
632  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
633  if (!D)
634  return false;
635  // We want to index the template parameters only once when indexing the
636  // canonical declaration.
637  if (const auto *FD = dyn_cast<FunctionDecl>(D))
638  return FD->getCanonicalDecl() == FD;
639  else if (const auto *TD = dyn_cast<TagDecl>(D))
640  return TD->getCanonicalDecl() == TD;
641  else if (const auto *VD = dyn_cast<VarDecl>(D))
642  return VD->getCanonicalDecl() == VD;
643  return true;
644  }
645 
646  bool VisitTemplateDecl(const TemplateDecl *D) {
647  // FIXME: Template parameters.
648 
649  // Index the default values for the template parameters.
650  const NamedDecl *Parent = D->getTemplatedDecl();
651  if (D->getTemplateParameters() &&
652  shouldIndexTemplateParameterDefaultValue(Parent)) {
653  const TemplateParameterList *Params = D->getTemplateParameters();
654  for (const NamedDecl *TP : *Params) {
655  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
656  if (TTP->hasDefaultArgument())
657  IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
658  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
659  if (NTTP->hasDefaultArgument())
660  IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
661  } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
662  if (TTPD->hasDefaultArgument())
663  handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
664  /*DC=*/nullptr);
665  }
666  }
667  }
668 
669  return Visit(D->getTemplatedDecl());
670  }
671 
672  bool VisitFriendDecl(const FriendDecl *D) {
673  if (auto ND = D->getFriendDecl()) {
674  // FIXME: Ignore a class template in a dependent context, these are not
675  // linked properly with their redeclarations, ending up with duplicate
676  // USRs.
677  // See comment "Friend templates are visible in fairly strange ways." in
678  // SemaTemplate.cpp which precedes code that prevents the friend template
679  // from becoming visible from the enclosing context.
680  if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
681  return true;
682  return Visit(ND);
683  }
684  if (auto Ty = D->getFriendType()) {
685  IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
686  }
687  return true;
688  }
689 
690  bool VisitImportDecl(const ImportDecl *D) {
691  return IndexCtx.importedModule(D);
692  }
693 
694  bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
695  IndexCtx.indexBody(D->getAssertExpr(),
696  dyn_cast<NamedDecl>(D->getDeclContext()),
697  D->getLexicalDeclContext());
698  return true;
699  }
700 };
701 
702 } // anonymous namespace
703 
704 bool IndexingContext::indexDecl(const Decl *D) {
705  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
706  return true;
707 
709  return true;
710 
711  IndexingDeclVisitor Visitor(*this);
712  bool ShouldContinue = Visitor.Visit(D);
713  if (!ShouldContinue)
714  return false;
715 
716  if (!Visitor.Handled && isa<DeclContext>(D))
717  return indexDeclContext(cast<DeclContext>(D));
718 
719  return true;
720 }
721 
723  for (const auto *I : DC->decls())
724  if (!indexDecl(I))
725  return false;
726  return true;
727 }
728 
730  if (D->getLocation().isInvalid())
731  return true;
732 
733  if (isa<ObjCMethodDecl>(D))
734  return true; // Wait for the objc container.
735 
736  return indexDecl(D);
737 }
738 
740  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
741  if (!indexTopLevelDecl(*I))
742  return false;
743  return true;
744 }
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1618
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:116
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2232
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:2434
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl * > &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1232
Stmt - This represents one statement.
Definition: Stmt.h:60
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:1537
#define TRY_DECL(D, CALL_EXPR)
Definition: IndexDecl.cpp:17
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
const Expr * getInitExpr() const
Definition: Decl.h:2571
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1452
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
Definition: Decl.h:2554
The template argument is an expression, and we've not resolved it to one of the other forms yet...
Definition: TemplateBase.h:69
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Definition: DeclBase.cpp:222
iterator end()
Definition: DeclGroup.h:108
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:81
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:729
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1009
const Expr * getInit() const
Definition: Decl.h:1146
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:461
A container of type source information.
Definition: Decl.h:62
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2329
Expr * getInClassInitializer() const
getInClassInitializer - Get the C++11 in-class initializer for this member, or null if one has not be...
Definition: Decl.h:2489
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:68
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Definition: DeclFriend.h:40
TRY_TO(TraverseType(T->getPointeeType()))
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:758
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1495
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:573
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:50
unsigned param_size() const
Definition: DeclObjC.h:348
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1434
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:697
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:786
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:108
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2707
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1292
return(__x >> __y)|(__x<< (32-__y))
Represents a class template specialization, which refers to a class template with a given set of temp...
SourceLocation getSelectorStartLoc() const
Definition: DeclObjC.h:297
bool hasAttr() const
Definition: DeclBase.h:521
SymbolRole
Set of roles that are attributed to symbol occurrences.
Definition: IndexSymbol.h:89
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2366
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition() - Return true if this declaration is a completion definition of the ty...
Definition: Decl.h:2954
T * getAttr() const
Definition: DeclBase.h:518
Represents a C++ using-declaration.
Definition: DeclCXX.h:3183
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:497
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:919
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:537
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:334
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:2955
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:2805
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:504
iterator begin()
Definition: DeclGroup.h:102
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:704
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:1985
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
Definition: DeclBase.h:796
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:510
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:3701
Represents an ObjC class declaration.
Definition: DeclObjC.h:1108
propimpl_range property_impls() const
Definition: DeclObjC.h:2367
detail::InMemoryDirectory::const_iterator I
bool isInvalid() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2645
unsigned SymbolRoleSet
Definition: IndexSymbol.h:113
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2126
llvm::PointerUnion< ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl * > getSpecializedTemplateOrPartial() const
Retrieve the class template or class template partial specialization which was specialized by this...
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2923
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:636
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:3324
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2711
Expr * getBitWidth() const
Definition: Decl.h:2448
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:722
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2551
Kind getKind() const
Definition: DeclBase.h:410
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:213
DeclContext * getDeclContext()
Definition: DeclBase.h:416
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:739
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
Definition: Decl.h:2752
static bool isTemplateImplicitInstantiation(const Decl *D)
bool isInstanceMethod() const
Definition: DeclObjC.h:416
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:266
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
Definition: Decl.h:258
shadow_range shadows() const
Definition: DeclCXX.h:3280
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:661
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:344
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2019
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:371
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
Definition: Decl.cpp:2597
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
const std::string ID
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2816
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:2951
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:793
bool getSynthesize() const
Definition: DeclObjC.h:1912
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2189
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2341
bool isPropertyAccessor() const
Definition: DeclObjC.h:423
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:704
loc_iterator loc_begin() const
Definition: DeclObjC.h:85
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1507
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:3576
SourceLocation getCategoryNameLoc() const
Definition: DeclObjC.h:2420
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3829
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2682
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2035
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3294
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1215
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:378
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:63
bool isFreeStanding() const
Definition: Decl.h:2982
A decomposition declaration.
Definition: DeclCXX.h:3672
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2714
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:1874
Selector getSelector() const
Definition: DeclObjC.h:328
detail::InMemoryDirectory::const_iterator E
iterator begin() const
Definition: DeclObjC.h:65
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2448
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:875
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:428
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:121
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:878
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1634
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3220
A list of Objective-C protocols, along with the source locations at which they were referenced...
Definition: DeclObjC.h:76
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1271
The template argument is a type.
Definition: TemplateBase.h:48
TemplateArgumentLocInfo getLocInfo() const
Definition: TemplateBase.h:475
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2702
bool isImplicitInterfaceDecl() const
isImplicitInterfaceDecl - check that this is an implicitly declared ObjCInterfaceDecl node...
Definition: DeclObjC.h:1811
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:431
Represents a C++ struct/union/class.
Definition: DeclCXX.h:267
The template argument is a template name that was provided for a template template parameter...
Definition: TemplateBase.h:60
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1866
Location information for a TemplateArgument.
Definition: TemplateBase.h:369
Declaration of a class template.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:410
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:314
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2797
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:3741
#define true
Definition: stdbool.h:32
SourceLocation getLocation() const
Definition: DeclBase.h:407
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213
Represents a C++ namespace alias.
Definition: DeclCXX.h:2861
Represents C++ using-directive.
Definition: DeclCXX.h:2758
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:2722
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:74
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:471
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2396
iterator end() const
Definition: DeclObjC.h:66
bool hasInClassInitializer() const
hasInClassInitializer - Determine whether this member has a C++11 in-class initializer.
Definition: Decl.h:2481