blob: bf3bfd1b95b3a1eaff71efd69d4442ea07d141fd [file] [log] [blame]
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +00001//===--- IndexSymbol.cpp - Types and functions for indexing symbols -------===//
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 "clang/Index/IndexSymbol.h"
11#include "clang/AST/DeclCXX.h"
12#include "clang/AST/DeclObjC.h"
13#include "clang/AST/DeclTemplate.h"
14
15using namespace clang;
16using namespace clang::index;
17
18SymbolInfo index::getSymbolInfo(const Decl *D) {
19 assert(D);
20 SymbolInfo Info;
21 Info.Kind = SymbolKind::Unknown;
22 Info.TemplateKind = SymbolCXXTemplateKind::NonTemplate;
23 Info.Lang = SymbolLanguage::C;
24
25 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
26 switch (TD->getTagKind()) {
27 case TTK_Struct:
28 Info.Kind = SymbolKind::Struct; break;
29 case TTK_Union:
30 Info.Kind = SymbolKind::Union; break;
31 case TTK_Class:
32 Info.Kind = SymbolKind::CXXClass;
33 Info.Lang = SymbolLanguage::CXX;
34 break;
35 case TTK_Interface:
36 Info.Kind = SymbolKind::CXXInterface;
37 Info.Lang = SymbolLanguage::CXX;
38 break;
39 case TTK_Enum:
40 Info.Kind = SymbolKind::Enum; break;
41 }
42
43 if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D))
44 if (!CXXRec->isCLike())
45 Info.Lang = SymbolLanguage::CXX;
46
47 if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
48 Info.TemplateKind = SymbolCXXTemplateKind::TemplatePartialSpecialization;
49 } else if (isa<ClassTemplateSpecializationDecl>(D)) {
50 Info.TemplateKind = SymbolCXXTemplateKind::TemplateSpecialization;
51 }
52
53 } else {
54 switch (D->getKind()) {
55 case Decl::Typedef:
56 Info.Kind = SymbolKind::Typedef; break;
57 case Decl::Function:
58 Info.Kind = SymbolKind::Function;
59 break;
60 case Decl::ParmVar:
61 Info.Kind = SymbolKind::Variable;
62 break;
63 case Decl::Var:
64 Info.Kind = SymbolKind::Variable;
65 if (isa<CXXRecordDecl>(D->getDeclContext())) {
66 Info.Kind = SymbolKind::CXXStaticVariable;
67 Info.Lang = SymbolLanguage::CXX;
68 }
69 break;
70 case Decl::Field:
71 Info.Kind = SymbolKind::Field;
72 if (const CXXRecordDecl *
73 CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
74 if (!CXXRec->isCLike())
75 Info.Lang = SymbolLanguage::CXX;
76 }
77 break;
78 case Decl::EnumConstant:
79 Info.Kind = SymbolKind::EnumConstant; break;
80 case Decl::ObjCInterface:
81 case Decl::ObjCImplementation:
82 Info.Kind = SymbolKind::ObjCClass;
83 Info.Lang = SymbolLanguage::ObjC;
84 break;
85 case Decl::ObjCProtocol:
86 Info.Kind = SymbolKind::ObjCProtocol;
87 Info.Lang = SymbolLanguage::ObjC;
88 break;
89 case Decl::ObjCCategory:
90 case Decl::ObjCCategoryImpl:
91 Info.Kind = SymbolKind::ObjCCategory;
92 Info.Lang = SymbolLanguage::ObjC;
93 break;
94 case Decl::ObjCMethod:
95 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
96 Info.Kind = SymbolKind::ObjCInstanceMethod;
97 else
98 Info.Kind = SymbolKind::ObjCClassMethod;
99 Info.Lang = SymbolLanguage::ObjC;
100 break;
101 case Decl::ObjCProperty:
102 Info.Kind = SymbolKind::ObjCProperty;
103 Info.Lang = SymbolLanguage::ObjC;
104 break;
105 case Decl::ObjCIvar:
106 Info.Kind = SymbolKind::ObjCIvar;
107 Info.Lang = SymbolLanguage::ObjC;
108 break;
109 case Decl::Namespace:
110 Info.Kind = SymbolKind::CXXNamespace;
111 Info.Lang = SymbolLanguage::CXX;
112 break;
113 case Decl::NamespaceAlias:
114 Info.Kind = SymbolKind::CXXNamespaceAlias;
115 Info.Lang = SymbolLanguage::CXX;
116 break;
117 case Decl::CXXConstructor:
118 Info.Kind = SymbolKind::CXXConstructor;
119 Info.Lang = SymbolLanguage::CXX;
120 break;
121 case Decl::CXXDestructor:
122 Info.Kind = SymbolKind::CXXDestructor;
123 Info.Lang = SymbolLanguage::CXX;
124 break;
125 case Decl::CXXConversion:
126 Info.Kind = SymbolKind::CXXConversionFunction;
127 Info.Lang = SymbolLanguage::CXX;
128 break;
129 case Decl::CXXMethod: {
130 const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
131 if (MD->isStatic())
132 Info.Kind = SymbolKind::CXXStaticMethod;
133 else
134 Info.Kind = SymbolKind::CXXInstanceMethod;
135 Info.Lang = SymbolLanguage::CXX;
136 break;
137 }
138 case Decl::ClassTemplate:
139 Info.Kind = SymbolKind::CXXClass;
140 Info.TemplateKind = SymbolCXXTemplateKind::Template;
141 break;
142 case Decl::FunctionTemplate:
143 Info.Kind = SymbolKind::Function;
144 Info.TemplateKind = SymbolCXXTemplateKind::Template;
145 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
146 cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
147 if (isa<CXXConstructorDecl>(MD))
148 Info.Kind = SymbolKind::CXXConstructor;
149 else if (isa<CXXDestructorDecl>(MD))
150 Info.Kind = SymbolKind::CXXDestructor;
151 else if (isa<CXXConversionDecl>(MD))
152 Info.Kind = SymbolKind::CXXConversionFunction;
153 else {
154 if (MD->isStatic())
155 Info.Kind = SymbolKind::CXXStaticMethod;
156 else
157 Info.Kind = SymbolKind::CXXInstanceMethod;
158 }
159 }
160 break;
161 case Decl::TypeAliasTemplate:
162 Info.Kind = SymbolKind::CXXTypeAlias;
163 Info.TemplateKind = SymbolCXXTemplateKind::Template;
164 break;
165 case Decl::TypeAlias:
166 Info.Kind = SymbolKind::CXXTypeAlias;
167 Info.Lang = SymbolLanguage::CXX;
168 break;
169 default:
170 break;
171 }
172 }
173
174 if (Info.Kind == SymbolKind::Unknown)
175 return Info;
176
177 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
178 if (FD->getTemplatedKind() ==
179 FunctionDecl::TK_FunctionTemplateSpecialization)
180 Info.TemplateKind = SymbolCXXTemplateKind::TemplateSpecialization;
181 }
182
183 if (Info.TemplateKind != SymbolCXXTemplateKind::NonTemplate)
184 Info.Lang = SymbolLanguage::CXX;
185
186 return Info;
187}
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000188
189void index::applyForEachSymbolRole(SymbolRoleSet Roles,
190 llvm::function_ref<void(SymbolRole)> Fn) {
191#define APPLY_FOR_ROLE(Role) \
192 if (Roles & (unsigned)SymbolRole::Role) \
193 Fn(SymbolRole::Role)
194
195 APPLY_FOR_ROLE(Declaration);
196 APPLY_FOR_ROLE(Definition);
197 APPLY_FOR_ROLE(Reference);
198 APPLY_FOR_ROLE(Read);
199 APPLY_FOR_ROLE(Write);
200 APPLY_FOR_ROLE(Call);
201 APPLY_FOR_ROLE(Dynamic);
202 APPLY_FOR_ROLE(AddressOf);
203 APPLY_FOR_ROLE(Implicit);
204 APPLY_FOR_ROLE(RelationChildOf);
205 APPLY_FOR_ROLE(RelationBaseOf);
206 APPLY_FOR_ROLE(RelationOverrideOf);
207 APPLY_FOR_ROLE(RelationReceivedBy);
208
209#undef APPLY_FOR_ROLE
210}
211
212void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
213 bool VisitedOnce = false;
214 applyForEachSymbolRole(Roles, [&](SymbolRole Role) {
215 if (VisitedOnce)
216 OS << '/';
217 else
218 VisitedOnce = true;
219 switch (Role) {
220 case SymbolRole::Declaration: OS << "Decl"; break;
221 case SymbolRole::Definition: OS << "Def"; break;
222 case SymbolRole::Reference: OS << "Ref"; break;
223 case SymbolRole::Read: OS << "Read"; break;
224 case SymbolRole::Write: OS << "Writ"; break;
225 case SymbolRole::Call: OS << "Call"; break;
226 case SymbolRole::Dynamic: OS << "Dyn"; break;
227 case SymbolRole::AddressOf: OS << "Addr"; break;
228 case SymbolRole::Implicit: OS << "Impl"; break;
229 case SymbolRole::RelationChildOf: OS << "RelChild"; break;
230 case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
231 case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
232 case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
233 }
234 });
235}
236
237StringRef index::getSymbolKindString(SymbolKind K) {
238 switch (K) {
239 case SymbolKind::Unknown: return "<unknown>";
240 case SymbolKind::Module: return "module";
241 case SymbolKind::Macro: return "macro";
242 case SymbolKind::Enum: return "enum";
243 case SymbolKind::Struct: return "struct";
244 case SymbolKind::Union: return "union";
245 case SymbolKind::Typedef: return "typedef";
246 case SymbolKind::Function: return "function";
247 case SymbolKind::Variable: return "variable";
248 case SymbolKind::Field: return "field";
249 case SymbolKind::EnumConstant: return "enumerator";
250 case SymbolKind::ObjCClass: return "objc-class";
251 case SymbolKind::ObjCProtocol: return "objc-protocol";
252 case SymbolKind::ObjCCategory: return "objc-category";
253 case SymbolKind::ObjCInstanceMethod: return "objc-instance-method";
254 case SymbolKind::ObjCClassMethod: return "objc-class-method";
255 case SymbolKind::ObjCProperty: return "objc-property";
256 case SymbolKind::ObjCIvar: return "objc-ivar";
257 case SymbolKind::CXXClass: return "c++-class";
258 case SymbolKind::CXXNamespace: return "namespace";
259 case SymbolKind::CXXNamespaceAlias: return "namespace-alias";
260 case SymbolKind::CXXStaticVariable: return "c++-static-var";
261 case SymbolKind::CXXStaticMethod: return "c++-static-method";
262 case SymbolKind::CXXInstanceMethod: return "c++-instance-method";
263 case SymbolKind::CXXConstructor: return "constructor";
264 case SymbolKind::CXXDestructor: return "destructor";
265 case SymbolKind::CXXConversionFunction: return "coversion-func";
266 case SymbolKind::CXXTypeAlias: return "type-alias";
267 case SymbolKind::CXXInterface: return "c++-__interface";
268 }
269}
270
271StringRef index::getTemplateKindStr(SymbolCXXTemplateKind TK) {
272 switch (TK) {
273 case SymbolCXXTemplateKind::NonTemplate: return "NT";
274 case SymbolCXXTemplateKind::Template : return "T";
275 case SymbolCXXTemplateKind::TemplatePartialSpecialization : return "TPS";
276 case SymbolCXXTemplateKind::TemplateSpecialization: return "TS";
277 }
278}
279
280StringRef index::getSymbolLanguageString(SymbolLanguage K) {
281 switch (K) {
282 case SymbolLanguage::C: return "C";
283 case SymbolLanguage::ObjC: return "ObjC";
284 case SymbolLanguage::CXX: return "C++";
285 }
286}