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