clang  3.9.0
IndexTypeSourceInfo.cpp
Go to the documentation of this file.
1 //===- IndexTypeSourceInfo.cpp - Indexing types ---------------------------===//
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 
13 using namespace clang;
14 using namespace index;
15 
16 namespace {
17 
18 class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
19  IndexingContext &IndexCtx;
20  const NamedDecl *Parent;
21  const DeclContext *ParentDC;
22  bool IsBase;
24 
26 
27 public:
28  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
29  const DeclContext *DC, bool isBase)
30  : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
31  if (IsBase) {
32  assert(Parent);
33  Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
34  }
35  }
36 
37  bool shouldWalkTypesOfTypeLocs() const { return false; }
38 
39  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
40  return IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
41  Parent, ParentDC, SymbolRoleSet(),
42  Relations);
43  }
44 
45 #define TRY_TO(CALL_EXPR) \
46  do { \
47  if (!CALL_EXPR) \
48  return false; \
49  } while (0)
50 
51  bool traverseParamVarHelper(ParmVarDecl *D) {
52  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
53  if (D->getTypeSourceInfo())
54  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
55  return true;
56  }
57 
58  bool TraverseParmVarDecl(ParmVarDecl *D) {
59  // Avoid visiting default arguments from the definition that were already
60  // visited in the declaration.
61  // FIXME: A free function definition can have default arguments.
62  // Avoiding double visitaiton of default arguments should be handled by the
63  // visitor probably with a bit in the AST to indicate if the attached
64  // default argument was 'inherited' or written in source.
65  if (auto FD = dyn_cast<FunctionDecl>(D->getDeclContext())) {
66  if (FD->isThisDeclarationADefinition()) {
67  return traverseParamVarHelper(D);
68  }
69  }
70 
71  return base::TraverseParmVarDecl(D);
72  }
73 
74  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
75  IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
76  return true;
77  }
78 
79  bool VisitTagTypeLoc(TagTypeLoc TL) {
80  TagDecl *D = TL.getDecl();
81  if (D->getParentFunctionOrMethod())
82  return true;
83 
84  if (TL.isDefinition()) {
85  IndexCtx.indexTagDecl(D);
86  return true;
87  }
88 
89  return IndexCtx.handleReference(D, TL.getNameLoc(),
90  Parent, ParentDC, SymbolRoleSet(),
91  Relations);
92  }
93 
94  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
95  return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
96  Parent, ParentDC, SymbolRoleSet());
97  }
98 
99  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
100  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
101  IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
102  Parent, ParentDC, SymbolRoleSet());
103  }
104  return true;
105  }
106 
107  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
108  if (const TemplateSpecializationType *T = TL.getTypePtr()) {
109  if (IndexCtx.shouldIndexImplicitTemplateInsts()) {
110  if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
111  IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
112  Parent, ParentDC, SymbolRoleSet(), Relations);
113  } else {
114  if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
115  IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
116  Parent, ParentDC, SymbolRoleSet(), Relations);
117  }
118  }
119  return true;
120  }
121 
122  bool TraverseStmt(Stmt *S) {
123  IndexCtx.indexBody(S, Parent, ParentDC);
124  return true;
125  }
126 };
127 
128 } // anonymous namespace
129 
131  const NamedDecl *Parent,
132  const DeclContext *DC,
133  bool isBase) {
134  if (!TInfo || TInfo->getTypeLoc().isNull())
135  return;
136 
137  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase);
138 }
139 
141  const NamedDecl *Parent,
142  const DeclContext *DC,
143  bool isBase) {
144  if (TL.isNull())
145  return;
146 
147  if (!DC)
148  DC = Parent->getLexicalDeclContext();
149  TypeIndexer(*this, Parent, DC, isBase).TraverseTypeLoc(TL);
150 }
151 
153  const NamedDecl *Parent,
154  const DeclContext *DC) {
155  if (!NNS)
156  return;
157 
158  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
159  indexNestedNameSpecifierLoc(Prefix, Parent, DC);
160 
161  if (!DC)
162  DC = Parent->getLexicalDeclContext();
163  SourceLocation Loc = NNS.getSourceRange().getBegin();
164 
165  switch (NNS.getNestedNameSpecifier()->getKind()) {
169  break;
170 
173  Loc, Parent, DC, SymbolRoleSet());
174  break;
177  Loc, Parent, DC, SymbolRoleSet());
178  break;
179 
182  indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
183  break;
184  }
185 }
186 
189  return;
190 
191  if (handleDecl(D)) {
192  if (D->isThisDeclarationADefinition()) {
194  if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
195  for (const auto &I : CXXRD->bases()) {
196  indexTypeSourceInfo(I.getTypeSourceInfo(), CXXRD, CXXRD, /*isBase=*/true);
197  }
198  }
199  indexDeclContext(D);
200  }
201  }
202 }
Wrapper for source info for tag types.
Definition: TypeLoc.h:657
void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false)
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in...
NestedNameSpecifierLoc getPrefix() const
Return the prefix of this nested-name-specifier.
bool handleReference(const NamedDecl *D, SourceLocation Loc, const NamedDecl *Parent, const DeclContext *DC, SymbolRoleSet Roles, ArrayRef< SymbolRelation > Relations=None, const Expr *RefE=nullptr, const Decl *RefD=nullptr)
Wrapper for source info for typedefs.
Definition: TypeLoc.h:620
A container of type source information.
Definition: Decl.h:62
An identifier, stored as an IdentifierInfo*.
TRY_TO(TraverseType(T->getPointeeType()))
A namespace, stored as a NamespaceDecl*.
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1377
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:707
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
bool isDefinition() const
True if the tag was defined in this type specifier.
Definition: TypeLoc.h:664
bool isNull() const
Definition: TypeLoc.h:95
A C++ nested-name-specifier augmented with source location information.
unsigned getNumProtocols() const
Definition: TypeLoc.h:910
bool isThisDeclarationADefinition() const
isThisDeclarationADefinition() - Return true if this declaration is a completion definition of the ty...
Definition: Decl.h:2865
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier (with source-location information) that qualifies the name of this...
Definition: Decl.h:2978
Wrapper for source info for ObjC interfaces.
Definition: TypeLoc.h:981
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
detail::InMemoryDirectory::const_iterator I
TypedefNameDecl * getTypedefNameDecl() const
Definition: TypeLoc.h:624
void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent, const DeclContext *DC=nullptr, bool isBase=false)
unsigned SymbolRoleSet
Definition: IndexSymbol.h:93
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
TagDecl * getDecl() const
Definition: TypeLoc.h:661
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
bool indexDeclContext(const DeclContext *DC)
Definition: IndexDecl.cpp:432
A namespace alias, stored as a NamespaceAliasDecl*.
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:1483
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:671
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
static bool isFunctionLocalDecl(const Decl *D)
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:215
Encodes a location in the source.
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2727
SourceLocation getNameLoc() const
Definition: TypeLoc.h:493
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
SourceLocation getBegin() const
SourceLocation getNameLoc() const
Definition: TypeLoc.h:990
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:1135
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:330
ObjCInterfaceDecl * getIFaceDecl() const
Definition: TypeLoc.h:986
A type that was preceded by the 'template' keyword, stored as a Type*.
void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, const NamedDecl *Parent, const DeclContext *DC=nullptr)
bool shouldIndexFunctionLocalSymbols() const
ObjCProtocolDecl * getProtocol(unsigned i) const
Definition: TypeLoc.h:923
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:379
SourceLocation getProtocolLoc(unsigned i) const
Definition: TypeLoc.h:914
Represents a C++ struct/union/class.
Definition: DeclCXX.h:263
void indexTagDecl(const TagDecl *D)
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213
The global specifier '::'. There is no stored value.
TemplateSpecializationType(TemplateName T, ArrayRef< TemplateArgument > Args, QualType Canon, QualType Aliased)