blob: 777afb9bb7a6c6c86fc1ef0e2765ff83db0b5a64 [file] [log] [blame]
Ted Kremenek8e0ac172010-05-14 21:29:26 +00001//===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
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// This file implements the 'CXTypes' API hooks in the Clang-C library.
11//
12//===--------------------------------------------------------------------===//
13
14#include "CIndexer.h"
15#include "CXCursor.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/Type.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/Frontend/ASTUnit.h"
21
22using namespace clang;
23
24static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
25#define BTCASE(K) case BuiltinType::K: return CXType_##K
26 switch (BT->getKind()) {
27 BTCASE(Void);
28 BTCASE(Bool);
29 BTCASE(Char_U);
30 BTCASE(UChar);
31 BTCASE(Char16);
32 BTCASE(Char32);
33 BTCASE(UShort);
34 BTCASE(UInt);
35 BTCASE(ULong);
36 BTCASE(ULongLong);
37 BTCASE(UInt128);
38 BTCASE(Char_S);
39 BTCASE(SChar);
40 BTCASE(WChar);
41 BTCASE(Short);
42 BTCASE(Int);
43 BTCASE(Long);
44 BTCASE(LongLong);
45 BTCASE(Int128);
46 BTCASE(Float);
47 BTCASE(Double);
48 BTCASE(LongDouble);
49 BTCASE(NullPtr);
50 BTCASE(Overload);
51 BTCASE(Dependent);
52 BTCASE(ObjCId);
53 BTCASE(ObjCClass);
54 BTCASE(ObjCSel);
55 default:
56 return CXType_Unexposed;
57 }
58#undef BTCASE
59}
60
61static CXTypeKind GetTypeKind(QualType T) {
62 Type *TP = T.getTypePtr();
63 if (!TP)
64 return CXType_Invalid;
65
66#define TKCASE(K) case Type::K: return CXType_##K
67 switch (TP->getTypeClass()) {
68 case Type::Builtin:
69 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
70 TKCASE(Complex);
71 TKCASE(Pointer);
72 TKCASE(BlockPointer);
73 TKCASE(LValueReference);
74 TKCASE(RValueReference);
75 TKCASE(Record);
76 TKCASE(Enum);
77 TKCASE(Typedef);
78 TKCASE(ObjCInterface);
79 TKCASE(ObjCObjectPointer);
80 default:
81 return CXType_Unexposed;
82 }
83#undef TKCASE
84}
85
86static CXType MakeCXType(QualType T, ASTUnit *TU) {
87 CXTypeKind TK = GetTypeKind(T);
88 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
89 return CT;
90}
91
92static inline QualType GetQualType(CXType CT) {
93 return QualType::getFromOpaquePtr(CT.data[0]);
94}
95
96static inline ASTUnit* GetASTU(CXType CT) {
97 return static_cast<ASTUnit*>(CT.data[1]);
98}
99
100extern "C" {
101
102CXType clang_getCursorType(CXCursor C) {
103 ASTUnit *AU = cxcursor::getCursorASTUnit(C);
104
105 if (clang_isExpression(C.kind)) {
106 QualType T = cxcursor::getCursorExpr(C)->getType();
107 return MakeCXType(T, AU);
108 }
109
110 if (clang_isDeclaration(C.kind)) {
111 Decl *D = cxcursor::getCursorDecl(C);
112
113 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
114 return MakeCXType(QualType(TD->getTypeForDecl(), 0), AU);
115 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
116 return MakeCXType(QualType(ID->getTypeForDecl(), 0), AU);
117 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
118 return MakeCXType(VD->getType(), AU);
119
120 return MakeCXType(QualType(), AU);
121 }
122
123 return MakeCXType(QualType(), AU);
124}
125
126CXType clang_getCanonicalType(CXType CT) {
127 if (CT.kind == CXType_Invalid)
128 return CT;
129
130 QualType T = GetQualType(CT);
131
132 if (T.isNull())
133 return MakeCXType(QualType(), GetASTU(CT));
134
135 ASTUnit *AU = GetASTU(CT);
136 return MakeCXType(AU->getASTContext().getCanonicalType(T), AU);
137}
138
139CXType clang_getPointeeType(CXType CT) {
140 QualType T = GetQualType(CT);
141 Type *TP = T.getTypePtr();
142
143 if (!TP)
144 return MakeCXType(QualType(), GetASTU(CT));
145
146 switch (TP->getTypeClass()) {
147 case Type::Pointer:
148 T = cast<PointerType>(TP)->getPointeeType();
149 break;
150 case Type::BlockPointer:
151 T = cast<BlockPointerType>(TP)->getPointeeType();
152 break;
153 case Type::LValueReference:
154 case Type::RValueReference:
155 T = cast<ReferenceType>(TP)->getPointeeType();
156 break;
157 case Type::ObjCObjectPointer:
158 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
159 break;
160 default:
161 T = QualType();
162 break;
163 }
164 return MakeCXType(T, GetASTU(CT));
165}
166
167CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000168 if (CT.kind == CXType_Invalid)
169 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
170
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000171 QualType T = GetQualType(CT);
172 Type *TP = T.getTypePtr();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000173
174 if (!TP)
175 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
176
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000177 Decl *D = 0;
178
179 switch (TP->getTypeClass()) {
180 case Type::Typedef:
181 D = cast<TypedefType>(TP)->getDecl();
182 break;
John McCallc12c5bb2010-05-15 11:32:37 +0000183 case Type::ObjCObject:
184 D = cast<ObjCObjectType>(TP)->getInterface();
185 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000186 case Type::ObjCInterface:
187 D = cast<ObjCInterfaceType>(TP)->getDecl();
188 break;
189 case Type::Record:
190 case Type::Enum:
191 D = cast<TagType>(TP)->getDecl();
192 break;
193 default:
194 break;
195 }
196
197 if (!D)
198 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
199
200 return cxcursor::MakeCXCursor(D, GetASTU(CT));
201}
202
203CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
204 const char *s = 0;
205#define TKIND(X) case CXType_##X: s = "" #X ""; break
206 switch (K) {
207 TKIND(Invalid);
208 TKIND(Unexposed);
209 TKIND(Void);
210 TKIND(Bool);
211 TKIND(Char_U);
212 TKIND(UChar);
213 TKIND(Char16);
214 TKIND(Char32);
215 TKIND(UShort);
216 TKIND(UInt);
217 TKIND(ULong);
218 TKIND(ULongLong);
219 TKIND(UInt128);
220 TKIND(Char_S);
221 TKIND(SChar);
222 TKIND(WChar);
223 TKIND(Short);
224 TKIND(Int);
225 TKIND(Long);
226 TKIND(LongLong);
227 TKIND(Int128);
228 TKIND(Float);
229 TKIND(Double);
230 TKIND(LongDouble);
231 TKIND(NullPtr);
232 TKIND(Overload);
233 TKIND(Dependent);
234 TKIND(ObjCId);
235 TKIND(ObjCClass);
236 TKIND(ObjCSel);
237 TKIND(Complex);
238 TKIND(Pointer);
239 TKIND(BlockPointer);
240 TKIND(LValueReference);
241 TKIND(RValueReference);
242 TKIND(Record);
243 TKIND(Enum);
244 TKIND(Typedef);
245 TKIND(ObjCInterface);
246 TKIND(ObjCObjectPointer);
247 }
248#undef TKIND
249 return cxstring::createCXString(s);
250}
251
252unsigned clang_equalTypes(CXType A, CXType B) {
253 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
254}
255
256} // end: extern "C"