blob: a42f009de2d11ea38fcbcf60fd716ac6a93c5fb0 [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"
Ted Kremenek0a90d322010-11-17 23:24:11 +000015#include "CXTranslationUnit.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000016#include "CXCursor.h"
Ted Kremeneked122732010-11-16 01:56:27 +000017#include "CXString.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000018#include "CXType.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000019#include "clang/AST/Expr.h"
20#include "clang/AST/Type.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclObjC.h"
Douglas Gregor3f0fee32010-10-02 21:57:58 +000023#include "clang/AST/DeclTemplate.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000024#include "clang/Frontend/ASTUnit.h"
25
26using namespace clang;
27
28static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
29#define BTCASE(K) case BuiltinType::K: return CXType_##K
30 switch (BT->getKind()) {
31 BTCASE(Void);
32 BTCASE(Bool);
33 BTCASE(Char_U);
34 BTCASE(UChar);
35 BTCASE(Char16);
36 BTCASE(Char32);
37 BTCASE(UShort);
38 BTCASE(UInt);
39 BTCASE(ULong);
40 BTCASE(ULongLong);
41 BTCASE(UInt128);
42 BTCASE(Char_S);
43 BTCASE(SChar);
44 BTCASE(WChar);
45 BTCASE(Short);
46 BTCASE(Int);
47 BTCASE(Long);
48 BTCASE(LongLong);
49 BTCASE(Int128);
50 BTCASE(Float);
51 BTCASE(Double);
52 BTCASE(LongDouble);
53 BTCASE(NullPtr);
54 BTCASE(Overload);
55 BTCASE(Dependent);
56 BTCASE(ObjCId);
57 BTCASE(ObjCClass);
58 BTCASE(ObjCSel);
59 default:
60 return CXType_Unexposed;
61 }
62#undef BTCASE
63}
64
65static CXTypeKind GetTypeKind(QualType T) {
66 Type *TP = T.getTypePtr();
67 if (!TP)
68 return CXType_Invalid;
69
70#define TKCASE(K) case Type::K: return CXType_##K
71 switch (TP->getTypeClass()) {
72 case Type::Builtin:
73 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
74 TKCASE(Complex);
75 TKCASE(Pointer);
76 TKCASE(BlockPointer);
77 TKCASE(LValueReference);
78 TKCASE(RValueReference);
79 TKCASE(Record);
80 TKCASE(Enum);
81 TKCASE(Typedef);
82 TKCASE(ObjCInterface);
83 TKCASE(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +000084 TKCASE(FunctionNoProto);
85 TKCASE(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000086 default:
87 return CXType_Unexposed;
88 }
89#undef TKCASE
90}
91
Ted Kremenek95f33552010-08-26 01:42:22 +000092
Ted Kremeneka60ed472010-11-16 08:15:36 +000093CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
Ted Kremenek8e0ac172010-05-14 21:29:26 +000094 CXTypeKind TK = GetTypeKind(T);
95 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
96 return CT;
97}
98
Ted Kremenek95f33552010-08-26 01:42:22 +000099using cxtype::MakeCXType;
100
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000101static inline QualType GetQualType(CXType CT) {
102 return QualType::getFromOpaquePtr(CT.data[0]);
103}
104
Ted Kremeneka60ed472010-11-16 08:15:36 +0000105static inline CXTranslationUnit GetTU(CXType CT) {
106 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000107}
108
109extern "C" {
110
111CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000112 using namespace cxcursor;
113
Ted Kremeneka60ed472010-11-16 08:15:36 +0000114 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000115 if (clang_isExpression(C.kind)) {
116 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000117 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000118 }
119
120 if (clang_isDeclaration(C.kind)) {
121 Decl *D = cxcursor::getCursorDecl(C);
122
123 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000124 return MakeCXType(QualType(TD->getTypeForDecl(), 0), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000125 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000126 return MakeCXType(QualType(ID->getTypeForDecl(), 0), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000127 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000128 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000129 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000130 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000131 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000132 return MakeCXType(FD->getType(), TU);
133 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000134 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000135
136 if (clang_isReference(C.kind)) {
137 switch (C.kind) {
138 case CXCursor_ObjCSuperClassRef:
139 return MakeCXType(
140 QualType(getCursorObjCSuperClassRef(C).first->getTypeForDecl(),
141 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000142 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000143
144 case CXCursor_ObjCClassRef:
145 return MakeCXType(
146 QualType(getCursorObjCClassRef(C).first->getTypeForDecl(),
147 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000148 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000149
150 case CXCursor_TypeRef:
151 return MakeCXType(QualType(getCursorTypeRef(C).first->getTypeForDecl(),
152 0),
Ted Kremeneka60ed472010-11-16 08:15:36 +0000153 TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000154
155 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000156 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000157
158 case CXCursor_ObjCProtocolRef:
159 case CXCursor_TemplateRef:
160 case CXCursor_NamespaceRef:
161 case CXCursor_MemberRef:
162 case CXCursor_OverloadedDeclRef:
163 default:
164 break;
165 }
166
Ted Kremeneka60ed472010-11-16 08:15:36 +0000167 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000168 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000169
Ted Kremeneka60ed472010-11-16 08:15:36 +0000170 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000171}
172
173CXType clang_getCanonicalType(CXType CT) {
174 if (CT.kind == CXType_Invalid)
175 return CT;
176
177 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000178 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000179
180 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000181 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000182
Ted Kremeneka60ed472010-11-16 08:15:36 +0000183 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
184 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000185}
186
187CXType clang_getPointeeType(CXType CT) {
188 QualType T = GetQualType(CT);
189 Type *TP = T.getTypePtr();
190
191 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000192 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000193
194 switch (TP->getTypeClass()) {
195 case Type::Pointer:
196 T = cast<PointerType>(TP)->getPointeeType();
197 break;
198 case Type::BlockPointer:
199 T = cast<BlockPointerType>(TP)->getPointeeType();
200 break;
201 case Type::LValueReference:
202 case Type::RValueReference:
203 T = cast<ReferenceType>(TP)->getPointeeType();
204 break;
205 case Type::ObjCObjectPointer:
206 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
207 break;
208 default:
209 T = QualType();
210 break;
211 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000212 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000213}
214
215CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000216 if (CT.kind == CXType_Invalid)
217 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
218
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000219 QualType T = GetQualType(CT);
220 Type *TP = T.getTypePtr();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000221
222 if (!TP)
223 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
224
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000225 Decl *D = 0;
226
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000227try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000228 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000229 case Type::Typedef:
230 D = cast<TypedefType>(TP)->getDecl();
231 break;
232 case Type::ObjCObject:
233 D = cast<ObjCObjectType>(TP)->getInterface();
234 break;
235 case Type::ObjCInterface:
236 D = cast<ObjCInterfaceType>(TP)->getDecl();
237 break;
238 case Type::Record:
239 case Type::Enum:
240 D = cast<TagType>(TP)->getDecl();
241 break;
242 case Type::TemplateSpecialization:
243 if (const RecordType *Record = TP->getAs<RecordType>())
244 D = Record->getDecl();
245 else
246 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
247 .getAsTemplateDecl();
248 break;
249
250 case Type::InjectedClassName:
251 D = cast<InjectedClassNameType>(TP)->getDecl();
252 break;
253
254 // FIXME: Template type parameters!
255
256 case Type::Elaborated:
257 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtr();
258 goto try_again;
259
260 default:
261 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000262 }
263
264 if (!D)
265 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
266
Ted Kremeneka60ed472010-11-16 08:15:36 +0000267 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000268}
269
270CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
271 const char *s = 0;
272#define TKIND(X) case CXType_##X: s = "" #X ""; break
273 switch (K) {
274 TKIND(Invalid);
275 TKIND(Unexposed);
276 TKIND(Void);
277 TKIND(Bool);
278 TKIND(Char_U);
279 TKIND(UChar);
280 TKIND(Char16);
281 TKIND(Char32);
282 TKIND(UShort);
283 TKIND(UInt);
284 TKIND(ULong);
285 TKIND(ULongLong);
286 TKIND(UInt128);
287 TKIND(Char_S);
288 TKIND(SChar);
289 TKIND(WChar);
290 TKIND(Short);
291 TKIND(Int);
292 TKIND(Long);
293 TKIND(LongLong);
294 TKIND(Int128);
295 TKIND(Float);
296 TKIND(Double);
297 TKIND(LongDouble);
298 TKIND(NullPtr);
299 TKIND(Overload);
300 TKIND(Dependent);
301 TKIND(ObjCId);
302 TKIND(ObjCClass);
303 TKIND(ObjCSel);
304 TKIND(Complex);
305 TKIND(Pointer);
306 TKIND(BlockPointer);
307 TKIND(LValueReference);
308 TKIND(RValueReference);
309 TKIND(Record);
310 TKIND(Enum);
311 TKIND(Typedef);
312 TKIND(ObjCInterface);
313 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000314 TKIND(FunctionNoProto);
315 TKIND(FunctionProto);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000316 }
317#undef TKIND
318 return cxstring::createCXString(s);
319}
320
321unsigned clang_equalTypes(CXType A, CXType B) {
322 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
323}
324
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000325CXType clang_getResultType(CXType X) {
326 QualType T = GetQualType(X);
327 if (!T.getTypePtr())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000328 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000329
330 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000331 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000332
Ted Kremeneka60ed472010-11-16 08:15:36 +0000333 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000334}
335
Ted Kremenek9a140842010-06-21 20:48:56 +0000336CXType clang_getCursorResultType(CXCursor C) {
337 if (clang_isDeclaration(C.kind)) {
338 Decl *D = cxcursor::getCursorDecl(C);
339 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000340 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000341
342 return clang_getResultType(clang_getCursorType(C));
343 }
344
Ted Kremeneka60ed472010-11-16 08:15:36 +0000345 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000346}
347
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000348unsigned clang_isPODType(CXType X) {
349 QualType T = GetQualType(X);
350 if (!T.getTypePtr())
351 return 0;
352 return T->isPODType() ? 1 : 0;
353}
354
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000355} // end: extern "C"