clang  10.0.0svn
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"
11 #include "clang/AST/DeclVisitor.h"
12 
13 using namespace clang;
14 using namespace index;
15 
16 #define TRY_DECL(D,CALL_EXPR) \
17  do { \
18  if (!IndexCtx.shouldIndex(D)) return true; \
19  if (!CALL_EXPR) \
20  return false; \
21  } while (0)
22 
23 #define TRY_TO(CALL_EXPR) \
24  do { \
25  if (!CALL_EXPR) \
26  return false; \
27  } while (0)
28 
29 namespace {
30 
31 class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
32  IndexingContext &IndexCtx;
33 
34 public:
35  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
36  : IndexCtx(indexCtx) { }
37 
38  bool Handled = true;
39 
40  bool VisitDecl(const Decl *D) {
41  Handled = false;
42  return true;
43  }
44 
45  /// Returns true if the given method has been defined explicitly by the
46  /// user.
47  static bool hasUserDefined(const ObjCMethodDecl *D,
48  const ObjCImplDecl *Container) {
49  const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
50  D->isInstanceMethod());
51  return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
52  }
53 
54  void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
55  const NamedDecl *Parent,
56  const DeclContext *DC) {
57  const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
58  switch (TALoc.getArgument().getKind()) {
60  IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
61  break;
63  IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
64  break;
68  Parent, DC);
69  if (const TemplateDecl *TD = TALoc.getArgument()
71  .getAsTemplateDecl()) {
72  if (const NamedDecl *TTD = TD->getTemplatedDecl())
73  IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
74  }
75  break;
76  default:
77  break;
78  }
79  }
80 
81  void handleDeclarator(const DeclaratorDecl *D,
82  const NamedDecl *Parent = nullptr,
83  bool isIBType = false) {
84  if (!Parent) Parent = D;
85 
87  Parent->getLexicalDeclContext(),
88  /*isBase=*/false, isIBType);
90  if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
91  if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
92  auto *DC = Parm->getDeclContext();
93  if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
94  if (IndexCtx.shouldIndexParametersInDeclarations() ||
95  FD->isThisDeclarationADefinition())
96  IndexCtx.handleDecl(Parm);
97  } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
98  if (MD->isThisDeclarationADefinition())
99  IndexCtx.handleDecl(Parm);
100  } else {
101  IndexCtx.handleDecl(Parm);
102  }
103  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
104  if (IndexCtx.shouldIndexParametersInDeclarations() ||
105  FD->isThisDeclarationADefinition()) {
106  for (auto PI : FD->parameters()) {
107  IndexCtx.handleDecl(PI);
108  }
109  }
110  }
111  } else {
112  // Index the default parameter value for function definitions.
113  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
114  if (FD->isThisDeclarationADefinition()) {
115  for (const auto *PV : FD->parameters()) {
116  if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
117  !PV->hasUnparsedDefaultArg())
118  IndexCtx.indexBody(PV->getDefaultArg(), D);
119  }
120  }
121  }
122  }
123  }
124 
125  bool handleObjCMethod(const ObjCMethodDecl *D,
126  const ObjCPropertyDecl *AssociatedProp = nullptr) {
129 
130  D->getOverriddenMethods(Overriden);
131  for(auto overridden: Overriden) {
132  Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
133  overridden);
134  }
135  if (AssociatedProp)
136  Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
137  AssociatedProp);
138 
139  // getLocation() returns beginning token of a method declaration, but for
140  // indexing purposes we want to point to the base name.
141  SourceLocation MethodLoc = D->getSelectorStartLoc();
142  if (MethodLoc.isInvalid())
143  MethodLoc = D->getLocation();
144 
145  SourceLocation AttrLoc;
146 
147  // check for (getter=/setter=)
148  if (AssociatedProp) {
149  bool isGetter = !D->param_size();
150  AttrLoc = isGetter ?
151  AssociatedProp->getGetterNameLoc():
152  AssociatedProp->getSetterNameLoc();
153  }
154 
156  if (D->isImplicit()) {
157  if (AttrLoc.isValid()) {
158  MethodLoc = AttrLoc;
159  } else {
161  }
162  } else if (AttrLoc.isValid()) {
163  IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
164  D->getDeclContext(), 0);
165  }
166 
167  TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
169  bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
170  for (const auto *I : D->parameters()) {
171  handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
172  hasIBActionAndFirst = false;
173  }
174 
175  if (D->isThisDeclarationADefinition()) {
176  const Stmt *Body = D->getBody();
177  if (Body) {
178  IndexCtx.indexBody(Body, D, D);
179  }
180  }
181  return true;
182  }
183 
184  /// Gather the declarations which the given declaration \D overrides in a
185  /// pseudo-override manner.
186  ///
187  /// Pseudo-overrides occur when a class template specialization declares
188  /// a declaration that has the same name as a similar declaration in the
189  /// non-specialized template.
190  void
191  gatherTemplatePseudoOverrides(const NamedDecl *D,
192  SmallVectorImpl<SymbolRelation> &Relations) {
193  if (!IndexCtx.getLangOpts().CPlusPlus)
194  return;
195  const auto *CTSD =
197  if (!CTSD)
198  return;
199  llvm::PointerUnion<ClassTemplateDecl *,
201  Template = CTSD->getSpecializedTemplateOrPartial();
202  if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
203  const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
204  bool TypeOverride = isa<TypeDecl>(D);
205  for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
206  if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
207  ND = CTD->getTemplatedDecl();
208  if (ND->isImplicit())
209  continue;
210  // Types can override other types.
211  if (!TypeOverride) {
212  if (ND->getKind() != D->getKind())
213  continue;
214  } else if (!isa<TypeDecl>(ND))
215  continue;
216  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
217  const auto *DFD = cast<FunctionDecl>(D);
218  // Function overrides are approximated using the number of parameters.
219  if (FD->getStorageClass() != DFD->getStorageClass() ||
220  FD->getNumParams() != DFD->getNumParams())
221  continue;
222  }
223  Relations.emplace_back(
225  }
226  }
227  }
228 
229  bool VisitFunctionDecl(const FunctionDecl *D) {
230  SymbolRoleSet Roles{};
232  if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
233  if (CXXMD->isVirtual())
234  Roles |= (unsigned)SymbolRole::Dynamic;
235  for (const CXXMethodDecl *O : CXXMD->overridden_methods()) {
236  Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, O);
237  }
238  }
239  gatherTemplatePseudoOverrides(D, Relations);
240  if (const auto *Base = D->getPrimaryTemplate())
241  Relations.push_back(
243  Base->getTemplatedDecl()));
244 
245  TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
246  handleDeclarator(D);
247 
248  if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
249  IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
250  Ctor->getParent(), Ctor->getDeclContext(),
251  (unsigned)SymbolRole::NameReference);
252 
253  // Constructor initializers.
254  for (const auto *Init : Ctor->inits()) {
255  if (Init->isWritten()) {
256  IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
257  if (const FieldDecl *Member = Init->getAnyMember())
258  IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
259  (unsigned)SymbolRole::Write);
260  IndexCtx.indexBody(Init->getInit(), D, D);
261  }
262  }
263  } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
264  if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
265  IndexCtx.handleReference(Dtor->getParent(),
266  TypeNameInfo->getTypeLoc().getBeginLoc(),
267  Dtor->getParent(), Dtor->getDeclContext(),
268  (unsigned)SymbolRole::NameReference);
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  TRY_DECL(D, IndexCtx.handleDecl(D));
330  handleDeclarator(D);
331  return true;
332  }
333 
334  bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
335  TRY_DECL(D, IndexCtx.handleDecl(D));
336  IndexCtx.indexBody(D->getInitExpr(), D);
337  return true;
338  }
339 
340  bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
341  if (!D->isTransparentTag()) {
343  gatherTemplatePseudoOverrides(D, Relations);
344  TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
345  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
346  }
347  return true;
348  }
349 
350  bool VisitTagDecl(const TagDecl *D) {
351  // Non-free standing tags are handled in indexTypeSourceInfo.
352  if (D->isFreeStanding()) {
353  if (D->isThisDeclarationADefinition()) {
355  gatherTemplatePseudoOverrides(D, Relations);
356  IndexCtx.indexTagDecl(D, Relations);
357  } else {
359  gatherTemplatePseudoOverrides(D, Relations);
360  return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
361  Relations, D->getLexicalDeclContext());
362  }
363  }
364  return true;
365  }
366 
367  bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
368  const ObjCContainerDecl *ContD,
369  SourceLocation SuperLoc) {
372  I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
373  SourceLocation Loc = *LI;
374  ObjCProtocolDecl *PD = *I;
375  SymbolRoleSet roles{};
376  if (Loc == SuperLoc)
378  TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
379  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
380  }
381  return true;
382  }
383 
384  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
385  if (D->isThisDeclarationADefinition()) {
386  TRY_DECL(D, IndexCtx.handleDecl(D));
387  SourceLocation SuperLoc = D->getSuperClassLoc();
388  if (auto *SuperD = D->getSuperClass()) {
389  bool hasSuperTypedef = false;
390  if (auto *TInfo = D->getSuperClassTInfo()) {
391  if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
392  if (auto *TD = TT->getDecl()) {
393  hasSuperTypedef = true;
394  TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
395  SymbolRoleSet()));
396  }
397  }
398  }
399  SymbolRoleSet superRoles{};
400  if (hasSuperTypedef)
401  superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
402  TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
403  SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
404  }
405  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
406  SuperLoc));
407  TRY_TO(IndexCtx.indexDeclContext(D));
408  } else {
409  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
410  D->getDeclContext(), SymbolRoleSet());
411  }
412  return true;
413  }
414 
415  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
416  if (D->isThisDeclarationADefinition()) {
417  TRY_DECL(D, IndexCtx.handleDecl(D));
418  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
419  /*SuperLoc=*/SourceLocation()));
420  TRY_TO(IndexCtx.indexDeclContext(D));
421  } else {
422  return IndexCtx.handleReference(D, D->getLocation(), nullptr,
423  D->getDeclContext(), SymbolRoleSet());
424  }
425  return true;
426  }
427 
428  bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
430  if (!Class)
431  return true;
432 
433  if (Class->isImplicitInterfaceDecl())
434  IndexCtx.handleDecl(Class);
435 
436  TRY_DECL(D, IndexCtx.handleDecl(D));
437 
438  // Visit implicit @synthesize property implementations first as their
439  // location is reported at the name of the @implementation block. This
440  // serves no purpose other than to simplify the FileCheck-based tests.
441  for (const auto *I : D->property_impls()) {
442  if (I->getLocation().isInvalid())
443  IndexCtx.indexDecl(I);
444  }
445  for (const auto *I : D->decls()) {
446  if (!isa<ObjCPropertyImplDecl>(I) ||
447  cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
448  IndexCtx.indexDecl(I);
449  }
450 
451  return true;
452  }
453 
454  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
455  if (!IndexCtx.shouldIndex(D))
456  return true;
457  const ObjCInterfaceDecl *C = D->getClassInterface();
458  if (!C)
459  return true;
460  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
462  (unsigned)SymbolRole::RelationExtendedBy, D
463  }));
464  SourceLocation CategoryLoc = D->getCategoryNameLoc();
465  if (!CategoryLoc.isValid())
466  CategoryLoc = D->getLocation();
467  TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
468  TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
469  /*SuperLoc=*/SourceLocation()));
470  TRY_TO(IndexCtx.indexDeclContext(D));
471  return true;
472  }
473 
474  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
475  const ObjCCategoryDecl *Cat = D->getCategoryDecl();
476  if (!Cat)
477  return true;
478  const ObjCInterfaceDecl *C = D->getClassInterface();
479  if (C)
480  TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
481  SymbolRoleSet()));
482  SourceLocation CategoryLoc = D->getCategoryNameLoc();
483  if (!CategoryLoc.isValid())
484  CategoryLoc = D->getLocation();
485  TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
486  IndexCtx.indexDeclContext(D);
487  return true;
488  }
489 
490  bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
491  // Methods associated with a property, even user-declared ones, are
492  // handled when we handle the property.
493  if (D->isPropertyAccessor())
494  return true;
495 
496  handleObjCMethod(D);
497  return true;
498  }
499 
500  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
501  if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
502  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
503  handleObjCMethod(MD, D);
504  if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
505  if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
506  handleObjCMethod(MD, D);
507  TRY_DECL(D, IndexCtx.handleDecl(D));
508  if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
509  IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
510  D->getLexicalDeclContext(), false, true);
511  IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
512  return true;
513  }
514 
515  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
517  auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
518  SourceLocation Loc = D->getLocation();
519  SymbolRoleSet Roles = 0;
521 
522  if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
523  Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
524  if (Loc.isInvalid()) {
525  Loc = Container->getLocation();
527  }
528  TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
529 
531  return true;
532 
534  SymbolRoleSet AccessorMethodRoles =
536  if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
537  if (MD->isPropertyAccessor() &&
538  !hasUserDefined(MD, Container))
539  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
540  }
541  if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
542  if (MD->isPropertyAccessor() &&
543  !hasUserDefined(MD, Container))
544  IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
545  }
546  if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
547  if (IvarD->getSynthesize()) {
548  // For synthesized ivars, use the location of its name in the
549  // corresponding @synthesize. If there isn't one, use the containing
550  // @implementation's location, rather than the property's location,
551  // otherwise the header file containing the @interface will have different
552  // indexing contents based on whether the @implementation was present or
553  // not in the translation unit.
554  SymbolRoleSet IvarRoles = 0;
555  SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
556  if (D->getLocation().isInvalid()) {
557  IvarLoc = Container->getLocation();
558  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
559  } else if (D->getLocation() == IvarLoc) {
560  IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
561  }
562  TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
563  } else {
564  IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
565  D->getDeclContext(), SymbolRoleSet());
566  }
567  }
568  return true;
569  }
570 
571  bool VisitNamespaceDecl(const NamespaceDecl *D) {
572  TRY_DECL(D, IndexCtx.handleDecl(D));
573  IndexCtx.indexDeclContext(D);
574  return true;
575  }
576 
577  bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
578  TRY_DECL(D, IndexCtx.handleDecl(D));
581  D->getLexicalDeclContext());
582  return true;
583  }
584 
585  bool VisitUsingDecl(const UsingDecl *D) {
586  IndexCtx.handleDecl(D);
587 
588  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
589  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
591  D->getLexicalDeclContext());
592  for (const auto *I : D->shadows())
593  IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
595  return true;
596  }
597 
598  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
599  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
600  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
601 
602  // NNS for the local 'using namespace' directives is visited by the body
603  // visitor.
604  if (!D->getParentFunctionOrMethod())
606  D->getLexicalDeclContext());
607 
608  return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
609  D->getLocation(), Parent,
611  SymbolRoleSet());
612  }
613 
614  bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
615  TRY_DECL(D, IndexCtx.handleDecl(D));
616  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
617  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
619  D->getLexicalDeclContext());
620  return true;
621  }
622 
623  bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
624  TRY_DECL(D, IndexCtx.handleDecl(D));
625  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
626  const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
628  D->getLexicalDeclContext());
629  return true;
630  }
631 
632  bool VisitClassTemplateSpecializationDecl(const
634  // FIXME: Notify subsequent callbacks if info comes from implicit
635  // instantiation.
636  llvm::PointerUnion<ClassTemplateDecl *,
638  Template = D->getSpecializedTemplateOrPartial();
639  const Decl *SpecializationOf =
640  Template.is<ClassTemplateDecl *>()
641  ? (Decl *)Template.get<ClassTemplateDecl *>()
642  : Template.get<ClassTemplatePartialSpecializationDecl *>();
645  IndexCtx.indexTagDecl(
647  SpecializationOf));
648  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
649  IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
650  D->getLexicalDeclContext());
651  return true;
652  }
653 
654  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
655  // We want to index the template parameters only once when indexing the
656  // canonical declaration.
657  if (!D)
658  return false;
659  if (const auto *FD = dyn_cast<FunctionDecl>(D))
660  return FD->getCanonicalDecl() == FD;
661  else if (const auto *TD = dyn_cast<TagDecl>(D))
662  return TD->getCanonicalDecl() == TD;
663  else if (const auto *VD = dyn_cast<VarDecl>(D))
664  return VD->getCanonicalDecl() == VD;
665  return true;
666  }
667 
668  bool VisitTemplateDecl(const TemplateDecl *D) {
669 
670  const NamedDecl *Parent = D->getTemplatedDecl();
671  if (!Parent)
672  return true;
673 
674  // Index the default values for the template parameters.
675  if (D->getTemplateParameters() &&
676  shouldIndexTemplateParameterDefaultValue(Parent)) {
677  const TemplateParameterList *Params = D->getTemplateParameters();
678  for (const NamedDecl *TP : *Params) {
679  if (IndexCtx.shouldIndexTemplateParameters())
680  IndexCtx.handleDecl(TP);
681  if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
682  if (TTP->hasDefaultArgument())
683  IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
684  } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
685  if (NTTP->hasDefaultArgument())
686  IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
687  } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
688  if (TTPD->hasDefaultArgument())
689  handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
690  TP->getLexicalDeclContext());
691  }
692  }
693  }
694 
695  return Visit(Parent);
696  }
697 
698  bool VisitFriendDecl(const FriendDecl *D) {
699  if (auto ND = D->getFriendDecl()) {
700  // FIXME: Ignore a class template in a dependent context, these are not
701  // linked properly with their redeclarations, ending up with duplicate
702  // USRs.
703  // See comment "Friend templates are visible in fairly strange ways." in
704  // SemaTemplate.cpp which precedes code that prevents the friend template
705  // from becoming visible from the enclosing context.
706  if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
707  return true;
708  return Visit(ND);
709  }
710  if (auto Ty = D->getFriendType()) {
711  IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
712  }
713  return true;
714  }
715 
716  bool VisitImportDecl(const ImportDecl *D) {
717  return IndexCtx.importedModule(D);
718  }
719 
720  bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
721  IndexCtx.indexBody(D->getAssertExpr(),
722  dyn_cast<NamedDecl>(D->getDeclContext()),
723  D->getLexicalDeclContext());
724  return true;
725  }
726 };
727 
728 } // anonymous namespace
729 
731  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
732  return true;
733 
734  if (isTemplateImplicitInstantiation(D) && !shouldIndexImplicitInstantiation())
735  return true;
736 
737  IndexingDeclVisitor Visitor(*this);
738  bool ShouldContinue = Visitor.Visit(D);
739  if (!ShouldContinue)
740  return false;
741 
742  if (!Visitor.Handled && isa<DeclContext>(D))
743  return indexDeclContext(cast<DeclContext>(D));
744 
745  return true;
746 }
747 
749  for (const auto *I : DC->decls())
750  if (!indexDecl(I))
751  return false;
752  return true;
753 }
754 
756  if (D->getLocation().isInvalid())
757  return true;
758 
759  if (isa<ObjCMethodDecl>(D))
760  return true; // Wait for the objc container.
761 
762  return indexDecl(D);
763 }
764 
766  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
767  if (!indexTopLevelDecl(*I))
768  return false;
769  return true;
770 }
Represents a function declaration or definition.
Definition: Decl.h:1784
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:514
Represents a relation to another symbol for a symbol occurrence.
Definition: IndexSymbol.h:130
unsigned param_size() const
Definition: DeclObjC.h:340
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2324
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:1529
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2826
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:531
Stmt - This represents one statement.
Definition: Stmt.h:66
Expr * getBitWidth() const
Definition: Decl.h:2732
#define TRY_DECL(D, CALL_EXPR)
Definition: IndexDecl.cpp:16
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:3604
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:2855
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:419
bool indexTopLevelDecl(const Decl *D)
Definition: IndexDecl.cpp:755
Represent a C++ namespace.
Definition: Decl.h:522
A container of type source information.
Definition: Decl.h:86
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2365
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:2783
SourceLocation getTargetNameLoc() const
Returns the location of the identifier in the named namespace.
Definition: DeclCXX.h:3041
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:827
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2028
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:67
Represents a parameter to a function.
Definition: Decl.h:1600
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:297
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:2120
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:2643
ObjCMethodDecl * getSetterMethodDecl() const
Definition: DeclObjC.h:924
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:3275
ArrayRef< BindingDecl * > bindings() const
Definition: DeclCXX.h:3809
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:2721
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:2849
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:968
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:2898
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:760
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:1284
bool indexDecl(const Decl *D)
Definition: IndexDecl.cpp:730
const Expr * getInitExpr() const
Definition: Decl.h:2874
SourceLocation getPropertyIvarDeclLoc() const
Definition: DeclObjC.h:2829
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2063
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:1171
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1609
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
Definition: Decl.cpp:3578
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2758
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:696
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3035
bool isTransparentTag() const
Determines if this typedef shares a name and spelling location with its underlying tag type...
Definition: Decl.h:3069
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:406
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:1572
TypeSourceInfo * getTypeSourceInfo() const
Definition: DeclObjC.h:826
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:748
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2629
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2033
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2220
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:558
SourceLocation getSelectorStartLoc() const
Definition: DeclObjC.h:288
overridden_method_range overridden_methods() const
Definition: DeclCXX.cpp:2285
DeclContext * getDeclContext()
Definition: DeclBase.h:438
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:337
bool indexDeclGroupRef(DeclGroupRef DG)
Definition: IndexDecl.cpp:765
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:2466
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:421
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1089
Selector getSelector() const
Definition: DeclObjC.h:320
ObjCProtocolList::iterator protocol_iterator
Definition: DeclObjC.h:1362
TypeSourceInfo * getAsTypeSourceInfo() const
Definition: TemplateBase.h:425
TypeSourceInfo * getReturnTypeSourceInfo() const
Definition: DeclObjC.h:336
Encodes a location in the source.
bool getSynthesize() const
Definition: DeclObjC.h:1990
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3133
ObjCCategoryDecl * getCategoryDecl() const
Definition: DeclObjC.cpp:2063
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:2790
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:851
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1905
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:2890
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2279
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:728
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:1892
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:4245
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:3360
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2985
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2439
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:387
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2822
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:1340
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name of the namespace, with source-location inf...
Definition: DeclCXX.h:3013
const Expr * getInit() const
Definition: Decl.h:1234
A decomposition declaration.
Definition: DeclCXX.h:3775
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3590
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:3626
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2551
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:723
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1744
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:3375
bool isThisDeclarationADefinition() const
Return true if this declaration is a completion definition of the type.
Definition: Decl.h:3233
Represents a C++ struct/union/class.
Definition: DeclCXX.h:255
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:1944
Location information for a TemplateArgument.
Definition: TemplateBase.h:392
Declaration of a class template.
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2817
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:3846
ObjCMethodDecl * getMethod(Selector Sel, bool isInstance, bool AllowHidden=false) const
Definition: DeclObjC.cpp:91
ObjCMethodDecl * getGetterMethodDecl() const
Definition: DeclObjC.h:921
This represents a decl that may have a name.
Definition: Decl.h:248
Represents a C++ namespace alias.
Definition: DeclCXX.h:2949
bool isPropertyAccessor() const
Definition: DeclObjC.h:431
Represents C++ using-directive.
Definition: DeclCXX.h:2845
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:3273
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2498
SourceLocation getLocation() const
Definition: DeclBase.h:429
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:366
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3045