blob: c7c3c8c4d6403e337e0366b3ea3a5064dbcf1d4c [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}