blob: 25ea2853d3fdb5beaaeb526621e496f1ee46a4c3 [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"
Ted Kremeneked122732010-11-16 01:56:27 +000016#include "CXString.h"
Chandler Carruthf59edb92012-12-04 09:25:21 +000017#include "CXTranslationUnit.h"
Ted Kremenek95f33552010-08-26 01:42:22 +000018#include "CXType.h"
Ted Kremenek8e0ac172010-05-14 21:29:26 +000019#include "clang/AST/Decl.h"
20#include "clang/AST/DeclObjC.h"
Douglas Gregor3f0fee32010-10-02 21:57:58 +000021#include "clang/AST/DeclTemplate.h"
Chandler Carruthf59edb92012-12-04 09:25:21 +000022#include "clang/AST/Expr.h"
23#include "clang/AST/Type.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) {
Argyrios Kyrtzidisae5ac1f2012-05-08 01:22:12 +000097 CXTypeKind TK = CXType_Invalid;
98
Argyrios Kyrtzidis25bd2792012-05-23 23:30:16 +000099 if (TU && !T.isNull()) {
Argyrios Kyrtzidisae5ac1f2012-05-08 01:22:12 +0000100 ASTContext &Ctx = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
101 if (Ctx.getLangOpts().ObjC1) {
Argyrios Kyrtzidis25bd2792012-05-23 23:30:16 +0000102 QualType UnqualT = T.getUnqualifiedType();
103 if (Ctx.isObjCIdType(UnqualT))
Argyrios Kyrtzidisae5ac1f2012-05-08 01:22:12 +0000104 TK = CXType_ObjCId;
Argyrios Kyrtzidis25bd2792012-05-23 23:30:16 +0000105 else if (Ctx.isObjCClassType(UnqualT))
Argyrios Kyrtzidisae5ac1f2012-05-08 01:22:12 +0000106 TK = CXType_ObjCClass;
Argyrios Kyrtzidis25bd2792012-05-23 23:30:16 +0000107 else if (Ctx.isObjCSelType(UnqualT))
Argyrios Kyrtzidisae5ac1f2012-05-08 01:22:12 +0000108 TK = CXType_ObjCSel;
109 }
110 }
111 if (TK == CXType_Invalid)
112 TK = GetTypeKind(T);
113
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000114 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
115 return CT;
116}
117
Ted Kremenek95f33552010-08-26 01:42:22 +0000118using cxtype::MakeCXType;
119
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000120static inline QualType GetQualType(CXType CT) {
121 return QualType::getFromOpaquePtr(CT.data[0]);
122}
123
Ted Kremeneka60ed472010-11-16 08:15:36 +0000124static inline CXTranslationUnit GetTU(CXType CT) {
125 return static_cast<CXTranslationUnit>(CT.data[1]);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000126}
127
128extern "C" {
129
130CXType clang_getCursorType(CXCursor C) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000131 using namespace cxcursor;
132
Ted Kremeneka60ed472010-11-16 08:15:36 +0000133 CXTranslationUnit TU = cxcursor::getCursorTU(C);
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000134 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000135 if (clang_isExpression(C.kind)) {
136 QualType T = cxcursor::getCursorExpr(C)->getType();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000137 return MakeCXType(T, TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000138 }
139
140 if (clang_isDeclaration(C.kind)) {
141 Decl *D = cxcursor::getCursorDecl(C);
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000142 if (!D)
143 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000144
145 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000146 return MakeCXType(Context.getTypeDeclType(TD), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000147 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000148 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000149 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000150 return MakeCXType(VD->getType(), TU);
Ted Kremenek0d32a682010-06-21 19:41:40 +0000151 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000152 return MakeCXType(PD->getType(), TU);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000153 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000154 return MakeCXType(FD->getType(), TU);
155 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000156 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000157
158 if (clang_isReference(C.kind)) {
159 switch (C.kind) {
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000160 case CXCursor_ObjCSuperClassRef: {
161 QualType T
162 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
163 return MakeCXType(T, TU);
164 }
165
166 case CXCursor_ObjCClassRef: {
167 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
168 return MakeCXType(T, TU);
169 }
170
171 case CXCursor_TypeRef: {
172 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
173 return MakeCXType(T, TU);
174
175 }
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000176
177 case CXCursor_CXXBaseSpecifier:
Ted Kremeneka60ed472010-11-16 08:15:36 +0000178 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
Douglas Gregor011d8b92012-02-15 00:54:55 +0000179
180 case CXCursor_MemberRef:
181 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
182
183 case CXCursor_VariableRef:
184 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
185
186 case CXCursor_ObjCProtocolRef:
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000187 case CXCursor_TemplateRef:
188 case CXCursor_NamespaceRef:
Douglas Gregor011d8b92012-02-15 00:54:55 +0000189 case CXCursor_OverloadedDeclRef:
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000190 default:
191 break;
192 }
193
Ted Kremeneka60ed472010-11-16 08:15:36 +0000194 return MakeCXType(QualType(), TU);
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000195 }
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000196
Ted Kremeneka60ed472010-11-16 08:15:36 +0000197 return MakeCXType(QualType(), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000198}
199
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000200CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
201 using namespace cxcursor;
202 CXTranslationUnit TU = cxcursor::getCursorTU(C);
203
204 if (clang_isDeclaration(C.kind)) {
205 Decl *D = cxcursor::getCursorDecl(C);
206
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000207 if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000208 QualType T = TD->getUnderlyingType();
209 return MakeCXType(T, TU);
210 }
211
212 return MakeCXType(QualType(), TU);
213 }
214
215 return MakeCXType(QualType(), TU);
216}
217
218CXType clang_getEnumDeclIntegerType(CXCursor C) {
219 using namespace cxcursor;
220 CXTranslationUnit TU = cxcursor::getCursorTU(C);
221
222 if (clang_isDeclaration(C.kind)) {
223 Decl *D = cxcursor::getCursorDecl(C);
224
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000225 if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000226 QualType T = TD->getIntegerType();
227 return MakeCXType(T, TU);
228 }
229
230 return MakeCXType(QualType(), TU);
231 }
232
233 return MakeCXType(QualType(), TU);
234}
235
236long long clang_getEnumConstantDeclValue(CXCursor C) {
237 using namespace cxcursor;
238
239 if (clang_isDeclaration(C.kind)) {
240 Decl *D = cxcursor::getCursorDecl(C);
241
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000242 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000243 return TD->getInitVal().getSExtValue();
244 }
245
246 return LLONG_MIN;
247 }
248
249 return LLONG_MIN;
250}
251
252unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
253 using namespace cxcursor;
254
255 if (clang_isDeclaration(C.kind)) {
256 Decl *D = cxcursor::getCursorDecl(C);
257
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000258 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000259 return TD->getInitVal().getZExtValue();
260 }
261
262 return ULLONG_MAX;
263 }
264
265 return ULLONG_MAX;
266}
267
Dmitri Gribenko1eb60822012-12-04 15:13:46 +0000268int clang_getFieldDeclBitWidth(CXCursor C) {
269 using namespace cxcursor;
270
271 if (clang_isDeclaration(C.kind)) {
272 Decl *D = getCursorDecl(C);
273
274 if (FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
275 if (FD->isBitField())
276 return FD->getBitWidthValue(getCursorContext(C));
277 }
278 }
279
280 return -1;
281}
282
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000283CXType clang_getCanonicalType(CXType CT) {
284 if (CT.kind == CXType_Invalid)
285 return CT;
286
287 QualType T = GetQualType(CT);
Ted Kremeneka60ed472010-11-16 08:15:36 +0000288 CXTranslationUnit TU = GetTU(CT);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000289
290 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000291 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000292
Ted Kremeneka60ed472010-11-16 08:15:36 +0000293 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
294 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000295}
296
Douglas Gregore72fb6f2011-01-27 16:27:11 +0000297unsigned clang_isConstQualifiedType(CXType CT) {
298 QualType T = GetQualType(CT);
299 return T.isLocalConstQualified();
300}
301
302unsigned clang_isVolatileQualifiedType(CXType CT) {
303 QualType T = GetQualType(CT);
304 return T.isLocalVolatileQualified();
305}
306
307unsigned clang_isRestrictQualifiedType(CXType CT) {
308 QualType T = GetQualType(CT);
309 return T.isLocalRestrictQualified();
310}
311
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000312CXType clang_getPointeeType(CXType CT) {
313 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000314 const Type *TP = T.getTypePtrOrNull();
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000315
316 if (!TP)
Ted Kremeneka60ed472010-11-16 08:15:36 +0000317 return MakeCXType(QualType(), GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000318
319 switch (TP->getTypeClass()) {
320 case Type::Pointer:
321 T = cast<PointerType>(TP)->getPointeeType();
322 break;
323 case Type::BlockPointer:
324 T = cast<BlockPointerType>(TP)->getPointeeType();
325 break;
326 case Type::LValueReference:
327 case Type::RValueReference:
328 T = cast<ReferenceType>(TP)->getPointeeType();
329 break;
330 case Type::ObjCObjectPointer:
331 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
332 break;
333 default:
334 T = QualType();
335 break;
336 }
Ted Kremeneka60ed472010-11-16 08:15:36 +0000337 return MakeCXType(T, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000338}
339
340CXCursor clang_getTypeDeclaration(CXType CT) {
Ted Kremenekb3da5392010-05-29 20:01:52 +0000341 if (CT.kind == CXType_Invalid)
342 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
343
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000344 QualType T = GetQualType(CT);
John McCallf4c73712011-01-19 06:33:43 +0000345 const Type *TP = T.getTypePtrOrNull();
Ted Kremenekb3da5392010-05-29 20:01:52 +0000346
347 if (!TP)
348 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
349
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000350 Decl *D = 0;
351
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000352try_again:
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000353 switch (TP->getTypeClass()) {
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000354 case Type::Typedef:
355 D = cast<TypedefType>(TP)->getDecl();
356 break;
357 case Type::ObjCObject:
358 D = cast<ObjCObjectType>(TP)->getInterface();
359 break;
360 case Type::ObjCInterface:
361 D = cast<ObjCInterfaceType>(TP)->getDecl();
362 break;
363 case Type::Record:
364 case Type::Enum:
365 D = cast<TagType>(TP)->getDecl();
366 break;
367 case Type::TemplateSpecialization:
368 if (const RecordType *Record = TP->getAs<RecordType>())
369 D = Record->getDecl();
370 else
371 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
372 .getAsTemplateDecl();
373 break;
374
375 case Type::InjectedClassName:
376 D = cast<InjectedClassNameType>(TP)->getDecl();
377 break;
378
379 // FIXME: Template type parameters!
380
381 case Type::Elaborated:
Douglas Gregor1ab55e92010-12-10 17:03:06 +0000382 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
Douglas Gregor3f0fee32010-10-02 21:57:58 +0000383 goto try_again;
384
385 default:
386 break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000387 }
388
389 if (!D)
390 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
391
Ted Kremeneka60ed472010-11-16 08:15:36 +0000392 return cxcursor::MakeCXCursor(D, GetTU(CT));
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000393}
394
395CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
396 const char *s = 0;
397#define TKIND(X) case CXType_##X: s = "" #X ""; break
398 switch (K) {
399 TKIND(Invalid);
400 TKIND(Unexposed);
401 TKIND(Void);
402 TKIND(Bool);
403 TKIND(Char_U);
404 TKIND(UChar);
405 TKIND(Char16);
406 TKIND(Char32);
407 TKIND(UShort);
408 TKIND(UInt);
409 TKIND(ULong);
410 TKIND(ULongLong);
411 TKIND(UInt128);
412 TKIND(Char_S);
413 TKIND(SChar);
Chris Lattner3f59c972010-12-25 23:25:43 +0000414 case CXType_WChar: s = "WChar"; break;
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000415 TKIND(Short);
416 TKIND(Int);
417 TKIND(Long);
418 TKIND(LongLong);
419 TKIND(Int128);
420 TKIND(Float);
421 TKIND(Double);
422 TKIND(LongDouble);
423 TKIND(NullPtr);
424 TKIND(Overload);
425 TKIND(Dependent);
426 TKIND(ObjCId);
427 TKIND(ObjCClass);
428 TKIND(ObjCSel);
429 TKIND(Complex);
430 TKIND(Pointer);
431 TKIND(BlockPointer);
432 TKIND(LValueReference);
433 TKIND(RValueReference);
434 TKIND(Record);
435 TKIND(Enum);
436 TKIND(Typedef);
437 TKIND(ObjCInterface);
438 TKIND(ObjCObjectPointer);
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000439 TKIND(FunctionNoProto);
440 TKIND(FunctionProto);
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000441 TKIND(ConstantArray);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000442 TKIND(Vector);
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000443 }
444#undef TKIND
445 return cxstring::createCXString(s);
446}
447
448unsigned clang_equalTypes(CXType A, CXType B) {
449 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
450}
451
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000452unsigned clang_isFunctionTypeVariadic(CXType X) {
453 QualType T = GetQualType(X);
454 if (T.isNull())
455 return 0;
456
457 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
458 return (unsigned)FD->isVariadic();
459
460 if (T->getAs<FunctionNoProtoType>())
461 return 1;
462
463 return 0;
464}
465
466CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
467 QualType T = GetQualType(X);
468 if (T.isNull())
469 return CXCallingConv_Invalid;
470
471 if (const FunctionType *FD = T->getAs<FunctionType>()) {
472#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
473 switch (FD->getCallConv()) {
474 TCALLINGCONV(Default);
475 TCALLINGCONV(C);
476 TCALLINGCONV(X86StdCall);
477 TCALLINGCONV(X86FastCall);
478 TCALLINGCONV(X86ThisCall);
479 TCALLINGCONV(X86Pascal);
480 TCALLINGCONV(AAPCS);
481 TCALLINGCONV(AAPCS_VFP);
Derek Schuff263366f2012-10-16 22:30:41 +0000482 TCALLINGCONV(PnaclCall);
Guy Benyei38980082012-12-25 08:53:55 +0000483 TCALLINGCONV(IntelOclBicc);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000484 }
485#undef TCALLINGCONV
486 }
487
488 return CXCallingConv_Invalid;
489}
490
Argyrios Kyrtzidisd98ef9a2012-04-11 19:32:19 +0000491int clang_getNumArgTypes(CXType X) {
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000492 QualType T = GetQualType(X);
493 if (T.isNull())
Argyrios Kyrtzidisd98ef9a2012-04-11 19:32:19 +0000494 return -1;
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000495
496 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
497 return FD->getNumArgs();
498 }
499
500 if (T->getAs<FunctionNoProtoType>()) {
501 return 0;
502 }
503
Argyrios Kyrtzidisd98ef9a2012-04-11 19:32:19 +0000504 return -1;
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000505}
506
507CXType clang_getArgType(CXType X, unsigned i) {
508 QualType T = GetQualType(X);
509 if (T.isNull())
510 return MakeCXType(QualType(), GetTU(X));
511
512 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
513 unsigned numArgs = FD->getNumArgs();
514 if (i >= numArgs)
515 return MakeCXType(QualType(), GetTU(X));
516
517 return MakeCXType(FD->getArgType(i), GetTU(X));
518 }
519
520 return MakeCXType(QualType(), GetTU(X));
521}
522
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000523CXType clang_getResultType(CXType X) {
524 QualType T = GetQualType(X);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000525 if (T.isNull())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000526 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000527
528 if (const FunctionType *FD = T->getAs<FunctionType>())
Ted Kremeneka60ed472010-11-16 08:15:36 +0000529 return MakeCXType(FD->getResultType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000530
Ted Kremeneka60ed472010-11-16 08:15:36 +0000531 return MakeCXType(QualType(), GetTU(X));
Ted Kremenek04c3cf32010-06-21 20:15:39 +0000532}
533
Ted Kremenek9a140842010-06-21 20:48:56 +0000534CXType clang_getCursorResultType(CXCursor C) {
535 if (clang_isDeclaration(C.kind)) {
536 Decl *D = cxcursor::getCursorDecl(C);
Argyrios Kyrtzidis16ed0e62011-12-10 02:36:25 +0000537 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
Ted Kremeneka60ed472010-11-16 08:15:36 +0000538 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000539
540 return clang_getResultType(clang_getCursorType(C));
541 }
542
Ted Kremeneka60ed472010-11-16 08:15:36 +0000543 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
Ted Kremenek9a140842010-06-21 20:48:56 +0000544}
545
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000546unsigned clang_isPODType(CXType X) {
547 QualType T = GetQualType(X);
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000548 if (T.isNull())
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000549 return 0;
John McCallf85e1932011-06-15 23:02:42 +0000550
551 CXTranslationUnit TU = GetTU(X);
552 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
553
554 return T.isPODType(AU->getASTContext()) ? 1 : 0;
Ted Kremenek3ce9e7d2010-07-30 00:14:11 +0000555}
556
Argyrios Kyrtzidis84b79642011-12-06 22:05:01 +0000557CXType clang_getElementType(CXType CT) {
558 QualType ET = QualType();
559 QualType T = GetQualType(CT);
560 const Type *TP = T.getTypePtrOrNull();
561
562 if (TP) {
563 switch (TP->getTypeClass()) {
564 case Type::ConstantArray:
565 ET = cast<ConstantArrayType> (TP)->getElementType();
566 break;
567 case Type::Vector:
568 ET = cast<VectorType> (TP)->getElementType();
569 break;
570 case Type::Complex:
571 ET = cast<ComplexType> (TP)->getElementType();
572 break;
573 default:
574 break;
575 }
576 }
577 return MakeCXType(ET, GetTU(CT));
578}
579
580long long clang_getNumElements(CXType CT) {
581 long long result = -1;
582 QualType T = GetQualType(CT);
583 const Type *TP = T.getTypePtrOrNull();
584
585 if (TP) {
586 switch (TP->getTypeClass()) {
587 case Type::ConstantArray:
588 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
589 break;
590 case Type::Vector:
591 result = cast<VectorType> (TP)->getNumElements();
592 break;
593 default:
594 break;
595 }
596 }
597 return result;
598}
599
Argyrios Kyrtzidis5f0bfc52011-09-27 17:44:34 +0000600CXType clang_getArrayElementType(CXType CT) {
601 QualType ET = QualType();
602 QualType T = GetQualType(CT);
603 const Type *TP = T.getTypePtrOrNull();
604
605 if (TP) {
606 switch (TP->getTypeClass()) {
607 case Type::ConstantArray:
608 ET = cast<ConstantArrayType> (TP)->getElementType();
609 break;
610 default:
611 break;
612 }
613 }
614 return MakeCXType(ET, GetTU(CT));
615}
616
617long long clang_getArraySize(CXType CT) {
618 long long result = -1;
619 QualType T = GetQualType(CT);
620 const Type *TP = T.getTypePtrOrNull();
621
622 if (TP) {
623 switch (TP->getTypeClass()) {
624 case Type::ConstantArray:
625 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
626 break;
627 default:
628 break;
629 }
630 }
631 return result;
632}
633
David Chisnall5389f482010-12-30 14:05:53 +0000634CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
Argyrios Kyrtzidis6a010122012-10-05 00:22:24 +0000635 if (!clang_isDeclaration(C.kind))
David Chisnall5389f482010-12-30 14:05:53 +0000636 return cxstring::createCXString("");
637
638 Decl *D = static_cast<Decl*>(C.data[0]);
639 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
640 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
641 ASTContext &Ctx = AU->getASTContext();
642 std::string encoding;
643
Douglas Gregorf968d832011-05-27 01:19:52 +0000644 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
645 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
646 return cxstring::createCXString("?");
647 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
David Chisnall5389f482010-12-30 14:05:53 +0000648 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
649 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
650 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
651 else {
652 QualType Ty;
653 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
Douglas Gregorfbcfeea2011-01-24 18:44:28 +0000654 Ty = Ctx.getTypeDeclType(TD);
David Chisnall5389f482010-12-30 14:05:53 +0000655 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
656 Ty = VD->getType();
657 else return cxstring::createCXString("?");
658 Ctx.getObjCEncodingForType(Ty, encoding);
659 }
660
661 return cxstring::createCXString(encoding);
662}
663
Ted Kremenek8e0ac172010-05-14 21:29:26 +0000664} // end: extern "C"