clang  6.0.0svn
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;
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 
88  Parent->getLexicalDeclContext(),
89  /*isBase=*/false, isIBType);
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));
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,
260  (unsigned)SymbolRole::Write);
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  } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
271  IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
272  Guide->getLocation(), Guide,
273  Guide->getDeclContext());
274  }
275  // Template specialization arguments.
276  if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
278  for (const auto &Arg : TemplateArgInfo->arguments())
279  handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
280  }
281 
282  if (D->isThisDeclarationADefinition()) {
283  const Stmt *Body = D->getBody();
284  if (Body) {
285  IndexCtx.indexBody(Body, D, D);
286  }
287  }
288  return true;
289  }
290 
291  bool VisitVarDecl(const VarDecl *D) {
293  gatherTemplatePseudoOverrides(D, Relations);
294  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
295  handleDeclarator(D);
296  IndexCtx.indexBody(D->getInit(), D);
297  return true;
298  }
299 
300  bool VisitDecompositionDecl(const DecompositionDecl *D) {
301  for (const auto *Binding : D->bindings())
302  TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
303  return Base::VisitDecompositionDecl(D);
304  }
305 
306  bool VisitFieldDecl(const FieldDecl *D) {
308  gatherTemplatePseudoOverrides(D, Relations);
309  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
310  handleDeclarator(D);
311  if (D->isBitField())
312  IndexCtx.indexBody(D->getBitWidth(), D);
313  else if (D->hasInClassInitializer())
314  IndexCtx.indexBody(D->getInClassInitializer(), D);
315  return true;
316  }
317 
318  bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
319  if (D->getSynthesize()) {
320  // handled in VisitObjCPropertyImplDecl
321  return true;
322  }
323  TRY_DECL(D, IndexCtx.handleDecl(D));
324  handleDeclarator(D);
325  return true;
326  }
327 
328  bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
329  handleDeclarator(D);
330  return true;
331  }
332 
333  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
334  TRY_DECL(D, IndexCtx.handleDecl(D));
335  IndexCtx.indexBody(D->getInitExpr(), D);
336  return true;
337  }
338 
339  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
340  if (!D->isTransparentTag()) {
342  gatherTemplatePseudoOverrides(D, Relations);
343  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
344  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
345  }
346  return true;
347  }
348 
349  bool VisitTagDecl(const TagDecl *D) {
350  // Non-free standing tags are handled in indexTypeSourceInfo.
351  if (D->isFreeStanding()) {
352  if (D->isThisDeclarationADefinition()) {
354  gatherTemplatePseudoOverrides(D, Relations);
355  IndexCtx.indexTagDecl(D, Relations);
356  } else {
358  gatherTemplatePseudoOverrides(D, Relations);
359  return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
360  Relations, D->getLexicalDeclContext());
361  }
362  }
363  return true;
364  }
365 
366  bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
367  const ObjCContainerDecl *ContD,
368  SourceLocation SuperLoc) {
371  I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
372  SourceLocation Loc = *LI;
373  ObjCProtocolDecl *PD = *I;
374  SymbolRoleSet roles{};
375  if (Loc == SuperLoc)
377  TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
378  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
379  }
380  return true;
381  }
382 
383  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
384  if (D->isThisDeclarationADefinition()) {
385  TRY_DECL(D, IndexCtx.handleDecl(D));
386  SourceLocation SuperLoc = D->getSuperClassLoc();
387  if (auto *SuperD = D->getSuperClass()) {
388  bool hasSuperTypedef = false;
389  if (auto *TInfo = D->getSuperClassTInfo()) {
390  if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
391  if (auto *TD = TT->getDecl()) {
392  hasSuperTypedef = true;
393  TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
394  SymbolRoleSet()));
395  }
396  }
397  }
398  SymbolRoleSet superRoles{};
399  if (hasSuperTypedef)
400  superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
401  TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
402  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
403  }
404  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
405  SuperLoc));
406  TRY_TO(IndexCtx.indexDeclContext(D));
407  } else {
408  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
409  D->getDeclContext(), SymbolRoleSet());
410  }
411  return true;
412  }
413 
414  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
415  if (D->isThisDeclarationADefinition()) {
416  TRY_DECL(D, IndexCtx.handleDecl(D));
417  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
418  /*superLoc=*/SourceLocation()));
419  TRY_TO(IndexCtx.indexDeclContext(D));
420  } else {
421  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
422  D->getDeclContext(), SymbolRoleSet());
423  }
424  return true;
425  }
426 
427  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
429  if (!Class)
430  return true;
431 
432  if (Class->isImplicitInterfaceDecl())
433  IndexCtx.handleDecl(Class);
434 
435  TRY_DECL(D, IndexCtx.handleDecl(D));
436 
437  // Visit implicit @synthesize property implementations first as their
438  // location is reported at the name of the @implementation block. This
439  // serves no purpose other than to simplify the FileCheck-based tests.
440  for (const auto *I : D->property_impls()) {
441  if (I->getLocation().isInvalid())
442  IndexCtx.indexDecl(I);
443  }
444  for (const auto *I : D->decls()) {
445  if (!isa<ObjCPropertyImplDecl>(I) ||
446  cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
447  IndexCtx.indexDecl(I);
448  }
449 
450  return true;
451  }
452 
453  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
454  if (!IndexCtx.shouldIndex(D))
455  return true;
456  const ObjCInterfaceDecl *C = D->getClassInterface();
457  if (!C)
458  return true;
459  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
461  (unsigned)SymbolRole::RelationExtendedBy, D
462  }));
463  SourceLocation CategoryLoc = D->getCategoryNameLoc();
464  if (!CategoryLoc.isValid())
465  CategoryLoc = D->getLocation();
466  TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
467  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
468  /*superLoc=*/SourceLocation()));
469  TRY_TO(IndexCtx.indexDeclContext(D));
470  return true;
471  }
472 
473  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
474  const ObjCCategoryDecl *Cat = D->getCategoryDecl();
475  if (!Cat)
476  return true;
477  const ObjCInterfaceDecl *C = D->getClassInterface();
478  if (C)
479  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
480  SymbolRoleSet()));
481  SourceLocation CategoryLoc = D->getCategoryNameLoc();
482  if (!CategoryLoc.isValid())
483  CategoryLoc = D->getLocation();
484  TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
485  IndexCtx.indexDeclContext(D);
486  return true;
487  }
488 
489  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
490  // Methods associated with a property, even user-declared ones, are
491  // handled when we handle the property.
492  if (D->isPropertyAccessor())
493  return true;
494 
495  handleObjCMethod(D);
496  return true;
497  }
498 
499  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
500  if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
501  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
502  handleObjCMethod(MD, D);
503  if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
504  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
505  handleObjCMethod(MD, D);
506  TRY_DECL(D, IndexCtx.handleDecl(D));
507  if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
508  IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
509  D->getLexicalDeclContext(), false, true);
510  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
511  return true;
512  }
513 
514  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
516  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
517  SourceLocation Loc = D->getLocation();
518  SymbolRoleSet Roles = 0;
520 
521  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
522  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
523  if (Loc.isInvalid()) {
524  Loc = Container->getLocation();
526  }
527  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
528 
530  return true;
531 
533  SymbolRoleSet AccessorMethodRoles =
535  if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
536  if (MD->isPropertyAccessor() &&
537  !hasUserDefined(MD, Container))
538  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
539  }
540  if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
541  if (MD->isPropertyAccessor() &&
542  !hasUserDefined(MD, Container))
543  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
544  }
545  if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
546  if (IvarD->getSynthesize()) {
547  // For synthesized ivars, use the location of its name in the
548  // corresponding @synthesize. If there isn't one, use the containing
549  // @implementation's location, rather than the property's location,
550  // otherwise the header file containing the @interface will have different
551  // indexing contents based on whether the @implementation was present or
552  // not in the translation unit.
553  SymbolRoleSet IvarRoles = 0;
554  SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
555  if (D->getLocation().isInvalid()) {
556  IvarLoc = Container->getLocation();
557  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
558  } else if (D->getLocation() == IvarLoc) {
559  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
560  }
561  TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
562  } else {
563  IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
564  D->getDeclContext(), SymbolRoleSet());
565  }
566  }
567  return true;
568  }
569 
570  bool VisitNamespaceDecl(const NamespaceDecl *D) {
571  TRY_DECL(D, IndexCtx.handleDecl(D));
572  IndexCtx.indexDeclContext(D);
573  return true;
574  }
575 
576  bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
577  TRY_DECL(D, IndexCtx.handleDecl(D));
580  D->getLexicalDeclContext());
581  return true;
582  }
583 
584  bool VisitUsingDecl(const UsingDecl *D) {
585  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
586  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
587 
589  D->getLexicalDeclContext());
590  for (const auto *I : D->shadows())
591  IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
593  return true;
594  }
595 
596  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
597  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
598  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
599 
600  // NNS for the local 'using namespace' directives is visited by the body
601  // visitor.
602  if (!D->getParentFunctionOrMethod())
604  D->getLexicalDeclContext());
605 
606  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
607  D->getLocation(), Parent,
609  SymbolRoleSet());
610  }
611 
612  bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
613  TRY_DECL(D, IndexCtx.handleDecl(D));
614  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
615  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
617  D->getLexicalDeclContext());
618  return true;
619  }
620 
621  bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
622  TRY_DECL(D, IndexCtx.handleDecl(D));
623  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
624  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
626  D->getLexicalDeclContext());
627  return true;
628  }
629 
630  bool VisitClassTemplateSpecializationDecl(const
632  // FIXME: Notify subsequent callbacks if info comes from implicit
633  // instantiation.
634  llvm::PointerUnion<ClassTemplateDecl *,
636  Template = D->getSpecializedTemplateOrPartial();
637  const Decl *SpecializationOf =
638  Template.is<ClassTemplateDecl *>()
639  ? (Decl *)Template.get<ClassTemplateDecl *>()
640  : Template.get<ClassTemplatePartialSpecializationDecl *>();
643  IndexCtx.indexTagDecl(
645  SpecializationOf));
646  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
647  IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
648  D->getLexicalDeclContext());
649  return true;
650  }
651 
652  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
653  if (!D)
654  return false;
655  // We want to index the template parameters only once when indexing the
656  // canonical declaration.
657  if (const auto *FD = dyn_cast<FunctionDecl>(D))
658  return FD->getCanonicalDecl() == FD;
659  else if (const auto *TD = dyn_cast<TagDecl>(D))
660  return TD->getCanonicalDecl() == TD;
661  else if (const auto *VD = dyn_cast<VarDecl>(D))
662  return VD->getCanonicalDecl() == VD;
663  return true;
664  }
665 
666  bool VisitTemplateDecl(const TemplateDecl *D) {
667 
668  // Index the default values for the template parameters.
669  const NamedDecl *Parent = D->getTemplatedDecl();
670  if (D->getTemplateParameters() &&
671  shouldIndexTemplateParameterDefaultValue(Parent)) {
672  const TemplateParameterList *Params = D->getTemplateParameters();
673  for (const NamedDecl *TP : *Params) {
674  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
675  if (TTP->hasDefaultArgument())
676  IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
677  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
678  if (NTTP->hasDefaultArgument())
679  IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
680  } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
681  if (TTPD->hasDefaultArgument())
682  handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
683  TP->getLexicalDeclContext());
684  }
685  }
686  }
687 
688  return Visit(D->getTemplatedDecl());
689  }
690 
691  bool VisitFriendDecl(const FriendDecl *D) {
692  if (auto ND = D->getFriendDecl()) {
693  // FIXME: Ignore a class template in a dependent context, these are not
694  // linked properly with their redeclarations, ending up with duplicate
695  // USRs.
696  // See comment "Friend templates are visible in fairly strange ways." in
697  // SemaTemplate.cpp which precedes code that prevents the friend template
698  // from becoming visible from the enclosing context.
699  if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
700  return true;
701  return Visit(ND);
702  }
703  if (auto Ty = D->getFriendType()) {
704  IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
705  }
706  return true;
707  }
708 
709  bool VisitImportDecl(const ImportDecl *D) {
710  return IndexCtx.importedModule(D);
711  }
712 
713  bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
714  IndexCtx.indexBody(D->getAssertExpr(),
715  dyn_cast<NamedDecl>(D->getDeclContext()),
716  D->getLexicalDeclContext());
717  return true;
718  }
719 };
720 
721 } // anonymous namespace
722 
724  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
725  return true;
726 
727  if (isTemplateImplicitInstantiation(D))
728  return true;
729 
730  IndexingDeclVisitor Visitor(*this);
731  bool ShouldContinue = Visitor.Visit(D);
732  if (!ShouldContinue)
733  return false;
734 
735  if (!Visitor.Handled && isa<DeclContext>(D))
736  return indexDeclContext(cast<DeclContext>(D));
737 
738  return true;
739 }
740 
742  for (const auto *I : DC->decls())
743  if (!indexDecl(I))
744  return false;
745  return true;
746 }
747 
749  if (D->getLocation().isInvalid())
750  return true;
751 
752  if (isa<ObjCMethodDecl>(D))
753  return true; // Wait for the objc container.
754 
755  return indexDecl(D);
756 }
757 
759  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
760  if (!indexTopLevelDecl(*I))
761  return false;
762  return true;
763 }
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1698
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:535
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:119
unsigned param_size() const
Definition: DeclObjC.h:379
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2344
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:1549
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2846
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:526
Stmt - This represents one statement.
Definition: Stmt.h:66
Expr * getBitWidth() const
Definition: Decl.h:2550
#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:3353
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
Definition: Decl.h:2665
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:350
The template argument is an expression, and we&#39;ve not resolved it to one of the other forms yet...
Definition: TemplateBase.h:87
iterator end()
Definition: DeclGroup.h:106
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:453
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:748
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:506
A container of type source information.
Definition: Decl.h:86
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2397
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Definition: DeclBase.cpp:243
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
Definition: Decl.h:2591
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:3039
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Definition: DeclFriend.h:54
TRY_TO(TraverseType(T->getPointeeType()))
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:807
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:1576
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:595
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:68
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1514
iterator end() const
Definition: DeclObjC.h:92
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
Definition: Decl.h:291
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:124
const LangOptions & getLangOpts() const
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2140
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2461
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:942
NamedDecl * getFriendDecl() const
If this friend declaration doesn&#39;t name a type, return the inner declaration.
Definition: DeclFriend.h:139
loc_iterator loc_begin() const
Definition: DeclObjC.h:112
Represents a C++ using-declaration.
Definition: DeclCXX.h:3275
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:3798
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:2539
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
Definition: Decl.cpp:2612
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:986
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:2896
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:746
iterator begin()
Definition: DeclGroup.h:100
bool shouldIndexFunctionLocalSymbols() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl *> &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1244
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:723
const Expr * getInitExpr() const
Definition: Decl.h:2684
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2849
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2083
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
Definition: DeclBase.h:820
Represents an ObjC class declaration.
Definition: DeclObjC.h:1191
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1521
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3323
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2778
NodeId Parent
Definition: ASTDiff.cpp:192
unsigned SymbolRoleSet
Definition: IndexSymbol.h:116
bool hasAttr() const
Definition: DeclBase.h:535
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:681
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:2841
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
Definition: Decl.h:2874
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:432
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3315
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1592
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:844
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:741
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2620
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:1969
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2240
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:551
SourceLocation getSelectorStartLoc() const
Definition: DeclObjC.h:327
DeclContext * getDeclContext()
Definition: DeclBase.h:425
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:330
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:758
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:2486
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:452
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1026
Selector getSelector() const
Definition: DeclObjC.h:359
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1382
TypeSourceInfo * getAsTypeSourceInfo() const
Definition: TemplateBase.h:426
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:375
Encodes a location in the source.
bool getSynthesize() const
Definition: DeclObjC.h:2010
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2938
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2029
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3494
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3536
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set...
Definition: Decl.h:2598
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:806
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2888
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2299
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:746
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:1912
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:3669
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3965
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:3198
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2796
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2459
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:493
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:1252
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2842
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:1360
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3011
const Expr * getInit() const
Definition: Decl.h:1213
A decomposition declaration.
Definition: DeclCXX.h:3766
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3590
Kind getKind() const
Definition: DeclBase.h:419
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3626
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2571
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:450
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
T * getAttr() const
Definition: DeclBase.h:531
void indexTagDecl(const TagDecl *D, ArrayRef< SymbolRelation > Relations=None)
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:708
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1648
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:235
shadow_range shadows() const
Definition: DeclCXX.h:3375
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition() - Return true if this declaration is a completion definition of the ty...
Definition: Decl.h:3085
Represents a C++ struct/union/class.
Definition: DeclCXX.h:299
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:497
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1964
Location information for a TemplateArgument.
Definition: TemplateBase.h:393
Declaration of a class template.
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2837
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:532
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
Definition: IndexBody.cpp:445
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:3835
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:85
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:939
NamedDecl - This represents a decl with a name.
Definition: Decl.h:245
Represents a C++ namespace alias.
Definition: DeclCXX.h:2947
bool isPropertyAccessor() const
Definition: DeclObjC.h:459
Represents C++ using-directive.
Definition: DeclCXX.h:2843
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:77
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:288
bool isFreeStanding() const
Definition: Decl.h:3113
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2518
SourceLocation getLocation() const
Definition: DeclBase.h:416
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:405
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3043