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