1 //===- CXTypes.cpp - Implements 'CXTypes' aspect of libclang ------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===--------------------------------------------------------------------===//
10 // This file implements the 'CXTypes' API hooks in the Clang-C library.
12 //===--------------------------------------------------------------------===//
17 #include "CXTranslationUnit.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"
26 using namespace clang;
28 static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
29 #define BTCASE(K) case BuiltinType::K: return CXType_##K
30 switch (BT->getKind()) {
44 case BuiltinType::WChar_S: return CXType_WChar;
45 case BuiltinType::WChar_U: return CXType_WChar;
63 return CXType_Unexposed;
68 static CXTypeKind GetTypeKind(QualType T) {
69 const Type *TP = T.getTypePtrOrNull();
71 return CXType_Invalid;
73 #define TKCASE(K) case Type::K: return CXType_##K
74 switch (TP->getTypeClass()) {
76 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
80 TKCASE(LValueReference);
81 TKCASE(RValueReference);
85 TKCASE(ObjCInterface);
86 TKCASE(ObjCObjectPointer);
87 TKCASE(FunctionNoProto);
88 TKCASE(FunctionProto);
89 TKCASE(ConstantArray);
90 TKCASE(IncompleteArray);
91 TKCASE(VariableArray);
92 TKCASE(DependentSizedArray);
94 TKCASE(MemberPointer);
98 return CXType_Unexposed;
104 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
105 CXTypeKind TK = CXType_Invalid;
107 if (TU && !T.isNull()) {
108 // Handle attributed types as the original type
109 if (auto *ATT = T->getAs<AttributedType>()) {
110 return MakeCXType(ATT->getModifiedType(), TU);
113 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
114 if (Ctx.getLangOpts().ObjC1) {
115 QualType UnqualT = T.getUnqualifiedType();
116 if (Ctx.isObjCIdType(UnqualT))
118 else if (Ctx.isObjCClassType(UnqualT))
119 TK = CXType_ObjCClass;
120 else if (Ctx.isObjCSelType(UnqualT))
124 /* Handle decayed types as the original type */
125 if (const DecayedType *DT = T->getAs<DecayedType>()) {
126 return MakeCXType(DT->getOriginalType(), TU);
129 if (TK == CXType_Invalid)
132 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
133 : T.getAsOpaquePtr(), TU } };
137 using cxtype::MakeCXType;
139 static inline QualType GetQualType(CXType CT) {
140 return QualType::getFromOpaquePtr(CT.data[0]);
143 static inline CXTranslationUnit GetTU(CXType CT) {
144 return static_cast<CXTranslationUnit>(CT.data[1]);
147 static Optional<ArrayRef<TemplateArgument>>
148 GetTemplateArguments(QualType Type) {
149 assert(!Type.isNull());
150 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
151 return Specialization->template_arguments();
153 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
154 const auto *TemplateDecl =
155 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
157 return TemplateDecl->getTemplateArgs().asArray();
163 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
164 if (A.getKind() == TemplateArgument::Type)
165 return A.getAsType();
169 static Optional<QualType>
170 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
171 unsigned current = 0;
172 for (const auto &A : TA) {
173 if (A.getKind() == TemplateArgument::Pack) {
174 if (index < current + A.pack_size())
175 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
176 current += A.pack_size();
179 if (current == index)
180 return TemplateArgumentToQualType(A);
186 CXType clang_getCursorType(CXCursor C) {
187 using namespace cxcursor;
189 CXTranslationUnit TU = cxcursor::getCursorTU(C);
191 return MakeCXType(QualType(), TU);
193 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
194 if (clang_isExpression(C.kind)) {
195 QualType T = cxcursor::getCursorExpr(C)->getType();
196 return MakeCXType(T, TU);
199 if (clang_isDeclaration(C.kind)) {
200 const Decl *D = cxcursor::getCursorDecl(C);
202 return MakeCXType(QualType(), TU);
204 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
205 return MakeCXType(Context.getTypeDeclType(TD), TU);
206 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
207 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
208 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
209 return MakeCXType(DD->getType(), TU);
210 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
211 return MakeCXType(VD->getType(), TU);
212 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
213 return MakeCXType(PD->getType(), TU);
214 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
215 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
216 return MakeCXType(QualType(), TU);
219 if (clang_isReference(C.kind)) {
221 case CXCursor_ObjCSuperClassRef: {
223 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
224 return MakeCXType(T, TU);
227 case CXCursor_ObjCClassRef: {
228 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
229 return MakeCXType(T, TU);
232 case CXCursor_TypeRef: {
233 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
234 return MakeCXType(T, TU);
238 case CXCursor_CXXBaseSpecifier:
239 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
241 case CXCursor_MemberRef:
242 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
244 case CXCursor_VariableRef:
245 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
247 case CXCursor_ObjCProtocolRef:
248 case CXCursor_TemplateRef:
249 case CXCursor_NamespaceRef:
250 case CXCursor_OverloadedDeclRef:
255 return MakeCXType(QualType(), TU);
258 return MakeCXType(QualType(), TU);
261 CXString clang_getTypeSpelling(CXType CT) {
262 QualType T = GetQualType(CT);
264 return cxstring::createEmpty();
266 CXTranslationUnit TU = GetTU(CT);
268 llvm::raw_svector_ostream OS(Str);
269 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
273 return cxstring::createDup(OS.str());
276 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
277 using namespace cxcursor;
278 CXTranslationUnit TU = cxcursor::getCursorTU(C);
280 if (clang_isDeclaration(C.kind)) {
281 const Decl *D = cxcursor::getCursorDecl(C);
283 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
284 QualType T = TD->getUnderlyingType();
285 return MakeCXType(T, TU);
288 return MakeCXType(QualType(), TU);
291 return MakeCXType(QualType(), TU);
294 CXType clang_getEnumDeclIntegerType(CXCursor C) {
295 using namespace cxcursor;
296 CXTranslationUnit TU = cxcursor::getCursorTU(C);
298 if (clang_isDeclaration(C.kind)) {
299 const Decl *D = cxcursor::getCursorDecl(C);
301 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
302 QualType T = TD->getIntegerType();
303 return MakeCXType(T, TU);
306 return MakeCXType(QualType(), TU);
309 return MakeCXType(QualType(), TU);
312 long long clang_getEnumConstantDeclValue(CXCursor C) {
313 using namespace cxcursor;
315 if (clang_isDeclaration(C.kind)) {
316 const Decl *D = cxcursor::getCursorDecl(C);
318 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
319 return TD->getInitVal().getSExtValue();
328 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
329 using namespace cxcursor;
331 if (clang_isDeclaration(C.kind)) {
332 const Decl *D = cxcursor::getCursorDecl(C);
334 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
335 return TD->getInitVal().getZExtValue();
344 int clang_getFieldDeclBitWidth(CXCursor C) {
345 using namespace cxcursor;
347 if (clang_isDeclaration(C.kind)) {
348 const Decl *D = getCursorDecl(C);
350 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
351 if (FD->isBitField())
352 return FD->getBitWidthValue(getCursorContext(C));
359 CXType clang_getCanonicalType(CXType CT) {
360 if (CT.kind == CXType_Invalid)
363 QualType T = GetQualType(CT);
364 CXTranslationUnit TU = GetTU(CT);
367 return MakeCXType(QualType(), GetTU(CT));
369 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
370 .getCanonicalType(T),
374 unsigned clang_isConstQualifiedType(CXType CT) {
375 QualType T = GetQualType(CT);
376 return T.isLocalConstQualified();
379 unsigned clang_isVolatileQualifiedType(CXType CT) {
380 QualType T = GetQualType(CT);
381 return T.isLocalVolatileQualified();
384 unsigned clang_isRestrictQualifiedType(CXType CT) {
385 QualType T = GetQualType(CT);
386 return T.isLocalRestrictQualified();
389 CXType clang_getPointeeType(CXType CT) {
390 QualType T = GetQualType(CT);
391 const Type *TP = T.getTypePtrOrNull();
394 return MakeCXType(QualType(), GetTU(CT));
396 switch (TP->getTypeClass()) {
398 T = cast<PointerType>(TP)->getPointeeType();
400 case Type::BlockPointer:
401 T = cast<BlockPointerType>(TP)->getPointeeType();
403 case Type::LValueReference:
404 case Type::RValueReference:
405 T = cast<ReferenceType>(TP)->getPointeeType();
407 case Type::ObjCObjectPointer:
408 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
410 case Type::MemberPointer:
411 T = cast<MemberPointerType>(TP)->getPointeeType();
417 return MakeCXType(T, GetTU(CT));
420 CXCursor clang_getTypeDeclaration(CXType CT) {
421 if (CT.kind == CXType_Invalid)
422 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
424 QualType T = GetQualType(CT);
425 const Type *TP = T.getTypePtrOrNull();
428 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
433 switch (TP->getTypeClass()) {
435 D = cast<TypedefType>(TP)->getDecl();
437 case Type::ObjCObject:
438 D = cast<ObjCObjectType>(TP)->getInterface();
440 case Type::ObjCInterface:
441 D = cast<ObjCInterfaceType>(TP)->getDecl();
445 D = cast<TagType>(TP)->getDecl();
447 case Type::TemplateSpecialization:
448 if (const RecordType *Record = TP->getAs<RecordType>())
449 D = Record->getDecl();
451 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
452 .getAsTemplateDecl();
456 case Type::DeducedTemplateSpecialization:
457 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
462 case Type::InjectedClassName:
463 D = cast<InjectedClassNameType>(TP)->getDecl();
466 // FIXME: Template type parameters!
468 case Type::Elaborated:
469 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
477 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
479 return cxcursor::MakeCXCursor(D, GetTU(CT));
482 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
483 const char *s = nullptr;
484 #define TKIND(X) case CXType_##X: s = "" #X ""; break
501 case CXType_WChar: s = "WChar"; break;
521 TKIND(LValueReference);
522 TKIND(RValueReference);
526 TKIND(ObjCInterface);
527 TKIND(ObjCObjectPointer);
528 TKIND(FunctionNoProto);
529 TKIND(FunctionProto);
530 TKIND(ConstantArray);
531 TKIND(IncompleteArray);
532 TKIND(VariableArray);
533 TKIND(DependentSizedArray);
535 TKIND(MemberPointer);
540 return cxstring::createRef(s);
543 unsigned clang_equalTypes(CXType A, CXType B) {
544 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
547 unsigned clang_isFunctionTypeVariadic(CXType X) {
548 QualType T = GetQualType(X);
552 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
553 return (unsigned)FD->isVariadic();
555 if (T->getAs<FunctionNoProtoType>())
561 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
562 QualType T = GetQualType(X);
564 return CXCallingConv_Invalid;
566 if (const FunctionType *FD = T->getAs<FunctionType>()) {
567 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
568 switch (FD->getCallConv()) {
570 TCALLINGCONV(X86StdCall);
571 TCALLINGCONV(X86FastCall);
572 TCALLINGCONV(X86ThisCall);
573 TCALLINGCONV(X86Pascal);
574 TCALLINGCONV(X86RegCall);
575 TCALLINGCONV(X86VectorCall);
576 TCALLINGCONV(X86_64Win64);
577 TCALLINGCONV(X86_64SysV);
579 TCALLINGCONV(AAPCS_VFP);
580 TCALLINGCONV(IntelOclBicc);
582 TCALLINGCONV(PreserveMost);
583 TCALLINGCONV(PreserveAll);
584 case CC_SpirFunction: return CXCallingConv_Unexposed;
585 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
591 return CXCallingConv_Invalid;
594 int clang_getNumArgTypes(CXType X) {
595 QualType T = GetQualType(X);
599 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
600 return FD->getNumParams();
603 if (T->getAs<FunctionNoProtoType>()) {
610 CXType clang_getArgType(CXType X, unsigned i) {
611 QualType T = GetQualType(X);
613 return MakeCXType(QualType(), GetTU(X));
615 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
616 unsigned numParams = FD->getNumParams();
618 return MakeCXType(QualType(), GetTU(X));
620 return MakeCXType(FD->getParamType(i), GetTU(X));
623 return MakeCXType(QualType(), GetTU(X));
626 CXType clang_getResultType(CXType X) {
627 QualType T = GetQualType(X);
629 return MakeCXType(QualType(), GetTU(X));
631 if (const FunctionType *FD = T->getAs<FunctionType>())
632 return MakeCXType(FD->getReturnType(), GetTU(X));
634 return MakeCXType(QualType(), GetTU(X));
637 CXType clang_getCursorResultType(CXCursor C) {
638 if (clang_isDeclaration(C.kind)) {
639 const Decl *D = cxcursor::getCursorDecl(C);
640 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
641 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
643 return clang_getResultType(clang_getCursorType(C));
646 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
649 unsigned clang_isPODType(CXType X) {
650 QualType T = GetQualType(X);
654 CXTranslationUnit TU = GetTU(X);
656 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
659 CXType clang_getElementType(CXType CT) {
660 QualType ET = QualType();
661 QualType T = GetQualType(CT);
662 const Type *TP = T.getTypePtrOrNull();
665 switch (TP->getTypeClass()) {
666 case Type::ConstantArray:
667 ET = cast<ConstantArrayType> (TP)->getElementType();
669 case Type::IncompleteArray:
670 ET = cast<IncompleteArrayType> (TP)->getElementType();
672 case Type::VariableArray:
673 ET = cast<VariableArrayType> (TP)->getElementType();
675 case Type::DependentSizedArray:
676 ET = cast<DependentSizedArrayType> (TP)->getElementType();
679 ET = cast<VectorType> (TP)->getElementType();
682 ET = cast<ComplexType> (TP)->getElementType();
688 return MakeCXType(ET, GetTU(CT));
691 long long clang_getNumElements(CXType CT) {
692 long long result = -1;
693 QualType T = GetQualType(CT);
694 const Type *TP = T.getTypePtrOrNull();
697 switch (TP->getTypeClass()) {
698 case Type::ConstantArray:
699 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
702 result = cast<VectorType> (TP)->getNumElements();
711 CXType clang_getArrayElementType(CXType CT) {
712 QualType ET = QualType();
713 QualType T = GetQualType(CT);
714 const Type *TP = T.getTypePtrOrNull();
717 switch (TP->getTypeClass()) {
718 case Type::ConstantArray:
719 ET = cast<ConstantArrayType> (TP)->getElementType();
721 case Type::IncompleteArray:
722 ET = cast<IncompleteArrayType> (TP)->getElementType();
724 case Type::VariableArray:
725 ET = cast<VariableArrayType> (TP)->getElementType();
727 case Type::DependentSizedArray:
728 ET = cast<DependentSizedArrayType> (TP)->getElementType();
734 return MakeCXType(ET, GetTU(CT));
737 long long clang_getArraySize(CXType CT) {
738 long long result = -1;
739 QualType T = GetQualType(CT);
740 const Type *TP = T.getTypePtrOrNull();
743 switch (TP->getTypeClass()) {
744 case Type::ConstantArray:
745 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
754 long long clang_Type_getAlignOf(CXType T) {
755 if (T.kind == CXType_Invalid)
756 return CXTypeLayoutError_Invalid;
757 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
758 QualType QT = GetQualType(T);
759 // [expr.alignof] p1: return size_t value for complete object type, reference
761 // [expr.alignof] p3: if reference type, return size of referenced type
762 if (QT->isReferenceType())
763 QT = QT.getNonReferenceType();
764 if (QT->isIncompleteType())
765 return CXTypeLayoutError_Incomplete;
766 if (QT->isDependentType())
767 return CXTypeLayoutError_Dependent;
768 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
769 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
770 // if (QT->isVoidType()) return 1;
771 return Ctx.getTypeAlignInChars(QT).getQuantity();
774 CXType clang_Type_getClassType(CXType CT) {
775 QualType ET = QualType();
776 QualType T = GetQualType(CT);
777 const Type *TP = T.getTypePtrOrNull();
779 if (TP && TP->getTypeClass() == Type::MemberPointer) {
780 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
782 return MakeCXType(ET, GetTU(CT));
785 long long clang_Type_getSizeOf(CXType T) {
786 if (T.kind == CXType_Invalid)
787 return CXTypeLayoutError_Invalid;
788 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
789 QualType QT = GetQualType(T);
790 // [expr.sizeof] p2: if reference type, return size of referenced type
791 if (QT->isReferenceType())
792 QT = QT.getNonReferenceType();
793 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
795 // Note: We get the cxtype, not the cxcursor, so we can't call
796 // FieldDecl->isBitField()
797 // [expr.sizeof] p3: pointer ok, function not ok.
798 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
799 if (QT->isIncompleteType())
800 return CXTypeLayoutError_Incomplete;
801 if (QT->isDependentType())
802 return CXTypeLayoutError_Dependent;
803 if (!QT->isConstantSizeType())
804 return CXTypeLayoutError_NotConstantSize;
805 // [gcc extension] lib/AST/ExprConstant.cpp:1372
806 // HandleSizeof : {voidtype,functype} == 1
807 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
808 if (QT->isVoidType() || QT->isFunctionType())
810 return Ctx.getTypeSizeInChars(QT).getQuantity();
813 static long long visitRecordForValidation(const RecordDecl *RD) {
814 for (const auto *I : RD->fields()){
815 QualType FQT = I->getType();
816 if (FQT->isIncompleteType())
817 return CXTypeLayoutError_Incomplete;
818 if (FQT->isDependentType())
819 return CXTypeLayoutError_Dependent;
821 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
822 if (const RecordDecl *Child = ChildType->getDecl()) {
823 long long ret = visitRecordForValidation(Child);
828 // else try next field
833 static long long validateFieldParentType(CXCursor PC, CXType PT){
834 if (clang_isInvalid(PC.kind))
835 return CXTypeLayoutError_Invalid;
836 const RecordDecl *RD =
837 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
838 // validate parent declaration
839 if (!RD || RD->isInvalidDecl())
840 return CXTypeLayoutError_Invalid;
841 RD = RD->getDefinition();
843 return CXTypeLayoutError_Incomplete;
844 if (RD->isInvalidDecl())
845 return CXTypeLayoutError_Invalid;
846 // validate parent type
847 QualType RT = GetQualType(PT);
848 if (RT->isIncompleteType())
849 return CXTypeLayoutError_Incomplete;
850 if (RT->isDependentType())
851 return CXTypeLayoutError_Dependent;
852 // We recurse into all record fields to detect incomplete and dependent types.
853 long long Error = visitRecordForValidation(RD);
859 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
860 // check that PT is not incomplete/dependent
861 CXCursor PC = clang_getTypeDeclaration(PT);
862 long long Error = validateFieldParentType(PC,PT);
866 return CXTypeLayoutError_InvalidFieldName;
868 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
869 IdentifierInfo *II = &Ctx.Idents.get(S);
870 DeclarationName FieldName(II);
871 const RecordDecl *RD =
872 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
873 // verified in validateFieldParentType
874 RD = RD->getDefinition();
875 RecordDecl::lookup_result Res = RD->lookup(FieldName);
876 // If a field of the parent record is incomplete, lookup will fail.
877 // and we would return InvalidFieldName instead of Incomplete.
878 // But this erroneous results does protects again a hidden assertion failure
879 // in the RecordLayoutBuilder
881 return CXTypeLayoutError_InvalidFieldName;
882 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
883 return Ctx.getFieldOffset(FD);
884 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
885 return Ctx.getFieldOffset(IFD);
886 // we don't want any other Decl Type.
887 return CXTypeLayoutError_InvalidFieldName;
890 long long clang_Cursor_getOffsetOfField(CXCursor C) {
891 if (clang_isDeclaration(C.kind)) {
892 // we need to validate the parent type
893 CXCursor PC = clang_getCursorSemanticParent(C);
894 CXType PT = clang_getCursorType(PC);
895 long long Error = validateFieldParentType(PC,PT);
898 // proceed with the offset calculation
899 const Decl *D = cxcursor::getCursorDecl(C);
900 ASTContext &Ctx = cxcursor::getCursorContext(C);
901 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
902 return Ctx.getFieldOffset(FD);
903 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
904 return Ctx.getFieldOffset(IFD);
909 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
910 QualType QT = GetQualType(T);
912 return CXRefQualifier_None;
913 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
915 return CXRefQualifier_None;
916 switch (FD->getRefQualifier()) {
918 return CXRefQualifier_None;
920 return CXRefQualifier_LValue;
922 return CXRefQualifier_RValue;
924 return CXRefQualifier_None;
927 unsigned clang_Cursor_isBitField(CXCursor C) {
928 if (!clang_isDeclaration(C.kind))
930 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
933 return FD->isBitField();
936 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
937 if (!clang_isDeclaration(C.kind))
938 return cxstring::createEmpty();
940 const Decl *D = cxcursor::getCursorDecl(C);
941 ASTContext &Ctx = cxcursor::getCursorContext(C);
942 std::string encoding;
944 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
945 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
946 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
947 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
948 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
949 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
952 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
953 Ty = Ctx.getTypeDeclType(TD);
954 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
956 else return cxstring::createRef("?");
957 Ctx.getObjCEncodingForType(Ty, encoding);
960 return cxstring::createDup(encoding);
963 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
964 unsigned size = TA.size();
965 for (const auto &Arg : TA)
966 if (Arg.getKind() == TemplateArgument::Pack)
967 size += Arg.pack_size() - 1;
971 int clang_Type_getNumTemplateArguments(CXType CT) {
972 QualType T = GetQualType(CT);
976 auto TA = GetTemplateArguments(T);
980 return GetTemplateArgumentArraySize(TA.getValue());
983 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
984 QualType T = GetQualType(CT);
986 return MakeCXType(QualType(), GetTU(CT));
988 auto TA = GetTemplateArguments(T);
990 return MakeCXType(QualType(), GetTU(CT));
992 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
993 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
996 unsigned clang_Type_visitFields(CXType PT,
997 CXFieldVisitor visitor,
998 CXClientData client_data){
999 CXCursor PC = clang_getTypeDeclaration(PT);
1000 if (clang_isInvalid(PC.kind))
1002 const RecordDecl *RD =
1003 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1004 if (!RD || RD->isInvalidDecl())
1006 RD = RD->getDefinition();
1007 if (!RD || RD->isInvalidDecl())
1010 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1012 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1013 // Callback to the client.
1014 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1017 case CXVisit_Continue:
1024 unsigned clang_Cursor_isAnonymous(CXCursor C){
1025 if (!clang_isDeclaration(C.kind))
1027 const Decl *D = cxcursor::getCursorDecl(C);
1028 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1029 return FD->isAnonymousStructOrUnion();
1033 CXType clang_Type_getNamedType(CXType CT){
1034 QualType T = GetQualType(CT);
1035 const Type *TP = T.getTypePtrOrNull();
1037 if (TP && TP->getTypeClass() == Type::Elaborated)
1038 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1040 return MakeCXType(QualType(), GetTU(CT));
1043 unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1044 QualType T = GetQualType(TT);
1045 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1046 if (auto *D = TT->getDecl())
1047 return D->isTransparentTag();