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/Basic/AddressSpaces.h"
25 #include "clang/Frontend/ASTUnit.h"
27 using namespace clang;
29 static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
30 #define BTCASE(K) case BuiltinType::K: return CXType_##K
31 switch (BT->getKind()) {
45 case BuiltinType::WChar_S: return CXType_WChar;
46 case BuiltinType::WChar_U: return CXType_WChar;
63 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id);
64 #include "clang/Basic/OpenCLImageTypes.def"
71 return CXType_Unexposed;
76 static CXTypeKind GetTypeKind(QualType T) {
77 const Type *TP = T.getTypePtrOrNull();
79 return CXType_Invalid;
81 #define TKCASE(K) case Type::K: return CXType_##K
82 switch (TP->getTypeClass()) {
84 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
88 TKCASE(LValueReference);
89 TKCASE(RValueReference);
93 TKCASE(ObjCInterface);
94 TKCASE(ObjCObjectPointer);
95 TKCASE(FunctionNoProto);
96 TKCASE(FunctionProto);
97 TKCASE(ConstantArray);
98 TKCASE(IncompleteArray);
99 TKCASE(VariableArray);
100 TKCASE(DependentSizedArray);
102 TKCASE(MemberPointer);
107 return CXType_Unexposed;
113 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
114 CXTypeKind TK = CXType_Invalid;
116 if (TU && !T.isNull()) {
117 // Handle attributed types as the original type
118 if (auto *ATT = T->getAs<AttributedType>()) {
119 return MakeCXType(ATT->getModifiedType(), TU);
122 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
123 if (Ctx.getLangOpts().ObjC1) {
124 QualType UnqualT = T.getUnqualifiedType();
125 if (Ctx.isObjCIdType(UnqualT))
127 else if (Ctx.isObjCClassType(UnqualT))
128 TK = CXType_ObjCClass;
129 else if (Ctx.isObjCSelType(UnqualT))
133 /* Handle decayed types as the original type */
134 if (const DecayedType *DT = T->getAs<DecayedType>()) {
135 return MakeCXType(DT->getOriginalType(), TU);
138 if (TK == CXType_Invalid)
141 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
142 : T.getAsOpaquePtr(), TU } };
146 using cxtype::MakeCXType;
148 static inline QualType GetQualType(CXType CT) {
149 return QualType::getFromOpaquePtr(CT.data[0]);
152 static inline CXTranslationUnit GetTU(CXType CT) {
153 return static_cast<CXTranslationUnit>(CT.data[1]);
156 static Optional<ArrayRef<TemplateArgument>>
157 GetTemplateArguments(QualType Type) {
158 assert(!Type.isNull());
159 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
160 return Specialization->template_arguments();
162 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
163 const auto *TemplateDecl =
164 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
166 return TemplateDecl->getTemplateArgs().asArray();
172 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
173 if (A.getKind() == TemplateArgument::Type)
174 return A.getAsType();
178 static Optional<QualType>
179 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
180 unsigned current = 0;
181 for (const auto &A : TA) {
182 if (A.getKind() == TemplateArgument::Pack) {
183 if (index < current + A.pack_size())
184 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
185 current += A.pack_size();
188 if (current == index)
189 return TemplateArgumentToQualType(A);
195 CXType clang_getCursorType(CXCursor C) {
196 using namespace cxcursor;
198 CXTranslationUnit TU = cxcursor::getCursorTU(C);
200 return MakeCXType(QualType(), TU);
202 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
203 if (clang_isExpression(C.kind)) {
204 QualType T = cxcursor::getCursorExpr(C)->getType();
205 return MakeCXType(T, TU);
208 if (clang_isDeclaration(C.kind)) {
209 const Decl *D = cxcursor::getCursorDecl(C);
211 return MakeCXType(QualType(), TU);
213 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
214 return MakeCXType(Context.getTypeDeclType(TD), TU);
215 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
216 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
217 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
218 return MakeCXType(DD->getType(), TU);
219 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
220 return MakeCXType(VD->getType(), TU);
221 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
222 return MakeCXType(PD->getType(), TU);
223 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
224 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
225 return MakeCXType(QualType(), TU);
228 if (clang_isReference(C.kind)) {
230 case CXCursor_ObjCSuperClassRef: {
232 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
233 return MakeCXType(T, TU);
236 case CXCursor_ObjCClassRef: {
237 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
238 return MakeCXType(T, TU);
241 case CXCursor_TypeRef: {
242 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
243 return MakeCXType(T, TU);
247 case CXCursor_CXXBaseSpecifier:
248 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
250 case CXCursor_MemberRef:
251 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
253 case CXCursor_VariableRef:
254 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
256 case CXCursor_ObjCProtocolRef:
257 case CXCursor_TemplateRef:
258 case CXCursor_NamespaceRef:
259 case CXCursor_OverloadedDeclRef:
264 return MakeCXType(QualType(), TU);
267 return MakeCXType(QualType(), TU);
270 CXString clang_getTypeSpelling(CXType CT) {
271 QualType T = GetQualType(CT);
273 return cxstring::createEmpty();
275 CXTranslationUnit TU = GetTU(CT);
277 llvm::raw_svector_ostream OS(Str);
278 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
282 return cxstring::createDup(OS.str());
285 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
286 using namespace cxcursor;
287 CXTranslationUnit TU = cxcursor::getCursorTU(C);
289 if (clang_isDeclaration(C.kind)) {
290 const Decl *D = cxcursor::getCursorDecl(C);
292 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
293 QualType T = TD->getUnderlyingType();
294 return MakeCXType(T, TU);
297 return MakeCXType(QualType(), TU);
300 return MakeCXType(QualType(), TU);
303 CXType clang_getEnumDeclIntegerType(CXCursor C) {
304 using namespace cxcursor;
305 CXTranslationUnit TU = cxcursor::getCursorTU(C);
307 if (clang_isDeclaration(C.kind)) {
308 const Decl *D = cxcursor::getCursorDecl(C);
310 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
311 QualType T = TD->getIntegerType();
312 return MakeCXType(T, TU);
315 return MakeCXType(QualType(), TU);
318 return MakeCXType(QualType(), TU);
321 long long clang_getEnumConstantDeclValue(CXCursor C) {
322 using namespace cxcursor;
324 if (clang_isDeclaration(C.kind)) {
325 const Decl *D = cxcursor::getCursorDecl(C);
327 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
328 return TD->getInitVal().getSExtValue();
337 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
338 using namespace cxcursor;
340 if (clang_isDeclaration(C.kind)) {
341 const Decl *D = cxcursor::getCursorDecl(C);
343 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
344 return TD->getInitVal().getZExtValue();
353 int clang_getFieldDeclBitWidth(CXCursor C) {
354 using namespace cxcursor;
356 if (clang_isDeclaration(C.kind)) {
357 const Decl *D = getCursorDecl(C);
359 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
360 if (FD->isBitField())
361 return FD->getBitWidthValue(getCursorContext(C));
368 CXType clang_getCanonicalType(CXType CT) {
369 if (CT.kind == CXType_Invalid)
372 QualType T = GetQualType(CT);
373 CXTranslationUnit TU = GetTU(CT);
376 return MakeCXType(QualType(), GetTU(CT));
378 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
379 .getCanonicalType(T),
383 unsigned clang_isConstQualifiedType(CXType CT) {
384 QualType T = GetQualType(CT);
385 return T.isLocalConstQualified();
388 unsigned clang_isVolatileQualifiedType(CXType CT) {
389 QualType T = GetQualType(CT);
390 return T.isLocalVolatileQualified();
393 unsigned clang_isRestrictQualifiedType(CXType CT) {
394 QualType T = GetQualType(CT);
395 return T.isLocalRestrictQualified();
398 unsigned clang_getAddressSpace(CXType CT) {
399 QualType T = GetQualType(CT);
401 // For non language-specific address space, use separate helper function.
402 if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) {
403 return T.getQualifiers().getAddressSpaceAttributePrintValue();
405 return T.getAddressSpace();
408 CXString clang_getTypedefName(CXType CT) {
409 QualType T = GetQualType(CT);
410 const TypedefType *TT = T->getAs<TypedefType>();
412 TypedefNameDecl *TD = TT->getDecl();
414 return cxstring::createDup(TD->getNameAsString().c_str());
416 return cxstring::createEmpty();
419 CXType clang_getPointeeType(CXType CT) {
420 QualType T = GetQualType(CT);
421 const Type *TP = T.getTypePtrOrNull();
424 return MakeCXType(QualType(), GetTU(CT));
426 switch (TP->getTypeClass()) {
428 T = cast<PointerType>(TP)->getPointeeType();
430 case Type::BlockPointer:
431 T = cast<BlockPointerType>(TP)->getPointeeType();
433 case Type::LValueReference:
434 case Type::RValueReference:
435 T = cast<ReferenceType>(TP)->getPointeeType();
437 case Type::ObjCObjectPointer:
438 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
440 case Type::MemberPointer:
441 T = cast<MemberPointerType>(TP)->getPointeeType();
447 return MakeCXType(T, GetTU(CT));
450 CXCursor clang_getTypeDeclaration(CXType CT) {
451 if (CT.kind == CXType_Invalid)
452 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
454 QualType T = GetQualType(CT);
455 const Type *TP = T.getTypePtrOrNull();
458 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
463 switch (TP->getTypeClass()) {
465 D = cast<TypedefType>(TP)->getDecl();
467 case Type::ObjCObject:
468 D = cast<ObjCObjectType>(TP)->getInterface();
470 case Type::ObjCInterface:
471 D = cast<ObjCInterfaceType>(TP)->getDecl();
475 D = cast<TagType>(TP)->getDecl();
477 case Type::TemplateSpecialization:
478 if (const RecordType *Record = TP->getAs<RecordType>())
479 D = Record->getDecl();
481 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
482 .getAsTemplateDecl();
486 case Type::DeducedTemplateSpecialization:
487 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
492 case Type::InjectedClassName:
493 D = cast<InjectedClassNameType>(TP)->getDecl();
496 // FIXME: Template type parameters!
498 case Type::Elaborated:
499 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
507 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
509 return cxcursor::MakeCXCursor(D, GetTU(CT));
512 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
513 const char *s = nullptr;
514 #define TKIND(X) case CXType_##X: s = "" #X ""; break
531 case CXType_WChar: s = "WChar"; break;
551 TKIND(LValueReference);
552 TKIND(RValueReference);
556 TKIND(ObjCInterface);
557 TKIND(ObjCObjectPointer);
558 TKIND(FunctionNoProto);
559 TKIND(FunctionProto);
560 TKIND(ConstantArray);
561 TKIND(IncompleteArray);
562 TKIND(VariableArray);
563 TKIND(DependentSizedArray);
565 TKIND(MemberPointer);
569 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
570 #include "clang/Basic/OpenCLImageTypes.def"
578 return cxstring::createRef(s);
581 unsigned clang_equalTypes(CXType A, CXType B) {
582 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
585 unsigned clang_isFunctionTypeVariadic(CXType X) {
586 QualType T = GetQualType(X);
590 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
591 return (unsigned)FD->isVariadic();
593 if (T->getAs<FunctionNoProtoType>())
599 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
600 QualType T = GetQualType(X);
602 return CXCallingConv_Invalid;
604 if (const FunctionType *FD = T->getAs<FunctionType>()) {
605 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
606 switch (FD->getCallConv()) {
608 TCALLINGCONV(X86StdCall);
609 TCALLINGCONV(X86FastCall);
610 TCALLINGCONV(X86ThisCall);
611 TCALLINGCONV(X86Pascal);
612 TCALLINGCONV(X86RegCall);
613 TCALLINGCONV(X86VectorCall);
614 TCALLINGCONV(X86_64Win64);
615 TCALLINGCONV(X86_64SysV);
617 TCALLINGCONV(AAPCS_VFP);
618 TCALLINGCONV(IntelOclBicc);
620 TCALLINGCONV(PreserveMost);
621 TCALLINGCONV(PreserveAll);
622 case CC_SpirFunction: return CXCallingConv_Unexposed;
623 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
629 return CXCallingConv_Invalid;
632 int clang_getNumArgTypes(CXType X) {
633 QualType T = GetQualType(X);
637 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
638 return FD->getNumParams();
641 if (T->getAs<FunctionNoProtoType>()) {
648 CXType clang_getArgType(CXType X, unsigned i) {
649 QualType T = GetQualType(X);
651 return MakeCXType(QualType(), GetTU(X));
653 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
654 unsigned numParams = FD->getNumParams();
656 return MakeCXType(QualType(), GetTU(X));
658 return MakeCXType(FD->getParamType(i), GetTU(X));
661 return MakeCXType(QualType(), GetTU(X));
664 CXType clang_getResultType(CXType X) {
665 QualType T = GetQualType(X);
667 return MakeCXType(QualType(), GetTU(X));
669 if (const FunctionType *FD = T->getAs<FunctionType>())
670 return MakeCXType(FD->getReturnType(), GetTU(X));
672 return MakeCXType(QualType(), GetTU(X));
675 CXType clang_getCursorResultType(CXCursor C) {
676 if (clang_isDeclaration(C.kind)) {
677 const Decl *D = cxcursor::getCursorDecl(C);
678 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
679 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
681 return clang_getResultType(clang_getCursorType(C));
684 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
687 int clang_getExceptionSpecificationType(CXType X) {
688 QualType T = GetQualType(X);
692 if (const auto *FD = T->getAs<FunctionProtoType>())
693 return static_cast<int>(FD->getExceptionSpecType());
698 int clang_getCursorExceptionSpecificationType(CXCursor C) {
699 if (clang_isDeclaration(C.kind))
700 return clang_getExceptionSpecificationType(clang_getCursorType(C));
705 unsigned clang_isPODType(CXType X) {
706 QualType T = GetQualType(X);
710 CXTranslationUnit TU = GetTU(X);
712 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
715 CXType clang_getElementType(CXType CT) {
716 QualType ET = QualType();
717 QualType T = GetQualType(CT);
718 const Type *TP = T.getTypePtrOrNull();
721 switch (TP->getTypeClass()) {
722 case Type::ConstantArray:
723 ET = cast<ConstantArrayType> (TP)->getElementType();
725 case Type::IncompleteArray:
726 ET = cast<IncompleteArrayType> (TP)->getElementType();
728 case Type::VariableArray:
729 ET = cast<VariableArrayType> (TP)->getElementType();
731 case Type::DependentSizedArray:
732 ET = cast<DependentSizedArrayType> (TP)->getElementType();
735 ET = cast<VectorType> (TP)->getElementType();
738 ET = cast<ComplexType> (TP)->getElementType();
744 return MakeCXType(ET, GetTU(CT));
747 long long clang_getNumElements(CXType CT) {
748 long long result = -1;
749 QualType T = GetQualType(CT);
750 const Type *TP = T.getTypePtrOrNull();
753 switch (TP->getTypeClass()) {
754 case Type::ConstantArray:
755 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
758 result = cast<VectorType> (TP)->getNumElements();
767 CXType clang_getArrayElementType(CXType CT) {
768 QualType ET = QualType();
769 QualType T = GetQualType(CT);
770 const Type *TP = T.getTypePtrOrNull();
773 switch (TP->getTypeClass()) {
774 case Type::ConstantArray:
775 ET = cast<ConstantArrayType> (TP)->getElementType();
777 case Type::IncompleteArray:
778 ET = cast<IncompleteArrayType> (TP)->getElementType();
780 case Type::VariableArray:
781 ET = cast<VariableArrayType> (TP)->getElementType();
783 case Type::DependentSizedArray:
784 ET = cast<DependentSizedArrayType> (TP)->getElementType();
790 return MakeCXType(ET, GetTU(CT));
793 long long clang_getArraySize(CXType CT) {
794 long long result = -1;
795 QualType T = GetQualType(CT);
796 const Type *TP = T.getTypePtrOrNull();
799 switch (TP->getTypeClass()) {
800 case Type::ConstantArray:
801 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
810 long long clang_Type_getAlignOf(CXType T) {
811 if (T.kind == CXType_Invalid)
812 return CXTypeLayoutError_Invalid;
813 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
814 QualType QT = GetQualType(T);
815 // [expr.alignof] p1: return size_t value for complete object type, reference
817 // [expr.alignof] p3: if reference type, return size of referenced type
818 if (QT->isReferenceType())
819 QT = QT.getNonReferenceType();
820 if (QT->isIncompleteType())
821 return CXTypeLayoutError_Incomplete;
822 if (QT->isDependentType())
823 return CXTypeLayoutError_Dependent;
824 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
825 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
826 // if (QT->isVoidType()) return 1;
827 return Ctx.getTypeAlignInChars(QT).getQuantity();
830 CXType clang_Type_getClassType(CXType CT) {
831 QualType ET = QualType();
832 QualType T = GetQualType(CT);
833 const Type *TP = T.getTypePtrOrNull();
835 if (TP && TP->getTypeClass() == Type::MemberPointer) {
836 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
838 return MakeCXType(ET, GetTU(CT));
841 long long clang_Type_getSizeOf(CXType T) {
842 if (T.kind == CXType_Invalid)
843 return CXTypeLayoutError_Invalid;
844 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
845 QualType QT = GetQualType(T);
846 // [expr.sizeof] p2: if reference type, return size of referenced type
847 if (QT->isReferenceType())
848 QT = QT.getNonReferenceType();
849 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
851 // Note: We get the cxtype, not the cxcursor, so we can't call
852 // FieldDecl->isBitField()
853 // [expr.sizeof] p3: pointer ok, function not ok.
854 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
855 if (QT->isIncompleteType())
856 return CXTypeLayoutError_Incomplete;
857 if (QT->isDependentType())
858 return CXTypeLayoutError_Dependent;
859 if (!QT->isConstantSizeType())
860 return CXTypeLayoutError_NotConstantSize;
861 // [gcc extension] lib/AST/ExprConstant.cpp:1372
862 // HandleSizeof : {voidtype,functype} == 1
863 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
864 if (QT->isVoidType() || QT->isFunctionType())
866 return Ctx.getTypeSizeInChars(QT).getQuantity();
869 static long long visitRecordForValidation(const RecordDecl *RD) {
870 for (const auto *I : RD->fields()){
871 QualType FQT = I->getType();
872 if (FQT->isIncompleteType())
873 return CXTypeLayoutError_Incomplete;
874 if (FQT->isDependentType())
875 return CXTypeLayoutError_Dependent;
877 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
878 if (const RecordDecl *Child = ChildType->getDecl()) {
879 long long ret = visitRecordForValidation(Child);
884 // else try next field
889 static long long validateFieldParentType(CXCursor PC, CXType PT){
890 if (clang_isInvalid(PC.kind))
891 return CXTypeLayoutError_Invalid;
892 const RecordDecl *RD =
893 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
894 // validate parent declaration
895 if (!RD || RD->isInvalidDecl())
896 return CXTypeLayoutError_Invalid;
897 RD = RD->getDefinition();
899 return CXTypeLayoutError_Incomplete;
900 if (RD->isInvalidDecl())
901 return CXTypeLayoutError_Invalid;
902 // validate parent type
903 QualType RT = GetQualType(PT);
904 if (RT->isIncompleteType())
905 return CXTypeLayoutError_Incomplete;
906 if (RT->isDependentType())
907 return CXTypeLayoutError_Dependent;
908 // We recurse into all record fields to detect incomplete and dependent types.
909 long long Error = visitRecordForValidation(RD);
915 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
916 // check that PT is not incomplete/dependent
917 CXCursor PC = clang_getTypeDeclaration(PT);
918 long long Error = validateFieldParentType(PC,PT);
922 return CXTypeLayoutError_InvalidFieldName;
924 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
925 IdentifierInfo *II = &Ctx.Idents.get(S);
926 DeclarationName FieldName(II);
927 const RecordDecl *RD =
928 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
929 // verified in validateFieldParentType
930 RD = RD->getDefinition();
931 RecordDecl::lookup_result Res = RD->lookup(FieldName);
932 // If a field of the parent record is incomplete, lookup will fail.
933 // and we would return InvalidFieldName instead of Incomplete.
934 // But this erroneous results does protects again a hidden assertion failure
935 // in the RecordLayoutBuilder
937 return CXTypeLayoutError_InvalidFieldName;
938 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
939 return Ctx.getFieldOffset(FD);
940 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
941 return Ctx.getFieldOffset(IFD);
942 // we don't want any other Decl Type.
943 return CXTypeLayoutError_InvalidFieldName;
946 long long clang_Cursor_getOffsetOfField(CXCursor C) {
947 if (clang_isDeclaration(C.kind)) {
948 // we need to validate the parent type
949 CXCursor PC = clang_getCursorSemanticParent(C);
950 CXType PT = clang_getCursorType(PC);
951 long long Error = validateFieldParentType(PC,PT);
954 // proceed with the offset calculation
955 const Decl *D = cxcursor::getCursorDecl(C);
956 ASTContext &Ctx = cxcursor::getCursorContext(C);
957 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
958 return Ctx.getFieldOffset(FD);
959 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
960 return Ctx.getFieldOffset(IFD);
965 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
966 QualType QT = GetQualType(T);
968 return CXRefQualifier_None;
969 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
971 return CXRefQualifier_None;
972 switch (FD->getRefQualifier()) {
974 return CXRefQualifier_None;
976 return CXRefQualifier_LValue;
978 return CXRefQualifier_RValue;
980 return CXRefQualifier_None;
983 unsigned clang_Cursor_isBitField(CXCursor C) {
984 if (!clang_isDeclaration(C.kind))
986 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
989 return FD->isBitField();
992 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
993 if (!clang_isDeclaration(C.kind))
994 return cxstring::createEmpty();
996 const Decl *D = cxcursor::getCursorDecl(C);
997 ASTContext &Ctx = cxcursor::getCursorContext(C);
998 std::string encoding;
1000 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
1001 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
1002 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
1003 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
1004 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1005 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
1008 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
1009 Ty = Ctx.getTypeDeclType(TD);
1010 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
1012 else return cxstring::createRef("?");
1013 Ctx.getObjCEncodingForType(Ty, encoding);
1016 return cxstring::createDup(encoding);
1019 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
1020 unsigned size = TA.size();
1021 for (const auto &Arg : TA)
1022 if (Arg.getKind() == TemplateArgument::Pack)
1023 size += Arg.pack_size() - 1;
1027 int clang_Type_getNumTemplateArguments(CXType CT) {
1028 QualType T = GetQualType(CT);
1032 auto TA = GetTemplateArguments(T);
1036 return GetTemplateArgumentArraySize(TA.getValue());
1039 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
1040 QualType T = GetQualType(CT);
1042 return MakeCXType(QualType(), GetTU(CT));
1044 auto TA = GetTemplateArguments(T);
1046 return MakeCXType(QualType(), GetTU(CT));
1048 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
1049 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
1052 unsigned clang_Type_visitFields(CXType PT,
1053 CXFieldVisitor visitor,
1054 CXClientData client_data){
1055 CXCursor PC = clang_getTypeDeclaration(PT);
1056 if (clang_isInvalid(PC.kind))
1058 const RecordDecl *RD =
1059 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1060 if (!RD || RD->isInvalidDecl())
1062 RD = RD->getDefinition();
1063 if (!RD || RD->isInvalidDecl())
1066 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1068 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1069 // Callback to the client.
1070 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1073 case CXVisit_Continue:
1080 unsigned clang_Cursor_isAnonymous(CXCursor C){
1081 if (!clang_isDeclaration(C.kind))
1083 const Decl *D = cxcursor::getCursorDecl(C);
1084 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1085 return FD->isAnonymousStructOrUnion();
1089 CXType clang_Type_getNamedType(CXType CT){
1090 QualType T = GetQualType(CT);
1091 const Type *TP = T.getTypePtrOrNull();
1093 if (TP && TP->getTypeClass() == Type::Elaborated)
1094 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1096 return MakeCXType(QualType(), GetTU(CT));
1099 unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1100 QualType T = GetQualType(TT);
1101 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1102 if (auto *D = TT->getDecl())
1103 return D->isTransparentTag();