blob: 0e62e2734b0c1a2d7e42181a501560e846f8e31e [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);
Chris Lattner3f59c972010-12-25 23:25:43 +000044 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
Ted Kremenek8e0ac172010-05-14 21:29:26 +000046 BTCASE(Short);
47 BTCASE(Int);
48 BTCASE(Long);
49 BTCASE(LongLong);
50 BTCASE(Int128);
51 BTCASE(Float);
52 BTCASE(Double);
53 BTCASE(LongDouble);
54 BTCASE(NullPtr);
55 BTCASE(Overload);
56 BTCASE(Dependent);
57 BTCASE(ObjCId);
58 BTCASE(ObjCClass);
59 BTCASE(ObjCSel);
60 default:
61 return CXType_Unexposed;
62 }
63#undef BTCASE
64}
65
66static CXTypeKind GetTypeKind(QualType T) {
John McCallf4c73712011-01-19 06:33:43 +000067 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +000068 if (!TP)
69 return CXType_Invalid;
70
71#define TKCASE(K) case Type::K: return CXType_##K
72 switch (TP->getTypeClass()) {
73 case Type::Builtin:
74 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
75 TKCASE(Complex);
76 TKCASE(Pointer);
77 TKCASE(BlockPointer);
78 TKCASE(LValueReference);
79 TKCASE(RValueReference);
80 TKCASE(Record);
81 TKCASE(Enum);
82 TKCASE(Typedef);
83 TKCASE(ObjCInterface);
84 TKCASE(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +000085 TKCASE(FunctionNoProto);
86 TKCASE(FunctionProto);
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +000087 TKCASE(ConstantArray);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000088 default:
89 return CXType_Unexposed;
90 }
91#undef TKCASE
92}
93
Ted Kremenek95f33552010-08-26 01:42:22 +000094
Ted Kremeneka60ed472010-11-16 08:15:36 +000095CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
Ted Kremenek8e0ac172010-05-14 21:29:26 +000096 CXTypeKind TK = GetTypeKind(T);
97 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
98 return CT;
99}
100
Ted Kremenek95f33552010-08-26 01:42:22 +0000101using cxtype::MakeCXType;
102
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000103static inline QualType GetQualType(CXType CT) {
104 return QualType::getFromOpaquePtr(CT.data[0]);
105}
106
Ted Kremeneka60ed472010-11-16 08:15:36 +0000107static inline CXTranslationUnit GetTU(CXType CT) {
108 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000109}
110
111extern "C" {
112
113CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000114 using namespace cxcursor;
115
Ted Kremeneka60ed472010-11-16 08:15:36 +0000116 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000117 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000118 if (clang_isExpression(C.kind)) {
119 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000120 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000121 }
122
123 if (clang_isDeclaration(C.kind)) {
124 Decl *D = cxcursor::getCursorDecl(C);
125
126 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000127 return MakeCXType(Context.getTypeDeclType(TD), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000128 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000129 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000130 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000131 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000132 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000133 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000134 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000135 return MakeCXType(FD->getType(), TU);
136 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000137 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000138
139 if (clang_isReference(C.kind)) {
140 switch (C.kind) {
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000141 case CXCursor_ObjCSuperClassRef: {
142 QualType T
143 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
144 return MakeCXType(T, TU);
145 }
146
147 case CXCursor_ObjCClassRef: {
148 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
149 return MakeCXType(T, TU);
150 }
151
152 case CXCursor_TypeRef: {
153 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
154 return MakeCXType(T, TU);
155
156 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000157
158 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000159 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000160
161 case CXCursor_ObjCProtocolRef:
162 case CXCursor_TemplateRef:
163 case CXCursor_NamespaceRef:
164 case CXCursor_MemberRef:
165 case CXCursor_OverloadedDeclRef:
166 default:
167 break;
168 }
169
Ted Kremeneka60ed472010-11-16 08:15:36 +0000170 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000171 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000172
Ted Kremeneka60ed472010-11-16 08:15:36 +0000173 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000174}
175
176CXType clang_getCanonicalType(CXType CT) {
177 if (CT.kind == CXType_Invalid)
178 return CT;
179
180 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000181 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000182
183 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000184 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000185
Ted Kremeneka60ed472010-11-16 08:15:36 +0000186 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
187 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000188}
189
Douglas Gregore72fb6f2011-01-27 16:27:11 +0000190unsigned clang_isConstQualifiedType(CXType CT) {
191 QualType T = GetQualType(CT);
192 return T.isLocalConstQualified();
193}
194
195unsigned clang_isVolatileQualifiedType(CXType CT) {
196 QualType T = GetQualType(CT);
197 return T.isLocalVolatileQualified();
198}
199
200unsigned clang_isRestrictQualifiedType(CXType CT) {
201 QualType T = GetQualType(CT);
202 return T.isLocalRestrictQualified();
203}
204
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000205CXType clang_getPointeeType(CXType CT) {
206 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000207 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000208
209 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000210 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000211
212 switch (TP->getTypeClass()) {
213 case Type::Pointer:
214 T = cast<PointerType>(TP)->getPointeeType();
215 break;
216 case Type::BlockPointer:
217 T = cast<BlockPointerType>(TP)->getPointeeType();
218 break;
219 case Type::LValueReference:
220 case Type::RValueReference:
221 T = cast<ReferenceType>(TP)->getPointeeType();
222 break;
223 case Type::ObjCObjectPointer:
224 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
225 break;
226 default:
227 T = QualType();
228 break;
229 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000230 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000231}
232
233CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000234 if (CT.kind == CXType_Invalid)
235 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
236
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000237 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000238 const Type *TP = T.getTypePtrOrNull();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000239
240 if (!TP)
241 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
242
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000243 Decl *D = 0;
244
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000245try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000246 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000247 case Type::Typedef:
248 D = cast<TypedefType>(TP)->getDecl();
249 break;
250 case Type::ObjCObject:
251 D = cast<ObjCObjectType>(TP)->getInterface();
252 break;
253 case Type::ObjCInterface:
254 D = cast<ObjCInterfaceType>(TP)->getDecl();
255 break;
256 case Type::Record:
257 case Type::Enum:
258 D = cast<TagType>(TP)->getDecl();
259 break;
260 case Type::TemplateSpecialization:
261 if (const RecordType *Record = TP->getAs<RecordType>())
262 D = Record->getDecl();
263 else
264 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
265 .getAsTemplateDecl();
266 break;
267
268 case Type::InjectedClassName:
269 D = cast<InjectedClassNameType>(TP)->getDecl();
270 break;
271
272 // FIXME: Template type parameters!
273
274 case Type::Elaborated:
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000275 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000276 goto try_again;
277
278 default:
279 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000280 }
281
282 if (!D)
283 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
284
Ted Kremeneka60ed472010-11-16 08:15:36 +0000285 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000286}
287
288CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
289 const char *s = 0;
290#define TKIND(X) case CXType_##X: s = "" #X ""; break
291 switch (K) {
292 TKIND(Invalid);
293 TKIND(Unexposed);
294 TKIND(Void);
295 TKIND(Bool);
296 TKIND(Char_U);
297 TKIND(UChar);
298 TKIND(Char16);
299 TKIND(Char32);
300 TKIND(UShort);
301 TKIND(UInt);
302 TKIND(ULong);
303 TKIND(ULongLong);
304 TKIND(UInt128);
305 TKIND(Char_S);
306 TKIND(SChar);
Chris Lattner3f59c972010-12-25 23:25:43 +0000307 case CXType_WChar: s = "WChar"; break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000308 TKIND(Short);
309 TKIND(Int);
310 TKIND(Long);
311 TKIND(LongLong);
312 TKIND(Int128);
313 TKIND(Float);
314 TKIND(Double);
315 TKIND(LongDouble);
316 TKIND(NullPtr);
317 TKIND(Overload);
318 TKIND(Dependent);
319 TKIND(ObjCId);
320 TKIND(ObjCClass);
321 TKIND(ObjCSel);
322 TKIND(Complex);
323 TKIND(Pointer);
324 TKIND(BlockPointer);
325 TKIND(LValueReference);
326 TKIND(RValueReference);
327 TKIND(Record);
328 TKIND(Enum);
329 TKIND(Typedef);
330 TKIND(ObjCInterface);
331 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000332 TKIND(FunctionNoProto);
333 TKIND(FunctionProto);
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000334 TKIND(ConstantArray);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000335 }
336#undef TKIND
337 return cxstring::createCXString(s);
338}
339
340unsigned clang_equalTypes(CXType A, CXType B) {
341 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
342}
343
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000344CXType clang_getResultType(CXType X) {
345 QualType T = GetQualType(X);
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000346 if (!T.getTypePtrOrNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000347 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000348
349 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000350 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000351
Ted Kremeneka60ed472010-11-16 08:15:36 +0000352 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000353}
354
Ted Kremenek9a140842010-06-21 20:48:56 +0000355CXType clang_getCursorResultType(CXCursor C) {
356 if (clang_isDeclaration(C.kind)) {
357 Decl *D = cxcursor::getCursorDecl(C);
358 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000359 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000360
361 return clang_getResultType(clang_getCursorType(C));
362 }
363
Ted Kremeneka60ed472010-11-16 08:15:36 +0000364 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000365}
366
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000367unsigned clang_isPODType(CXType X) {
368 QualType T = GetQualType(X);
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000369 if (!T.getTypePtrOrNull())
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000370 return 0;
John McCallf85e1932011-06-15 23:02:42 +0000371
372 CXTranslationUnit TU = GetTU(X);
373 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
374
375 return T.isPODType(AU->getASTContext()) ? 1 : 0;
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000376}
377
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000378CXType clang_getArrayElementType(CXType CT) {
379 QualType ET = QualType();
380 QualType T = GetQualType(CT);
381 const Type *TP = T.getTypePtrOrNull();
382
383 if (TP) {
384 switch (TP->getTypeClass()) {
385 case Type::ConstantArray:
386 ET = cast<ConstantArrayType> (TP)->getElementType();
387 break;
388 default:
389 break;
390 }
391 }
392 return MakeCXType(ET, GetTU(CT));
393}
394
395long long clang_getArraySize(CXType CT) {
396 long long result = -1;
397 QualType T = GetQualType(CT);
398 const Type *TP = T.getTypePtrOrNull();
399
400 if (TP) {
401 switch (TP->getTypeClass()) {
402 case Type::ConstantArray:
403 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
404 break;
405 default:
406 break;
407 }
408 }
409 return result;
410}
411
David Chisnall5389f482010-12-30 14:05:53 +0000412CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
413 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
414 return cxstring::createCXString("");
415
416 Decl *D = static_cast<Decl*>(C.data[0]);
417 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
418 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
419 ASTContext &Ctx = AU->getASTContext();
420 std::string encoding;
421
Douglas Gregorf968d832011-05-27 01:19:52 +0000422 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
423 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
424 return cxstring::createCXString("?");
425 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
David Chisnall5389f482010-12-30 14:05:53 +0000426 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
427 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
428 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
429 else {
430 QualType Ty;
431 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000432 Ty = Ctx.getTypeDeclType(TD);
David Chisnall5389f482010-12-30 14:05:53 +0000433 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
434 Ty = VD->getType();
435 else return cxstring::createCXString("?");
436 Ctx.getObjCEncodingForType(Ty, encoding);
437 }
438
439 return cxstring::createCXString(encoding);
440}
441
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000442} // end: extern "C"