blob: eba0405994ebe4b56848c8a96ad747a470cb1e3e [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);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +000088 TKCASE(Vector);
Ted Kremenek8e0ac172010-05-14 21:29:26 +000089 default:
90 return CXType_Unexposed;
91 }
92#undef TKCASE
93}
94
Ted Kremenek95f33552010-08-26 01:42:22 +000095
Ted Kremeneka60ed472010-11-16 08:15:36 +000096CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
Ted Kremenek8e0ac172010-05-14 21:29:26 +000097 CXTypeKind TK = GetTypeKind(T);
98 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
99 return CT;
100}
101
Ted Kremenek95f33552010-08-26 01:42:22 +0000102using cxtype::MakeCXType;
103
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000104static inline QualType GetQualType(CXType CT) {
105 return QualType::getFromOpaquePtr(CT.data[0]);
106}
107
Ted Kremeneka60ed472010-11-16 08:15:36 +0000108static inline CXTranslationUnit GetTU(CXType CT) {
109 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000110}
111
112extern "C" {
113
114CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000115 using namespace cxcursor;
116
Ted Kremeneka60ed472010-11-16 08:15:36 +0000117 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000118 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000119 if (clang_isExpression(C.kind)) {
120 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000121 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000122 }
123
124 if (clang_isDeclaration(C.kind)) {
125 Decl *D = cxcursor::getCursorDecl(C);
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000126 if (!D)
127 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000128
129 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000130 return MakeCXType(Context.getTypeDeclType(TD), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000131 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000132 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000133 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000134 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000135 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000136 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000137 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000138 return MakeCXType(FD->getType(), TU);
139 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000140 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000141
142 if (clang_isReference(C.kind)) {
143 switch (C.kind) {
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000144 case CXCursor_ObjCSuperClassRef: {
145 QualType T
146 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
147 return MakeCXType(T, TU);
148 }
149
150 case CXCursor_ObjCClassRef: {
151 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
152 return MakeCXType(T, TU);
153 }
154
155 case CXCursor_TypeRef: {
156 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
157 return MakeCXType(T, TU);
158
159 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000160
161 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000162 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000163
164 case CXCursor_ObjCProtocolRef:
165 case CXCursor_TemplateRef:
166 case CXCursor_NamespaceRef:
167 case CXCursor_MemberRef:
168 case CXCursor_OverloadedDeclRef:
169 default:
170 break;
171 }
172
Ted Kremeneka60ed472010-11-16 08:15:36 +0000173 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000174 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000175
Ted Kremeneka60ed472010-11-16 08:15:36 +0000176 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000177}
178
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000179CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
180 using namespace cxcursor;
181 CXTranslationUnit TU = cxcursor::getCursorTU(C);
182
183 if (clang_isDeclaration(C.kind)) {
184 Decl *D = cxcursor::getCursorDecl(C);
185
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000186 if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000187 QualType T = TD->getUnderlyingType();
188 return MakeCXType(T, TU);
189 }
190
191 return MakeCXType(QualType(), TU);
192 }
193
194 return MakeCXType(QualType(), TU);
195}
196
197CXType clang_getEnumDeclIntegerType(CXCursor C) {
198 using namespace cxcursor;
199 CXTranslationUnit TU = cxcursor::getCursorTU(C);
200
201 if (clang_isDeclaration(C.kind)) {
202 Decl *D = cxcursor::getCursorDecl(C);
203
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000204 if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000205 QualType T = TD->getIntegerType();
206 return MakeCXType(T, TU);
207 }
208
209 return MakeCXType(QualType(), TU);
210 }
211
212 return MakeCXType(QualType(), TU);
213}
214
215long long clang_getEnumConstantDeclValue(CXCursor C) {
216 using namespace cxcursor;
217
218 if (clang_isDeclaration(C.kind)) {
219 Decl *D = cxcursor::getCursorDecl(C);
220
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000221 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000222 return TD->getInitVal().getSExtValue();
223 }
224
225 return LLONG_MIN;
226 }
227
228 return LLONG_MIN;
229}
230
231unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
232 using namespace cxcursor;
233
234 if (clang_isDeclaration(C.kind)) {
235 Decl *D = cxcursor::getCursorDecl(C);
236
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000237 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000238 return TD->getInitVal().getZExtValue();
239 }
240
241 return ULLONG_MAX;
242 }
243
244 return ULLONG_MAX;
245}
246
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000247CXType clang_getCanonicalType(CXType CT) {
248 if (CT.kind == CXType_Invalid)
249 return CT;
250
251 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000252 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000253
254 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000255 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000256
Ted Kremeneka60ed472010-11-16 08:15:36 +0000257 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
258 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000259}
260
Douglas Gregore72fb6f2011-01-27 16:27:11 +0000261unsigned clang_isConstQualifiedType(CXType CT) {
262 QualType T = GetQualType(CT);
263 return T.isLocalConstQualified();
264}
265
266unsigned clang_isVolatileQualifiedType(CXType CT) {
267 QualType T = GetQualType(CT);
268 return T.isLocalVolatileQualified();
269}
270
271unsigned clang_isRestrictQualifiedType(CXType CT) {
272 QualType T = GetQualType(CT);
273 return T.isLocalRestrictQualified();
274}
275
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000276CXType clang_getPointeeType(CXType CT) {
277 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000278 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000279
280 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000281 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000282
283 switch (TP->getTypeClass()) {
284 case Type::Pointer:
285 T = cast<PointerType>(TP)->getPointeeType();
286 break;
287 case Type::BlockPointer:
288 T = cast<BlockPointerType>(TP)->getPointeeType();
289 break;
290 case Type::LValueReference:
291 case Type::RValueReference:
292 T = cast<ReferenceType>(TP)->getPointeeType();
293 break;
294 case Type::ObjCObjectPointer:
295 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
296 break;
297 default:
298 T = QualType();
299 break;
300 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000301 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000302}
303
304CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000305 if (CT.kind == CXType_Invalid)
306 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
307
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000308 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000309 const Type *TP = T.getTypePtrOrNull();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000310
311 if (!TP)
312 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
313
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000314 Decl *D = 0;
315
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000316try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000317 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000318 case Type::Typedef:
319 D = cast<TypedefType>(TP)->getDecl();
320 break;
321 case Type::ObjCObject:
322 D = cast<ObjCObjectType>(TP)->getInterface();
323 break;
324 case Type::ObjCInterface:
325 D = cast<ObjCInterfaceType>(TP)->getDecl();
326 break;
327 case Type::Record:
328 case Type::Enum:
329 D = cast<TagType>(TP)->getDecl();
330 break;
331 case Type::TemplateSpecialization:
332 if (const RecordType *Record = TP->getAs<RecordType>())
333 D = Record->getDecl();
334 else
335 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
336 .getAsTemplateDecl();
337 break;
338
339 case Type::InjectedClassName:
340 D = cast<InjectedClassNameType>(TP)->getDecl();
341 break;
342
343 // FIXME: Template type parameters!
344
345 case Type::Elaborated:
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000346 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000347 goto try_again;
348
349 default:
350 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000351 }
352
353 if (!D)
354 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
355
Ted Kremeneka60ed472010-11-16 08:15:36 +0000356 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000357}
358
359CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
360 const char *s = 0;
361#define TKIND(X) case CXType_##X: s = "" #X ""; break
362 switch (K) {
363 TKIND(Invalid);
364 TKIND(Unexposed);
365 TKIND(Void);
366 TKIND(Bool);
367 TKIND(Char_U);
368 TKIND(UChar);
369 TKIND(Char16);
370 TKIND(Char32);
371 TKIND(UShort);
372 TKIND(UInt);
373 TKIND(ULong);
374 TKIND(ULongLong);
375 TKIND(UInt128);
376 TKIND(Char_S);
377 TKIND(SChar);
Chris Lattner3f59c972010-12-25 23:25:43 +0000378 case CXType_WChar: s = "WChar"; break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000379 TKIND(Short);
380 TKIND(Int);
381 TKIND(Long);
382 TKIND(LongLong);
383 TKIND(Int128);
384 TKIND(Float);
385 TKIND(Double);
386 TKIND(LongDouble);
387 TKIND(NullPtr);
388 TKIND(Overload);
389 TKIND(Dependent);
390 TKIND(ObjCId);
391 TKIND(ObjCClass);
392 TKIND(ObjCSel);
393 TKIND(Complex);
394 TKIND(Pointer);
395 TKIND(BlockPointer);
396 TKIND(LValueReference);
397 TKIND(RValueReference);
398 TKIND(Record);
399 TKIND(Enum);
400 TKIND(Typedef);
401 TKIND(ObjCInterface);
402 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000403 TKIND(FunctionNoProto);
404 TKIND(FunctionProto);
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000405 TKIND(ConstantArray);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000406 TKIND(Vector);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000407 }
408#undef TKIND
409 return cxstring::createCXString(s);
410}
411
412unsigned clang_equalTypes(CXType A, CXType B) {
413 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
414}
415
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000416unsigned clang_isFunctionTypeVariadic(CXType X) {
417 QualType T = GetQualType(X);
418 if (T.isNull())
419 return 0;
420
421 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
422 return (unsigned)FD->isVariadic();
423
424 if (T->getAs<FunctionNoProtoType>())
425 return 1;
426
427 return 0;
428}
429
430CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
431 QualType T = GetQualType(X);
432 if (T.isNull())
433 return CXCallingConv_Invalid;
434
435 if (const FunctionType *FD = T->getAs<FunctionType>()) {
436#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
437 switch (FD->getCallConv()) {
438 TCALLINGCONV(Default);
439 TCALLINGCONV(C);
440 TCALLINGCONV(X86StdCall);
441 TCALLINGCONV(X86FastCall);
442 TCALLINGCONV(X86ThisCall);
443 TCALLINGCONV(X86Pascal);
444 TCALLINGCONV(AAPCS);
445 TCALLINGCONV(AAPCS_VFP);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000446 }
447#undef TCALLINGCONV
448 }
449
450 return CXCallingConv_Invalid;
451}
452
453unsigned clang_getNumArgTypes(CXType X) {
454 QualType T = GetQualType(X);
455 if (T.isNull())
456 return UINT_MAX;
457
458 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
459 return FD->getNumArgs();
460 }
461
462 if (T->getAs<FunctionNoProtoType>()) {
463 return 0;
464 }
465
466 return UINT_MAX;
467}
468
469CXType clang_getArgType(CXType X, unsigned i) {
470 QualType T = GetQualType(X);
471 if (T.isNull())
472 return MakeCXType(QualType(), GetTU(X));
473
474 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
475 unsigned numArgs = FD->getNumArgs();
476 if (i >= numArgs)
477 return MakeCXType(QualType(), GetTU(X));
478
479 return MakeCXType(FD->getArgType(i), GetTU(X));
480 }
481
482 return MakeCXType(QualType(), GetTU(X));
483}
484
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000485CXType clang_getResultType(CXType X) {
486 QualType T = GetQualType(X);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000487 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000488 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000489
490 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000491 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000492
Ted Kremeneka60ed472010-11-16 08:15:36 +0000493 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000494}
495
Ted Kremenek9a140842010-06-21 20:48:56 +0000496CXType clang_getCursorResultType(CXCursor C) {
497 if (clang_isDeclaration(C.kind)) {
498 Decl *D = cxcursor::getCursorDecl(C);
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000499 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000500 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000501
502 return clang_getResultType(clang_getCursorType(C));
503 }
504
Ted Kremeneka60ed472010-11-16 08:15:36 +0000505 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000506}
507
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000508unsigned clang_isPODType(CXType X) {
509 QualType T = GetQualType(X);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000510 if (T.isNull())
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000511 return 0;
John McCallf85e1932011-06-15 23:02:42 +0000512
513 CXTranslationUnit TU = GetTU(X);
514 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
515
516 return T.isPODType(AU->getASTContext()) ? 1 : 0;
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000517}
518
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000519CXType clang_getElementType(CXType CT) {
520 QualType ET = QualType();
521 QualType T = GetQualType(CT);
522 const Type *TP = T.getTypePtrOrNull();
523
524 if (TP) {
525 switch (TP->getTypeClass()) {
526 case Type::ConstantArray:
527 ET = cast<ConstantArrayType> (TP)->getElementType();
528 break;
529 case Type::Vector:
530 ET = cast<VectorType> (TP)->getElementType();
531 break;
532 case Type::Complex:
533 ET = cast<ComplexType> (TP)->getElementType();
534 break;
535 default:
536 break;
537 }
538 }
539 return MakeCXType(ET, GetTU(CT));
540}
541
542long long clang_getNumElements(CXType CT) {
543 long long result = -1;
544 QualType T = GetQualType(CT);
545 const Type *TP = T.getTypePtrOrNull();
546
547 if (TP) {
548 switch (TP->getTypeClass()) {
549 case Type::ConstantArray:
550 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
551 break;
552 case Type::Vector:
553 result = cast<VectorType> (TP)->getNumElements();
554 break;
555 default:
556 break;
557 }
558 }
559 return result;
560}
561
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000562CXType clang_getArrayElementType(CXType CT) {
563 QualType ET = QualType();
564 QualType T = GetQualType(CT);
565 const Type *TP = T.getTypePtrOrNull();
566
567 if (TP) {
568 switch (TP->getTypeClass()) {
569 case Type::ConstantArray:
570 ET = cast<ConstantArrayType> (TP)->getElementType();
571 break;
572 default:
573 break;
574 }
575 }
576 return MakeCXType(ET, GetTU(CT));
577}
578
579long long clang_getArraySize(CXType CT) {
580 long long result = -1;
581 QualType T = GetQualType(CT);
582 const Type *TP = T.getTypePtrOrNull();
583
584 if (TP) {
585 switch (TP->getTypeClass()) {
586 case Type::ConstantArray:
587 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
588 break;
589 default:
590 break;
591 }
592 }
593 return result;
594}
595
David Chisnall5389f482010-12-30 14:05:53 +0000596CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
597 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
598 return cxstring::createCXString("");
599
600 Decl *D = static_cast<Decl*>(C.data[0]);
601 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
602 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
603 ASTContext &Ctx = AU->getASTContext();
604 std::string encoding;
605
Douglas Gregorf968d832011-05-27 01:19:52 +0000606 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
607 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
608 return cxstring::createCXString("?");
609 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
David Chisnall5389f482010-12-30 14:05:53 +0000610 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
611 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
612 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
613 else {
614 QualType Ty;
615 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000616 Ty = Ctx.getTypeDeclType(TD);
David Chisnall5389f482010-12-30 14:05:53 +0000617 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
618 Ty = VD->getType();
619 else return cxstring::createCXString("?");
620 Ctx.getObjCEncodingForType(Ty, encoding);
621 }
622
623 return cxstring::createCXString(encoding);
624}
625
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000626} // end: extern "C"