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;
70 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id);
71 #include "clang/Basic/OpenCLImageTypes.def"
78 return CXType_Unexposed;
83 static CXTypeKind GetTypeKind(QualType T) {
84 const Type *TP = T.getTypePtrOrNull();
86 return CXType_Invalid;
88 #define TKCASE(K) case Type::K: return CXType_##K
89 switch (TP->getTypeClass()) {
91 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
95 TKCASE(LValueReference);
96 TKCASE(RValueReference);
100 TKCASE(ObjCInterface);
101 TKCASE(ObjCObjectPointer);
102 TKCASE(FunctionNoProto);
103 TKCASE(FunctionProto);
104 TKCASE(ConstantArray);
105 TKCASE(IncompleteArray);
106 TKCASE(VariableArray);
107 TKCASE(DependentSizedArray);
109 TKCASE(MemberPointer);
114 return CXType_Unexposed;
120 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
121 CXTypeKind TK = CXType_Invalid;
123 if (TU && !T.isNull()) {
124 // Handle attributed types as the original type
125 if (auto *ATT = T->getAs<AttributedType>()) {
126 return MakeCXType(ATT->getModifiedType(), TU);
128 // Handle paren types as the original type
129 if (auto *PTT = T->getAs<ParenType>()) {
130 return MakeCXType(PTT->getInnerType(), TU);
133 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
134 if (Ctx.getLangOpts().ObjC1) {
135 QualType UnqualT = T.getUnqualifiedType();
136 if (Ctx.isObjCIdType(UnqualT))
138 else if (Ctx.isObjCClassType(UnqualT))
139 TK = CXType_ObjCClass;
140 else if (Ctx.isObjCSelType(UnqualT))
144 /* Handle decayed types as the original type */
145 if (const DecayedType *DT = T->getAs<DecayedType>()) {
146 return MakeCXType(DT->getOriginalType(), TU);
149 if (TK == CXType_Invalid)
152 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
153 : T.getAsOpaquePtr(), TU } };
157 using cxtype::MakeCXType;
159 static inline QualType GetQualType(CXType CT) {
160 return QualType::getFromOpaquePtr(CT.data[0]);
163 static inline CXTranslationUnit GetTU(CXType CT) {
164 return static_cast<CXTranslationUnit>(CT.data[1]);
167 static Optional<ArrayRef<TemplateArgument>>
168 GetTemplateArguments(QualType Type) {
169 assert(!Type.isNull());
170 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
171 return Specialization->template_arguments();
173 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
174 const auto *TemplateDecl =
175 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
177 return TemplateDecl->getTemplateArgs().asArray();
183 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
184 if (A.getKind() == TemplateArgument::Type)
185 return A.getAsType();
189 static Optional<QualType>
190 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
191 unsigned current = 0;
192 for (const auto &A : TA) {
193 if (A.getKind() == TemplateArgument::Pack) {
194 if (index < current + A.pack_size())
195 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
196 current += A.pack_size();
199 if (current == index)
200 return TemplateArgumentToQualType(A);
206 CXType clang_getCursorType(CXCursor C) {
207 using namespace cxcursor;
209 CXTranslationUnit TU = cxcursor::getCursorTU(C);
211 return MakeCXType(QualType(), TU);
213 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
214 if (clang_isExpression(C.kind)) {
215 QualType T = cxcursor::getCursorExpr(C)->getType();
216 return MakeCXType(T, TU);
219 if (clang_isDeclaration(C.kind)) {
220 const Decl *D = cxcursor::getCursorDecl(C);
222 return MakeCXType(QualType(), TU);
224 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
225 return MakeCXType(Context.getTypeDeclType(TD), TU);
226 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
227 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
228 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
229 return MakeCXType(DD->getType(), TU);
230 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
231 return MakeCXType(VD->getType(), TU);
232 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
233 return MakeCXType(PD->getType(), TU);
234 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
235 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
236 return MakeCXType(QualType(), TU);
239 if (clang_isReference(C.kind)) {
241 case CXCursor_ObjCSuperClassRef: {
243 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
244 return MakeCXType(T, TU);
247 case CXCursor_ObjCClassRef: {
248 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
249 return MakeCXType(T, TU);
252 case CXCursor_TypeRef: {
253 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
254 return MakeCXType(T, TU);
258 case CXCursor_CXXBaseSpecifier:
259 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
261 case CXCursor_MemberRef:
262 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
264 case CXCursor_VariableRef:
265 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
267 case CXCursor_ObjCProtocolRef:
268 case CXCursor_TemplateRef:
269 case CXCursor_NamespaceRef:
270 case CXCursor_OverloadedDeclRef:
275 return MakeCXType(QualType(), TU);
278 return MakeCXType(QualType(), TU);
281 CXString clang_getTypeSpelling(CXType CT) {
282 QualType T = GetQualType(CT);
284 return cxstring::createEmpty();
286 CXTranslationUnit TU = GetTU(CT);
288 llvm::raw_svector_ostream OS(Str);
289 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
293 return cxstring::createDup(OS.str());
296 CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
297 using namespace cxcursor;
298 CXTranslationUnit TU = cxcursor::getCursorTU(C);
300 if (clang_isDeclaration(C.kind)) {
301 const Decl *D = cxcursor::getCursorDecl(C);
303 if (const TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
304 QualType T = TD->getUnderlyingType();
305 return MakeCXType(T, TU);
308 return MakeCXType(QualType(), TU);
311 return MakeCXType(QualType(), TU);
314 CXType clang_getEnumDeclIntegerType(CXCursor C) {
315 using namespace cxcursor;
316 CXTranslationUnit TU = cxcursor::getCursorTU(C);
318 if (clang_isDeclaration(C.kind)) {
319 const Decl *D = cxcursor::getCursorDecl(C);
321 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
322 QualType T = TD->getIntegerType();
323 return MakeCXType(T, TU);
326 return MakeCXType(QualType(), TU);
329 return MakeCXType(QualType(), TU);
332 long long clang_getEnumConstantDeclValue(CXCursor C) {
333 using namespace cxcursor;
335 if (clang_isDeclaration(C.kind)) {
336 const Decl *D = cxcursor::getCursorDecl(C);
338 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
339 return TD->getInitVal().getSExtValue();
348 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
349 using namespace cxcursor;
351 if (clang_isDeclaration(C.kind)) {
352 const Decl *D = cxcursor::getCursorDecl(C);
354 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
355 return TD->getInitVal().getZExtValue();
364 int clang_getFieldDeclBitWidth(CXCursor C) {
365 using namespace cxcursor;
367 if (clang_isDeclaration(C.kind)) {
368 const Decl *D = getCursorDecl(C);
370 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
371 if (FD->isBitField())
372 return FD->getBitWidthValue(getCursorContext(C));
379 CXType clang_getCanonicalType(CXType CT) {
380 if (CT.kind == CXType_Invalid)
383 QualType T = GetQualType(CT);
384 CXTranslationUnit TU = GetTU(CT);
387 return MakeCXType(QualType(), GetTU(CT));
389 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
390 .getCanonicalType(T),
394 unsigned clang_isConstQualifiedType(CXType CT) {
395 QualType T = GetQualType(CT);
396 return T.isLocalConstQualified();
399 unsigned clang_isVolatileQualifiedType(CXType CT) {
400 QualType T = GetQualType(CT);
401 return T.isLocalVolatileQualified();
404 unsigned clang_isRestrictQualifiedType(CXType CT) {
405 QualType T = GetQualType(CT);
406 return T.isLocalRestrictQualified();
409 unsigned clang_getAddressSpace(CXType CT) {
410 QualType T = GetQualType(CT);
412 // For non language-specific address space, use separate helper function.
413 if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) {
414 return T.getQualifiers().getAddressSpaceAttributePrintValue();
416 // FIXME: this function returns either a LangAS or a target AS
417 // Those values can overlap which makes this function rather unpredictable
419 return (unsigned)T.getAddressSpace();
422 CXString clang_getTypedefName(CXType CT) {
423 QualType T = GetQualType(CT);
424 const TypedefType *TT = T->getAs<TypedefType>();
426 TypedefNameDecl *TD = TT->getDecl();
428 return cxstring::createDup(TD->getNameAsString().c_str());
430 return cxstring::createEmpty();
433 CXType clang_getPointeeType(CXType CT) {
434 QualType T = GetQualType(CT);
435 const Type *TP = T.getTypePtrOrNull();
438 return MakeCXType(QualType(), GetTU(CT));
440 switch (TP->getTypeClass()) {
442 T = cast<PointerType>(TP)->getPointeeType();
444 case Type::BlockPointer:
445 T = cast<BlockPointerType>(TP)->getPointeeType();
447 case Type::LValueReference:
448 case Type::RValueReference:
449 T = cast<ReferenceType>(TP)->getPointeeType();
451 case Type::ObjCObjectPointer:
452 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
454 case Type::MemberPointer:
455 T = cast<MemberPointerType>(TP)->getPointeeType();
461 return MakeCXType(T, GetTU(CT));
464 CXCursor clang_getTypeDeclaration(CXType CT) {
465 if (CT.kind == CXType_Invalid)
466 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
468 QualType T = GetQualType(CT);
469 const Type *TP = T.getTypePtrOrNull();
472 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
477 switch (TP->getTypeClass()) {
479 D = cast<TypedefType>(TP)->getDecl();
481 case Type::ObjCObject:
482 D = cast<ObjCObjectType>(TP)->getInterface();
484 case Type::ObjCInterface:
485 D = cast<ObjCInterfaceType>(TP)->getDecl();
489 D = cast<TagType>(TP)->getDecl();
491 case Type::TemplateSpecialization:
492 if (const RecordType *Record = TP->getAs<RecordType>())
493 D = Record->getDecl();
495 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
496 .getAsTemplateDecl();
500 case Type::DeducedTemplateSpecialization:
501 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
506 case Type::InjectedClassName:
507 D = cast<InjectedClassNameType>(TP)->getDecl();
510 // FIXME: Template type parameters!
512 case Type::Elaborated:
513 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
521 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
523 return cxcursor::MakeCXCursor(D, GetTU(CT));
526 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
527 const char *s = nullptr;
528 #define TKIND(X) case CXType_##X: s = "" #X ""; break
545 case CXType_WChar: s = "WChar"; break;
572 TKIND(LValueReference);
573 TKIND(RValueReference);
577 TKIND(ObjCInterface);
578 TKIND(ObjCObjectPointer);
579 TKIND(FunctionNoProto);
580 TKIND(FunctionProto);
581 TKIND(ConstantArray);
582 TKIND(IncompleteArray);
583 TKIND(VariableArray);
584 TKIND(DependentSizedArray);
586 TKIND(MemberPointer);
590 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
591 #include "clang/Basic/OpenCLImageTypes.def"
599 return cxstring::createRef(s);
602 unsigned clang_equalTypes(CXType A, CXType B) {
603 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
606 unsigned clang_isFunctionTypeVariadic(CXType X) {
607 QualType T = GetQualType(X);
611 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
612 return (unsigned)FD->isVariadic();
614 if (T->getAs<FunctionNoProtoType>())
620 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
621 QualType T = GetQualType(X);
623 return CXCallingConv_Invalid;
625 if (const FunctionType *FD = T->getAs<FunctionType>()) {
626 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
627 switch (FD->getCallConv()) {
629 TCALLINGCONV(X86StdCall);
630 TCALLINGCONV(X86FastCall);
631 TCALLINGCONV(X86ThisCall);
632 TCALLINGCONV(X86Pascal);
633 TCALLINGCONV(X86RegCall);
634 TCALLINGCONV(X86VectorCall);
636 TCALLINGCONV(X86_64SysV);
638 TCALLINGCONV(AAPCS_VFP);
639 TCALLINGCONV(IntelOclBicc);
641 TCALLINGCONV(PreserveMost);
642 TCALLINGCONV(PreserveAll);
643 case CC_SpirFunction: return CXCallingConv_Unexposed;
644 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
650 return CXCallingConv_Invalid;
653 int clang_getNumArgTypes(CXType X) {
654 QualType T = GetQualType(X);
658 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
659 return FD->getNumParams();
662 if (T->getAs<FunctionNoProtoType>()) {
669 CXType clang_getArgType(CXType X, unsigned i) {
670 QualType T = GetQualType(X);
672 return MakeCXType(QualType(), GetTU(X));
674 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
675 unsigned numParams = FD->getNumParams();
677 return MakeCXType(QualType(), GetTU(X));
679 return MakeCXType(FD->getParamType(i), GetTU(X));
682 return MakeCXType(QualType(), GetTU(X));
685 CXType clang_getResultType(CXType X) {
686 QualType T = GetQualType(X);
688 return MakeCXType(QualType(), GetTU(X));
690 if (const FunctionType *FD = T->getAs<FunctionType>())
691 return MakeCXType(FD->getReturnType(), GetTU(X));
693 return MakeCXType(QualType(), GetTU(X));
696 CXType clang_getCursorResultType(CXCursor C) {
697 if (clang_isDeclaration(C.kind)) {
698 const Decl *D = cxcursor::getCursorDecl(C);
699 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
700 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
702 return clang_getResultType(clang_getCursorType(C));
705 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
708 // FIXME: We should expose the canThrow(...) result instead of the EST.
709 static CXCursor_ExceptionSpecificationKind
710 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST) {
713 return CXCursor_ExceptionSpecificationKind_None;
714 case EST_DynamicNone:
715 return CXCursor_ExceptionSpecificationKind_DynamicNone;
717 return CXCursor_ExceptionSpecificationKind_Dynamic;
719 return CXCursor_ExceptionSpecificationKind_MSAny;
720 case EST_BasicNoexcept:
721 return CXCursor_ExceptionSpecificationKind_BasicNoexcept;
722 case EST_NoexceptFalse:
723 case EST_NoexceptTrue:
724 case EST_DependentNoexcept:
725 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept;
726 case EST_Unevaluated:
727 return CXCursor_ExceptionSpecificationKind_Unevaluated;
728 case EST_Uninstantiated:
729 return CXCursor_ExceptionSpecificationKind_Uninstantiated;
731 return CXCursor_ExceptionSpecificationKind_Unparsed;
733 llvm_unreachable("invalid EST value");
736 int clang_getExceptionSpecificationType(CXType X) {
737 QualType T = GetQualType(X);
741 if (const auto *FD = T->getAs<FunctionProtoType>())
742 return getExternalExceptionSpecificationKind(FD->getExceptionSpecType());
747 int clang_getCursorExceptionSpecificationType(CXCursor C) {
748 if (clang_isDeclaration(C.kind))
749 return clang_getExceptionSpecificationType(clang_getCursorType(C));
754 unsigned clang_isPODType(CXType X) {
755 QualType T = GetQualType(X);
759 CXTranslationUnit TU = GetTU(X);
761 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
764 CXType clang_getElementType(CXType CT) {
765 QualType ET = QualType();
766 QualType T = GetQualType(CT);
767 const Type *TP = T.getTypePtrOrNull();
770 switch (TP->getTypeClass()) {
771 case Type::ConstantArray:
772 ET = cast<ConstantArrayType> (TP)->getElementType();
774 case Type::IncompleteArray:
775 ET = cast<IncompleteArrayType> (TP)->getElementType();
777 case Type::VariableArray:
778 ET = cast<VariableArrayType> (TP)->getElementType();
780 case Type::DependentSizedArray:
781 ET = cast<DependentSizedArrayType> (TP)->getElementType();
784 ET = cast<VectorType> (TP)->getElementType();
787 ET = cast<ComplexType> (TP)->getElementType();
793 return MakeCXType(ET, GetTU(CT));
796 long long clang_getNumElements(CXType CT) {
797 long long result = -1;
798 QualType T = GetQualType(CT);
799 const Type *TP = T.getTypePtrOrNull();
802 switch (TP->getTypeClass()) {
803 case Type::ConstantArray:
804 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
807 result = cast<VectorType> (TP)->getNumElements();
816 CXType clang_getArrayElementType(CXType CT) {
817 QualType ET = QualType();
818 QualType T = GetQualType(CT);
819 const Type *TP = T.getTypePtrOrNull();
822 switch (TP->getTypeClass()) {
823 case Type::ConstantArray:
824 ET = cast<ConstantArrayType> (TP)->getElementType();
826 case Type::IncompleteArray:
827 ET = cast<IncompleteArrayType> (TP)->getElementType();
829 case Type::VariableArray:
830 ET = cast<VariableArrayType> (TP)->getElementType();
832 case Type::DependentSizedArray:
833 ET = cast<DependentSizedArrayType> (TP)->getElementType();
839 return MakeCXType(ET, GetTU(CT));
842 long long clang_getArraySize(CXType CT) {
843 long long result = -1;
844 QualType T = GetQualType(CT);
845 const Type *TP = T.getTypePtrOrNull();
848 switch (TP->getTypeClass()) {
849 case Type::ConstantArray:
850 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
859 long long clang_Type_getAlignOf(CXType T) {
860 if (T.kind == CXType_Invalid)
861 return CXTypeLayoutError_Invalid;
862 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
863 QualType QT = GetQualType(T);
864 // [expr.alignof] p1: return size_t value for complete object type, reference
866 // [expr.alignof] p3: if reference type, return size of referenced type
867 if (QT->isReferenceType())
868 QT = QT.getNonReferenceType();
869 if (QT->isIncompleteType())
870 return CXTypeLayoutError_Incomplete;
871 if (QT->isDependentType())
872 return CXTypeLayoutError_Dependent;
873 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
874 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
875 // if (QT->isVoidType()) return 1;
876 return Ctx.getTypeAlignInChars(QT).getQuantity();
879 CXType clang_Type_getClassType(CXType CT) {
880 QualType ET = QualType();
881 QualType T = GetQualType(CT);
882 const Type *TP = T.getTypePtrOrNull();
884 if (TP && TP->getTypeClass() == Type::MemberPointer) {
885 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
887 return MakeCXType(ET, GetTU(CT));
890 long long clang_Type_getSizeOf(CXType T) {
891 if (T.kind == CXType_Invalid)
892 return CXTypeLayoutError_Invalid;
893 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
894 QualType QT = GetQualType(T);
895 // [expr.sizeof] p2: if reference type, return size of referenced type
896 if (QT->isReferenceType())
897 QT = QT.getNonReferenceType();
898 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
900 // Note: We get the cxtype, not the cxcursor, so we can't call
901 // FieldDecl->isBitField()
902 // [expr.sizeof] p3: pointer ok, function not ok.
903 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
904 if (QT->isIncompleteType())
905 return CXTypeLayoutError_Incomplete;
906 if (QT->isDependentType())
907 return CXTypeLayoutError_Dependent;
908 if (!QT->isConstantSizeType())
909 return CXTypeLayoutError_NotConstantSize;
910 // [gcc extension] lib/AST/ExprConstant.cpp:1372
911 // HandleSizeof : {voidtype,functype} == 1
912 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
913 if (QT->isVoidType() || QT->isFunctionType())
915 return Ctx.getTypeSizeInChars(QT).getQuantity();
918 static long long visitRecordForValidation(const RecordDecl *RD) {
919 for (const auto *I : RD->fields()){
920 QualType FQT = I->getType();
921 if (FQT->isIncompleteType())
922 return CXTypeLayoutError_Incomplete;
923 if (FQT->isDependentType())
924 return CXTypeLayoutError_Dependent;
926 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
927 if (const RecordDecl *Child = ChildType->getDecl()) {
928 long long ret = visitRecordForValidation(Child);
933 // else try next field
938 static long long validateFieldParentType(CXCursor PC, CXType PT){
939 if (clang_isInvalid(PC.kind))
940 return CXTypeLayoutError_Invalid;
941 const RecordDecl *RD =
942 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
943 // validate parent declaration
944 if (!RD || RD->isInvalidDecl())
945 return CXTypeLayoutError_Invalid;
946 RD = RD->getDefinition();
948 return CXTypeLayoutError_Incomplete;
949 if (RD->isInvalidDecl())
950 return CXTypeLayoutError_Invalid;
951 // validate parent type
952 QualType RT = GetQualType(PT);
953 if (RT->isIncompleteType())
954 return CXTypeLayoutError_Incomplete;
955 if (RT->isDependentType())
956 return CXTypeLayoutError_Dependent;
957 // We recurse into all record fields to detect incomplete and dependent types.
958 long long Error = visitRecordForValidation(RD);
964 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
965 // check that PT is not incomplete/dependent
966 CXCursor PC = clang_getTypeDeclaration(PT);
967 long long Error = validateFieldParentType(PC,PT);
971 return CXTypeLayoutError_InvalidFieldName;
973 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
974 IdentifierInfo *II = &Ctx.Idents.get(S);
975 DeclarationName FieldName(II);
976 const RecordDecl *RD =
977 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
978 // verified in validateFieldParentType
979 RD = RD->getDefinition();
980 RecordDecl::lookup_result Res = RD->lookup(FieldName);
981 // If a field of the parent record is incomplete, lookup will fail.
982 // and we would return InvalidFieldName instead of Incomplete.
983 // But this erroneous results does protects again a hidden assertion failure
984 // in the RecordLayoutBuilder
986 return CXTypeLayoutError_InvalidFieldName;
987 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
988 return Ctx.getFieldOffset(FD);
989 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
990 return Ctx.getFieldOffset(IFD);
991 // we don't want any other Decl Type.
992 return CXTypeLayoutError_InvalidFieldName;
995 long long clang_Cursor_getOffsetOfField(CXCursor C) {
996 if (clang_isDeclaration(C.kind)) {
997 // we need to validate the parent type
998 CXCursor PC = clang_getCursorSemanticParent(C);
999 CXType PT = clang_getCursorType(PC);
1000 long long Error = validateFieldParentType(PC,PT);
1003 // proceed with the offset calculation
1004 const Decl *D = cxcursor::getCursorDecl(C);
1005 ASTContext &Ctx = cxcursor::getCursorContext(C);
1006 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
1007 return Ctx.getFieldOffset(FD);
1008 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
1009 return Ctx.getFieldOffset(IFD);
1014 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
1015 QualType QT = GetQualType(T);
1017 return CXRefQualifier_None;
1018 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
1020 return CXRefQualifier_None;
1021 switch (FD->getRefQualifier()) {
1023 return CXRefQualifier_None;
1025 return CXRefQualifier_LValue;
1027 return CXRefQualifier_RValue;
1029 return CXRefQualifier_None;
1032 unsigned clang_Cursor_isBitField(CXCursor C) {
1033 if (!clang_isDeclaration(C.kind))
1035 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
1038 return FD->isBitField();
1041 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
1042 if (!clang_isDeclaration(C.kind))
1043 return cxstring::createEmpty();
1045 const Decl *D = cxcursor::getCursorDecl(C);
1046 ASTContext &Ctx = cxcursor::getCursorContext(C);
1047 std::string encoding;
1049 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
1050 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
1051 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
1052 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
1053 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1054 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
1057 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
1058 Ty = Ctx.getTypeDeclType(TD);
1059 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
1061 else return cxstring::createRef("?");
1062 Ctx.getObjCEncodingForType(Ty, encoding);
1065 return cxstring::createDup(encoding);
1068 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
1069 unsigned size = TA.size();
1070 for (const auto &Arg : TA)
1071 if (Arg.getKind() == TemplateArgument::Pack)
1072 size += Arg.pack_size() - 1;
1076 int clang_Type_getNumTemplateArguments(CXType CT) {
1077 QualType T = GetQualType(CT);
1081 auto TA = GetTemplateArguments(T);
1085 return GetTemplateArgumentArraySize(TA.getValue());
1088 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
1089 QualType T = GetQualType(CT);
1091 return MakeCXType(QualType(), GetTU(CT));
1093 auto TA = GetTemplateArguments(T);
1095 return MakeCXType(QualType(), GetTU(CT));
1097 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
1098 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
1101 unsigned clang_Type_visitFields(CXType PT,
1102 CXFieldVisitor visitor,
1103 CXClientData client_data){
1104 CXCursor PC = clang_getTypeDeclaration(PT);
1105 if (clang_isInvalid(PC.kind))
1107 const RecordDecl *RD =
1108 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1109 if (!RD || RD->isInvalidDecl())
1111 RD = RD->getDefinition();
1112 if (!RD || RD->isInvalidDecl())
1115 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1117 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1118 // Callback to the client.
1119 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1122 case CXVisit_Continue:
1129 unsigned clang_Cursor_isAnonymous(CXCursor C){
1130 if (!clang_isDeclaration(C.kind))
1132 const Decl *D = cxcursor::getCursorDecl(C);
1133 if (const RecordDecl *FD = dyn_cast_or_null<RecordDecl>(D))
1134 return FD->isAnonymousStructOrUnion();
1138 CXType clang_Type_getNamedType(CXType CT){
1139 QualType T = GetQualType(CT);
1140 const Type *TP = T.getTypePtrOrNull();
1142 if (TP && TP->getTypeClass() == Type::Elaborated)
1143 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1145 return MakeCXType(QualType(), GetTU(CT));
1148 unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1149 QualType T = GetQualType(TT);
1150 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1151 if (auto *D = TT->getDecl())
1152 return D->isTransparentTag();