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"
73 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id);
74 #include "clang/Basic/OpenCLExtensionTypes.def"
80 return CXType_Unexposed;
85 static CXTypeKind GetTypeKind(QualType T) {
86 const Type *TP = T.getTypePtrOrNull();
88 return CXType_Invalid;
90 #define TKCASE(K) case Type::K: return CXType_##K
91 switch (TP->getTypeClass()) {
93 return GetBuiltinTypeKind(cast<BuiltinType>(TP));
97 TKCASE(LValueReference);
98 TKCASE(RValueReference);
102 TKCASE(ObjCInterface);
104 TKCASE(ObjCObjectPointer);
105 TKCASE(ObjCTypeParam);
106 TKCASE(FunctionNoProto);
107 TKCASE(FunctionProto);
108 TKCASE(ConstantArray);
109 TKCASE(IncompleteArray);
110 TKCASE(VariableArray);
111 TKCASE(DependentSizedArray);
113 TKCASE(MemberPointer);
119 return CXType_Unexposed;
125 CXType cxtype::MakeCXType(QualType T, CXTranslationUnit TU) {
126 CXTypeKind TK = CXType_Invalid;
128 if (TU && !T.isNull()) {
129 // Handle attributed types as the original type
130 if (auto *ATT = T->getAs<AttributedType>()) {
131 if (!(TU->ParsingOptions & CXTranslationUnit_IncludeAttributedTypes)) {
132 return MakeCXType(ATT->getModifiedType(), TU);
135 // Handle paren types as the original type
136 if (auto *PTT = T->getAs<ParenType>()) {
137 return MakeCXType(PTT->getInnerType(), TU);
140 ASTContext &Ctx = cxtu::getASTUnit(TU)->getASTContext();
141 if (Ctx.getLangOpts().ObjC) {
142 QualType UnqualT = T.getUnqualifiedType();
143 if (Ctx.isObjCIdType(UnqualT))
145 else if (Ctx.isObjCClassType(UnqualT))
146 TK = CXType_ObjCClass;
147 else if (Ctx.isObjCSelType(UnqualT))
151 /* Handle decayed types as the original type */
152 if (const DecayedType *DT = T->getAs<DecayedType>()) {
153 return MakeCXType(DT->getOriginalType(), TU);
156 if (TK == CXType_Invalid)
159 CXType CT = { TK, { TK == CXType_Invalid ? nullptr
160 : T.getAsOpaquePtr(), TU } };
164 using cxtype::MakeCXType;
166 static inline QualType GetQualType(CXType CT) {
167 return QualType::getFromOpaquePtr(CT.data[0]);
170 static inline CXTranslationUnit GetTU(CXType CT) {
171 return static_cast<CXTranslationUnit>(CT.data[1]);
174 static Optional<ArrayRef<TemplateArgument>>
175 GetTemplateArguments(QualType Type) {
176 assert(!Type.isNull());
177 if (const auto *Specialization = Type->getAs<TemplateSpecializationType>())
178 return Specialization->template_arguments();
180 if (const auto *RecordDecl = Type->getAsCXXRecordDecl()) {
181 const auto *TemplateDecl =
182 dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
184 return TemplateDecl->getTemplateArgs().asArray();
190 static Optional<QualType> TemplateArgumentToQualType(const TemplateArgument &A) {
191 if (A.getKind() == TemplateArgument::Type)
192 return A.getAsType();
196 static Optional<QualType>
197 FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
198 unsigned current = 0;
199 for (const auto &A : TA) {
200 if (A.getKind() == TemplateArgument::Pack) {
201 if (index < current + A.pack_size())
202 return TemplateArgumentToQualType(A.getPackAsArray()[index - current]);
203 current += A.pack_size();
206 if (current == index)
207 return TemplateArgumentToQualType(A);
213 CXType clang_getCursorType(CXCursor C) {
214 using namespace cxcursor;
216 CXTranslationUnit TU = cxcursor::getCursorTU(C);
218 return MakeCXType(QualType(), TU);
220 ASTContext &Context = cxtu::getASTUnit(TU)->getASTContext();
221 if (clang_isExpression(C.kind)) {
222 QualType T = cxcursor::getCursorExpr(C)->getType();
223 return MakeCXType(T, TU);
226 if (clang_isDeclaration(C.kind)) {
227 const Decl *D = cxcursor::getCursorDecl(C);
229 return MakeCXType(QualType(), TU);
231 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
232 return MakeCXType(Context.getTypeDeclType(TD), TU);
233 if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
234 return MakeCXType(Context.getObjCInterfaceType(ID), TU);
235 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
236 return MakeCXType(DD->getType(), TU);
237 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
238 return MakeCXType(VD->getType(), TU);
239 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
240 return MakeCXType(PD->getType(), TU);
241 if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
242 return MakeCXType(FTD->getTemplatedDecl()->getType(), TU);
243 return MakeCXType(QualType(), TU);
246 if (clang_isReference(C.kind)) {
248 case CXCursor_ObjCSuperClassRef: {
250 = Context.getObjCInterfaceType(getCursorObjCSuperClassRef(C).first);
251 return MakeCXType(T, TU);
254 case CXCursor_ObjCClassRef: {
255 QualType T = Context.getObjCInterfaceType(getCursorObjCClassRef(C).first);
256 return MakeCXType(T, TU);
259 case CXCursor_TypeRef: {
260 QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
261 return MakeCXType(T, TU);
265 case CXCursor_CXXBaseSpecifier:
266 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
268 case CXCursor_MemberRef:
269 return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU);
271 case CXCursor_VariableRef:
272 return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU);
274 case CXCursor_ObjCProtocolRef:
275 case CXCursor_TemplateRef:
276 case CXCursor_NamespaceRef:
277 case CXCursor_OverloadedDeclRef:
282 return MakeCXType(QualType(), TU);
285 return MakeCXType(QualType(), TU);
288 CXString clang_getTypeSpelling(CXType CT) {
289 QualType T = GetQualType(CT);
291 return cxstring::createEmpty();
293 CXTranslationUnit TU = GetTU(CT);
295 llvm::raw_svector_ostream OS(Str);
296 PrintingPolicy PP(cxtu::getASTUnit(TU)->getASTContext().getLangOpts());
300 return cxstring::createDup(OS.str());
303 CXType clang_getTypedefDeclUnderlyingType(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 TypedefNameDecl *TD = dyn_cast_or_null<TypedefNameDecl>(D)) {
311 QualType T = TD->getUnderlyingType();
312 return MakeCXType(T, TU);
315 return MakeCXType(QualType(), TU);
318 return MakeCXType(QualType(), TU);
321 CXType clang_getEnumDeclIntegerType(CXCursor C) {
322 using namespace cxcursor;
323 CXTranslationUnit TU = cxcursor::getCursorTU(C);
325 if (clang_isDeclaration(C.kind)) {
326 const Decl *D = cxcursor::getCursorDecl(C);
328 if (const EnumDecl *TD = dyn_cast_or_null<EnumDecl>(D)) {
329 QualType T = TD->getIntegerType();
330 return MakeCXType(T, TU);
333 return MakeCXType(QualType(), TU);
336 return MakeCXType(QualType(), TU);
339 long long clang_getEnumConstantDeclValue(CXCursor C) {
340 using namespace cxcursor;
342 if (clang_isDeclaration(C.kind)) {
343 const Decl *D = cxcursor::getCursorDecl(C);
345 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
346 return TD->getInitVal().getSExtValue();
355 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
356 using namespace cxcursor;
358 if (clang_isDeclaration(C.kind)) {
359 const Decl *D = cxcursor::getCursorDecl(C);
361 if (const EnumConstantDecl *TD = dyn_cast_or_null<EnumConstantDecl>(D)) {
362 return TD->getInitVal().getZExtValue();
371 int clang_getFieldDeclBitWidth(CXCursor C) {
372 using namespace cxcursor;
374 if (clang_isDeclaration(C.kind)) {
375 const Decl *D = getCursorDecl(C);
377 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
378 if (FD->isBitField())
379 return FD->getBitWidthValue(getCursorContext(C));
386 CXType clang_getCanonicalType(CXType CT) {
387 if (CT.kind == CXType_Invalid)
390 QualType T = GetQualType(CT);
391 CXTranslationUnit TU = GetTU(CT);
394 return MakeCXType(QualType(), GetTU(CT));
396 return MakeCXType(cxtu::getASTUnit(TU)->getASTContext()
397 .getCanonicalType(T),
401 unsigned clang_isConstQualifiedType(CXType CT) {
402 QualType T = GetQualType(CT);
403 return T.isLocalConstQualified();
406 unsigned clang_isVolatileQualifiedType(CXType CT) {
407 QualType T = GetQualType(CT);
408 return T.isLocalVolatileQualified();
411 unsigned clang_isRestrictQualifiedType(CXType CT) {
412 QualType T = GetQualType(CT);
413 return T.isLocalRestrictQualified();
416 unsigned clang_getAddressSpace(CXType CT) {
417 QualType T = GetQualType(CT);
419 // For non language-specific address space, use separate helper function.
420 if (T.getAddressSpace() >= LangAS::FirstTargetAddressSpace) {
421 return T.getQualifiers().getAddressSpaceAttributePrintValue();
423 // FIXME: this function returns either a LangAS or a target AS
424 // Those values can overlap which makes this function rather unpredictable
426 return (unsigned)T.getAddressSpace();
429 CXString clang_getTypedefName(CXType CT) {
430 QualType T = GetQualType(CT);
431 const TypedefType *TT = T->getAs<TypedefType>();
433 TypedefNameDecl *TD = TT->getDecl();
435 return cxstring::createDup(TD->getNameAsString().c_str());
437 return cxstring::createEmpty();
440 CXType clang_getPointeeType(CXType CT) {
441 QualType T = GetQualType(CT);
442 const Type *TP = T.getTypePtrOrNull();
445 return MakeCXType(QualType(), GetTU(CT));
448 switch (TP->getTypeClass()) {
450 T = cast<PointerType>(TP)->getPointeeType();
452 case Type::BlockPointer:
453 T = cast<BlockPointerType>(TP)->getPointeeType();
455 case Type::LValueReference:
456 case Type::RValueReference:
457 T = cast<ReferenceType>(TP)->getPointeeType();
459 case Type::ObjCObjectPointer:
460 T = cast<ObjCObjectPointerType>(TP)->getPointeeType();
462 case Type::MemberPointer:
463 T = cast<MemberPointerType>(TP)->getPointeeType();
466 case Type::DeducedTemplateSpecialization:
467 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
475 return MakeCXType(T, GetTU(CT));
478 CXCursor clang_getTypeDeclaration(CXType CT) {
479 if (CT.kind == CXType_Invalid)
480 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
482 QualType T = GetQualType(CT);
483 const Type *TP = T.getTypePtrOrNull();
486 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
491 switch (TP->getTypeClass()) {
493 D = cast<TypedefType>(TP)->getDecl();
495 case Type::ObjCObject:
496 D = cast<ObjCObjectType>(TP)->getInterface();
498 case Type::ObjCInterface:
499 D = cast<ObjCInterfaceType>(TP)->getDecl();
503 D = cast<TagType>(TP)->getDecl();
505 case Type::TemplateSpecialization:
506 if (const RecordType *Record = TP->getAs<RecordType>())
507 D = Record->getDecl();
509 D = cast<TemplateSpecializationType>(TP)->getTemplateName()
510 .getAsTemplateDecl();
514 case Type::DeducedTemplateSpecialization:
515 TP = cast<DeducedType>(TP)->getDeducedType().getTypePtrOrNull();
520 case Type::InjectedClassName:
521 D = cast<InjectedClassNameType>(TP)->getDecl();
524 // FIXME: Template type parameters!
526 case Type::Elaborated:
527 TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
535 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
537 return cxcursor::MakeCXCursor(D, GetTU(CT));
540 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
541 const char *s = nullptr;
542 #define TKIND(X) case CXType_##X: s = "" #X ""; break
559 case CXType_WChar: s = "WChar"; break;
586 TKIND(LValueReference);
587 TKIND(RValueReference);
591 TKIND(ObjCInterface);
593 TKIND(ObjCObjectPointer);
594 TKIND(ObjCTypeParam);
595 TKIND(FunctionNoProto);
596 TKIND(FunctionProto);
597 TKIND(ConstantArray);
598 TKIND(IncompleteArray);
599 TKIND(VariableArray);
600 TKIND(DependentSizedArray);
602 TKIND(MemberPointer);
607 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
608 #include "clang/Basic/OpenCLImageTypes.def"
610 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id);
611 #include "clang/Basic/OpenCLExtensionTypes.def"
618 return cxstring::createRef(s);
621 unsigned clang_equalTypes(CXType A, CXType B) {
622 return A.data[0] == B.data[0] && A.data[1] == B.data[1];
625 unsigned clang_isFunctionTypeVariadic(CXType X) {
626 QualType T = GetQualType(X);
630 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
631 return (unsigned)FD->isVariadic();
633 if (T->getAs<FunctionNoProtoType>())
639 CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
640 QualType T = GetQualType(X);
642 return CXCallingConv_Invalid;
644 if (const FunctionType *FD = T->getAs<FunctionType>()) {
645 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
646 switch (FD->getCallConv()) {
648 TCALLINGCONV(X86StdCall);
649 TCALLINGCONV(X86FastCall);
650 TCALLINGCONV(X86ThisCall);
651 TCALLINGCONV(X86Pascal);
652 TCALLINGCONV(X86RegCall);
653 TCALLINGCONV(X86VectorCall);
654 TCALLINGCONV(AArch64VectorCall);
656 TCALLINGCONV(X86_64SysV);
658 TCALLINGCONV(AAPCS_VFP);
659 TCALLINGCONV(IntelOclBicc);
661 TCALLINGCONV(PreserveMost);
662 TCALLINGCONV(PreserveAll);
663 case CC_SpirFunction: return CXCallingConv_Unexposed;
664 case CC_OpenCLKernel: return CXCallingConv_Unexposed;
670 return CXCallingConv_Invalid;
673 int clang_getNumArgTypes(CXType X) {
674 QualType T = GetQualType(X);
678 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
679 return FD->getNumParams();
682 if (T->getAs<FunctionNoProtoType>()) {
689 CXType clang_getArgType(CXType X, unsigned i) {
690 QualType T = GetQualType(X);
692 return MakeCXType(QualType(), GetTU(X));
694 if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
695 unsigned numParams = FD->getNumParams();
697 return MakeCXType(QualType(), GetTU(X));
699 return MakeCXType(FD->getParamType(i), GetTU(X));
702 return MakeCXType(QualType(), GetTU(X));
705 CXType clang_getResultType(CXType X) {
706 QualType T = GetQualType(X);
708 return MakeCXType(QualType(), GetTU(X));
710 if (const FunctionType *FD = T->getAs<FunctionType>())
711 return MakeCXType(FD->getReturnType(), GetTU(X));
713 return MakeCXType(QualType(), GetTU(X));
716 CXType clang_getCursorResultType(CXCursor C) {
717 if (clang_isDeclaration(C.kind)) {
718 const Decl *D = cxcursor::getCursorDecl(C);
719 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
720 return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
722 return clang_getResultType(clang_getCursorType(C));
725 return MakeCXType(QualType(), cxcursor::getCursorTU(C));
728 // FIXME: We should expose the canThrow(...) result instead of the EST.
729 static CXCursor_ExceptionSpecificationKind
730 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST) {
733 return CXCursor_ExceptionSpecificationKind_None;
734 case EST_DynamicNone:
735 return CXCursor_ExceptionSpecificationKind_DynamicNone;
737 return CXCursor_ExceptionSpecificationKind_Dynamic;
739 return CXCursor_ExceptionSpecificationKind_MSAny;
740 case EST_BasicNoexcept:
741 return CXCursor_ExceptionSpecificationKind_BasicNoexcept;
742 case EST_NoexceptFalse:
743 case EST_NoexceptTrue:
744 case EST_DependentNoexcept:
745 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept;
746 case EST_Unevaluated:
747 return CXCursor_ExceptionSpecificationKind_Unevaluated;
748 case EST_Uninstantiated:
749 return CXCursor_ExceptionSpecificationKind_Uninstantiated;
751 return CXCursor_ExceptionSpecificationKind_Unparsed;
753 llvm_unreachable("invalid EST value");
756 int clang_getExceptionSpecificationType(CXType X) {
757 QualType T = GetQualType(X);
761 if (const auto *FD = T->getAs<FunctionProtoType>())
762 return getExternalExceptionSpecificationKind(FD->getExceptionSpecType());
767 int clang_getCursorExceptionSpecificationType(CXCursor C) {
768 if (clang_isDeclaration(C.kind))
769 return clang_getExceptionSpecificationType(clang_getCursorType(C));
774 unsigned clang_isPODType(CXType X) {
775 QualType T = GetQualType(X);
779 CXTranslationUnit TU = GetTU(X);
781 return T.isPODType(cxtu::getASTUnit(TU)->getASTContext()) ? 1 : 0;
784 CXType clang_getElementType(CXType CT) {
785 QualType ET = QualType();
786 QualType T = GetQualType(CT);
787 const Type *TP = T.getTypePtrOrNull();
790 switch (TP->getTypeClass()) {
791 case Type::ConstantArray:
792 ET = cast<ConstantArrayType> (TP)->getElementType();
794 case Type::IncompleteArray:
795 ET = cast<IncompleteArrayType> (TP)->getElementType();
797 case Type::VariableArray:
798 ET = cast<VariableArrayType> (TP)->getElementType();
800 case Type::DependentSizedArray:
801 ET = cast<DependentSizedArrayType> (TP)->getElementType();
804 ET = cast<VectorType> (TP)->getElementType();
807 ET = cast<ComplexType> (TP)->getElementType();
813 return MakeCXType(ET, GetTU(CT));
816 long long clang_getNumElements(CXType CT) {
817 long long result = -1;
818 QualType T = GetQualType(CT);
819 const Type *TP = T.getTypePtrOrNull();
822 switch (TP->getTypeClass()) {
823 case Type::ConstantArray:
824 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
827 result = cast<VectorType> (TP)->getNumElements();
836 CXType clang_getArrayElementType(CXType CT) {
837 QualType ET = QualType();
838 QualType T = GetQualType(CT);
839 const Type *TP = T.getTypePtrOrNull();
842 switch (TP->getTypeClass()) {
843 case Type::ConstantArray:
844 ET = cast<ConstantArrayType> (TP)->getElementType();
846 case Type::IncompleteArray:
847 ET = cast<IncompleteArrayType> (TP)->getElementType();
849 case Type::VariableArray:
850 ET = cast<VariableArrayType> (TP)->getElementType();
852 case Type::DependentSizedArray:
853 ET = cast<DependentSizedArrayType> (TP)->getElementType();
859 return MakeCXType(ET, GetTU(CT));
862 long long clang_getArraySize(CXType CT) {
863 long long result = -1;
864 QualType T = GetQualType(CT);
865 const Type *TP = T.getTypePtrOrNull();
868 switch (TP->getTypeClass()) {
869 case Type::ConstantArray:
870 result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
879 long long clang_Type_getAlignOf(CXType T) {
880 if (T.kind == CXType_Invalid)
881 return CXTypeLayoutError_Invalid;
882 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
883 QualType QT = GetQualType(T);
884 // [expr.alignof] p1: return size_t value for complete object type, reference
886 // [expr.alignof] p3: if reference type, return size of referenced type
887 if (QT->isReferenceType())
888 QT = QT.getNonReferenceType();
889 if (QT->isIncompleteType())
890 return CXTypeLayoutError_Incomplete;
891 if (QT->isDependentType())
892 return CXTypeLayoutError_Dependent;
893 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
894 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
895 // if (QT->isVoidType()) return 1;
896 return Ctx.getTypeAlignInChars(QT).getQuantity();
899 CXType clang_Type_getClassType(CXType CT) {
900 QualType ET = QualType();
901 QualType T = GetQualType(CT);
902 const Type *TP = T.getTypePtrOrNull();
904 if (TP && TP->getTypeClass() == Type::MemberPointer) {
905 ET = QualType(cast<MemberPointerType> (TP)->getClass(), 0);
907 return MakeCXType(ET, GetTU(CT));
910 long long clang_Type_getSizeOf(CXType T) {
911 if (T.kind == CXType_Invalid)
912 return CXTypeLayoutError_Invalid;
913 ASTContext &Ctx = cxtu::getASTUnit(GetTU(T))->getASTContext();
914 QualType QT = GetQualType(T);
915 // [expr.sizeof] p2: if reference type, return size of referenced type
916 if (QT->isReferenceType())
917 QT = QT.getNonReferenceType();
918 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
920 // Note: We get the cxtype, not the cxcursor, so we can't call
921 // FieldDecl->isBitField()
922 // [expr.sizeof] p3: pointer ok, function not ok.
923 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
924 if (QT->isIncompleteType())
925 return CXTypeLayoutError_Incomplete;
926 if (QT->isDependentType())
927 return CXTypeLayoutError_Dependent;
928 if (!QT->isConstantSizeType())
929 return CXTypeLayoutError_NotConstantSize;
930 // [gcc extension] lib/AST/ExprConstant.cpp:1372
931 // HandleSizeof : {voidtype,functype} == 1
932 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
933 if (QT->isVoidType() || QT->isFunctionType())
935 return Ctx.getTypeSizeInChars(QT).getQuantity();
938 static long long visitRecordForValidation(const RecordDecl *RD) {
939 for (const auto *I : RD->fields()){
940 QualType FQT = I->getType();
941 if (FQT->isIncompleteType())
942 return CXTypeLayoutError_Incomplete;
943 if (FQT->isDependentType())
944 return CXTypeLayoutError_Dependent;
946 if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
947 if (const RecordDecl *Child = ChildType->getDecl()) {
948 long long ret = visitRecordForValidation(Child);
953 // else try next field
958 static long long validateFieldParentType(CXCursor PC, CXType PT){
959 if (clang_isInvalid(PC.kind))
960 return CXTypeLayoutError_Invalid;
961 const RecordDecl *RD =
962 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
963 // validate parent declaration
964 if (!RD || RD->isInvalidDecl())
965 return CXTypeLayoutError_Invalid;
966 RD = RD->getDefinition();
968 return CXTypeLayoutError_Incomplete;
969 if (RD->isInvalidDecl())
970 return CXTypeLayoutError_Invalid;
971 // validate parent type
972 QualType RT = GetQualType(PT);
973 if (RT->isIncompleteType())
974 return CXTypeLayoutError_Incomplete;
975 if (RT->isDependentType())
976 return CXTypeLayoutError_Dependent;
977 // We recurse into all record fields to detect incomplete and dependent types.
978 long long Error = visitRecordForValidation(RD);
984 long long clang_Type_getOffsetOf(CXType PT, const char *S) {
985 // check that PT is not incomplete/dependent
986 CXCursor PC = clang_getTypeDeclaration(PT);
987 long long Error = validateFieldParentType(PC,PT);
991 return CXTypeLayoutError_InvalidFieldName;
993 ASTContext &Ctx = cxtu::getASTUnit(GetTU(PT))->getASTContext();
994 IdentifierInfo *II = &Ctx.Idents.get(S);
995 DeclarationName FieldName(II);
996 const RecordDecl *RD =
997 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
998 // verified in validateFieldParentType
999 RD = RD->getDefinition();
1000 RecordDecl::lookup_result Res = RD->lookup(FieldName);
1001 // If a field of the parent record is incomplete, lookup will fail.
1002 // and we would return InvalidFieldName instead of Incomplete.
1003 // But this erroneous results does protects again a hidden assertion failure
1004 // in the RecordLayoutBuilder
1005 if (Res.size() != 1)
1006 return CXTypeLayoutError_InvalidFieldName;
1007 if (const FieldDecl *FD = dyn_cast<FieldDecl>(Res.front()))
1008 return Ctx.getFieldOffset(FD);
1009 if (const IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(Res.front()))
1010 return Ctx.getFieldOffset(IFD);
1011 // we don't want any other Decl Type.
1012 return CXTypeLayoutError_InvalidFieldName;
1015 CXType clang_Type_getModifiedType(CXType CT) {
1016 QualType T = GetQualType(CT);
1018 return MakeCXType(QualType(), GetTU(CT));
1020 if (auto *ATT = T->getAs<AttributedType>())
1021 return MakeCXType(ATT->getModifiedType(), GetTU(CT));
1023 return MakeCXType(QualType(), GetTU(CT));
1026 long long clang_Cursor_getOffsetOfField(CXCursor C) {
1027 if (clang_isDeclaration(C.kind)) {
1028 // we need to validate the parent type
1029 CXCursor PC = clang_getCursorSemanticParent(C);
1030 CXType PT = clang_getCursorType(PC);
1031 long long Error = validateFieldParentType(PC,PT);
1034 // proceed with the offset calculation
1035 const Decl *D = cxcursor::getCursorDecl(C);
1036 ASTContext &Ctx = cxcursor::getCursorContext(C);
1037 if (const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D))
1038 return Ctx.getFieldOffset(FD);
1039 if (const IndirectFieldDecl *IFD = dyn_cast_or_null<IndirectFieldDecl>(D))
1040 return Ctx.getFieldOffset(IFD);
1045 enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
1046 QualType QT = GetQualType(T);
1048 return CXRefQualifier_None;
1049 const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
1051 return CXRefQualifier_None;
1052 switch (FD->getRefQualifier()) {
1054 return CXRefQualifier_None;
1056 return CXRefQualifier_LValue;
1058 return CXRefQualifier_RValue;
1060 return CXRefQualifier_None;
1063 unsigned clang_Cursor_isBitField(CXCursor C) {
1064 if (!clang_isDeclaration(C.kind))
1066 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(cxcursor::getCursorDecl(C));
1069 return FD->isBitField();
1072 CXString clang_getDeclObjCTypeEncoding(CXCursor C) {
1073 if (!clang_isDeclaration(C.kind))
1074 return cxstring::createEmpty();
1076 const Decl *D = cxcursor::getCursorDecl(C);
1077 ASTContext &Ctx = cxcursor::getCursorContext(C);
1078 std::string encoding;
1080 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
1081 encoding = Ctx.getObjCEncodingForMethodDecl(OMD);
1082 } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
1083 encoding = Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr);
1084 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1085 encoding = Ctx.getObjCEncodingForFunctionDecl(FD);
1088 if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
1089 Ty = Ctx.getTypeDeclType(TD);
1090 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
1092 else return cxstring::createRef("?");
1093 Ctx.getObjCEncodingForType(Ty, encoding);
1096 return cxstring::createDup(encoding);
1099 static unsigned GetTemplateArgumentArraySize(ArrayRef<TemplateArgument> TA) {
1100 unsigned size = TA.size();
1101 for (const auto &Arg : TA)
1102 if (Arg.getKind() == TemplateArgument::Pack)
1103 size += Arg.pack_size() - 1;
1107 int clang_Type_getNumTemplateArguments(CXType CT) {
1108 QualType T = GetQualType(CT);
1112 auto TA = GetTemplateArguments(T);
1116 return GetTemplateArgumentArraySize(TA.getValue());
1119 CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned index) {
1120 QualType T = GetQualType(CT);
1122 return MakeCXType(QualType(), GetTU(CT));
1124 auto TA = GetTemplateArguments(T);
1126 return MakeCXType(QualType(), GetTU(CT));
1128 Optional<QualType> QT = FindTemplateArgumentTypeAt(TA.getValue(), index);
1129 return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
1132 CXType clang_Type_getObjCObjectBaseType(CXType CT) {
1133 QualType T = GetQualType(CT);
1135 return MakeCXType(QualType(), GetTU(CT));
1137 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1139 return MakeCXType(QualType(), GetTU(CT));
1141 return MakeCXType(OT->getBaseType(), GetTU(CT));
1144 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) {
1145 QualType T = GetQualType(CT);
1149 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1153 return OT->getNumProtocols();
1156 CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) {
1157 QualType T = GetQualType(CT);
1159 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1161 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1163 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1165 const ObjCProtocolDecl *PD = OT->getProtocol(i);
1167 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
1169 return cxcursor::MakeCXCursor(PD, GetTU(CT));
1172 unsigned clang_Type_getNumObjCTypeArgs(CXType CT) {
1173 QualType T = GetQualType(CT);
1177 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1181 return OT->getTypeArgs().size();
1184 CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) {
1185 QualType T = GetQualType(CT);
1187 return MakeCXType(QualType(), GetTU(CT));
1189 const ObjCObjectType *OT = dyn_cast<ObjCObjectType>(T);
1191 return MakeCXType(QualType(), GetTU(CT));
1193 const ArrayRef<QualType> TA = OT->getTypeArgs();
1194 if ((size_t)i >= TA.size())
1195 return MakeCXType(QualType(), GetTU(CT));
1197 return MakeCXType(TA[i], GetTU(CT));
1200 unsigned clang_Type_visitFields(CXType PT,
1201 CXFieldVisitor visitor,
1202 CXClientData client_data){
1203 CXCursor PC = clang_getTypeDeclaration(PT);
1204 if (clang_isInvalid(PC.kind))
1206 const RecordDecl *RD =
1207 dyn_cast_or_null<RecordDecl>(cxcursor::getCursorDecl(PC));
1208 if (!RD || RD->isInvalidDecl())
1210 RD = RD->getDefinition();
1211 if (!RD || RD->isInvalidDecl())
1214 for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
1216 const FieldDecl *FD = dyn_cast_or_null<FieldDecl>((*I));
1217 // Callback to the client.
1218 switch (visitor(cxcursor::MakeCXCursor(FD, GetTU(PT)), client_data)){
1221 case CXVisit_Continue:
1228 unsigned clang_Cursor_isAnonymous(CXCursor C){
1229 if (!clang_isDeclaration(C.kind))
1231 const Decl *D = cxcursor::getCursorDecl(C);
1232 if (const NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(D)) {
1233 return ND->isAnonymousNamespace();
1234 } else if (const TagDecl *TD = dyn_cast_or_null<TagDecl>(D)) {
1235 return TD->getTypedefNameForAnonDecl() == nullptr &&
1236 TD->getIdentifier() == nullptr;
1241 CXType clang_Type_getNamedType(CXType CT){
1242 QualType T = GetQualType(CT);
1243 const Type *TP = T.getTypePtrOrNull();
1245 if (TP && TP->getTypeClass() == Type::Elaborated)
1246 return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
1248 return MakeCXType(QualType(), GetTU(CT));
1251 unsigned clang_Type_isTransparentTagTypedef(CXType TT){
1252 QualType T = GetQualType(TT);
1253 if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
1254 if (auto *D = TT->getDecl())
1255 return D->isTransparentTag();
1260 enum CXTypeNullabilityKind clang_Type_getNullability(CXType CT) {
1261 QualType T = GetQualType(CT);
1263 return CXTypeNullability_Invalid;
1265 ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext();
1266 if (auto nullability = T->getNullability(Ctx)) {
1267 switch (*nullability) {
1268 case NullabilityKind::NonNull:
1269 return CXTypeNullability_NonNull;
1270 case NullabilityKind::Nullable:
1271 return CXTypeNullability_Nullable;
1272 case NullabilityKind::Unspecified:
1273 return CXTypeNullability_Unspecified;
1276 return CXTypeNullability_Invalid;