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 //===--------------------------------------------------------------------===//
17 #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"
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
;
71 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) BTCASE(Id);
72 #include "clang/Basic/OpenCLImageTypes.def"
74 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) BTCASE(Id);
75 #include "clang/Basic/OpenCLExtensionTypes.def"
81 return CXType_Unexposed
;
86 static CXTypeKind
GetTypeKind(QualType T
) {
87 const Type
*TP
= T
.getTypePtrOrNull();
89 return CXType_Invalid
;
91 #define TKCASE(K) case Type::K: return CXType_##K
92 switch (TP
->getTypeClass()) {
94 return GetBuiltinTypeKind(cast
<BuiltinType
>(TP
));
98 TKCASE(LValueReference
);
99 TKCASE(RValueReference
);
103 TKCASE(ObjCInterface
);
105 TKCASE(ObjCObjectPointer
);
106 TKCASE(ObjCTypeParam
);
107 TKCASE(FunctionNoProto
);
108 TKCASE(FunctionProto
);
109 TKCASE(ConstantArray
);
110 TKCASE(IncompleteArray
);
111 TKCASE(VariableArray
);
112 TKCASE(DependentSizedArray
);
115 TKCASE(MemberPointer
);
120 TKCASE(BTFTagAttributed
);
123 return CXType_Unexposed
;
129 CXType
cxtype::MakeCXType(QualType T
, CXTranslationUnit TU
) {
130 CXTypeKind TK
= CXType_Invalid
;
132 if (TU
&& !T
.isNull()) {
133 // Handle attributed types as the original type
134 if (auto *ATT
= T
->getAs
<AttributedType
>()) {
135 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
)) {
136 // Return the equivalent type which represents the canonically
138 return MakeCXType(ATT
->getEquivalentType(), TU
);
141 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>()) {
142 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
))
143 return MakeCXType(ATT
->getWrappedType(), TU
);
145 // Handle paren types as the original type
146 if (auto *PTT
= T
->getAs
<ParenType
>()) {
147 return MakeCXType(PTT
->getInnerType(), TU
);
150 ASTContext
&Ctx
= cxtu::getASTUnit(TU
)->getASTContext();
151 if (Ctx
.getLangOpts().ObjC
) {
152 QualType UnqualT
= T
.getUnqualifiedType();
153 if (Ctx
.isObjCIdType(UnqualT
))
155 else if (Ctx
.isObjCClassType(UnqualT
))
156 TK
= CXType_ObjCClass
;
157 else if (Ctx
.isObjCSelType(UnqualT
))
161 /* Handle decayed types as the original type */
162 if (const DecayedType
*DT
= T
->getAs
<DecayedType
>()) {
163 return MakeCXType(DT
->getOriginalType(), TU
);
166 if (TK
== CXType_Invalid
)
169 CXType CT
= { TK
, { TK
== CXType_Invalid
? nullptr
170 : T
.getAsOpaquePtr(), TU
} };
174 using cxtype::MakeCXType
;
176 static inline QualType
GetQualType(CXType CT
) {
177 return QualType::getFromOpaquePtr(CT
.data
[0]);
180 static inline CXTranslationUnit
GetTU(CXType CT
) {
181 return static_cast<CXTranslationUnit
>(CT
.data
[1]);
184 static std::optional
<ArrayRef
<TemplateArgument
>>
185 GetTemplateArguments(QualType Type
) {
186 assert(!Type
.isNull());
187 if (const auto *Specialization
= Type
->getAs
<TemplateSpecializationType
>())
188 return Specialization
->template_arguments();
190 if (const auto *RecordDecl
= Type
->getAsCXXRecordDecl()) {
191 const auto *TemplateDecl
=
192 dyn_cast
<ClassTemplateSpecializationDecl
>(RecordDecl
);
194 return TemplateDecl
->getTemplateArgs().asArray();
200 static std::optional
<QualType
>
201 TemplateArgumentToQualType(const TemplateArgument
&A
) {
202 if (A
.getKind() == TemplateArgument::Type
)
203 return A
.getAsType();
207 static std::optional
<QualType
>
208 FindTemplateArgumentTypeAt(ArrayRef
<TemplateArgument
> TA
, unsigned index
) {
209 unsigned current
= 0;
210 for (const auto &A
: TA
) {
211 if (A
.getKind() == TemplateArgument::Pack
) {
212 if (index
< current
+ A
.pack_size())
213 return TemplateArgumentToQualType(A
.getPackAsArray()[index
- current
]);
214 current
+= A
.pack_size();
217 if (current
== index
)
218 return TemplateArgumentToQualType(A
);
224 CXType
clang_getCursorType(CXCursor C
) {
225 using namespace cxcursor
;
227 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
229 return MakeCXType(QualType(), TU
);
231 ASTContext
&Context
= cxtu::getASTUnit(TU
)->getASTContext();
232 if (clang_isExpression(C
.kind
)) {
233 QualType T
= cxcursor::getCursorExpr(C
)->getType();
234 return MakeCXType(T
, TU
);
237 if (clang_isDeclaration(C
.kind
)) {
238 const Decl
*D
= cxcursor::getCursorDecl(C
);
240 return MakeCXType(QualType(), TU
);
242 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
243 return MakeCXType(Context
.getTypeDeclType(TD
), TU
);
244 if (const ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
))
245 return MakeCXType(Context
.getObjCInterfaceType(ID
), TU
);
246 if (const DeclaratorDecl
*DD
= dyn_cast
<DeclaratorDecl
>(D
))
247 return MakeCXType(DD
->getType(), TU
);
248 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
249 return MakeCXType(VD
->getType(), TU
);
250 if (const ObjCPropertyDecl
*PD
= dyn_cast
<ObjCPropertyDecl
>(D
))
251 return MakeCXType(PD
->getType(), TU
);
252 if (const FunctionTemplateDecl
*FTD
= dyn_cast
<FunctionTemplateDecl
>(D
))
253 return MakeCXType(FTD
->getTemplatedDecl()->getType(), TU
);
254 return MakeCXType(QualType(), TU
);
257 if (clang_isReference(C
.kind
)) {
259 case CXCursor_ObjCSuperClassRef
: {
261 = Context
.getObjCInterfaceType(getCursorObjCSuperClassRef(C
).first
);
262 return MakeCXType(T
, TU
);
265 case CXCursor_ObjCClassRef
: {
266 QualType T
= Context
.getObjCInterfaceType(getCursorObjCClassRef(C
).first
);
267 return MakeCXType(T
, TU
);
270 case CXCursor_TypeRef
: {
271 QualType T
= Context
.getTypeDeclType(getCursorTypeRef(C
).first
);
272 return MakeCXType(T
, TU
);
276 case CXCursor_CXXBaseSpecifier
:
277 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C
)->getType(), TU
);
279 case CXCursor_MemberRef
:
280 return cxtype::MakeCXType(getCursorMemberRef(C
).first
->getType(), TU
);
282 case CXCursor_VariableRef
:
283 return cxtype::MakeCXType(getCursorVariableRef(C
).first
->getType(), TU
);
285 case CXCursor_ObjCProtocolRef
:
286 case CXCursor_TemplateRef
:
287 case CXCursor_NamespaceRef
:
288 case CXCursor_OverloadedDeclRef
:
293 return MakeCXType(QualType(), TU
);
296 return MakeCXType(QualType(), TU
);
299 CXString
clang_getTypeSpelling(CXType CT
) {
300 QualType T
= GetQualType(CT
);
302 return cxstring::createEmpty();
304 CXTranslationUnit TU
= GetTU(CT
);
306 llvm::raw_svector_ostream
OS(Str
);
307 PrintingPolicy
PP(cxtu::getASTUnit(TU
)->getASTContext().getLangOpts());
311 return cxstring::createDup(OS
.str());
314 CXType
clang_getTypedefDeclUnderlyingType(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 TypedefNameDecl
*TD
= dyn_cast_or_null
<TypedefNameDecl
>(D
)) {
322 QualType T
= TD
->getUnderlyingType();
323 return MakeCXType(T
, 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
);
343 return MakeCXType(QualType(), TU
);
346 long long clang_getEnumConstantDeclValue(CXCursor C
) {
347 using namespace cxcursor
;
349 if (clang_isDeclaration(C
.kind
)) {
350 const Decl
*D
= cxcursor::getCursorDecl(C
);
352 if (const EnumConstantDecl
*TD
= dyn_cast_or_null
<EnumConstantDecl
>(D
)) {
353 return TD
->getInitVal().getSExtValue();
360 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C
) {
361 using namespace cxcursor
;
363 if (clang_isDeclaration(C
.kind
)) {
364 const Decl
*D
= cxcursor::getCursorDecl(C
);
366 if (const EnumConstantDecl
*TD
= dyn_cast_or_null
<EnumConstantDecl
>(D
)) {
367 return TD
->getInitVal().getZExtValue();
374 int clang_getFieldDeclBitWidth(CXCursor C
) {
375 using namespace cxcursor
;
377 if (clang_isDeclaration(C
.kind
)) {
378 const Decl
*D
= getCursorDecl(C
);
380 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
)) {
381 if (FD
->isBitField() && !FD
->getBitWidth()->isValueDependent())
382 return FD
->getBitWidthValue(getCursorContext(C
));
389 CXType
clang_getCanonicalType(CXType CT
) {
390 if (CT
.kind
== CXType_Invalid
)
393 QualType T
= GetQualType(CT
);
394 CXTranslationUnit TU
= GetTU(CT
);
397 return MakeCXType(QualType(), GetTU(CT
));
399 return MakeCXType(cxtu::getASTUnit(TU
)->getASTContext()
400 .getCanonicalType(T
),
404 unsigned clang_isConstQualifiedType(CXType CT
) {
405 QualType T
= GetQualType(CT
);
406 return T
.isLocalConstQualified();
409 unsigned clang_isVolatileQualifiedType(CXType CT
) {
410 QualType T
= GetQualType(CT
);
411 return T
.isLocalVolatileQualified();
414 unsigned clang_isRestrictQualifiedType(CXType CT
) {
415 QualType T
= GetQualType(CT
);
416 return T
.isLocalRestrictQualified();
419 unsigned clang_getAddressSpace(CXType CT
) {
420 QualType T
= GetQualType(CT
);
422 // For non language-specific address space, use separate helper function.
423 if (T
.getAddressSpace() >= LangAS::FirstTargetAddressSpace
) {
424 return T
.getQualifiers().getAddressSpaceAttributePrintValue();
426 // FIXME: this function returns either a LangAS or a target AS
427 // Those values can overlap which makes this function rather unpredictable
429 return (unsigned)T
.getAddressSpace();
432 CXString
clang_getTypedefName(CXType CT
) {
433 QualType T
= GetQualType(CT
);
434 const TypedefType
*TT
= T
->getAs
<TypedefType
>();
436 TypedefNameDecl
*TD
= TT
->getDecl();
438 return cxstring::createDup(TD
->getNameAsString().c_str());
440 return cxstring::createEmpty();
443 CXType
clang_getPointeeType(CXType CT
) {
444 QualType T
= GetQualType(CT
);
445 const Type
*TP
= T
.getTypePtrOrNull();
448 return MakeCXType(QualType(), GetTU(CT
));
451 switch (TP
->getTypeClass()) {
453 T
= cast
<PointerType
>(TP
)->getPointeeType();
455 case Type::BlockPointer
:
456 T
= cast
<BlockPointerType
>(TP
)->getPointeeType();
458 case Type::LValueReference
:
459 case Type::RValueReference
:
460 T
= cast
<ReferenceType
>(TP
)->getPointeeType();
462 case Type::ObjCObjectPointer
:
463 T
= cast
<ObjCObjectPointerType
>(TP
)->getPointeeType();
465 case Type::MemberPointer
:
466 T
= cast
<MemberPointerType
>(TP
)->getPointeeType();
469 case Type::DeducedTemplateSpecialization
:
470 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
478 return MakeCXType(T
, GetTU(CT
));
481 CXType
clang_getUnqualifiedType(CXType CT
) {
482 return MakeCXType(GetQualType(CT
).getUnqualifiedType(), GetTU(CT
));
485 CXType
clang_getNonReferenceType(CXType CT
) {
486 return MakeCXType(GetQualType(CT
).getNonReferenceType(), GetTU(CT
));
489 CXCursor
clang_getTypeDeclaration(CXType CT
) {
490 if (CT
.kind
== CXType_Invalid
)
491 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
493 QualType T
= GetQualType(CT
);
494 const Type
*TP
= T
.getTypePtrOrNull();
497 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
502 switch (TP
->getTypeClass()) {
504 D
= cast
<TypedefType
>(TP
)->getDecl();
506 case Type::ObjCObject
:
507 D
= cast
<ObjCObjectType
>(TP
)->getInterface();
509 case Type::ObjCInterface
:
510 D
= cast
<ObjCInterfaceType
>(TP
)->getDecl();
514 D
= cast
<TagType
>(TP
)->getDecl();
516 case Type::TemplateSpecialization
:
517 if (const RecordType
*Record
= TP
->getAs
<RecordType
>())
518 D
= Record
->getDecl();
520 D
= cast
<TemplateSpecializationType
>(TP
)->getTemplateName()
521 .getAsTemplateDecl();
525 case Type::DeducedTemplateSpecialization
:
526 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
531 case Type::InjectedClassName
:
532 D
= cast
<InjectedClassNameType
>(TP
)->getDecl();
535 // FIXME: Template type parameters!
537 case Type::Elaborated
:
538 TP
= cast
<ElaboratedType
>(TP
)->getNamedType().getTypePtrOrNull();
546 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
548 return cxcursor::MakeCXCursor(D
, GetTU(CT
));
551 CXString
clang_getTypeKindSpelling(enum CXTypeKind K
) {
552 const char *s
= nullptr;
553 #define TKIND(X) case CXType_##X: s = "" #X ""; break
570 case CXType_WChar
: s
= "WChar"; break;
598 TKIND(LValueReference
);
599 TKIND(RValueReference
);
603 TKIND(ObjCInterface
);
605 TKIND(ObjCObjectPointer
);
606 TKIND(ObjCTypeParam
);
607 TKIND(FunctionNoProto
);
608 TKIND(FunctionProto
);
609 TKIND(ConstantArray
);
610 TKIND(IncompleteArray
);
611 TKIND(VariableArray
);
612 TKIND(DependentSizedArray
);
615 TKIND(MemberPointer
);
620 TKIND(BTFTagAttributed
);
622 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
623 #include "clang/Basic/OpenCLImageTypes.def"
625 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id);
626 #include "clang/Basic/OpenCLExtensionTypes.def"
634 return cxstring::createRef(s
);
637 unsigned clang_equalTypes(CXType A
, CXType B
) {
638 return A
.data
[0] == B
.data
[0] && A
.data
[1] == B
.data
[1];
641 unsigned clang_isFunctionTypeVariadic(CXType X
) {
642 QualType T
= GetQualType(X
);
646 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>())
647 return (unsigned)FD
->isVariadic();
649 if (T
->getAs
<FunctionNoProtoType
>())
655 CXCallingConv
clang_getFunctionTypeCallingConv(CXType X
) {
656 QualType T
= GetQualType(X
);
658 return CXCallingConv_Invalid
;
660 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>()) {
661 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
662 switch (FD
->getCallConv()) {
664 TCALLINGCONV(X86StdCall
);
665 TCALLINGCONV(X86FastCall
);
666 TCALLINGCONV(X86ThisCall
);
667 TCALLINGCONV(X86Pascal
);
668 TCALLINGCONV(X86RegCall
);
669 TCALLINGCONV(X86VectorCall
);
670 TCALLINGCONV(AArch64VectorCall
);
671 TCALLINGCONV(AArch64SVEPCS
);
673 TCALLINGCONV(X86_64SysV
);
675 TCALLINGCONV(AAPCS_VFP
);
676 TCALLINGCONV(IntelOclBicc
);
678 TCALLINGCONV(SwiftAsync
);
679 TCALLINGCONV(PreserveMost
);
680 TCALLINGCONV(PreserveAll
);
681 TCALLINGCONV(M68kRTD
);
682 case CC_SpirFunction
: return CXCallingConv_Unexposed
;
683 case CC_AMDGPUKernelCall
: return CXCallingConv_Unexposed
;
684 case CC_OpenCLKernel
: return CXCallingConv_Unexposed
;
690 return CXCallingConv_Invalid
;
693 int clang_getNumArgTypes(CXType X
) {
694 QualType T
= GetQualType(X
);
698 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
699 return FD
->getNumParams();
702 if (T
->getAs
<FunctionNoProtoType
>()) {
709 CXType
clang_getArgType(CXType X
, unsigned i
) {
710 QualType T
= GetQualType(X
);
712 return MakeCXType(QualType(), GetTU(X
));
714 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
715 unsigned numParams
= FD
->getNumParams();
717 return MakeCXType(QualType(), GetTU(X
));
719 return MakeCXType(FD
->getParamType(i
), GetTU(X
));
722 return MakeCXType(QualType(), GetTU(X
));
725 CXType
clang_getResultType(CXType X
) {
726 QualType T
= GetQualType(X
);
728 return MakeCXType(QualType(), GetTU(X
));
730 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>())
731 return MakeCXType(FD
->getReturnType(), GetTU(X
));
733 return MakeCXType(QualType(), GetTU(X
));
736 CXType
clang_getCursorResultType(CXCursor C
) {
737 if (clang_isDeclaration(C
.kind
)) {
738 const Decl
*D
= cxcursor::getCursorDecl(C
);
739 if (const ObjCMethodDecl
*MD
= dyn_cast_or_null
<ObjCMethodDecl
>(D
))
740 return MakeCXType(MD
->getReturnType(), cxcursor::getCursorTU(C
));
742 return clang_getResultType(clang_getCursorType(C
));
745 return MakeCXType(QualType(), cxcursor::getCursorTU(C
));
748 // FIXME: We should expose the canThrow(...) result instead of the EST.
749 static CXCursor_ExceptionSpecificationKind
750 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST
) {
753 return CXCursor_ExceptionSpecificationKind_None
;
754 case EST_DynamicNone
:
755 return CXCursor_ExceptionSpecificationKind_DynamicNone
;
757 return CXCursor_ExceptionSpecificationKind_Dynamic
;
759 return CXCursor_ExceptionSpecificationKind_MSAny
;
760 case EST_BasicNoexcept
:
761 return CXCursor_ExceptionSpecificationKind_BasicNoexcept
;
763 return CXCursor_ExceptionSpecificationKind_NoThrow
;
764 case EST_NoexceptFalse
:
765 case EST_NoexceptTrue
:
766 case EST_DependentNoexcept
:
767 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept
;
768 case EST_Unevaluated
:
769 return CXCursor_ExceptionSpecificationKind_Unevaluated
;
770 case EST_Uninstantiated
:
771 return CXCursor_ExceptionSpecificationKind_Uninstantiated
;
773 return CXCursor_ExceptionSpecificationKind_Unparsed
;
775 llvm_unreachable("invalid EST value");
778 int clang_getExceptionSpecificationType(CXType X
) {
779 QualType T
= GetQualType(X
);
783 if (const auto *FD
= T
->getAs
<FunctionProtoType
>())
784 return getExternalExceptionSpecificationKind(FD
->getExceptionSpecType());
789 int clang_getCursorExceptionSpecificationType(CXCursor C
) {
790 if (clang_isDeclaration(C
.kind
))
791 return clang_getExceptionSpecificationType(clang_getCursorType(C
));
796 unsigned clang_isPODType(CXType X
) {
797 QualType T
= GetQualType(X
);
801 CXTranslationUnit TU
= GetTU(X
);
803 return T
.isPODType(cxtu::getASTUnit(TU
)->getASTContext()) ? 1 : 0;
806 CXType
clang_getElementType(CXType CT
) {
807 QualType ET
= QualType();
808 QualType T
= GetQualType(CT
);
809 const Type
*TP
= T
.getTypePtrOrNull();
812 switch (TP
->getTypeClass()) {
813 case Type::ConstantArray
:
814 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
816 case Type::IncompleteArray
:
817 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
819 case Type::VariableArray
:
820 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
822 case Type::DependentSizedArray
:
823 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
826 ET
= cast
<VectorType
> (TP
)->getElementType();
828 case Type::ExtVector
:
829 ET
= cast
<ExtVectorType
>(TP
)->getElementType();
832 ET
= cast
<ComplexType
> (TP
)->getElementType();
838 return MakeCXType(ET
, GetTU(CT
));
841 long long clang_getNumElements(CXType CT
) {
842 long long result
= -1;
843 QualType T
= GetQualType(CT
);
844 const Type
*TP
= T
.getTypePtrOrNull();
847 switch (TP
->getTypeClass()) {
848 case Type::ConstantArray
:
849 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
852 result
= cast
<VectorType
> (TP
)->getNumElements();
854 case Type::ExtVector
:
855 result
= cast
<ExtVectorType
>(TP
)->getNumElements();
864 CXType
clang_getArrayElementType(CXType CT
) {
865 QualType ET
= QualType();
866 QualType T
= GetQualType(CT
);
867 const Type
*TP
= T
.getTypePtrOrNull();
870 switch (TP
->getTypeClass()) {
871 case Type::ConstantArray
:
872 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
874 case Type::IncompleteArray
:
875 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
877 case Type::VariableArray
:
878 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
880 case Type::DependentSizedArray
:
881 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
887 return MakeCXType(ET
, GetTU(CT
));
890 long long clang_getArraySize(CXType CT
) {
891 long long result
= -1;
892 QualType T
= GetQualType(CT
);
893 const Type
*TP
= T
.getTypePtrOrNull();
896 switch (TP
->getTypeClass()) {
897 case Type::ConstantArray
:
898 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
907 static bool isIncompleteTypeWithAlignment(QualType QT
) {
908 return QT
->isIncompleteArrayType() || !QT
->isIncompleteType();
911 long long clang_Type_getAlignOf(CXType T
) {
912 if (T
.kind
== CXType_Invalid
)
913 return CXTypeLayoutError_Invalid
;
914 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
915 QualType QT
= GetQualType(T
);
916 // [expr.alignof] p1: return size_t value for complete object type, reference
918 // [expr.alignof] p3: if reference type, return size of referenced type
919 if (QT
->isReferenceType())
920 QT
= QT
.getNonReferenceType();
921 if (!isIncompleteTypeWithAlignment(QT
))
922 return CXTypeLayoutError_Incomplete
;
923 if (QT
->isDependentType())
924 return CXTypeLayoutError_Dependent
;
925 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
926 if (Deduced
->getDeducedType().isNull())
927 return CXTypeLayoutError_Undeduced
;
928 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
929 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
930 // if (QT->isVoidType()) return 1;
931 return Ctx
.getTypeAlignInChars(QT
).getQuantity();
934 CXType
clang_Type_getClassType(CXType CT
) {
935 QualType ET
= QualType();
936 QualType T
= GetQualType(CT
);
937 const Type
*TP
= T
.getTypePtrOrNull();
939 if (TP
&& TP
->getTypeClass() == Type::MemberPointer
) {
940 ET
= QualType(cast
<MemberPointerType
> (TP
)->getClass(), 0);
942 return MakeCXType(ET
, GetTU(CT
));
945 long long clang_Type_getSizeOf(CXType T
) {
946 if (T
.kind
== CXType_Invalid
)
947 return CXTypeLayoutError_Invalid
;
948 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
949 QualType QT
= GetQualType(T
);
950 // [expr.sizeof] p2: if reference type, return size of referenced type
951 if (QT
->isReferenceType())
952 QT
= QT
.getNonReferenceType();
953 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
955 // Note: We get the cxtype, not the cxcursor, so we can't call
956 // FieldDecl->isBitField()
957 // [expr.sizeof] p3: pointer ok, function not ok.
958 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
959 if (QT
->isIncompleteType())
960 return CXTypeLayoutError_Incomplete
;
961 if (QT
->isDependentType())
962 return CXTypeLayoutError_Dependent
;
963 if (!QT
->isConstantSizeType())
964 return CXTypeLayoutError_NotConstantSize
;
965 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
966 if (Deduced
->getDeducedType().isNull())
967 return CXTypeLayoutError_Undeduced
;
968 // [gcc extension] lib/AST/ExprConstant.cpp:1372
969 // HandleSizeof : {voidtype,functype} == 1
970 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
971 if (QT
->isVoidType() || QT
->isFunctionType())
973 return Ctx
.getTypeSizeInChars(QT
).getQuantity();
976 static bool isTypeIncompleteForLayout(QualType QT
) {
977 return QT
->isIncompleteType() && !QT
->isIncompleteArrayType();
980 static long long visitRecordForValidation(const RecordDecl
*RD
) {
981 for (const auto *I
: RD
->fields()){
982 QualType FQT
= I
->getType();
983 if (isTypeIncompleteForLayout(FQT
))
984 return CXTypeLayoutError_Incomplete
;
985 if (FQT
->isDependentType())
986 return CXTypeLayoutError_Dependent
;
988 if (const RecordType
*ChildType
= I
->getType()->getAs
<RecordType
>()) {
989 if (const RecordDecl
*Child
= ChildType
->getDecl()) {
990 long long ret
= visitRecordForValidation(Child
);
995 // else try next field
1000 static long long validateFieldParentType(CXCursor PC
, CXType PT
){
1001 if (clang_isInvalid(PC
.kind
))
1002 return CXTypeLayoutError_Invalid
;
1003 const RecordDecl
*RD
=
1004 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1005 // validate parent declaration
1006 if (!RD
|| RD
->isInvalidDecl())
1007 return CXTypeLayoutError_Invalid
;
1008 RD
= RD
->getDefinition();
1010 return CXTypeLayoutError_Incomplete
;
1011 if (RD
->isInvalidDecl())
1012 return CXTypeLayoutError_Invalid
;
1013 // validate parent type
1014 QualType RT
= GetQualType(PT
);
1015 if (RT
->isIncompleteType())
1016 return CXTypeLayoutError_Incomplete
;
1017 if (RT
->isDependentType())
1018 return CXTypeLayoutError_Dependent
;
1019 // We recurse into all record fields to detect incomplete and dependent types.
1020 long long Error
= visitRecordForValidation(RD
);
1026 long long clang_Type_getOffsetOf(CXType PT
, const char *S
) {
1027 // check that PT is not incomplete/dependent
1028 CXCursor PC
= clang_getTypeDeclaration(PT
);
1029 long long Error
= validateFieldParentType(PC
,PT
);
1033 return CXTypeLayoutError_InvalidFieldName
;
1035 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(PT
))->getASTContext();
1036 IdentifierInfo
*II
= &Ctx
.Idents
.get(S
);
1037 DeclarationName
FieldName(II
);
1038 const RecordDecl
*RD
=
1039 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1040 // verified in validateFieldParentType
1041 RD
= RD
->getDefinition();
1042 RecordDecl::lookup_result Res
= RD
->lookup(FieldName
);
1043 // If a field of the parent record is incomplete, lookup will fail.
1044 // and we would return InvalidFieldName instead of Incomplete.
1045 // But this erroneous results does protects again a hidden assertion failure
1046 // in the RecordLayoutBuilder
1047 if (!Res
.isSingleResult())
1048 return CXTypeLayoutError_InvalidFieldName
;
1049 if (const FieldDecl
*FD
= dyn_cast
<FieldDecl
>(Res
.front()))
1050 return Ctx
.getFieldOffset(FD
);
1051 if (const IndirectFieldDecl
*IFD
= dyn_cast
<IndirectFieldDecl
>(Res
.front()))
1052 return Ctx
.getFieldOffset(IFD
);
1053 // we don't want any other Decl Type.
1054 return CXTypeLayoutError_InvalidFieldName
;
1057 CXType
clang_Type_getModifiedType(CXType CT
) {
1058 QualType T
= GetQualType(CT
);
1060 return MakeCXType(QualType(), GetTU(CT
));
1062 if (auto *ATT
= T
->getAs
<AttributedType
>())
1063 return MakeCXType(ATT
->getModifiedType(), GetTU(CT
));
1065 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>())
1066 return MakeCXType(ATT
->getWrappedType(), GetTU(CT
));
1068 return MakeCXType(QualType(), GetTU(CT
));
1071 long long clang_Cursor_getOffsetOfField(CXCursor C
) {
1072 if (clang_isDeclaration(C
.kind
)) {
1073 // we need to validate the parent type
1074 CXCursor PC
= clang_getCursorSemanticParent(C
);
1075 CXType PT
= clang_getCursorType(PC
);
1076 long long Error
= validateFieldParentType(PC
,PT
);
1079 // proceed with the offset calculation
1080 const Decl
*D
= cxcursor::getCursorDecl(C
);
1081 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1082 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
))
1083 return Ctx
.getFieldOffset(FD
);
1084 if (const IndirectFieldDecl
*IFD
= dyn_cast_or_null
<IndirectFieldDecl
>(D
))
1085 return Ctx
.getFieldOffset(IFD
);
1090 enum CXRefQualifierKind
clang_Type_getCXXRefQualifier(CXType T
) {
1091 QualType QT
= GetQualType(T
);
1093 return CXRefQualifier_None
;
1094 const FunctionProtoType
*FD
= QT
->getAs
<FunctionProtoType
>();
1096 return CXRefQualifier_None
;
1097 switch (FD
->getRefQualifier()) {
1099 return CXRefQualifier_None
;
1101 return CXRefQualifier_LValue
;
1103 return CXRefQualifier_RValue
;
1105 return CXRefQualifier_None
;
1108 unsigned clang_Cursor_isBitField(CXCursor C
) {
1109 if (!clang_isDeclaration(C
.kind
))
1111 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(cxcursor::getCursorDecl(C
));
1114 return FD
->isBitField();
1117 CXString
clang_getDeclObjCTypeEncoding(CXCursor C
) {
1118 if (!clang_isDeclaration(C
.kind
))
1119 return cxstring::createEmpty();
1121 const Decl
*D
= cxcursor::getCursorDecl(C
);
1122 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1123 std::string encoding
;
1125 if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
1126 encoding
= Ctx
.getObjCEncodingForMethodDecl(OMD
);
1127 } else if (const ObjCPropertyDecl
*OPD
= dyn_cast
<ObjCPropertyDecl
>(D
))
1128 encoding
= Ctx
.getObjCEncodingForPropertyDecl(OPD
, nullptr);
1129 else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
1130 encoding
= Ctx
.getObjCEncodingForFunctionDecl(FD
);
1133 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
1134 Ty
= Ctx
.getTypeDeclType(TD
);
1135 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
1137 else return cxstring::createRef("?");
1138 Ctx
.getObjCEncodingForType(Ty
, encoding
);
1141 return cxstring::createDup(encoding
);
1144 static unsigned GetTemplateArgumentArraySize(ArrayRef
<TemplateArgument
> TA
) {
1145 unsigned size
= TA
.size();
1146 for (const auto &Arg
: TA
)
1147 if (Arg
.getKind() == TemplateArgument::Pack
)
1148 size
+= Arg
.pack_size() - 1;
1152 int clang_Type_getNumTemplateArguments(CXType CT
) {
1153 QualType T
= GetQualType(CT
);
1157 auto TA
= GetTemplateArguments(T
);
1161 return GetTemplateArgumentArraySize(*TA
);
1164 CXType
clang_Type_getTemplateArgumentAsType(CXType CT
, unsigned index
) {
1165 QualType T
= GetQualType(CT
);
1167 return MakeCXType(QualType(), GetTU(CT
));
1169 auto TA
= GetTemplateArguments(T
);
1171 return MakeCXType(QualType(), GetTU(CT
));
1173 std::optional
<QualType
> QT
= FindTemplateArgumentTypeAt(*TA
, index
);
1174 return MakeCXType(QT
.value_or(QualType()), GetTU(CT
));
1177 CXType
clang_Type_getObjCObjectBaseType(CXType CT
) {
1178 QualType T
= GetQualType(CT
);
1180 return MakeCXType(QualType(), GetTU(CT
));
1182 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1184 return MakeCXType(QualType(), GetTU(CT
));
1186 return MakeCXType(OT
->getBaseType(), GetTU(CT
));
1189 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT
) {
1190 QualType T
= GetQualType(CT
);
1194 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1198 return OT
->getNumProtocols();
1201 CXCursor
clang_Type_getObjCProtocolDecl(CXType CT
, unsigned i
) {
1202 QualType T
= GetQualType(CT
);
1204 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1206 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1208 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1210 const ObjCProtocolDecl
*PD
= OT
->getProtocol(i
);
1212 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1214 return cxcursor::MakeCXCursor(PD
, GetTU(CT
));
1217 unsigned clang_Type_getNumObjCTypeArgs(CXType CT
) {
1218 QualType T
= GetQualType(CT
);
1222 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1226 return OT
->getTypeArgs().size();
1229 CXType
clang_Type_getObjCTypeArg(CXType CT
, unsigned i
) {
1230 QualType T
= GetQualType(CT
);
1232 return MakeCXType(QualType(), GetTU(CT
));
1234 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1236 return MakeCXType(QualType(), GetTU(CT
));
1238 const ArrayRef
<QualType
> TA
= OT
->getTypeArgs();
1239 if ((size_t)i
>= TA
.size())
1240 return MakeCXType(QualType(), GetTU(CT
));
1242 return MakeCXType(TA
[i
], GetTU(CT
));
1245 unsigned clang_Type_visitFields(CXType PT
,
1246 CXFieldVisitor visitor
,
1247 CXClientData client_data
){
1248 CXCursor PC
= clang_getTypeDeclaration(PT
);
1249 if (clang_isInvalid(PC
.kind
))
1251 const RecordDecl
*RD
=
1252 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1253 if (!RD
|| RD
->isInvalidDecl())
1255 RD
= RD
->getDefinition();
1256 if (!RD
|| RD
->isInvalidDecl())
1259 for (RecordDecl::field_iterator I
= RD
->field_begin(), E
= RD
->field_end();
1261 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>((*I
));
1262 // Callback to the client.
1263 switch (visitor(cxcursor::MakeCXCursor(FD
, GetTU(PT
)), client_data
)){
1266 case CXVisit_Continue
:
1273 unsigned clang_Cursor_isAnonymous(CXCursor C
){
1274 if (!clang_isDeclaration(C
.kind
))
1276 const Decl
*D
= cxcursor::getCursorDecl(C
);
1277 if (const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
)) {
1278 return ND
->isAnonymousNamespace();
1279 } else if (const TagDecl
*TD
= dyn_cast_or_null
<TagDecl
>(D
)) {
1280 return TD
->getTypedefNameForAnonDecl() == nullptr &&
1281 TD
->getIdentifier() == nullptr;
1287 unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C
){
1288 if (!clang_isDeclaration(C
.kind
))
1290 const Decl
*D
= cxcursor::getCursorDecl(C
);
1291 if (const RecordDecl
*FD
= dyn_cast_or_null
<RecordDecl
>(D
))
1292 return FD
->isAnonymousStructOrUnion();
1296 unsigned clang_Cursor_isInlineNamespace(CXCursor C
) {
1297 if (!clang_isDeclaration(C
.kind
))
1299 const Decl
*D
= cxcursor::getCursorDecl(C
);
1300 const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
);
1301 return ND
? ND
->isInline() : 0;
1304 CXType
clang_Type_getNamedType(CXType CT
){
1305 QualType T
= GetQualType(CT
);
1306 const Type
*TP
= T
.getTypePtrOrNull();
1308 if (TP
&& TP
->getTypeClass() == Type::Elaborated
)
1309 return MakeCXType(cast
<ElaboratedType
>(TP
)->getNamedType(), GetTU(CT
));
1311 return MakeCXType(QualType(), GetTU(CT
));
1314 unsigned clang_Type_isTransparentTagTypedef(CXType TT
){
1315 QualType T
= GetQualType(TT
);
1316 if (auto *TT
= dyn_cast_or_null
<TypedefType
>(T
.getTypePtrOrNull())) {
1317 if (auto *D
= TT
->getDecl())
1318 return D
->isTransparentTag();
1323 enum CXTypeNullabilityKind
clang_Type_getNullability(CXType CT
) {
1324 QualType T
= GetQualType(CT
);
1326 return CXTypeNullability_Invalid
;
1328 if (auto nullability
= T
->getNullability()) {
1329 switch (*nullability
) {
1330 case NullabilityKind::NonNull
:
1331 return CXTypeNullability_NonNull
;
1332 case NullabilityKind::Nullable
:
1333 return CXTypeNullability_Nullable
;
1334 case NullabilityKind::NullableResult
:
1335 return CXTypeNullability_NullableResult
;
1336 case NullabilityKind::Unspecified
:
1337 return CXTypeNullability_Unspecified
;
1340 return CXTypeNullability_Invalid
;
1343 CXType
clang_Type_getValueType(CXType CT
) {
1344 QualType T
= GetQualType(CT
);
1346 if (T
.isNull() || !T
->isAtomicType())
1347 return MakeCXType(QualType(), GetTU(CT
));
1349 const auto *AT
= T
->castAs
<AtomicType
>();
1350 return MakeCXType(AT
->getValueType(), GetTU(CT
));