1 //===- 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 "CXTranslationUnit.h"
16 #include "CXCursor.h"
17 #include "CXString.h"
18 #include "CXType.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/Type.h"
21 #include "clang/AST/Decl.h"
22 #include "clang/AST/DeclObjC.h"
23 #include "clang/AST/DeclTemplate.h"
24 #include "clang/Frontend/ASTUnit.h"
25
26 using namespace clang;
27
GetBuiltinTypeKind(const BuiltinType * BT)28 static 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 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
46 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
GetTypeKind(QualType T)66 static CXTypeKind GetTypeKind(QualType T) {
67 const Type *TP = T.getTypePtrOrNull();
68 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);
85 TKCASE(FunctionNoProto);
86 TKCASE(FunctionProto);
87 TKCASE(ConstantArray);
88 TKCASE(Vector);
89 default:
90 return CXType_Unexposed;
91 }
92 #undef TKCASE
93 }
94
95
MakeCXType(QualType T,CXTranslationUnit TU)96 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
97 CXTypeKind TK = GetTypeKind(T);
98 CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
99 return CT;
100 }
101
102 using cxtype::MakeCXType;
103
GetQualType(CXType CT)104 static inline QualType GetQualType(CXType CT) {
105 return QualType::getFromOpaquePtr(CT.data[0]);
106 }
107
GetTU(CXType CT)108 static inline CXTranslationUnit GetTU(CXType CT) {
109 return static_cast<CXTranslationUnit>(CT.data[1]);
110 }
111
112 extern "C" {
113
clang_getCursorType(CXCursor C)114 CXType clang_getCursorType(CXCursor C) {
115 using namespace cxcursor;
116
117 CXTranslationUnit TU = cxcursor::getCursorTU(C);
118 ASTContext &Context = static_cast<ASTUnit *>(TU->TUData)->getASTContext();
119 if (clang_isExpression(C.kind)) {
120 QualType T = cxcursor::getCursorExpr(C)->getType();
121 return MakeCXType(T, TU);
122 }
123
124 if (clang_isDeclaration(C.kind)) {
125 Decl *D = cxcursor::getCursorDecl(C);
126 if (!D)
127 return MakeCXType(QualType(), TU);
128
129 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
130 return MakeCXType(Context.getTypeDeclType(TD), TU);
131 if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
132 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
133 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
134 return MakeCXType(VD->getType(), TU);
135 if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
136 return MakeCXType(PD->getType(), TU);
137 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
138 return MakeCXType(FD->getType(), TU);
139 return MakeCXType(QualType(), TU);
140 }
141
142 if (clang_isReference(C.kind)) {
143 switch (C.kind) {
144 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 }
160
161 case CXCursor_CXXBaseSpecifier:
162 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
163
164 case CXCursor_MemberRef:
165 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
166
167 case CXCursor_VariableRef:
168 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
169
170 case CXCursor_ObjCProtocolRef:
171 case CXCursor_TemplateRef:
172 case CXCursor_NamespaceRef:
173 case CXCursor_OverloadedDeclRef:
174 default:
175 break;
176 }
177
178 return MakeCXType(QualType(), TU);
179 }
180
181 return MakeCXType(QualType(), TU);
182 }
183
clang_getTypedefDeclUnderlyingType(CXCursor C)184 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
185 using namespace cxcursor;
186 CXTranslationUnit TU = cxcursor::getCursorTU(C);
187
188 if (clang_isDeclaration(C.kind)) {
189 Decl *D = cxcursor::getCursorDecl(C);
190
191 if (TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
192 QualType T = TD->getUnderlyingType();
193 return MakeCXType(T, TU);
194 }
195
196 return MakeCXType(QualType(), TU);
197 }
198
199 return MakeCXType(QualType(), TU);
200 }
201
clang_getEnumDeclIntegerType(CXCursor C)202 CXType clang_getEnumDeclIntegerType(CXCursor C) {
203 using namespace cxcursor;
204 CXTranslationUnit TU = cxcursor::getCursorTU(C);
205
206 if (clang_isDeclaration(C.kind)) {
207 Decl *D = cxcursor::getCursorDecl(C);
208
209 if (EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
210 QualType T = TD->getIntegerType();
211 return MakeCXType(T, TU);
212 }
213
214 return MakeCXType(QualType(), TU);
215 }
216
217 return MakeCXType(QualType(), TU);
218 }
219
clang_getEnumConstantDeclValue(CXCursor C)220 long long clang_getEnumConstantDeclValue(CXCursor C) {
221 using namespace cxcursor;
222
223 if (clang_isDeclaration(C.kind)) {
224 Decl *D = cxcursor::getCursorDecl(C);
225
226 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
227 return TD->getInitVal().getSExtValue();
228 }
229
230 return LLONG_MIN;
231 }
232
233 return LLONG_MIN;
234 }
235
clang_getEnumConstantDeclUnsignedValue(CXCursor C)236 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
237 using namespace cxcursor;
238
239 if (clang_isDeclaration(C.kind)) {
240 Decl *D = cxcursor::getCursorDecl(C);
241
242 if (EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
243 return TD->getInitVal().getZExtValue();
244 }
245
246 return ULLONG_MAX;
247 }
248
249 return ULLONG_MAX;
250 }
251
clang_getCanonicalType(CXType CT)252 CXType clang_getCanonicalType(CXType CT) {
253 if (CT.kind == CXType_Invalid)
254 return CT;
255
256 QualType T = GetQualType(CT);
257 CXTranslationUnit TU = GetTU(CT);
258
259 if (T.isNull())
260 return MakeCXType(QualType(), GetTU(CT));
261
262 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
263 return MakeCXType(AU->getASTContext().getCanonicalType(T), TU);
264 }
265
clang_isConstQualifiedType(CXType CT)266 unsigned clang_isConstQualifiedType(CXType CT) {
267 QualType T = GetQualType(CT);
268 return T.isLocalConstQualified();
269 }
270
clang_isVolatileQualifiedType(CXType CT)271 unsigned clang_isVolatileQualifiedType(CXType CT) {
272 QualType T = GetQualType(CT);
273 return T.isLocalVolatileQualified();
274 }
275
clang_isRestrictQualifiedType(CXType CT)276 unsigned clang_isRestrictQualifiedType(CXType CT) {
277 QualType T = GetQualType(CT);
278 return T.isLocalRestrictQualified();
279 }
280
clang_getPointeeType(CXType CT)281 CXType clang_getPointeeType(CXType CT) {
282 QualType T = GetQualType(CT);
283 const Type *TP = T.getTypePtrOrNull();
284
285 if (!TP)
286 return MakeCXType(QualType(), GetTU(CT));
287
288 switch (TP->getTypeClass()) {
289 case Type::Pointer:
290 T = cast<PointerType>(TP)->getPointeeType();
291 break;
292 case Type::BlockPointer:
293 T = cast<BlockPointerType>(TP)->getPointeeType();
294 break;
295 case Type::LValueReference:
296 case Type::RValueReference:
297 T = cast<ReferenceType>(TP)->getPointeeType();
298 break;
299 case Type::ObjCObjectPointer:
300 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
301 break;
302 default:
303 T = QualType();
304 break;
305 }
306 return MakeCXType(T, GetTU(CT));
307 }
308
clang_getTypeDeclaration(CXType CT)309 CXCursor clang_getTypeDeclaration(CXType CT) {
310 if (CT.kind == CXType_Invalid)
311 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
312
313 QualType T = GetQualType(CT);
314 const Type *TP = T.getTypePtrOrNull();
315
316 if (!TP)
317 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
318
319 Decl *D = 0;
320
321 try_again:
322 switch (TP->getTypeClass()) {
323 case Type::Typedef:
324 D = cast<TypedefType>(TP)->getDecl();
325 break;
326 case Type::ObjCObject:
327 D = cast<ObjCObjectType>(TP)->getInterface();
328 break;
329 case Type::ObjCInterface:
330 D = cast<ObjCInterfaceType>(TP)->getDecl();
331 break;
332 case Type::Record:
333 case Type::Enum:
334 D = cast<TagType>(TP)->getDecl();
335 break;
336 case Type::TemplateSpecialization:
337 if (const RecordType *Record = TP->getAs<RecordType>())
338 D = Record->getDecl();
339 else
340 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
341 .getAsTemplateDecl();
342 break;
343
344 case Type::InjectedClassName:
345 D = cast<InjectedClassNameType>(TP)->getDecl();
346 break;
347
348 // FIXME: Template type parameters!
349
350 case Type::Elaborated:
351 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
352 goto try_again;
353
354 default:
355 break;
356 }
357
358 if (!D)
359 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
360
361 return cxcursor::MakeCXCursor(D, GetTU(CT));
362 }
363
clang_getTypeKindSpelling(enum CXTypeKind K)364 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
365 const char *s = 0;
366 #define TKIND(X) case CXType_##X: s = "" #X ""; break
367 switch (K) {
368 TKIND(Invalid);
369 TKIND(Unexposed);
370 TKIND(Void);
371 TKIND(Bool);
372 TKIND(Char_U);
373 TKIND(UChar);
374 TKIND(Char16);
375 TKIND(Char32);
376 TKIND(UShort);
377 TKIND(UInt);
378 TKIND(ULong);
379 TKIND(ULongLong);
380 TKIND(UInt128);
381 TKIND(Char_S);
382 TKIND(SChar);
383 case CXType_WChar: s = "WChar"; break;
384 TKIND(Short);
385 TKIND(Int);
386 TKIND(Long);
387 TKIND(LongLong);
388 TKIND(Int128);
389 TKIND(Float);
390 TKIND(Double);
391 TKIND(LongDouble);
392 TKIND(NullPtr);
393 TKIND(Overload);
394 TKIND(Dependent);
395 TKIND(ObjCId);
396 TKIND(ObjCClass);
397 TKIND(ObjCSel);
398 TKIND(Complex);
399 TKIND(Pointer);
400 TKIND(BlockPointer);
401 TKIND(LValueReference);
402 TKIND(RValueReference);
403 TKIND(Record);
404 TKIND(Enum);
405 TKIND(Typedef);
406 TKIND(ObjCInterface);
407 TKIND(ObjCObjectPointer);
408 TKIND(FunctionNoProto);
409 TKIND(FunctionProto);
410 TKIND(ConstantArray);
411 TKIND(Vector);
412 }
413 #undef TKIND
414 return cxstring::createCXString(s);
415 }
416
clang_equalTypes(CXType A,CXType B)417 unsigned clang_equalTypes(CXType A, CXType B) {
418 return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
419 }
420
clang_isFunctionTypeVariadic(CXType X)421 unsigned clang_isFunctionTypeVariadic(CXType X) {
422 QualType T = GetQualType(X);
423 if (T.isNull())
424 return 0;
425
426 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
427 return (unsigned)FD->isVariadic();
428
429 if (T->getAs<FunctionNoProtoType>())
430 return 1;
431
432 return 0;
433 }
434
clang_getFunctionTypeCallingConv(CXType X)435 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
436 QualType T = GetQualType(X);
437 if (T.isNull())
438 return CXCallingConv_Invalid;
439
440 if (const FunctionType *FD = T->getAs<FunctionType>()) {
441 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
442 switch (FD->getCallConv()) {
443 TCALLINGCONV(Default);
444 TCALLINGCONV(C);
445 TCALLINGCONV(X86StdCall);
446 TCALLINGCONV(X86FastCall);
447 TCALLINGCONV(X86ThisCall);
448 TCALLINGCONV(X86Pascal);
449 TCALLINGCONV(AAPCS);
450 TCALLINGCONV(AAPCS_VFP);
451 }
452 #undef TCALLINGCONV
453 }
454
455 return CXCallingConv_Invalid;
456 }
457
clang_getNumArgTypes(CXType X)458 int clang_getNumArgTypes(CXType X) {
459 QualType T = GetQualType(X);
460 if (T.isNull())
461 return -1;
462
463 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
464 return FD->getNumArgs();
465 }
466
467 if (T->getAs<FunctionNoProtoType>()) {
468 return 0;
469 }
470
471 return -1;
472 }
473
clang_getArgType(CXType X,unsigned i)474 CXType clang_getArgType(CXType X, unsigned i) {
475 QualType T = GetQualType(X);
476 if (T.isNull())
477 return MakeCXType(QualType(), GetTU(X));
478
479 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
480 unsigned numArgs = FD->getNumArgs();
481 if (i >= numArgs)
482 return MakeCXType(QualType(), GetTU(X));
483
484 return MakeCXType(FD->getArgType(i), GetTU(X));
485 }
486
487 return MakeCXType(QualType(), GetTU(X));
488 }
489
clang_getResultType(CXType X)490 CXType clang_getResultType(CXType X) {
491 QualType T = GetQualType(X);
492 if (T.isNull())
493 return MakeCXType(QualType(), GetTU(X));
494
495 if (const FunctionType *FD = T->getAs<FunctionType>())
496 return MakeCXType(FD->getResultType(), GetTU(X));
497
498 return MakeCXType(QualType(), GetTU(X));
499 }
500
clang_getCursorResultType(CXCursor C)501 CXType clang_getCursorResultType(CXCursor C) {
502 if (clang_isDeclaration(C.kind)) {
503 Decl *D = cxcursor::getCursorDecl(C);
504 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
505 return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
506
507 return clang_getResultType(clang_getCursorType(C));
508 }
509
510 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
511 }
512
clang_isPODType(CXType X)513 unsigned clang_isPODType(CXType X) {
514 QualType T = GetQualType(X);
515 if (T.isNull())
516 return 0;
517
518 CXTranslationUnit TU = GetTU(X);
519 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
520
521 return T.isPODType(AU->getASTContext()) ? 1 : 0;
522 }
523
clang_getElementType(CXType CT)524 CXType clang_getElementType(CXType CT) {
525 QualType ET = QualType();
526 QualType T = GetQualType(CT);
527 const Type *TP = T.getTypePtrOrNull();
528
529 if (TP) {
530 switch (TP->getTypeClass()) {
531 case Type::ConstantArray:
532 ET = cast<ConstantArrayType> (TP)->getElementType();
533 break;
534 case Type::Vector:
535 ET = cast<VectorType> (TP)->getElementType();
536 break;
537 case Type::Complex:
538 ET = cast<ComplexType> (TP)->getElementType();
539 break;
540 default:
541 break;
542 }
543 }
544 return MakeCXType(ET, GetTU(CT));
545 }
546
clang_getNumElements(CXType CT)547 long long clang_getNumElements(CXType CT) {
548 long long result = -1;
549 QualType T = GetQualType(CT);
550 const Type *TP = T.getTypePtrOrNull();
551
552 if (TP) {
553 switch (TP->getTypeClass()) {
554 case Type::ConstantArray:
555 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
556 break;
557 case Type::Vector:
558 result = cast<VectorType> (TP)->getNumElements();
559 break;
560 default:
561 break;
562 }
563 }
564 return result;
565 }
566
clang_getArrayElementType(CXType CT)567 CXType clang_getArrayElementType(CXType CT) {
568 QualType ET = QualType();
569 QualType T = GetQualType(CT);
570 const Type *TP = T.getTypePtrOrNull();
571
572 if (TP) {
573 switch (TP->getTypeClass()) {
574 case Type::ConstantArray:
575 ET = cast<ConstantArrayType> (TP)->getElementType();
576 break;
577 default:
578 break;
579 }
580 }
581 return MakeCXType(ET, GetTU(CT));
582 }
583
clang_getArraySize(CXType CT)584 long long clang_getArraySize(CXType CT) {
585 long long result = -1;
586 QualType T = GetQualType(CT);
587 const Type *TP = T.getTypePtrOrNull();
588
589 if (TP) {
590 switch (TP->getTypeClass()) {
591 case Type::ConstantArray:
592 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
593 break;
594 default:
595 break;
596 }
597 }
598 return result;
599 }
600
clang_getDeclObjCTypeEncoding(CXCursor C)601 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
602 if ((C.kind < CXCursor_FirstDecl) || (C.kind > CXCursor_LastDecl))
603 return cxstring::createCXString("");
604
605 Decl *D = static_cast<Decl*>(C.data[0]);
606 CXTranslationUnit TU = static_cast<CXTranslationUnit>(C.data[2]);
607 ASTUnit *AU = static_cast<ASTUnit*>(TU->TUData);
608 ASTContext &Ctx = AU->getASTContext();
609 std::string encoding;
610
611 if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
612 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
613 return cxstring::createCXString("?");
614 } else if (ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
615 Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
616 else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
617 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
618 else {
619 QualType Ty;
620 if (TypeDecl *TD = dyn_cast<TypeDecl>(D))
621 Ty = Ctx.getTypeDeclType(TD);
622 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
623 Ty = VD->getType();
624 else return cxstring::createCXString("?");
625 Ctx.getObjCEncodingForType(Ty, encoding);
626 }
627
628 return cxstring::createCXString(encoding);
629 }
630
631 } // end: extern "C"
632