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 "CXCursor.h"
16 #include "CXString.h"
17 #include "CXTranslationUnit.h"
18 #include "CXType.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/DeclTemplate.h"
22 #include "clang/AST/Expr.h"
23 #include "clang/AST/Type.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(Float128);
55 BTCASE(NullPtr);
56 BTCASE(Overload);
57 BTCASE(Dependent);
58 BTCASE(ObjCId);
59 BTCASE(ObjCClass);
60 BTCASE(ObjCSel);
61 default:
62 return CXType_Unexposed;
63 }
64 #undef BTCASE
65 }
66
GetTypeKind(QualType T)67 static CXTypeKind GetTypeKind(QualType T) {
68 const Type *TP = T.getTypePtrOrNull();
69 if (!TP)
70 return CXType_Invalid;
71
72 #define TKCASE(K) case Type::K: return CXType_##K
73 switch (TP->getTypeClass()) {
74 case Type::Builtin:
75 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
76 TKCASE(Complex);
77 TKCASE(Pointer);
78 TKCASE(BlockPointer);
79 TKCASE(LValueReference);
80 TKCASE(RValueReference);
81 TKCASE(Record);
82 TKCASE(Enum);
83 TKCASE(Typedef);
84 TKCASE(ObjCInterface);
85 TKCASE(ObjCObjectPointer);
86 TKCASE(FunctionNoProto);
87 TKCASE(FunctionProto);
88 TKCASE(ConstantArray);
89 TKCASE(IncompleteArray);
90 TKCASE(VariableArray);
91 TKCASE(DependentSizedArray);
92 TKCASE(Vector);
93 TKCASE(MemberPointer);
94 TKCASE(Auto);
95 TKCASE(Elaborated);
96 default:
97 return CXType_Unexposed;
98 }
99 #undef TKCASE
100 }
101
102
MakeCXType(QualType T,CXTranslationUnit TU)103 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
104 CXTypeKind TK = CXType_Invalid;
105
106 if (TU && !T.isNull()) {
107 // Handle attributed types as the original type
108 if (auto *ATT = T->getAs<AttributedType>()) {
109 return MakeCXType(ATT->getModifiedType(), TU);
110 }
111
112 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
113 if (Ctx.getLangOpts().ObjC1) {
114 QualType UnqualT = T.getUnqualifiedType();
115 if (Ctx.isObjCIdType(UnqualT))
116 TK = CXType_ObjCId;
117 else if (Ctx.isObjCClassType(UnqualT))
118 TK = CXType_ObjCClass;
119 else if (Ctx.isObjCSelType(UnqualT))
120 TK = CXType_ObjCSel;
121 }
122
123 /* Handle decayed types as the original type */
124 if (const DecayedType *DT = T->getAs<DecayedType>()) {
125 return MakeCXType(DT->getOriginalType(), TU);
126 }
127 }
128 if (TK == CXType_Invalid)
129 TK = GetTypeKind(T);
130
131 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
132 : T.getAsOpaquePtr(), TU } };
133 return CT;
134 }
135
136 using cxtype::MakeCXType;
137
GetQualType(CXType CT)138 static inline QualType GetQualType(CXType CT) {
139 return QualType::getFromOpaquePtr(CT.data[0]);
140 }
141
GetTU(CXType CT)142 static inline CXTranslationUnit GetTU(CXType CT) {
143 return static_cast<CXTranslationUnit>(CT.data[1]);
144 }
145
146 extern "C" {
147
clang_getCursorType(CXCursor C)148 CXType clang_getCursorType(CXCursor C) {
149 using namespace cxcursor;
150
151 CXTranslationUnit TU = cxcursor::getCursorTU(C);
152 if (!TU)
153 return MakeCXType(QualType(), TU);
154
155 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
156 if (clang_isExpression(C.kind)) {
157 QualType T = cxcursor::getCursorExpr(C)->getType();
158 return MakeCXType(T, TU);
159 }
160
161 if (clang_isDeclaration(C.kind)) {
162 const Decl *D = cxcursor::getCursorDecl(C);
163 if (!D)
164 return MakeCXType(QualType(), TU);
165
166 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
167 return MakeCXType(Context.getTypeDeclType(TD), TU);
168 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
169 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
170 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
171 return MakeCXType(DD->getType(), TU);
172 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
173 return MakeCXType(VD->getType(), TU);
174 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
175 return MakeCXType(PD->getType(), TU);
176 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
177 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
178 return MakeCXType(QualType(), TU);
179 }
180
181 if (clang_isReference(C.kind)) {
182 switch (C.kind) {
183 case CXCursor_ObjCSuperClassRef: {
184 QualType T
185 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
186 return MakeCXType(T, TU);
187 }
188
189 case CXCursor_ObjCClassRef: {
190 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
191 return MakeCXType(T, TU);
192 }
193
194 case CXCursor_TypeRef: {
195 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
196 return MakeCXType(T, TU);
197
198 }
199
200 case CXCursor_CXXBaseSpecifier:
201 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
202
203 case CXCursor_MemberRef:
204 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
205
206 case CXCursor_VariableRef:
207 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
208
209 case CXCursor_ObjCProtocolRef:
210 case CXCursor_TemplateRef:
211 case CXCursor_NamespaceRef:
212 case CXCursor_OverloadedDeclRef:
213 default:
214 break;
215 }
216
217 return MakeCXType(QualType(), TU);
218 }
219
220 return MakeCXType(QualType(), TU);
221 }
222
clang_getTypeSpelling(CXType CT)223 CXString clang_getTypeSpelling(CXType CT) {
224 QualType T = GetQualType(CT);
225 if (T.isNull())
226 return cxstring::createEmpty();
227
228 CXTranslationUnit TU = GetTU(CT);
229 SmallString<64> Str;
230 llvm::raw_svector_ostream OS(Str);
231 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
232
233 T.print(OS, PP);
234
235 return cxstring::createDup(OS.str());
236 }
237
clang_getTypedefDeclUnderlyingType(CXCursor C)238 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
239 using namespace cxcursor;
240 CXTranslationUnit TU = cxcursor::getCursorTU(C);
241
242 if (clang_isDeclaration(C.kind)) {
243 const Decl *D = cxcursor::getCursorDecl(C);
244
245 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
246 QualType T = TD->getUnderlyingType();
247 return MakeCXType(T, TU);
248 }
249
250 return MakeCXType(QualType(), TU);
251 }
252
253 return MakeCXType(QualType(), TU);
254 }
255
clang_getEnumDeclIntegerType(CXCursor C)256 CXType clang_getEnumDeclIntegerType(CXCursor C) {
257 using namespace cxcursor;
258 CXTranslationUnit TU = cxcursor::getCursorTU(C);
259
260 if (clang_isDeclaration(C.kind)) {
261 const Decl *D = cxcursor::getCursorDecl(C);
262
263 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
264 QualType T = TD->getIntegerType();
265 return MakeCXType(T, TU);
266 }
267
268 return MakeCXType(QualType(), TU);
269 }
270
271 return MakeCXType(QualType(), TU);
272 }
273
clang_getEnumConstantDeclValue(CXCursor C)274 long long clang_getEnumConstantDeclValue(CXCursor C) {
275 using namespace cxcursor;
276
277 if (clang_isDeclaration(C.kind)) {
278 const Decl *D = cxcursor::getCursorDecl(C);
279
280 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
281 return TD->getInitVal().getSExtValue();
282 }
283
284 return LLONG_MIN;
285 }
286
287 return LLONG_MIN;
288 }
289
clang_getEnumConstantDeclUnsignedValue(CXCursor C)290 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
291 using namespace cxcursor;
292
293 if (clang_isDeclaration(C.kind)) {
294 const Decl *D = cxcursor::getCursorDecl(C);
295
296 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
297 return TD->getInitVal().getZExtValue();
298 }
299
300 return ULLONG_MAX;
301 }
302
303 return ULLONG_MAX;
304 }
305
clang_getFieldDeclBitWidth(CXCursor C)306 int clang_getFieldDeclBitWidth(CXCursor C) {
307 using namespace cxcursor;
308
309 if (clang_isDeclaration(C.kind)) {
310 const Decl *D = getCursorDecl(C);
311
312 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
313 if (FD->isBitField())
314 return FD->getBitWidthValue(getCursorContext(C));
315 }
316 }
317
318 return -1;
319 }
320
clang_getCanonicalType(CXType CT)321 CXType clang_getCanonicalType(CXType CT) {
322 if (CT.kind == CXType_Invalid)
323 return CT;
324
325 QualType T = GetQualType(CT);
326 CXTranslationUnit TU = GetTU(CT);
327
328 if (T.isNull())
329 return MakeCXType(QualType(), GetTU(CT));
330
331 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
332 .getCanonicalType(T),
333 TU);
334 }
335
clang_isConstQualifiedType(CXType CT)336 unsigned clang_isConstQualifiedType(CXType CT) {
337 QualType T = GetQualType(CT);
338 return T.isLocalConstQualified();
339 }
340
clang_isVolatileQualifiedType(CXType CT)341 unsigned clang_isVolatileQualifiedType(CXType CT) {
342 QualType T = GetQualType(CT);
343 return T.isLocalVolatileQualified();
344 }
345
clang_isRestrictQualifiedType(CXType CT)346 unsigned clang_isRestrictQualifiedType(CXType CT) {
347 QualType T = GetQualType(CT);
348 return T.isLocalRestrictQualified();
349 }
350
clang_getPointeeType(CXType CT)351 CXType clang_getPointeeType(CXType CT) {
352 QualType T = GetQualType(CT);
353 const Type *TP = T.getTypePtrOrNull();
354
355 if (!TP)
356 return MakeCXType(QualType(), GetTU(CT));
357
358 switch (TP->getTypeClass()) {
359 case Type::Pointer:
360 T = cast<PointerType>(TP)->getPointeeType();
361 break;
362 case Type::BlockPointer:
363 T = cast<BlockPointerType>(TP)->getPointeeType();
364 break;
365 case Type::LValueReference:
366 case Type::RValueReference:
367 T = cast<ReferenceType>(TP)->getPointeeType();
368 break;
369 case Type::ObjCObjectPointer:
370 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
371 break;
372 case Type::MemberPointer:
373 T = cast<MemberPointerType>(TP)->getPointeeType();
374 break;
375 default:
376 T = QualType();
377 break;
378 }
379 return MakeCXType(T, GetTU(CT));
380 }
381
clang_getTypeDeclaration(CXType CT)382 CXCursor clang_getTypeDeclaration(CXType CT) {
383 if (CT.kind == CXType_Invalid)
384 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
385
386 QualType T = GetQualType(CT);
387 const Type *TP = T.getTypePtrOrNull();
388
389 if (!TP)
390 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
391
392 Decl *D = nullptr;
393
394 try_again:
395 switch (TP->getTypeClass()) {
396 case Type::Typedef:
397 D = cast<TypedefType>(TP)->getDecl();
398 break;
399 case Type::ObjCObject:
400 D = cast<ObjCObjectType>(TP)->getInterface();
401 break;
402 case Type::ObjCInterface:
403 D = cast<ObjCInterfaceType>(TP)->getDecl();
404 break;
405 case Type::Record:
406 case Type::Enum:
407 D = cast<TagType>(TP)->getDecl();
408 break;
409 case Type::TemplateSpecialization:
410 if (const RecordType *Record = TP->getAs<RecordType>())
411 D = Record->getDecl();
412 else
413 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
414 .getAsTemplateDecl();
415 break;
416
417 case Type::Auto:
418 TP = cast<AutoType>(TP)->getDeducedType().getTypePtrOrNull();
419 if (TP)
420 goto try_again;
421 break;
422
423 case Type::InjectedClassName:
424 D = cast<InjectedClassNameType>(TP)->getDecl();
425 break;
426
427 // FIXME: Template type parameters!
428
429 case Type::Elaborated:
430 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
431 goto try_again;
432
433 default:
434 break;
435 }
436
437 if (!D)
438 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
439
440 return cxcursor::MakeCXCursor(D, GetTU(CT));
441 }
442
clang_getTypeKindSpelling(enum CXTypeKind K)443 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
444 const char *s = nullptr;
445 #define TKIND(X) case CXType_##X: s = "" #X ""; break
446 switch (K) {
447 TKIND(Invalid);
448 TKIND(Unexposed);
449 TKIND(Void);
450 TKIND(Bool);
451 TKIND(Char_U);
452 TKIND(UChar);
453 TKIND(Char16);
454 TKIND(Char32);
455 TKIND(UShort);
456 TKIND(UInt);
457 TKIND(ULong);
458 TKIND(ULongLong);
459 TKIND(UInt128);
460 TKIND(Char_S);
461 TKIND(SChar);
462 case CXType_WChar: s = "WChar"; break;
463 TKIND(Short);
464 TKIND(Int);
465 TKIND(Long);
466 TKIND(LongLong);
467 TKIND(Int128);
468 TKIND(Float);
469 TKIND(Double);
470 TKIND(LongDouble);
471 TKIND(Float128);
472 TKIND(NullPtr);
473 TKIND(Overload);
474 TKIND(Dependent);
475 TKIND(ObjCId);
476 TKIND(ObjCClass);
477 TKIND(ObjCSel);
478 TKIND(Complex);
479 TKIND(Pointer);
480 TKIND(BlockPointer);
481 TKIND(LValueReference);
482 TKIND(RValueReference);
483 TKIND(Record);
484 TKIND(Enum);
485 TKIND(Typedef);
486 TKIND(ObjCInterface);
487 TKIND(ObjCObjectPointer);
488 TKIND(FunctionNoProto);
489 TKIND(FunctionProto);
490 TKIND(ConstantArray);
491 TKIND(IncompleteArray);
492 TKIND(VariableArray);
493 TKIND(DependentSizedArray);
494 TKIND(Vector);
495 TKIND(MemberPointer);
496 TKIND(Auto);
497 TKIND(Elaborated);
498 }
499 #undef TKIND
500 return cxstring::createRef(s);
501 }
502
clang_equalTypes(CXType A,CXType B)503 unsigned clang_equalTypes(CXType A, CXType B) {
504 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
505 }
506
clang_isFunctionTypeVariadic(CXType X)507 unsigned clang_isFunctionTypeVariadic(CXType X) {
508 QualType T = GetQualType(X);
509 if (T.isNull())
510 return 0;
511
512 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
513 return (unsigned)FD->isVariadic();
514
515 if (T->getAs<FunctionNoProtoType>())
516 return 1;
517
518 return 0;
519 }
520
clang_getFunctionTypeCallingConv(CXType X)521 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
522 QualType T = GetQualType(X);
523 if (T.isNull())
524 return CXCallingConv_Invalid;
525
526 if (const FunctionType *FD = T->getAs<FunctionType>()) {
527 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
528 switch (FD->getCallConv()) {
529 TCALLINGCONV(C);
530 TCALLINGCONV(X86StdCall);
531 TCALLINGCONV(X86FastCall);
532 TCALLINGCONV(X86ThisCall);
533 TCALLINGCONV(X86Pascal);
534 TCALLINGCONV(X86VectorCall);
535 TCALLINGCONV(X86_64Win64);
536 TCALLINGCONV(X86_64SysV);
537 TCALLINGCONV(AAPCS);
538 TCALLINGCONV(AAPCS_VFP);
539 TCALLINGCONV(IntelOclBicc);
540 TCALLINGCONV(Swift);
541 TCALLINGCONV(PreserveMost);
542 TCALLINGCONV(PreserveAll);
543 case CC_SpirFunction: return CXCallingConv_Unexposed;
544 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
545 break;
546 }
547 #undef TCALLINGCONV
548 }
549
550 return CXCallingConv_Invalid;
551 }
552
clang_getNumArgTypes(CXType X)553 int clang_getNumArgTypes(CXType X) {
554 QualType T = GetQualType(X);
555 if (T.isNull())
556 return -1;
557
558 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
559 return FD->getNumParams();
560 }
561
562 if (T->getAs<FunctionNoProtoType>()) {
563 return 0;
564 }
565
566 return -1;
567 }
568
clang_getArgType(CXType X,unsigned i)569 CXType clang_getArgType(CXType X, unsigned i) {
570 QualType T = GetQualType(X);
571 if (T.isNull())
572 return MakeCXType(QualType(), GetTU(X));
573
574 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
575 unsigned numParams = FD->getNumParams();
576 if (i >= numParams)
577 return MakeCXType(QualType(), GetTU(X));
578
579 return MakeCXType(FD->getParamType(i), GetTU(X));
580 }
581
582 return MakeCXType(QualType(), GetTU(X));
583 }
584
clang_getResultType(CXType X)585 CXType clang_getResultType(CXType X) {
586 QualType T = GetQualType(X);
587 if (T.isNull())
588 return MakeCXType(QualType(), GetTU(X));
589
590 if (const FunctionType *FD = T->getAs<FunctionType>())
591 return MakeCXType(FD->getReturnType(), GetTU(X));
592
593 return MakeCXType(QualType(), GetTU(X));
594 }
595
clang_getCursorResultType(CXCursor C)596 CXType clang_getCursorResultType(CXCursor C) {
597 if (clang_isDeclaration(C.kind)) {
598 const Decl *D = cxcursor::getCursorDecl(C);
599 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
600 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
601
602 return clang_getResultType(clang_getCursorType(C));
603 }
604
605 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
606 }
607
clang_isPODType(CXType X)608 unsigned clang_isPODType(CXType X) {
609 QualType T = GetQualType(X);
610 if (T.isNull())
611 return 0;
612
613 CXTranslationUnit TU = GetTU(X);
614
615 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
616 }
617
clang_getElementType(CXType CT)618 CXType clang_getElementType(CXType CT) {
619 QualType ET = QualType();
620 QualType T = GetQualType(CT);
621 const Type *TP = T.getTypePtrOrNull();
622
623 if (TP) {
624 switch (TP->getTypeClass()) {
625 case Type::ConstantArray:
626 ET = cast<ConstantArrayType> (TP)->getElementType();
627 break;
628 case Type::IncompleteArray:
629 ET = cast<IncompleteArrayType> (TP)->getElementType();
630 break;
631 case Type::VariableArray:
632 ET = cast<VariableArrayType> (TP)->getElementType();
633 break;
634 case Type::DependentSizedArray:
635 ET = cast<DependentSizedArrayType> (TP)->getElementType();
636 break;
637 case Type::Vector:
638 ET = cast<VectorType> (TP)->getElementType();
639 break;
640 case Type::Complex:
641 ET = cast<ComplexType> (TP)->getElementType();
642 break;
643 default:
644 break;
645 }
646 }
647 return MakeCXType(ET, GetTU(CT));
648 }
649
clang_getNumElements(CXType CT)650 long long clang_getNumElements(CXType CT) {
651 long long result = -1;
652 QualType T = GetQualType(CT);
653 const Type *TP = T.getTypePtrOrNull();
654
655 if (TP) {
656 switch (TP->getTypeClass()) {
657 case Type::ConstantArray:
658 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
659 break;
660 case Type::Vector:
661 result = cast<VectorType> (TP)->getNumElements();
662 break;
663 default:
664 break;
665 }
666 }
667 return result;
668 }
669
clang_getArrayElementType(CXType CT)670 CXType clang_getArrayElementType(CXType CT) {
671 QualType ET = QualType();
672 QualType T = GetQualType(CT);
673 const Type *TP = T.getTypePtrOrNull();
674
675 if (TP) {
676 switch (TP->getTypeClass()) {
677 case Type::ConstantArray:
678 ET = cast<ConstantArrayType> (TP)->getElementType();
679 break;
680 case Type::IncompleteArray:
681 ET = cast<IncompleteArrayType> (TP)->getElementType();
682 break;
683 case Type::VariableArray:
684 ET = cast<VariableArrayType> (TP)->getElementType();
685 break;
686 case Type::DependentSizedArray:
687 ET = cast<DependentSizedArrayType> (TP)->getElementType();
688 break;
689 default:
690 break;
691 }
692 }
693 return MakeCXType(ET, GetTU(CT));
694 }
695
clang_getArraySize(CXType CT)696 long long clang_getArraySize(CXType CT) {
697 long long result = -1;
698 QualType T = GetQualType(CT);
699 const Type *TP = T.getTypePtrOrNull();
700
701 if (TP) {
702 switch (TP->getTypeClass()) {
703 case Type::ConstantArray:
704 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
705 break;
706 default:
707 break;
708 }
709 }
710 return result;
711 }
712
clang_Type_getAlignOf(CXType T)713 long long clang_Type_getAlignOf(CXType T) {
714 if (T.kind == CXType_Invalid)
715 return CXTypeLayoutError_Invalid;
716 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
717 QualType QT = GetQualType(T);
718 // [expr.alignof] p1: return size_t value for complete object type, reference
719 // or array.
720 // [expr.alignof] p3: if reference type, return size of referenced type
721 if (QT->isReferenceType())
722 QT = QT.getNonReferenceType();
723 if (QT->isIncompleteType())
724 return CXTypeLayoutError_Incomplete;
725 if (QT->isDependentType())
726 return CXTypeLayoutError_Dependent;
727 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
728 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
729 // if (QT->isVoidType()) return 1;
730 return Ctx.getTypeAlignInChars(QT).getQuantity();
731 }
732
clang_Type_getClassType(CXType CT)733 CXType clang_Type_getClassType(CXType CT) {
734 QualType ET = QualType();
735 QualType T = GetQualType(CT);
736 const Type *TP = T.getTypePtrOrNull();
737
738 if (TP && TP->getTypeClass() == Type::MemberPointer) {
739 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
740 }
741 return MakeCXType(ET, GetTU(CT));
742 }
743
clang_Type_getSizeOf(CXType T)744 long long clang_Type_getSizeOf(CXType T) {
745 if (T.kind == CXType_Invalid)
746 return CXTypeLayoutError_Invalid;
747 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
748 QualType QT = GetQualType(T);
749 // [expr.sizeof] p2: if reference type, return size of referenced type
750 if (QT->isReferenceType())
751 QT = QT.getNonReferenceType();
752 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
753 // enumeration
754 // Note: We get the cxtype, not the cxcursor, so we can't call
755 // FieldDecl->isBitField()
756 // [expr.sizeof] p3: pointer ok, function not ok.
757 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
758 if (QT->isIncompleteType())
759 return CXTypeLayoutError_Incomplete;
760 if (QT->isDependentType())
761 return CXTypeLayoutError_Dependent;
762 if (!QT->isConstantSizeType())
763 return CXTypeLayoutError_NotConstantSize;
764 // [gcc extension] lib/AST/ExprConstant.cpp:1372
765 // HandleSizeof : {voidtype,functype} == 1
766 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
767 if (QT->isVoidType() || QT->isFunctionType())
768 return 1;
769 return Ctx.getTypeSizeInChars(QT).getQuantity();
770 }
771
visitRecordForValidation(const RecordDecl * RD)772 static long long visitRecordForValidation(const RecordDecl *RD) {
773 for (const auto *I : RD->fields()){
774 QualType FQT = I->getType();
775 if (FQT->isIncompleteType())
776 return CXTypeLayoutError_Incomplete;
777 if (FQT->isDependentType())
778 return CXTypeLayoutError_Dependent;
779 // recurse
780 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
781 if (const RecordDecl *Child = ChildType->getDecl()) {
782 long long ret = visitRecordForValidation(Child);
783 if (ret < 0)
784 return ret;
785 }
786 }
787 // else try next field
788 }
789 return 0;
790 }
791
validateFieldParentType(CXCursor PC,CXType PT)792 static long long validateFieldParentType(CXCursor PC, CXType PT){
793 if (clang_isInvalid(PC.kind))
794 return CXTypeLayoutError_Invalid;
795 const RecordDecl *RD =
796 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
797 // validate parent declaration
798 if (!RD || RD->isInvalidDecl())
799 return CXTypeLayoutError_Invalid;
800 RD = RD->getDefinition();
801 if (!RD)
802 return CXTypeLayoutError_Incomplete;
803 if (RD->isInvalidDecl())
804 return CXTypeLayoutError_Invalid;
805 // validate parent type
806 QualType RT = GetQualType(PT);
807 if (RT->isIncompleteType())
808 return CXTypeLayoutError_Incomplete;
809 if (RT->isDependentType())
810 return CXTypeLayoutError_Dependent;
811 // We recurse into all record fields to detect incomplete and dependent types.
812 long long Error = visitRecordForValidation(RD);
813 if (Error < 0)
814 return Error;
815 return 0;
816 }
817
clang_Type_getOffsetOf(CXType PT,const char * S)818 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
819 // check that PT is not incomplete/dependent
820 CXCursor PC = clang_getTypeDeclaration(PT);
821 long long Error = validateFieldParentType(PC,PT);
822 if (Error < 0)
823 return Error;
824 if (!S)
825 return CXTypeLayoutError_InvalidFieldName;
826 // lookup field
827 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
828 IdentifierInfo *II = &Ctx.Idents.get(S);
829 DeclarationName FieldName(II);
830 const RecordDecl *RD =
831 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
832 // verified in validateFieldParentType
833 RD = RD->getDefinition();
834 RecordDecl::lookup_result Res = RD->lookup(FieldName);
835 // If a field of the parent record is incomplete, lookup will fail.
836 // and we would return InvalidFieldName instead of Incomplete.
837 // But this erroneous results does protects again a hidden assertion failure
838 // in the RecordLayoutBuilder
839 if (Res.size() != 1)
840 return CXTypeLayoutError_InvalidFieldName;
841 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
842 return Ctx.getFieldOffset(FD);
843 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
844 return Ctx.getFieldOffset(IFD);
845 // we don't want any other Decl Type.
846 return CXTypeLayoutError_InvalidFieldName;
847 }
848
clang_Cursor_getOffsetOfField(CXCursor C)849 long long clang_Cursor_getOffsetOfField(CXCursor C) {
850 if (clang_isDeclaration(C.kind)) {
851 // we need to validate the parent type
852 CXCursor PC = clang_getCursorSemanticParent(C);
853 CXType PT = clang_getCursorType(PC);
854 long long Error = validateFieldParentType(PC,PT);
855 if (Error < 0)
856 return Error;
857 // proceed with the offset calculation
858 const Decl *D = cxcursor::getCursorDecl(C);
859 ASTContext &Ctx = cxcursor::getCursorContext(C);
860 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
861 return Ctx.getFieldOffset(FD);
862 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
863 return Ctx.getFieldOffset(IFD);
864 }
865 return -1;
866 }
867
clang_Type_getCXXRefQualifier(CXType T)868 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
869 QualType QT = GetQualType(T);
870 if (QT.isNull())
871 return CXRefQualifier_None;
872 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
873 if (!FD)
874 return CXRefQualifier_None;
875 switch (FD->getRefQualifier()) {
876 case RQ_None:
877 return CXRefQualifier_None;
878 case RQ_LValue:
879 return CXRefQualifier_LValue;
880 case RQ_RValue:
881 return CXRefQualifier_RValue;
882 }
883 return CXRefQualifier_None;
884 }
885
clang_Cursor_isBitField(CXCursor C)886 unsigned clang_Cursor_isBitField(CXCursor C) {
887 if (!clang_isDeclaration(C.kind))
888 return 0;
889 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
890 if (!FD)
891 return 0;
892 return FD->isBitField();
893 }
894
clang_getDeclObjCTypeEncoding(CXCursor C)895 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
896 if (!clang_isDeclaration(C.kind))
897 return cxstring::createEmpty();
898
899 const Decl *D = cxcursor::getCursorDecl(C);
900 ASTContext &Ctx = cxcursor::getCursorContext(C);
901 std::string encoding;
902
903 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
904 if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
905 return cxstring::createRef("?");
906 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
907 Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding);
908 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
909 Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
910 else {
911 QualType Ty;
912 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
913 Ty = Ctx.getTypeDeclType(TD);
914 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
915 Ty = VD->getType();
916 else return cxstring::createRef("?");
917 Ctx.getObjCEncodingForType(Ty, encoding);
918 }
919
920 return cxstring::createDup(encoding);
921 }
922
clang_Type_getNumTemplateArguments(CXType CT)923 int clang_Type_getNumTemplateArguments(CXType CT) {
924 QualType T = GetQualType(CT);
925 if (T.isNull())
926 return -1;
927 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
928 if (!RecordDecl)
929 return -1;
930 const ClassTemplateSpecializationDecl *TemplateDecl =
931 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
932 if (!TemplateDecl)
933 return -1;
934 return TemplateDecl->getTemplateArgs().size();
935 }
936
clang_Type_getTemplateArgumentAsType(CXType CT,unsigned i)937 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
938 QualType T = GetQualType(CT);
939 if (T.isNull())
940 return MakeCXType(QualType(), GetTU(CT));
941 const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
942 if (!RecordDecl)
943 return MakeCXType(QualType(), GetTU(CT));
944 const ClassTemplateSpecializationDecl *TemplateDecl =
945 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
946 if (!TemplateDecl)
947 return MakeCXType(QualType(), GetTU(CT));
948 const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
949 if (TA.size() <= i)
950 return MakeCXType(QualType(), GetTU(CT));
951 const TemplateArgument &A = TA.get(i);
952 if (A.getKind() != TemplateArgument::Type)
953 return MakeCXType(QualType(), GetTU(CT));
954 return MakeCXType(A.getAsType(), GetTU(CT));
955 }
956
clang_Type_visitFields(CXType PT,CXFieldVisitor visitor,CXClientData client_data)957 unsigned clang_Type_visitFields(CXType PT,
958 CXFieldVisitor visitor,
959 CXClientData client_data){
960 CXCursor PC = clang_getTypeDeclaration(PT);
961 if (clang_isInvalid(PC.kind))
962 return false;
963 const RecordDecl *RD =
964 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
965 if (!RD || RD->isInvalidDecl())
966 return false;
967 RD = RD->getDefinition();
968 if (!RD || RD->isInvalidDecl())
969 return false;
970
971 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
972 I != E; ++I){
973 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
974 // Callback to the client.
975 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
976 case CXVisit_Break:
977 return true;
978 case CXVisit_Continue:
979 break;
980 }
981 }
982 return true;
983 }
984
clang_Cursor_isAnonymous(CXCursor C)985 unsigned clang_Cursor_isAnonymous(CXCursor C){
986 if (!clang_isDeclaration(C.kind))
987 return 0;
988 const Decl *D = cxcursor::getCursorDecl(C);
989 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
990 return FD->isAnonymousStructOrUnion();
991 return 0;
992 }
993
clang_Type_getNamedType(CXType CT)994 CXType clang_Type_getNamedType(CXType CT){
995 QualType T = GetQualType(CT);
996 const Type *TP = T.getTypePtrOrNull();
997
998 if (TP && TP->getTypeClass() == Type::Elaborated)
999 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1000
1001 return MakeCXType(QualType(), GetTU(CT));
1002 }
1003
1004 } // end: extern "C"
1005