1 //===- CXType.cpp - Implements 'CXTypes' aspect of libclang ---------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===--------------------------------------------------------------------===//
9 // This file implements the 'CXTypes' API hooks in the Clang-C library.
11 //===--------------------------------------------------------------------===//
16 #include "CXTranslationUnit.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclObjC.h"
20 #include "clang/AST/DeclTemplate.h"
21 #include "clang/AST/Expr.h"
22 #include "clang/AST/Type.h"
23 #include "clang/Basic/AddressSpaces.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
;
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
);
114 TKCASE(MemberPointer
);
119 TKCASE(BTFTagAttributed
);
122 return CXType_Unexposed
;
128 CXType
cxtype::MakeCXType(QualType T
, CXTranslationUnit TU
) {
129 CXTypeKind TK
= CXType_Invalid
;
131 if (TU
&& !T
.isNull()) {
132 // Handle attributed types as the original type
133 if (auto *ATT
= T
->getAs
<AttributedType
>()) {
134 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
)) {
135 // Return the equivalent type which represents the canonically
137 return MakeCXType(ATT
->getEquivalentType(), TU
);
140 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>()) {
141 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
))
142 return MakeCXType(ATT
->getWrappedType(), TU
);
144 // Handle paren types as the original type
145 if (auto *PTT
= T
->getAs
<ParenType
>()) {
146 return MakeCXType(PTT
->getInnerType(), TU
);
149 ASTContext
&Ctx
= cxtu::getASTUnit(TU
)->getASTContext();
150 if (Ctx
.getLangOpts().ObjC
) {
151 QualType UnqualT
= T
.getUnqualifiedType();
152 if (Ctx
.isObjCIdType(UnqualT
))
154 else if (Ctx
.isObjCClassType(UnqualT
))
155 TK
= CXType_ObjCClass
;
156 else if (Ctx
.isObjCSelType(UnqualT
))
160 /* Handle decayed types as the original type */
161 if (const DecayedType
*DT
= T
->getAs
<DecayedType
>()) {
162 return MakeCXType(DT
->getOriginalType(), TU
);
165 if (TK
== CXType_Invalid
)
168 CXType CT
= { TK
, { TK
== CXType_Invalid
? nullptr
169 : T
.getAsOpaquePtr(), TU
} };
173 using cxtype::MakeCXType
;
175 static inline QualType
GetQualType(CXType CT
) {
176 return QualType::getFromOpaquePtr(CT
.data
[0]);
179 static inline CXTranslationUnit
GetTU(CXType CT
) {
180 return static_cast<CXTranslationUnit
>(CT
.data
[1]);
183 static Optional
<ArrayRef
<TemplateArgument
>>
184 GetTemplateArguments(QualType Type
) {
185 assert(!Type
.isNull());
186 if (const auto *Specialization
= Type
->getAs
<TemplateSpecializationType
>())
187 return Specialization
->template_arguments();
189 if (const auto *RecordDecl
= Type
->getAsCXXRecordDecl()) {
190 const auto *TemplateDecl
=
191 dyn_cast
<ClassTemplateSpecializationDecl
>(RecordDecl
);
193 return TemplateDecl
->getTemplateArgs().asArray();
199 static Optional
<QualType
> TemplateArgumentToQualType(const TemplateArgument
&A
) {
200 if (A
.getKind() == TemplateArgument::Type
)
201 return A
.getAsType();
205 static Optional
<QualType
>
206 FindTemplateArgumentTypeAt(ArrayRef
<TemplateArgument
> TA
, unsigned index
) {
207 unsigned current
= 0;
208 for (const auto &A
: TA
) {
209 if (A
.getKind() == TemplateArgument::Pack
) {
210 if (index
< current
+ A
.pack_size())
211 return TemplateArgumentToQualType(A
.getPackAsArray()[index
- current
]);
212 current
+= A
.pack_size();
215 if (current
== index
)
216 return TemplateArgumentToQualType(A
);
222 CXType
clang_getCursorType(CXCursor C
) {
223 using namespace cxcursor
;
225 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
227 return MakeCXType(QualType(), TU
);
229 ASTContext
&Context
= cxtu::getASTUnit(TU
)->getASTContext();
230 if (clang_isExpression(C
.kind
)) {
231 QualType T
= cxcursor::getCursorExpr(C
)->getType();
232 return MakeCXType(T
, TU
);
235 if (clang_isDeclaration(C
.kind
)) {
236 const Decl
*D
= cxcursor::getCursorDecl(C
);
238 return MakeCXType(QualType(), TU
);
240 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
241 return MakeCXType(Context
.getTypeDeclType(TD
), TU
);
242 if (const ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
))
243 return MakeCXType(Context
.getObjCInterfaceType(ID
), TU
);
244 if (const DeclaratorDecl
*DD
= dyn_cast
<DeclaratorDecl
>(D
))
245 return MakeCXType(DD
->getType(), TU
);
246 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
247 return MakeCXType(VD
->getType(), TU
);
248 if (const ObjCPropertyDecl
*PD
= dyn_cast
<ObjCPropertyDecl
>(D
))
249 return MakeCXType(PD
->getType(), TU
);
250 if (const FunctionTemplateDecl
*FTD
= dyn_cast
<FunctionTemplateDecl
>(D
))
251 return MakeCXType(FTD
->getTemplatedDecl()->getType(), TU
);
252 return MakeCXType(QualType(), TU
);
255 if (clang_isReference(C
.kind
)) {
257 case CXCursor_ObjCSuperClassRef
: {
259 = Context
.getObjCInterfaceType(getCursorObjCSuperClassRef(C
).first
);
260 return MakeCXType(T
, TU
);
263 case CXCursor_ObjCClassRef
: {
264 QualType T
= Context
.getObjCInterfaceType(getCursorObjCClassRef(C
).first
);
265 return MakeCXType(T
, TU
);
268 case CXCursor_TypeRef
: {
269 QualType T
= Context
.getTypeDeclType(getCursorTypeRef(C
).first
);
270 return MakeCXType(T
, TU
);
274 case CXCursor_CXXBaseSpecifier
:
275 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C
)->getType(), TU
);
277 case CXCursor_MemberRef
:
278 return cxtype::MakeCXType(getCursorMemberRef(C
).first
->getType(), TU
);
280 case CXCursor_VariableRef
:
281 return cxtype::MakeCXType(getCursorVariableRef(C
).first
->getType(), TU
);
283 case CXCursor_ObjCProtocolRef
:
284 case CXCursor_TemplateRef
:
285 case CXCursor_NamespaceRef
:
286 case CXCursor_OverloadedDeclRef
:
291 return MakeCXType(QualType(), TU
);
294 return MakeCXType(QualType(), TU
);
297 CXString
clang_getTypeSpelling(CXType CT
) {
298 QualType T
= GetQualType(CT
);
300 return cxstring::createEmpty();
302 CXTranslationUnit TU
= GetTU(CT
);
304 llvm::raw_svector_ostream
OS(Str
);
305 PrintingPolicy
PP(cxtu::getASTUnit(TU
)->getASTContext().getLangOpts());
309 return cxstring::createDup(OS
.str());
312 CXType
clang_getTypedefDeclUnderlyingType(CXCursor C
) {
313 using namespace cxcursor
;
314 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
316 if (clang_isDeclaration(C
.kind
)) {
317 const Decl
*D
= cxcursor::getCursorDecl(C
);
319 if (const TypedefNameDecl
*TD
= dyn_cast_or_null
<TypedefNameDecl
>(D
)) {
320 QualType T
= TD
->getUnderlyingType();
321 return MakeCXType(T
, TU
);
324 return MakeCXType(QualType(), TU
);
327 return MakeCXType(QualType(), TU
);
330 CXType
clang_getEnumDeclIntegerType(CXCursor C
) {
331 using namespace cxcursor
;
332 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
334 if (clang_isDeclaration(C
.kind
)) {
335 const Decl
*D
= cxcursor::getCursorDecl(C
);
337 if (const EnumDecl
*TD
= dyn_cast_or_null
<EnumDecl
>(D
)) {
338 QualType T
= TD
->getIntegerType();
339 return MakeCXType(T
, TU
);
342 return MakeCXType(QualType(), TU
);
345 return MakeCXType(QualType(), TU
);
348 long long clang_getEnumConstantDeclValue(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().getSExtValue();
364 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C
) {
365 using namespace cxcursor
;
367 if (clang_isDeclaration(C
.kind
)) {
368 const Decl
*D
= cxcursor::getCursorDecl(C
);
370 if (const EnumConstantDecl
*TD
= dyn_cast_or_null
<EnumConstantDecl
>(D
)) {
371 return TD
->getInitVal().getZExtValue();
380 int clang_getFieldDeclBitWidth(CXCursor C
) {
381 using namespace cxcursor
;
383 if (clang_isDeclaration(C
.kind
)) {
384 const Decl
*D
= getCursorDecl(C
);
386 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
)) {
387 if (FD
->isBitField())
388 return FD
->getBitWidthValue(getCursorContext(C
));
395 CXType
clang_getCanonicalType(CXType CT
) {
396 if (CT
.kind
== CXType_Invalid
)
399 QualType T
= GetQualType(CT
);
400 CXTranslationUnit TU
= GetTU(CT
);
403 return MakeCXType(QualType(), GetTU(CT
));
405 return MakeCXType(cxtu::getASTUnit(TU
)->getASTContext()
406 .getCanonicalType(T
),
410 unsigned clang_isConstQualifiedType(CXType CT
) {
411 QualType T
= GetQualType(CT
);
412 return T
.isLocalConstQualified();
415 unsigned clang_isVolatileQualifiedType(CXType CT
) {
416 QualType T
= GetQualType(CT
);
417 return T
.isLocalVolatileQualified();
420 unsigned clang_isRestrictQualifiedType(CXType CT
) {
421 QualType T
= GetQualType(CT
);
422 return T
.isLocalRestrictQualified();
425 unsigned clang_getAddressSpace(CXType CT
) {
426 QualType T
= GetQualType(CT
);
428 // For non language-specific address space, use separate helper function.
429 if (T
.getAddressSpace() >= LangAS::FirstTargetAddressSpace
) {
430 return T
.getQualifiers().getAddressSpaceAttributePrintValue();
432 // FIXME: this function returns either a LangAS or a target AS
433 // Those values can overlap which makes this function rather unpredictable
435 return (unsigned)T
.getAddressSpace();
438 CXString
clang_getTypedefName(CXType CT
) {
439 QualType T
= GetQualType(CT
);
440 const TypedefType
*TT
= T
->getAs
<TypedefType
>();
442 TypedefNameDecl
*TD
= TT
->getDecl();
444 return cxstring::createDup(TD
->getNameAsString().c_str());
446 return cxstring::createEmpty();
449 CXType
clang_getPointeeType(CXType CT
) {
450 QualType T
= GetQualType(CT
);
451 const Type
*TP
= T
.getTypePtrOrNull();
454 return MakeCXType(QualType(), GetTU(CT
));
457 switch (TP
->getTypeClass()) {
459 T
= cast
<PointerType
>(TP
)->getPointeeType();
461 case Type::BlockPointer
:
462 T
= cast
<BlockPointerType
>(TP
)->getPointeeType();
464 case Type::LValueReference
:
465 case Type::RValueReference
:
466 T
= cast
<ReferenceType
>(TP
)->getPointeeType();
468 case Type::ObjCObjectPointer
:
469 T
= cast
<ObjCObjectPointerType
>(TP
)->getPointeeType();
471 case Type::MemberPointer
:
472 T
= cast
<MemberPointerType
>(TP
)->getPointeeType();
475 case Type::DeducedTemplateSpecialization
:
476 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
484 return MakeCXType(T
, GetTU(CT
));
487 CXCursor
clang_getTypeDeclaration(CXType CT
) {
488 if (CT
.kind
== CXType_Invalid
)
489 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
491 QualType T
= GetQualType(CT
);
492 const Type
*TP
= T
.getTypePtrOrNull();
495 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
500 switch (TP
->getTypeClass()) {
502 D
= cast
<TypedefType
>(TP
)->getDecl();
504 case Type::ObjCObject
:
505 D
= cast
<ObjCObjectType
>(TP
)->getInterface();
507 case Type::ObjCInterface
:
508 D
= cast
<ObjCInterfaceType
>(TP
)->getDecl();
512 D
= cast
<TagType
>(TP
)->getDecl();
514 case Type::TemplateSpecialization
:
515 if (const RecordType
*Record
= TP
->getAs
<RecordType
>())
516 D
= Record
->getDecl();
518 D
= cast
<TemplateSpecializationType
>(TP
)->getTemplateName()
519 .getAsTemplateDecl();
523 case Type::DeducedTemplateSpecialization
:
524 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
529 case Type::InjectedClassName
:
530 D
= cast
<InjectedClassNameType
>(TP
)->getDecl();
533 // FIXME: Template type parameters!
535 case Type::Elaborated
:
536 TP
= cast
<ElaboratedType
>(TP
)->getNamedType().getTypePtrOrNull();
544 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
546 return cxcursor::MakeCXCursor(D
, GetTU(CT
));
549 CXString
clang_getTypeKindSpelling(enum CXTypeKind K
) {
550 const char *s
= nullptr;
551 #define TKIND(X) case CXType_##X: s = "" #X ""; break
568 case CXType_WChar
: s
= "WChar"; break;
596 TKIND(LValueReference
);
597 TKIND(RValueReference
);
601 TKIND(ObjCInterface
);
603 TKIND(ObjCObjectPointer
);
604 TKIND(ObjCTypeParam
);
605 TKIND(FunctionNoProto
);
606 TKIND(FunctionProto
);
607 TKIND(ConstantArray
);
608 TKIND(IncompleteArray
);
609 TKIND(VariableArray
);
610 TKIND(DependentSizedArray
);
613 TKIND(MemberPointer
);
618 TKIND(BTFTagAttributed
);
620 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
621 #include "clang/Basic/OpenCLImageTypes.def"
623 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id);
624 #include "clang/Basic/OpenCLExtensionTypes.def"
632 return cxstring::createRef(s
);
635 unsigned clang_equalTypes(CXType A
, CXType B
) {
636 return A
.data
[0] == B
.data
[0] && A
.data
[1] == B
.data
[1];
639 unsigned clang_isFunctionTypeVariadic(CXType X
) {
640 QualType T
= GetQualType(X
);
644 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>())
645 return (unsigned)FD
->isVariadic();
647 if (T
->getAs
<FunctionNoProtoType
>())
653 CXCallingConv
clang_getFunctionTypeCallingConv(CXType X
) {
654 QualType T
= GetQualType(X
);
656 return CXCallingConv_Invalid
;
658 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>()) {
659 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
660 switch (FD
->getCallConv()) {
662 TCALLINGCONV(X86StdCall
);
663 TCALLINGCONV(X86FastCall
);
664 TCALLINGCONV(X86ThisCall
);
665 TCALLINGCONV(X86Pascal
);
666 TCALLINGCONV(X86RegCall
);
667 TCALLINGCONV(X86VectorCall
);
668 TCALLINGCONV(AArch64VectorCall
);
669 TCALLINGCONV(AArch64SVEPCS
);
671 TCALLINGCONV(X86_64SysV
);
673 TCALLINGCONV(AAPCS_VFP
);
674 TCALLINGCONV(IntelOclBicc
);
676 TCALLINGCONV(SwiftAsync
);
677 TCALLINGCONV(PreserveMost
);
678 TCALLINGCONV(PreserveAll
);
679 case CC_SpirFunction
: return CXCallingConv_Unexposed
;
680 case CC_AMDGPUKernelCall
: return CXCallingConv_Unexposed
;
681 case CC_OpenCLKernel
: return CXCallingConv_Unexposed
;
687 return CXCallingConv_Invalid
;
690 int clang_getNumArgTypes(CXType X
) {
691 QualType T
= GetQualType(X
);
695 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
696 return FD
->getNumParams();
699 if (T
->getAs
<FunctionNoProtoType
>()) {
706 CXType
clang_getArgType(CXType X
, unsigned i
) {
707 QualType T
= GetQualType(X
);
709 return MakeCXType(QualType(), GetTU(X
));
711 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
712 unsigned numParams
= FD
->getNumParams();
714 return MakeCXType(QualType(), GetTU(X
));
716 return MakeCXType(FD
->getParamType(i
), GetTU(X
));
719 return MakeCXType(QualType(), GetTU(X
));
722 CXType
clang_getResultType(CXType X
) {
723 QualType T
= GetQualType(X
);
725 return MakeCXType(QualType(), GetTU(X
));
727 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>())
728 return MakeCXType(FD
->getReturnType(), GetTU(X
));
730 return MakeCXType(QualType(), GetTU(X
));
733 CXType
clang_getCursorResultType(CXCursor C
) {
734 if (clang_isDeclaration(C
.kind
)) {
735 const Decl
*D
= cxcursor::getCursorDecl(C
);
736 if (const ObjCMethodDecl
*MD
= dyn_cast_or_null
<ObjCMethodDecl
>(D
))
737 return MakeCXType(MD
->getReturnType(), cxcursor::getCursorTU(C
));
739 return clang_getResultType(clang_getCursorType(C
));
742 return MakeCXType(QualType(), cxcursor::getCursorTU(C
));
745 // FIXME: We should expose the canThrow(...) result instead of the EST.
746 static CXCursor_ExceptionSpecificationKind
747 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST
) {
750 return CXCursor_ExceptionSpecificationKind_None
;
751 case EST_DynamicNone
:
752 return CXCursor_ExceptionSpecificationKind_DynamicNone
;
754 return CXCursor_ExceptionSpecificationKind_Dynamic
;
756 return CXCursor_ExceptionSpecificationKind_MSAny
;
757 case EST_BasicNoexcept
:
758 return CXCursor_ExceptionSpecificationKind_BasicNoexcept
;
760 return CXCursor_ExceptionSpecificationKind_NoThrow
;
761 case EST_NoexceptFalse
:
762 case EST_NoexceptTrue
:
763 case EST_DependentNoexcept
:
764 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept
;
765 case EST_Unevaluated
:
766 return CXCursor_ExceptionSpecificationKind_Unevaluated
;
767 case EST_Uninstantiated
:
768 return CXCursor_ExceptionSpecificationKind_Uninstantiated
;
770 return CXCursor_ExceptionSpecificationKind_Unparsed
;
772 llvm_unreachable("invalid EST value");
775 int clang_getExceptionSpecificationType(CXType X
) {
776 QualType T
= GetQualType(X
);
780 if (const auto *FD
= T
->getAs
<FunctionProtoType
>())
781 return getExternalExceptionSpecificationKind(FD
->getExceptionSpecType());
786 int clang_getCursorExceptionSpecificationType(CXCursor C
) {
787 if (clang_isDeclaration(C
.kind
))
788 return clang_getExceptionSpecificationType(clang_getCursorType(C
));
793 unsigned clang_isPODType(CXType X
) {
794 QualType T
= GetQualType(X
);
798 CXTranslationUnit TU
= GetTU(X
);
800 return T
.isPODType(cxtu::getASTUnit(TU
)->getASTContext()) ? 1 : 0;
803 CXType
clang_getElementType(CXType CT
) {
804 QualType ET
= QualType();
805 QualType T
= GetQualType(CT
);
806 const Type
*TP
= T
.getTypePtrOrNull();
809 switch (TP
->getTypeClass()) {
810 case Type::ConstantArray
:
811 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
813 case Type::IncompleteArray
:
814 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
816 case Type::VariableArray
:
817 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
819 case Type::DependentSizedArray
:
820 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
823 ET
= cast
<VectorType
> (TP
)->getElementType();
825 case Type::ExtVector
:
826 ET
= cast
<ExtVectorType
>(TP
)->getElementType();
829 ET
= cast
<ComplexType
> (TP
)->getElementType();
835 return MakeCXType(ET
, GetTU(CT
));
838 long long clang_getNumElements(CXType CT
) {
839 long long result
= -1;
840 QualType T
= GetQualType(CT
);
841 const Type
*TP
= T
.getTypePtrOrNull();
844 switch (TP
->getTypeClass()) {
845 case Type::ConstantArray
:
846 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
849 result
= cast
<VectorType
> (TP
)->getNumElements();
851 case Type::ExtVector
:
852 result
= cast
<ExtVectorType
>(TP
)->getNumElements();
861 CXType
clang_getArrayElementType(CXType CT
) {
862 QualType ET
= QualType();
863 QualType T
= GetQualType(CT
);
864 const Type
*TP
= T
.getTypePtrOrNull();
867 switch (TP
->getTypeClass()) {
868 case Type::ConstantArray
:
869 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
871 case Type::IncompleteArray
:
872 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
874 case Type::VariableArray
:
875 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
877 case Type::DependentSizedArray
:
878 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
884 return MakeCXType(ET
, GetTU(CT
));
887 long long clang_getArraySize(CXType CT
) {
888 long long result
= -1;
889 QualType T
= GetQualType(CT
);
890 const Type
*TP
= T
.getTypePtrOrNull();
893 switch (TP
->getTypeClass()) {
894 case Type::ConstantArray
:
895 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
904 static bool isIncompleteTypeWithAlignment(QualType QT
) {
905 return QT
->isIncompleteArrayType() || !QT
->isIncompleteType();
908 long long clang_Type_getAlignOf(CXType T
) {
909 if (T
.kind
== CXType_Invalid
)
910 return CXTypeLayoutError_Invalid
;
911 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
912 QualType QT
= GetQualType(T
);
913 // [expr.alignof] p1: return size_t value for complete object type, reference
915 // [expr.alignof] p3: if reference type, return size of referenced type
916 if (QT
->isReferenceType())
917 QT
= QT
.getNonReferenceType();
918 if (!isIncompleteTypeWithAlignment(QT
))
919 return CXTypeLayoutError_Incomplete
;
920 if (QT
->isDependentType())
921 return CXTypeLayoutError_Dependent
;
922 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
923 if (Deduced
->getDeducedType().isNull())
924 return CXTypeLayoutError_Undeduced
;
925 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
926 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
927 // if (QT->isVoidType()) return 1;
928 return Ctx
.getTypeAlignInChars(QT
).getQuantity();
931 CXType
clang_Type_getClassType(CXType CT
) {
932 QualType ET
= QualType();
933 QualType T
= GetQualType(CT
);
934 const Type
*TP
= T
.getTypePtrOrNull();
936 if (TP
&& TP
->getTypeClass() == Type::MemberPointer
) {
937 ET
= QualType(cast
<MemberPointerType
> (TP
)->getClass(), 0);
939 return MakeCXType(ET
, GetTU(CT
));
942 long long clang_Type_getSizeOf(CXType T
) {
943 if (T
.kind
== CXType_Invalid
)
944 return CXTypeLayoutError_Invalid
;
945 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
946 QualType QT
= GetQualType(T
);
947 // [expr.sizeof] p2: if reference type, return size of referenced type
948 if (QT
->isReferenceType())
949 QT
= QT
.getNonReferenceType();
950 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
952 // Note: We get the cxtype, not the cxcursor, so we can't call
953 // FieldDecl->isBitField()
954 // [expr.sizeof] p3: pointer ok, function not ok.
955 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
956 if (QT
->isIncompleteType())
957 return CXTypeLayoutError_Incomplete
;
958 if (QT
->isDependentType())
959 return CXTypeLayoutError_Dependent
;
960 if (!QT
->isConstantSizeType())
961 return CXTypeLayoutError_NotConstantSize
;
962 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
963 if (Deduced
->getDeducedType().isNull())
964 return CXTypeLayoutError_Undeduced
;
965 // [gcc extension] lib/AST/ExprConstant.cpp:1372
966 // HandleSizeof : {voidtype,functype} == 1
967 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
968 if (QT
->isVoidType() || QT
->isFunctionType())
970 return Ctx
.getTypeSizeInChars(QT
).getQuantity();
973 static bool isTypeIncompleteForLayout(QualType QT
) {
974 return QT
->isIncompleteType() && !QT
->isIncompleteArrayType();
977 static long long visitRecordForValidation(const RecordDecl
*RD
) {
978 for (const auto *I
: RD
->fields()){
979 QualType FQT
= I
->getType();
980 if (isTypeIncompleteForLayout(FQT
))
981 return CXTypeLayoutError_Incomplete
;
982 if (FQT
->isDependentType())
983 return CXTypeLayoutError_Dependent
;
985 if (const RecordType
*ChildType
= I
->getType()->getAs
<RecordType
>()) {
986 if (const RecordDecl
*Child
= ChildType
->getDecl()) {
987 long long ret
= visitRecordForValidation(Child
);
992 // else try next field
997 static long long validateFieldParentType(CXCursor PC
, CXType PT
){
998 if (clang_isInvalid(PC
.kind
))
999 return CXTypeLayoutError_Invalid
;
1000 const RecordDecl
*RD
=
1001 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1002 // validate parent declaration
1003 if (!RD
|| RD
->isInvalidDecl())
1004 return CXTypeLayoutError_Invalid
;
1005 RD
= RD
->getDefinition();
1007 return CXTypeLayoutError_Incomplete
;
1008 if (RD
->isInvalidDecl())
1009 return CXTypeLayoutError_Invalid
;
1010 // validate parent type
1011 QualType RT
= GetQualType(PT
);
1012 if (RT
->isIncompleteType())
1013 return CXTypeLayoutError_Incomplete
;
1014 if (RT
->isDependentType())
1015 return CXTypeLayoutError_Dependent
;
1016 // We recurse into all record fields to detect incomplete and dependent types.
1017 long long Error
= visitRecordForValidation(RD
);
1023 long long clang_Type_getOffsetOf(CXType PT
, const char *S
) {
1024 // check that PT is not incomplete/dependent
1025 CXCursor PC
= clang_getTypeDeclaration(PT
);
1026 long long Error
= validateFieldParentType(PC
,PT
);
1030 return CXTypeLayoutError_InvalidFieldName
;
1032 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(PT
))->getASTContext();
1033 IdentifierInfo
*II
= &Ctx
.Idents
.get(S
);
1034 DeclarationName
FieldName(II
);
1035 const RecordDecl
*RD
=
1036 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1037 // verified in validateFieldParentType
1038 RD
= RD
->getDefinition();
1039 RecordDecl::lookup_result Res
= RD
->lookup(FieldName
);
1040 // If a field of the parent record is incomplete, lookup will fail.
1041 // and we would return InvalidFieldName instead of Incomplete.
1042 // But this erroneous results does protects again a hidden assertion failure
1043 // in the RecordLayoutBuilder
1044 if (!Res
.isSingleResult())
1045 return CXTypeLayoutError_InvalidFieldName
;
1046 if (const FieldDecl
*FD
= dyn_cast
<FieldDecl
>(Res
.front()))
1047 return Ctx
.getFieldOffset(FD
);
1048 if (const IndirectFieldDecl
*IFD
= dyn_cast
<IndirectFieldDecl
>(Res
.front()))
1049 return Ctx
.getFieldOffset(IFD
);
1050 // we don't want any other Decl Type.
1051 return CXTypeLayoutError_InvalidFieldName
;
1054 CXType
clang_Type_getModifiedType(CXType CT
) {
1055 QualType T
= GetQualType(CT
);
1057 return MakeCXType(QualType(), GetTU(CT
));
1059 if (auto *ATT
= T
->getAs
<AttributedType
>())
1060 return MakeCXType(ATT
->getModifiedType(), GetTU(CT
));
1062 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>())
1063 return MakeCXType(ATT
->getWrappedType(), GetTU(CT
));
1065 return MakeCXType(QualType(), GetTU(CT
));
1068 long long clang_Cursor_getOffsetOfField(CXCursor C
) {
1069 if (clang_isDeclaration(C
.kind
)) {
1070 // we need to validate the parent type
1071 CXCursor PC
= clang_getCursorSemanticParent(C
);
1072 CXType PT
= clang_getCursorType(PC
);
1073 long long Error
= validateFieldParentType(PC
,PT
);
1076 // proceed with the offset calculation
1077 const Decl
*D
= cxcursor::getCursorDecl(C
);
1078 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1079 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
))
1080 return Ctx
.getFieldOffset(FD
);
1081 if (const IndirectFieldDecl
*IFD
= dyn_cast_or_null
<IndirectFieldDecl
>(D
))
1082 return Ctx
.getFieldOffset(IFD
);
1087 enum CXRefQualifierKind
clang_Type_getCXXRefQualifier(CXType T
) {
1088 QualType QT
= GetQualType(T
);
1090 return CXRefQualifier_None
;
1091 const FunctionProtoType
*FD
= QT
->getAs
<FunctionProtoType
>();
1093 return CXRefQualifier_None
;
1094 switch (FD
->getRefQualifier()) {
1096 return CXRefQualifier_None
;
1098 return CXRefQualifier_LValue
;
1100 return CXRefQualifier_RValue
;
1102 return CXRefQualifier_None
;
1105 unsigned clang_Cursor_isBitField(CXCursor C
) {
1106 if (!clang_isDeclaration(C
.kind
))
1108 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(cxcursor::getCursorDecl(C
));
1111 return FD
->isBitField();
1114 CXString
clang_getDeclObjCTypeEncoding(CXCursor C
) {
1115 if (!clang_isDeclaration(C
.kind
))
1116 return cxstring::createEmpty();
1118 const Decl
*D
= cxcursor::getCursorDecl(C
);
1119 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1120 std::string encoding
;
1122 if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
1123 encoding
= Ctx
.getObjCEncodingForMethodDecl(OMD
);
1124 } else if (const ObjCPropertyDecl
*OPD
= dyn_cast
<ObjCPropertyDecl
>(D
))
1125 encoding
= Ctx
.getObjCEncodingForPropertyDecl(OPD
, nullptr);
1126 else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
1127 encoding
= Ctx
.getObjCEncodingForFunctionDecl(FD
);
1130 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
1131 Ty
= Ctx
.getTypeDeclType(TD
);
1132 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
1134 else return cxstring::createRef("?");
1135 Ctx
.getObjCEncodingForType(Ty
, encoding
);
1138 return cxstring::createDup(encoding
);
1141 static unsigned GetTemplateArgumentArraySize(ArrayRef
<TemplateArgument
> TA
) {
1142 unsigned size
= TA
.size();
1143 for (const auto &Arg
: TA
)
1144 if (Arg
.getKind() == TemplateArgument::Pack
)
1145 size
+= Arg
.pack_size() - 1;
1149 int clang_Type_getNumTemplateArguments(CXType CT
) {
1150 QualType T
= GetQualType(CT
);
1154 auto TA
= GetTemplateArguments(T
);
1158 return GetTemplateArgumentArraySize(*TA
);
1161 CXType
clang_Type_getTemplateArgumentAsType(CXType CT
, unsigned index
) {
1162 QualType T
= GetQualType(CT
);
1164 return MakeCXType(QualType(), GetTU(CT
));
1166 auto TA
= GetTemplateArguments(T
);
1168 return MakeCXType(QualType(), GetTU(CT
));
1170 Optional
<QualType
> QT
= FindTemplateArgumentTypeAt(*TA
, index
);
1171 return MakeCXType(QT
.value_or(QualType()), GetTU(CT
));
1174 CXType
clang_Type_getObjCObjectBaseType(CXType CT
) {
1175 QualType T
= GetQualType(CT
);
1177 return MakeCXType(QualType(), GetTU(CT
));
1179 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1181 return MakeCXType(QualType(), GetTU(CT
));
1183 return MakeCXType(OT
->getBaseType(), GetTU(CT
));
1186 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT
) {
1187 QualType T
= GetQualType(CT
);
1191 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1195 return OT
->getNumProtocols();
1198 CXCursor
clang_Type_getObjCProtocolDecl(CXType CT
, unsigned i
) {
1199 QualType T
= GetQualType(CT
);
1201 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1203 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1205 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1207 const ObjCProtocolDecl
*PD
= OT
->getProtocol(i
);
1209 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1211 return cxcursor::MakeCXCursor(PD
, GetTU(CT
));
1214 unsigned clang_Type_getNumObjCTypeArgs(CXType CT
) {
1215 QualType T
= GetQualType(CT
);
1219 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1223 return OT
->getTypeArgs().size();
1226 CXType
clang_Type_getObjCTypeArg(CXType CT
, unsigned i
) {
1227 QualType T
= GetQualType(CT
);
1229 return MakeCXType(QualType(), GetTU(CT
));
1231 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1233 return MakeCXType(QualType(), GetTU(CT
));
1235 const ArrayRef
<QualType
> TA
= OT
->getTypeArgs();
1236 if ((size_t)i
>= TA
.size())
1237 return MakeCXType(QualType(), GetTU(CT
));
1239 return MakeCXType(TA
[i
], GetTU(CT
));
1242 unsigned clang_Type_visitFields(CXType PT
,
1243 CXFieldVisitor visitor
,
1244 CXClientData client_data
){
1245 CXCursor PC
= clang_getTypeDeclaration(PT
);
1246 if (clang_isInvalid(PC
.kind
))
1248 const RecordDecl
*RD
=
1249 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1250 if (!RD
|| RD
->isInvalidDecl())
1252 RD
= RD
->getDefinition();
1253 if (!RD
|| RD
->isInvalidDecl())
1256 for (RecordDecl::field_iterator I
= RD
->field_begin(), E
= RD
->field_end();
1258 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>((*I
));
1259 // Callback to the client.
1260 switch (visitor(cxcursor::MakeCXCursor(FD
, GetTU(PT
)), client_data
)){
1263 case CXVisit_Continue
:
1270 unsigned clang_Cursor_isAnonymous(CXCursor C
){
1271 if (!clang_isDeclaration(C
.kind
))
1273 const Decl
*D
= cxcursor::getCursorDecl(C
);
1274 if (const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
)) {
1275 return ND
->isAnonymousNamespace();
1276 } else if (const TagDecl
*TD
= dyn_cast_or_null
<TagDecl
>(D
)) {
1277 return TD
->getTypedefNameForAnonDecl() == nullptr &&
1278 TD
->getIdentifier() == nullptr;
1284 unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C
){
1285 if (!clang_isDeclaration(C
.kind
))
1287 const Decl
*D
= cxcursor::getCursorDecl(C
);
1288 if (const RecordDecl
*FD
= dyn_cast_or_null
<RecordDecl
>(D
))
1289 return FD
->isAnonymousStructOrUnion();
1293 unsigned clang_Cursor_isInlineNamespace(CXCursor C
) {
1294 if (!clang_isDeclaration(C
.kind
))
1296 const Decl
*D
= cxcursor::getCursorDecl(C
);
1297 const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
);
1298 return ND
? ND
->isInline() : 0;
1301 CXType
clang_Type_getNamedType(CXType CT
){
1302 QualType T
= GetQualType(CT
);
1303 const Type
*TP
= T
.getTypePtrOrNull();
1305 if (TP
&& TP
->getTypeClass() == Type::Elaborated
)
1306 return MakeCXType(cast
<ElaboratedType
>(TP
)->getNamedType(), GetTU(CT
));
1308 return MakeCXType(QualType(), GetTU(CT
));
1311 unsigned clang_Type_isTransparentTagTypedef(CXType TT
){
1312 QualType T
= GetQualType(TT
);
1313 if (auto *TT
= dyn_cast_or_null
<TypedefType
>(T
.getTypePtrOrNull())) {
1314 if (auto *D
= TT
->getDecl())
1315 return D
->isTransparentTag();
1320 enum CXTypeNullabilityKind
clang_Type_getNullability(CXType CT
) {
1321 QualType T
= GetQualType(CT
);
1323 return CXTypeNullability_Invalid
;
1325 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(CT
))->getASTContext();
1326 if (auto nullability
= T
->getNullability(Ctx
)) {
1327 switch (*nullability
) {
1328 case NullabilityKind::NonNull
:
1329 return CXTypeNullability_NonNull
;
1330 case NullabilityKind::Nullable
:
1331 return CXTypeNullability_Nullable
;
1332 case NullabilityKind::NullableResult
:
1333 return CXTypeNullability_NullableResult
;
1334 case NullabilityKind::Unspecified
:
1335 return CXTypeNullability_Unspecified
;
1338 return CXTypeNullability_Invalid
;
1341 CXType
clang_Type_getValueType(CXType CT
) {
1342 QualType T
= GetQualType(CT
);
1344 if (T
.isNull() || !T
->isAtomicType())
1345 return MakeCXType(QualType(), GetTU(CT
));
1347 const auto *AT
= T
->castAs
<AtomicType
>();
1348 return MakeCXType(AT
->getValueType(), GetTU(CT
));