blob: 9f91e6274d40cd0cceb8285f7de9468d579399ab [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"
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +000014#include "clang/AST/PrettyPrinter.h"
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000015
16using namespace clang;
17using namespace clang::index;
18
19SymbolInfo index::getSymbolInfo(const Decl *D) {
20 assert(D);
21 SymbolInfo Info;
22 Info.Kind = SymbolKind::Unknown;
23 Info.TemplateKind = SymbolCXXTemplateKind::NonTemplate;
24 Info.Lang = SymbolLanguage::C;
25
26 if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
27 switch (TD->getTagKind()) {
28 case TTK_Struct:
29 Info.Kind = SymbolKind::Struct; break;
30 case TTK_Union:
31 Info.Kind = SymbolKind::Union; break;
32 case TTK_Class:
Ben Langmuir443913f2016-03-25 17:01:59 +000033 Info.Kind = SymbolKind::Class;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000034 Info.Lang = SymbolLanguage::CXX;
35 break;
36 case TTK_Interface:
Ben Langmuir443913f2016-03-25 17:01:59 +000037 Info.Kind = SymbolKind::Protocol;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000038 Info.Lang = SymbolLanguage::CXX;
39 break;
40 case TTK_Enum:
41 Info.Kind = SymbolKind::Enum; break;
42 }
43
44 if (const CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(D))
45 if (!CXXRec->isCLike())
46 Info.Lang = SymbolLanguage::CXX;
47
48 if (isa<ClassTemplatePartialSpecializationDecl>(D)) {
49 Info.TemplateKind = SymbolCXXTemplateKind::TemplatePartialSpecialization;
50 } else if (isa<ClassTemplateSpecializationDecl>(D)) {
51 Info.TemplateKind = SymbolCXXTemplateKind::TemplateSpecialization;
52 }
53
54 } else {
55 switch (D->getKind()) {
Argyrios Kyrtzidis113387e2016-02-29 07:56:07 +000056 case Decl::Import:
57 Info.Kind = SymbolKind::Module;
58 break;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000059 case Decl::Typedef:
Ben Langmuir443913f2016-03-25 17:01:59 +000060 Info.Kind = SymbolKind::TypeAlias; break; // Lang = C
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000061 case Decl::Function:
62 Info.Kind = SymbolKind::Function;
63 break;
64 case Decl::ParmVar:
65 Info.Kind = SymbolKind::Variable;
66 break;
67 case Decl::Var:
68 Info.Kind = SymbolKind::Variable;
69 if (isa<CXXRecordDecl>(D->getDeclContext())) {
Ben Langmuir443913f2016-03-25 17:01:59 +000070 Info.Kind = SymbolKind::StaticProperty;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000071 Info.Lang = SymbolLanguage::CXX;
72 }
73 break;
74 case Decl::Field:
75 Info.Kind = SymbolKind::Field;
76 if (const CXXRecordDecl *
77 CXXRec = dyn_cast<CXXRecordDecl>(D->getDeclContext())) {
78 if (!CXXRec->isCLike())
79 Info.Lang = SymbolLanguage::CXX;
80 }
81 break;
82 case Decl::EnumConstant:
83 Info.Kind = SymbolKind::EnumConstant; break;
84 case Decl::ObjCInterface:
85 case Decl::ObjCImplementation:
Ben Langmuir443913f2016-03-25 17:01:59 +000086 Info.Kind = SymbolKind::Class;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000087 Info.Lang = SymbolLanguage::ObjC;
88 break;
89 case Decl::ObjCProtocol:
Ben Langmuir443913f2016-03-25 17:01:59 +000090 Info.Kind = SymbolKind::Protocol;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000091 Info.Lang = SymbolLanguage::ObjC;
92 break;
93 case Decl::ObjCCategory:
94 case Decl::ObjCCategoryImpl:
Ben Langmuir443913f2016-03-25 17:01:59 +000095 Info.Kind = SymbolKind::Extension;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +000096 Info.Lang = SymbolLanguage::ObjC;
97 break;
98 case Decl::ObjCMethod:
99 if (cast<ObjCMethodDecl>(D)->isInstanceMethod())
Ben Langmuir443913f2016-03-25 17:01:59 +0000100 Info.Kind = SymbolKind::InstanceMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000101 else
Ben Langmuir443913f2016-03-25 17:01:59 +0000102 Info.Kind = SymbolKind::ClassMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000103 Info.Lang = SymbolLanguage::ObjC;
104 break;
105 case Decl::ObjCProperty:
Ben Langmuir443913f2016-03-25 17:01:59 +0000106 Info.Kind = SymbolKind::InstanceProperty;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000107 Info.Lang = SymbolLanguage::ObjC;
108 break;
109 case Decl::ObjCIvar:
Ben Langmuir443913f2016-03-25 17:01:59 +0000110 Info.Kind = SymbolKind::Field;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000111 Info.Lang = SymbolLanguage::ObjC;
112 break;
113 case Decl::Namespace:
Ben Langmuir443913f2016-03-25 17:01:59 +0000114 Info.Kind = SymbolKind::Namespace;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000115 Info.Lang = SymbolLanguage::CXX;
116 break;
117 case Decl::NamespaceAlias:
Ben Langmuir443913f2016-03-25 17:01:59 +0000118 Info.Kind = SymbolKind::NamespaceAlias;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000119 Info.Lang = SymbolLanguage::CXX;
120 break;
121 case Decl::CXXConstructor:
Ben Langmuir443913f2016-03-25 17:01:59 +0000122 Info.Kind = SymbolKind::Constructor;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000123 Info.Lang = SymbolLanguage::CXX;
124 break;
125 case Decl::CXXDestructor:
Ben Langmuir443913f2016-03-25 17:01:59 +0000126 Info.Kind = SymbolKind::Destructor;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000127 Info.Lang = SymbolLanguage::CXX;
128 break;
129 case Decl::CXXConversion:
Ben Langmuir443913f2016-03-25 17:01:59 +0000130 Info.Kind = SymbolKind::ConversionFunction;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000131 Info.Lang = SymbolLanguage::CXX;
132 break;
133 case Decl::CXXMethod: {
134 const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
135 if (MD->isStatic())
Ben Langmuir443913f2016-03-25 17:01:59 +0000136 Info.Kind = SymbolKind::StaticMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000137 else
Ben Langmuir443913f2016-03-25 17:01:59 +0000138 Info.Kind = SymbolKind::InstanceMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000139 Info.Lang = SymbolLanguage::CXX;
140 break;
141 }
142 case Decl::ClassTemplate:
Ben Langmuir443913f2016-03-25 17:01:59 +0000143 Info.Kind = SymbolKind::Class;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000144 Info.TemplateKind = SymbolCXXTemplateKind::Template;
Ben Langmuir443913f2016-03-25 17:01:59 +0000145 Info.Lang = SymbolLanguage::CXX;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000146 break;
147 case Decl::FunctionTemplate:
148 Info.Kind = SymbolKind::Function;
149 Info.TemplateKind = SymbolCXXTemplateKind::Template;
Ben Langmuir443913f2016-03-25 17:01:59 +0000150 Info.Lang = SymbolLanguage::CXX;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000151 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(
152 cast<FunctionTemplateDecl>(D)->getTemplatedDecl())) {
153 if (isa<CXXConstructorDecl>(MD))
Ben Langmuir443913f2016-03-25 17:01:59 +0000154 Info.Kind = SymbolKind::Constructor;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000155 else if (isa<CXXDestructorDecl>(MD))
Ben Langmuir443913f2016-03-25 17:01:59 +0000156 Info.Kind = SymbolKind::Destructor;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000157 else if (isa<CXXConversionDecl>(MD))
Ben Langmuir443913f2016-03-25 17:01:59 +0000158 Info.Kind = SymbolKind::ConversionFunction;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000159 else {
160 if (MD->isStatic())
Ben Langmuir443913f2016-03-25 17:01:59 +0000161 Info.Kind = SymbolKind::StaticMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000162 else
Ben Langmuir443913f2016-03-25 17:01:59 +0000163 Info.Kind = SymbolKind::InstanceMethod;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000164 }
165 }
166 break;
167 case Decl::TypeAliasTemplate:
Ben Langmuir443913f2016-03-25 17:01:59 +0000168 Info.Kind = SymbolKind::TypeAlias;
169 Info.Lang = SymbolLanguage::CXX;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000170 Info.TemplateKind = SymbolCXXTemplateKind::Template;
171 break;
172 case Decl::TypeAlias:
Ben Langmuir443913f2016-03-25 17:01:59 +0000173 Info.Kind = SymbolKind::TypeAlias;
Argyrios Kyrtzidisf4fb85b2016-02-12 23:10:59 +0000174 Info.Lang = SymbolLanguage::CXX;
175 break;
176 default:
177 break;
178 }
179 }
180
181 if (Info.Kind == SymbolKind::Unknown)
182 return Info;
183
184 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
185 if (FD->getTemplatedKind() ==
186 FunctionDecl::TK_FunctionTemplateSpecialization)
187 Info.TemplateKind = SymbolCXXTemplateKind::TemplateSpecialization;
188 }
189
190 if (Info.TemplateKind != SymbolCXXTemplateKind::NonTemplate)
191 Info.Lang = SymbolLanguage::CXX;
192
193 return Info;
194}
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000195
196void index::applyForEachSymbolRole(SymbolRoleSet Roles,
197 llvm::function_ref<void(SymbolRole)> Fn) {
198#define APPLY_FOR_ROLE(Role) \
199 if (Roles & (unsigned)SymbolRole::Role) \
200 Fn(SymbolRole::Role)
201
202 APPLY_FOR_ROLE(Declaration);
203 APPLY_FOR_ROLE(Definition);
204 APPLY_FOR_ROLE(Reference);
205 APPLY_FOR_ROLE(Read);
206 APPLY_FOR_ROLE(Write);
207 APPLY_FOR_ROLE(Call);
208 APPLY_FOR_ROLE(Dynamic);
209 APPLY_FOR_ROLE(AddressOf);
210 APPLY_FOR_ROLE(Implicit);
211 APPLY_FOR_ROLE(RelationChildOf);
212 APPLY_FOR_ROLE(RelationBaseOf);
213 APPLY_FOR_ROLE(RelationOverrideOf);
214 APPLY_FOR_ROLE(RelationReceivedBy);
Argyrios Kyrtzidisa8b51c12016-02-29 07:56:00 +0000215 APPLY_FOR_ROLE(RelationCalledBy);
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000216
217#undef APPLY_FOR_ROLE
218}
219
220void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
221 bool VisitedOnce = false;
222 applyForEachSymbolRole(Roles, [&](SymbolRole Role) {
223 if (VisitedOnce)
Argyrios Kyrtzidisd97ec182016-02-29 07:55:51 +0000224 OS << ',';
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000225 else
226 VisitedOnce = true;
227 switch (Role) {
228 case SymbolRole::Declaration: OS << "Decl"; break;
229 case SymbolRole::Definition: OS << "Def"; break;
230 case SymbolRole::Reference: OS << "Ref"; break;
231 case SymbolRole::Read: OS << "Read"; break;
232 case SymbolRole::Write: OS << "Writ"; break;
233 case SymbolRole::Call: OS << "Call"; break;
234 case SymbolRole::Dynamic: OS << "Dyn"; break;
235 case SymbolRole::AddressOf: OS << "Addr"; break;
236 case SymbolRole::Implicit: OS << "Impl"; break;
237 case SymbolRole::RelationChildOf: OS << "RelChild"; break;
238 case SymbolRole::RelationBaseOf: OS << "RelBase"; break;
239 case SymbolRole::RelationOverrideOf: OS << "RelOver"; break;
240 case SymbolRole::RelationReceivedBy: OS << "RelRec"; break;
Argyrios Kyrtzidisa8b51c12016-02-29 07:56:00 +0000241 case SymbolRole::RelationCalledBy: OS << "RelCall"; break;
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000242 }
243 });
244}
245
Argyrios Kyrtzidisd5719082016-02-15 01:32:36 +0000246bool index::printSymbolName(const Decl *D, const LangOptions &LO,
247 raw_ostream &OS) {
248 if (auto *ND = dyn_cast<NamedDecl>(D)) {
249 PrintingPolicy Policy(LO);
250 // Forward references can have different template argument names. Suppress
251 // the template argument names in constructors to make their name more
252 // stable.
253 Policy.SuppressTemplateArgsInCXXConstructors = true;
254 DeclarationName DeclName = ND->getDeclName();
255 if (DeclName.isEmpty())
256 return true;
257 DeclName.print(OS, Policy);
258 return false;
259 } else {
260 return true;
261 }
262}
263
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000264StringRef index::getSymbolKindString(SymbolKind K) {
265 switch (K) {
266 case SymbolKind::Unknown: return "<unknown>";
267 case SymbolKind::Module: return "module";
Ben Langmuir443913f2016-03-25 17:01:59 +0000268 case SymbolKind::Namespace: return "namespace";
269 case SymbolKind::NamespaceAlias: return "namespace-alias";
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000270 case SymbolKind::Macro: return "macro";
271 case SymbolKind::Enum: return "enum";
272 case SymbolKind::Struct: return "struct";
Ben Langmuir443913f2016-03-25 17:01:59 +0000273 case SymbolKind::Class: return "class";
274 case SymbolKind::Protocol: return "protocol";
275 case SymbolKind::Extension: return "extension";
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000276 case SymbolKind::Union: return "union";
Ben Langmuir443913f2016-03-25 17:01:59 +0000277 case SymbolKind::TypeAlias: return "type-alias";
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000278 case SymbolKind::Function: return "function";
279 case SymbolKind::Variable: return "variable";
280 case SymbolKind::Field: return "field";
281 case SymbolKind::EnumConstant: return "enumerator";
Ben Langmuir443913f2016-03-25 17:01:59 +0000282 case SymbolKind::InstanceMethod: return "instance-method";
283 case SymbolKind::ClassMethod: return "class-method";
284 case SymbolKind::StaticMethod: return "static-method";
285 case SymbolKind::InstanceProperty: return "instance-property";
286 case SymbolKind::ClassProperty: return "class-property";
287 case SymbolKind::StaticProperty: return "static-property";
288 case SymbolKind::Constructor: return "constructor";
289 case SymbolKind::Destructor: return "destructor";
290 case SymbolKind::ConversionFunction: return "coversion-func";
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000291 }
Saleem Abdulrasool9b0ac332016-02-15 00:36:52 +0000292 llvm_unreachable("invalid symbol kind");
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000293}
294
295StringRef index::getTemplateKindStr(SymbolCXXTemplateKind TK) {
296 switch (TK) {
297 case SymbolCXXTemplateKind::NonTemplate: return "NT";
298 case SymbolCXXTemplateKind::Template : return "T";
299 case SymbolCXXTemplateKind::TemplatePartialSpecialization : return "TPS";
300 case SymbolCXXTemplateKind::TemplateSpecialization: return "TS";
301 }
Saleem Abdulrasool9b0ac332016-02-15 00:36:52 +0000302 llvm_unreachable("invalid template kind");
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000303}
304
305StringRef index::getSymbolLanguageString(SymbolLanguage K) {
306 switch (K) {
307 case SymbolLanguage::C: return "C";
308 case SymbolLanguage::ObjC: return "ObjC";
309 case SymbolLanguage::CXX: return "C++";
310 }
Saleem Abdulrasool9b0ac332016-02-15 00:36:52 +0000311 llvm_unreachable("invalid symbol language kind");
Argyrios Kyrtzidis6fdcb9c2016-02-14 06:39:11 +0000312}