clang  10.0.0git
IndexDecl.cpp
Go to the documentation of this file.
1 //===- IndexDecl.cpp - Indexing declarations ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "IndexingContext.h"
10 #include "clang/AST/Attr.h"
11 #include "clang/AST/DeclVisitor.h"
13 
14 using namespace clang;
15 using namespace index;
16 
17 #define TRY_DECL(D,CALL_EXPR) \
18  do { \
19  if (!IndexCtx.shouldIndex(D)) return true; \
20  if (!CALL_EXPR) \
21  return false; \
22  } while (0)
23 
24 #define TRY_TO(CALL_EXPR) \
25  do { \
26  if (!CALL_EXPR) \
27  return false; \
28  } while (0)
29 
30 namespace {
31 
32 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
33  IndexingContext &IndexCtx;
34 
35 public:
36  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
37  : IndexCtx(indexCtx) { }
38 
39  bool Handled = true;
40 
41  bool VisitDecl(const Decl *D) {
42  Handled = false;
43  return true;
44  }
45 
46  void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
47  const NamedDecl *Parent,
48  const DeclContext *DC) {
49  const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
50  switch (TALoc.getArgument().getKind()) {
52  IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
53  break;
55  IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
56  break;
60  Parent, DC);
61  if (const TemplateDecl *TD = TALoc.getArgument()
63  .getAsTemplateDecl()) {
64  if (const NamedDecl *TTD = TD->getTemplatedDecl())
65  IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
66  }
67  break;
68  default:
69  break;
70  }
71  }
72 
73  /// Returns true if the given method has been defined explicitly by the
74  /// user.
75  static bool hasUserDefined(const ObjCMethodDecl *D,
76  const ObjCImplDecl *Container) {
77  const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
78  D->isInstanceMethod());
79  return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition() &&
81  }
82 
83 
84  void handleDeclarator(const DeclaratorDecl *D,
85  const NamedDecl *Parent = nullptr,
86  bool isIBType = false) {
87  if (!Parent) Parent = D;
88 
90  Parent->getLexicalDeclContext(),
91  /*isBase=*/false, isIBType);
93  if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
94  if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
95  auto *DC = Parm->getDeclContext();
96  if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
97  if (IndexCtx.shouldIndexParametersInDeclarations() ||
98  FD->isThisDeclarationADefinition())
99  IndexCtx.handleDecl(Parm);
100  } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
101  if (MD->isThisDeclarationADefinition())
102  IndexCtx.handleDecl(Parm);
103  } else {
104  IndexCtx.handleDecl(Parm);
105  }
106  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
107  if (IndexCtx.shouldIndexParametersInDeclarations() ||
108  FD->isThisDeclarationADefinition()) {
109  for (auto PI : FD->parameters()) {
110  IndexCtx.handleDecl(PI);
111  }
112  }
113  }
114  } else {
115  // Index the default parameter value for function definitions.
116  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
117  if (FD->isThisDeclarationADefinition()) {
118  for (const auto *PV : FD->parameters()) {
119  if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
120  !PV->hasUnparsedDefaultArg())
121  IndexCtx.indexBody(PV->getDefaultArg(), D);
122  }
123  }
124  }
125  }
126  }
127 
128  bool handleObjCMethod(const ObjCMethodDecl *D,
129  const ObjCPropertyDecl *AssociatedProp = nullptr) {
132 
133  D->getOverriddenMethods(Overriden);
134  for(auto overridden: Overriden) {
135  Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
136  overridden);
137  }
138  if (AssociatedProp)
139  Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
140  AssociatedProp);
141 
142  // getLocation() returns beginning token of a method declaration, but for
143  // indexing purposes we want to point to the base name.
144  SourceLocation MethodLoc = D->getSelectorStartLoc();
145  if (MethodLoc.isInvalid())
146  MethodLoc = D->getLocation();
147 
148  SourceLocation AttrLoc;
149 
150  // check for (getter=/setter=)
151  if (AssociatedProp) {
152  bool isGetter = !D->param_size();
153  AttrLoc = isGetter ?
154  AssociatedProp->getGetterNameLoc():
155  AssociatedProp->getSetterNameLoc();
156  }
157 
159  if (D->isImplicit()) {
160  if (AttrLoc.isValid()) {
161  MethodLoc = AttrLoc;
162  } else {
164  }
165  } else if (AttrLoc.isValid()) {
166  IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
167  D->getDeclContext(), 0);
168  }
169 
170  TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
172  bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
173  for (const auto *I : D->parameters()) {
174  handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
175  hasIBActionAndFirst = false;
176  }
177 
178  if (D->isThisDeclarationADefinition()) {
179  const Stmt *Body = D->getBody();
180  if (Body) {
181  IndexCtx.indexBody(Body, D, D);
182  }
183  }
184  return true;
185  }
186 
187  /// Gather the declarations which the given declaration \D overrides in a
188  /// pseudo-override manner.
189  ///
190  /// Pseudo-overrides occur when a class template specialization declares
191  /// a declaration that has the same name as a similar declaration in the
192  /// non-specialized template.
193  void
194  gatherTemplatePseudoOverrides(const NamedDecl *D,
195  SmallVectorImpl<SymbolRelation> &Relations) {
196  if (!IndexCtx.getLangOpts().CPlusPlus)
197  return;
198  const auto *CTSD =
200  if (!CTSD)
201  return;
202  llvm::PointerUnion<ClassTemplateDecl *,
204  Template = CTSD->getSpecializedTemplateOrPartial();
205  if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
206  const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
207  bool TypeOverride = isa<TypeDecl>(D);
208  for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
209  if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
210  ND = CTD->getTemplatedDecl();
211  if (ND->isImplicit())
212  continue;
213  // Types can override other types.
214  if (!TypeOverride) {
215  if (ND->getKind() != D->getKind())
216  continue;
217  } else if (!isa<TypeDecl>(ND))
218  continue;
219  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
220  const auto *DFD = cast<FunctionDecl>(D);
221  // Function overrides are approximated using the number of parameters.
222  if (FD->getStorageClass() != DFD->getStorageClass() ||
223  FD->getNumParams() != DFD->getNumParams())
224  continue;
225  }
226  Relations.emplace_back(
228  }
229  }
230  }
231 
232  bool VisitFunctionDecl(const FunctionDecl *D) {
233  SymbolRoleSet Roles{};
235  if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
236  if (CXXMD->isVirtual())
237  Roles |= (unsigned)SymbolRole::Dynamic;
238  for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
239  Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
240  }
241  }
242  gatherTemplatePseudoOverrides(D, Relations);
243  if (const auto *Base = D->getPrimaryTemplate())
244  Relations.push_back(
246  Base->getTemplatedDecl()));
247 
248  TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
249  handleDeclarator(D);
250 
251  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
252  IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
253  Ctor->getParent(), Ctor->getDeclContext(),
254  (unsigned)SymbolRole::NameReference);
255 
256  // Constructor initializers.
257  for (const auto *Init : Ctor->inits()) {
258  if (Init->isWritten()) {
259  IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
260  if (const FieldDecl *Member = Init->getAnyMember())
261  IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
262  (unsigned)SymbolRole::Write);
263  IndexCtx.indexBody(Init->getInit(), D, D);
264  }
265  }
266  } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
267  if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
268  IndexCtx.handleReference(Dtor->getParent(),
269  TypeNameInfo->getTypeLoc().getBeginLoc(),
270  Dtor->getParent(), Dtor->getDeclContext(),
271  (unsigned)SymbolRole::NameReference);
272  }
273  } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
274  IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
275  Guide->getLocation(), Guide,
276  Guide->getDeclContext());
277  }
278  // Template specialization arguments.
279  if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
281  for (const auto &Arg : TemplateArgInfo->arguments())
282  handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
283  }
284 
285  if (D->isThisDeclarationADefinition()) {
286  const Stmt *Body = D->getBody();
287  if (Body) {
288  IndexCtx.indexBody(Body, D, D);
289  }
290  }
291  return true;
292  }
293 
294  bool VisitVarDecl(const VarDecl *D) {
296  gatherTemplatePseudoOverrides(D, Relations);
297  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
298  handleDeclarator(D);
299  IndexCtx.indexBody(D->getInit(), D);
300  return true;
301  }
302 
303  bool VisitDecompositionDecl(const DecompositionDecl *D) {
304  for (const auto *Binding : D->bindings())
305  TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
306  return Base::VisitDecompositionDecl(D);
307  }
308 
309  bool VisitFieldDecl(const FieldDecl *D) {
311  gatherTemplatePseudoOverrides(D, Relations);
312  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
313  handleDeclarator(D);
314  if (D->isBitField())
315  IndexCtx.indexBody(D->getBitWidth(), D);
316  else if (D->hasInClassInitializer())
317  IndexCtx.indexBody(D->getInClassInitializer(), D);
318  return true;
319  }
320 
321  bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
322  if (D->getSynthesize()) {
323  // handled in VisitObjCPropertyImplDecl
324  return true;
325  }
326  TRY_DECL(D, IndexCtx.handleDecl(D));
327  handleDeclarator(D);
328  return true;
329  }
330 
331  bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
332  TRY_DECL(D, IndexCtx.handleDecl(D));
333  handleDeclarator(D);
334  return true;
335  }
336 
337  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
338  TRY_DECL(D, IndexCtx.handleDecl(D));
339  IndexCtx.indexBody(D->getInitExpr(), D);
340  return true;
341  }
342 
343  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
344  if (!D->isTransparentTag()) {
346  gatherTemplatePseudoOverrides(D, Relations);
347  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
348  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
349  }
350  return true;
351  }
352 
353  bool VisitTagDecl(const TagDecl *D) {
354  // Non-free standing tags are handled in indexTypeSourceInfo.
355  if (D->isFreeStanding()) {
356  if (D->isThisDeclarationADefinition()) {
358  gatherTemplatePseudoOverrides(D, Relations);
359  IndexCtx.indexTagDecl(D, Relations);
360  } else {
362  gatherTemplatePseudoOverrides(D, Relations);
363  return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
364  Relations, D->getLexicalDeclContext());
365  }
366  }
367  return true;
368  }
369 
370  bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
371  const ObjCContainerDecl *ContD,
372  SourceLocation SuperLoc) {
375  I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
376  SourceLocation Loc = *LI;
377  ObjCProtocolDecl *PD = *I;
378  SymbolRoleSet roles{};
379  if (Loc == SuperLoc)
381  TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
382  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
383  }
384  return true;
385  }
386 
387  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
388  if (D->isThisDeclarationADefinition()) {
389  TRY_DECL(D, IndexCtx.handleDecl(D));
390  SourceLocation SuperLoc = D->getSuperClassLoc();
391  if (auto *SuperD = D->getSuperClass()) {
392  bool hasSuperTypedef = false;
393  if (auto *TInfo = D->getSuperClassTInfo()) {
394  if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
395  if (auto *TD = TT->getDecl()) {
396  hasSuperTypedef = true;
397  TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
398  SymbolRoleSet()));
399  }
400  }
401  }
402  SymbolRoleSet superRoles{};
403  if (hasSuperTypedef)
404  superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
405  TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
406  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
407  }
408  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
409  SuperLoc));
410  TRY_TO(IndexCtx.indexDeclContext(D));
411  } else {
412  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
413  D->getDeclContext(), SymbolRoleSet());
414  }
415  return true;
416  }
417 
418  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
419  if (D->isThisDeclarationADefinition()) {
420  TRY_DECL(D, IndexCtx.handleDecl(D));
421  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
422  /*SuperLoc=*/SourceLocation()));
423  TRY_TO(IndexCtx.indexDeclContext(D));
424  } else {
425  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
426  D->getDeclContext(), SymbolRoleSet());
427  }
428  return true;
429  }
430 
431  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
433  if (!Class)
434  return true;
435 
436  if (Class->isImplicitInterfaceDecl())
437  IndexCtx.handleDecl(Class);
438 
439  TRY_DECL(D, IndexCtx.handleDecl(D));
440 
441  // Visit implicit @synthesize property implementations first as their
442  // location is reported at the name of the @implementation block. This
443  // serves no purpose other than to simplify the FileCheck-based tests.
444  for (const auto *I : D->property_impls()) {
445  if (I->getLocation().isInvalid())
446  IndexCtx.indexDecl(I);
447  }
448  for (const auto *I : D->decls()) {
449  if (!isa<ObjCPropertyImplDecl>(I) ||
450  cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
451  IndexCtx.indexDecl(I);
452  }
453 
454  return true;
455  }
456 
457  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
458  if (!IndexCtx.shouldIndex(D))
459  return true;
460  const ObjCInterfaceDecl *C = D->getClassInterface();
461  if (!C)
462  return true;
463  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
465  (unsigned)SymbolRole::RelationExtendedBy, D
466  }));
467  SourceLocation CategoryLoc = D->getCategoryNameLoc();
468  if (!CategoryLoc.isValid())
469  CategoryLoc = D->getLocation();
470  TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
471  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
472  /*SuperLoc=*/SourceLocation()));
473  TRY_TO(IndexCtx.indexDeclContext(D));
474  return true;
475  }
476 
477  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
478  const ObjCCategoryDecl *Cat = D->getCategoryDecl();
479  if (!Cat)
480  return true;
481  const ObjCInterfaceDecl *C = D->getClassInterface();
482  if (C)
483  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
484  SymbolRoleSet()));
485  SourceLocation CategoryLoc = D->getCategoryNameLoc();
486  if (!CategoryLoc.isValid())
487  CategoryLoc = D->getLocation();
488  TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
489  IndexCtx.indexDeclContext(D);
490  return true;
491  }
492 
493  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
494  // Methods associated with a property, even user-declared ones, are
495  // handled when we handle the property.
496  if (D->isPropertyAccessor())
497  return true;
498 
499  handleObjCMethod(D);
500  return true;
501  }
502 
503  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
504  if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
505  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
506  handleObjCMethod(MD, D);
507  if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
508  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
509  handleObjCMethod(MD, D);
510  TRY_DECL(D, IndexCtx.handleDecl(D));
511  if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
512  IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
513  D->getLexicalDeclContext(), false, true);
514  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
515  return true;
516  }
517 
518  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
520  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
521  SourceLocation Loc = D->getLocation();
522  SymbolRoleSet Roles = 0;
524 
525  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
526  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
527  if (Loc.isInvalid()) {
528  Loc = Container->getLocation();
530  }
531  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
532 
534  return true;
535 
537  SymbolRoleSet AccessorMethodRoles =
539  if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
540  if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container))
541  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
542  }
543  if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
544  if (MD->isPropertyAccessor() && !hasUserDefined(MD, Container))
545  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
546  }
547  if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
548  if (IvarD->getSynthesize()) {
549  // For synthesized ivars, use the location of its name in the
550  // corresponding @synthesize. If there isn't one, use the containing
551  // @implementation's location, rather than the property's location,
552  // otherwise the header file containing the @interface will have different
553  // indexing contents based on whether the @implementation was present or
554  // not in the translation unit.
555  SymbolRoleSet IvarRoles = 0;
556  SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
557  if (D->getLocation().isInvalid()) {
558  IvarLoc = Container->getLocation();
559  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
560  } else if (D->getLocation() == IvarLoc) {
561  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
562  }
563  TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
564  } else {
565  IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
566  D->getDeclContext(), SymbolRoleSet());
567  }
568  }
569  return true;
570  }
571 
572  bool VisitNamespaceDecl(const NamespaceDecl *D) {
573  TRY_DECL(D, IndexCtx.handleDecl(D));
574  IndexCtx.indexDeclContext(D);
575  return true;
576  }
577 
578  bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
579  TRY_DECL(D, IndexCtx.handleDecl(D));
582  D->getLexicalDeclContext());
583  return true;
584  }
585 
586  bool VisitUsingDecl(const UsingDecl *D) {
587  IndexCtx.handleDecl(D);
588 
589  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
590  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
592  D->getLexicalDeclContext());
593  for (const auto *I : D->shadows())
594  IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
596  return true;
597  }
598 
599  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
600  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
601  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
602 
603  // NNS for the local 'using namespace' directives is visited by the body
604  // visitor.
605  if (!D->getParentFunctionOrMethod())
607  D->getLexicalDeclContext());
608 
609  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
610  D->getLocation(), Parent,
612  SymbolRoleSet());
613  }
614 
615  bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
616  TRY_DECL(D, IndexCtx.handleDecl(D));
617  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
618  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
620  D->getLexicalDeclContext());
621  return true;
622  }
623 
624  bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
625  TRY_DECL(D, IndexCtx.handleDecl(D));
626  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
627  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
629  D->getLexicalDeclContext());
630  return true;
631  }
632 
633  bool VisitClassTemplateSpecializationDecl(const
635  // FIXME: Notify subsequent callbacks if info comes from implicit
636  // instantiation.
637  llvm::PointerUnion<ClassTemplateDecl *,
639  Template = D->getSpecializedTemplateOrPartial();
640  const Decl *SpecializationOf =
641  Template.is<ClassTemplateDecl *>()
642  ? (Decl *)Template.get<ClassTemplateDecl *>()
643  : Template.get<ClassTemplatePartialSpecializationDecl *>();
646  IndexCtx.indexTagDecl(
648  SpecializationOf));
649  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
650  IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
651  D->getLexicalDeclContext());
652  return true;
653  }
654 
655  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
656  // We want to index the template parameters only once when indexing the
657  // canonical declaration.
658  if (!D)
659  return false;
660  if (const auto *FD = dyn_cast<FunctionDecl>(D))
661  return FD->getCanonicalDecl() == FD;
662  else if (const auto *TD = dyn_cast<TagDecl>(D))
663  return TD->getCanonicalDecl() == TD;
664  else if (const auto *VD = dyn_cast<VarDecl>(D))
665  return VD->getCanonicalDecl() == VD;
666  return true;
667  }
668 
669  bool VisitTemplateDecl(const TemplateDecl *D) {
670 
671  const NamedDecl *Parent = D->getTemplatedDecl();
672  if (!Parent)
673  return true;
674 
675  // Index the default values for the template parameters.
676  if (D->getTemplateParameters() &&
677  shouldIndexTemplateParameterDefaultValue(Parent)) {
678  const TemplateParameterList *Params = D->getTemplateParameters();
679  for (const NamedDecl *TP : *Params) {
680  if (IndexCtx.shouldIndexTemplateParameters())
681  IndexCtx.handleDecl(TP);
682  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
683  if (TTP->hasDefaultArgument())
684  IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
685  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
686  if (NTTP->hasDefaultArgument())
687  IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
688  } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
689  if (TTPD->hasDefaultArgument())
690  handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
691  TP->getLexicalDeclContext());
692  }
693  }
694  }
695 
696  return Visit(Parent);
697  }
698 
699  bool VisitFriendDecl(const FriendDecl *D) {
700  if (auto ND = D->getFriendDecl()) {
701  // FIXME: Ignore a class template in a dependent context, these are not
702  // linked properly with their redeclarations, ending up with duplicate
703  // USRs.
704  // See comment "Friend templates are visible in fairly strange ways." in
705  // SemaTemplate.cpp which precedes code that prevents the friend template
706  // from becoming visible from the enclosing context.
707  if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
708  return true;
709  return Visit(ND);
710  }
711  if (auto Ty = D->getFriendType()) {
712  IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
713  }
714  return true;
715  }
716 
717  bool VisitImportDecl(const ImportDecl *D) {
718  return IndexCtx.importedModule(D);
719  }
720 
721  bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
722  IndexCtx.indexBody(D->getAssertExpr(),
723  dyn_cast<NamedDecl>(D->getDeclContext()),
724  D->getLexicalDeclContext());
725  return true;
726  }
727 };
728 
729 } // anonymous namespace
730 
732  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
733  return true;
734 
735  if (isTemplateImplicitInstantiation(D) && !shouldIndexImplicitInstantiation())
736  return true;
737 
738  IndexingDeclVisitor Visitor(*this);
739  bool ShouldContinue = Visitor.Visit(D);
740  if (!ShouldContinue)
741  return false;
742 
743  if (!Visitor.Handled && isa<DeclContext>(D))
744  return indexDeclContext(cast<DeclContext>(D));
745 
746  return true;
747 }
748 
750  for (const auto *I : DC->decls())
751  if (!indexDecl(I))
752  return false;
753  return true;
754 }
755 
757  if (D->getLocation().isInvalid())
758  return true;
759 
760  if (isa<ObjCMethodDecl>(D))
761  return true; // Wait for the objc container.
762 
763  return indexDecl(D);
764 }
765 
767  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
768  if (!indexTopLevelDecl(*I))
769  return false;
770  return true;
771 }
Represents a function declaration or definition.
Definition: Decl.h:1783
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:527
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:130
unsigned param_size() const
Definition: DeclObjC.h:342
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2339
iterator begin() const
Definition: DeclObjC.h:90
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1544
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2846
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:531
Stmt - This represents one statement.
Definition: Stmt.h:66
Expr * getBitWidth() const
Definition: Decl.h:2818
#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:3679
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:2941
SourceLocation getSuperClassLoc() const
Retrieve the starting location of the superclass.
Definition: DeclObjC.cpp:357
The template argument is an expression, and we&#39;ve not resolved it to one of the other forms yet...
Definition: TemplateBase.h:86
iterator end()
Definition: DeclGroup.h:105
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:434
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:756
Represent a C++ namespace.
Definition: Decl.h:497
A container of type source information.
Definition: Type.h:6227
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2383
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Definition: DeclBase.cpp:254
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
Definition: Decl.h:2869
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:3059
FriendDecl - Represents the declaration of a friend entity, which can be a function, a type, or a templated function or type.
Definition: DeclFriend.h:53
TRY_TO(TraverseType(T->getPointeeType()))
Represents a variable declaration or definition.
Definition: Decl.h:820
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2033
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:603
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:69
Represents a parameter to a function.
Definition: Decl.h:1595
iterator end() const
Definition: DeclObjC.h:91
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:272
Represents a class template specialization, which refers to a class template with a given set of temp...
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:123
const LangOptions & getLangOpts() const
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2135
TemplateDecl * getAsTemplateDecl() const
Retrieve the underlying template declaration that this template name refers to, if known...
Represents a member of a struct/union/class.
Definition: Decl.h:2729
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:939
NamedDecl * getFriendDecl() const
If this friend declaration doesn&#39;t name a type, return the inner declaration.
Definition: DeclFriend.h:138
loc_iterator loc_begin() const
Definition: DeclObjC.h:111
bool shouldIndexParametersInDeclarations() const
Represents a C++ using-declaration.
Definition: DeclCXX.h:3369
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:3903
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:2807
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:2894
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:983
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:2916
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:737
iterator begin()
Definition: DeclGroup.h:99
bool shouldIndexFunctionLocalSymbols() const
void getOverriddenMethods(SmallVectorImpl< const ObjCMethodDecl *> &Overridden) const
Return overridden methods for the given Method.
Definition: DeclObjC.cpp:1296
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:731
const Expr * getInitExpr() const
Definition: Decl.h:2960
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2849
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2078
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC)...
Definition: DeclBase.h:828
Represents an ObjC class declaration.
Definition: DeclObjC.h:1186
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1612
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3653
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2773
NodeId Parent
Definition: ASTDiff.cpp:191
unsigned SymbolRoleSet
Definition: IndexSymbol.h:127
bool hasAttr() const
Definition: DeclBase.h:542
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:671
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3121
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
Definition: Decl.h:3155
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:421
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3409
TypeSourceInfo * getSuperClassTInfo() const
Definition: DeclObjC.h:1587
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:840
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:749
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2649
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2071
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2235
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:558
SourceLocation getSelectorStartLoc() const
Definition: DeclObjC.h:290
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2327
DeclContext * getDeclContext()
Definition: DeclBase.h:438
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:337
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:766
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:2481
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:423
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1091
Selector getSelector() const
Definition: DeclObjC.h:322
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1377
TypeSourceInfo * getAsTypeSourceInfo() const
Definition: TemplateBase.h:425
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:338
bool isSynthesizedAccessorStub() const
Definition: DeclObjC.h:441
Encodes a location in the source.
bool getSynthesize() const
Definition: DeclObjC.h:2005
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3219
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2089
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3588
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3630
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set...
Definition: Decl.h:2876
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:855
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1931
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2908
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2294
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:741
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:1907
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:3763
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:4331
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:3446
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3071
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2454
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:498
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:1271
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:402
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:79
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1355
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3031
const Expr * getInit() const
Definition: Decl.h:1229
A decomposition declaration.
Definition: DeclCXX.h:3869
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3684
Kind getKind() const
Definition: DeclBase.h:432
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source-location information.
Definition: DeclCXX.h:3720
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2566
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:449
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
T * getAttr() const
Definition: DeclBase.h:538
void indexTagDecl(const TagDecl *D, ArrayRef< SymbolRelation > Relations=None)
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:700
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1747
bool importedModule(const ImportDecl *ImportD)
A list of Objective-C protocols, along with the source locations at which they were referenced...
Definition: DeclObjC.h:101
The template argument is a type.
Definition: TemplateBase.h:59
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:234
shadow_range shadows() const
Definition: DeclCXX.h:3469
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3319
Represents a C++ struct/union/class.
Definition: DeclCXX.h:253
The template argument is a template name that was provided for a template template parameter...
Definition: TemplateBase.h:75
TemplateArgumentLocInfo getLocInfo() const
Definition: TemplateBase.h:502
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1959
Location information for a TemplateArgument.
Definition: TemplateBase.h:392
Declaration of a class template.
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2837
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:538
void indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC=nullptr)
Definition: IndexBody.cpp:471
An instance of this class represents the declaration of a property member.
Definition: DeclCXX.h:3940
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:91
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:936
This represents a decl that may have a name.
Definition: Decl.h:223
Represents a C++ namespace alias.
Definition: DeclCXX.h:2967
bool isPropertyAccessor() const
Definition: DeclObjC.h:433
Represents C++ using-directive.
Definition: DeclCXX.h:2863
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:73
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion, return the pattern as a template name.
Definition: TemplateBase.h:287
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition: Decl.h:3359
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2513
SourceLocation getLocation() const
Definition: DeclBase.h:429
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:368
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3063