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"
80 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) BTCASE(Id);
81 #include "clang/Basic/HLSLIntangibleTypes.def"
83 return CXType_Unexposed
;
88 static CXTypeKind
GetTypeKind(QualType T
) {
89 const Type
*TP
= T
.getTypePtrOrNull();
91 return CXType_Invalid
;
93 #define TKCASE(K) case Type::K: return CXType_##K
94 switch (TP
->getTypeClass()) {
96 return GetBuiltinTypeKind(cast
<BuiltinType
>(TP
));
100 TKCASE(LValueReference
);
101 TKCASE(RValueReference
);
105 TKCASE(ObjCInterface
);
107 TKCASE(ObjCObjectPointer
);
108 TKCASE(ObjCTypeParam
);
109 TKCASE(FunctionNoProto
);
110 TKCASE(FunctionProto
);
111 TKCASE(ConstantArray
);
112 TKCASE(IncompleteArray
);
113 TKCASE(VariableArray
);
114 TKCASE(DependentSizedArray
);
117 TKCASE(MemberPointer
);
122 TKCASE(BTFTagAttributed
);
125 return CXType_Unexposed
;
131 CXType
cxtype::MakeCXType(QualType T
, CXTranslationUnit TU
) {
132 CXTypeKind TK
= CXType_Invalid
;
134 if (TU
&& !T
.isNull()) {
135 // Handle attributed types as the original type
136 if (auto *ATT
= T
->getAs
<AttributedType
>()) {
137 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
)) {
138 // Return the equivalent type which represents the canonically
140 return MakeCXType(ATT
->getEquivalentType(), TU
);
143 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>()) {
144 if (!(TU
->ParsingOptions
& CXTranslationUnit_IncludeAttributedTypes
))
145 return MakeCXType(ATT
->getWrappedType(), TU
);
147 // Handle paren types as the original type
148 if (auto *PTT
= T
->getAs
<ParenType
>()) {
149 return MakeCXType(PTT
->getInnerType(), TU
);
152 ASTContext
&Ctx
= cxtu::getASTUnit(TU
)->getASTContext();
153 if (Ctx
.getLangOpts().ObjC
) {
154 QualType UnqualT
= T
.getUnqualifiedType();
155 if (Ctx
.isObjCIdType(UnqualT
))
157 else if (Ctx
.isObjCClassType(UnqualT
))
158 TK
= CXType_ObjCClass
;
159 else if (Ctx
.isObjCSelType(UnqualT
))
163 /* Handle decayed types as the original type */
164 if (const DecayedType
*DT
= T
->getAs
<DecayedType
>()) {
165 return MakeCXType(DT
->getOriginalType(), TU
);
168 if (TK
== CXType_Invalid
)
171 CXType CT
= { TK
, { TK
== CXType_Invalid
? nullptr
172 : T
.getAsOpaquePtr(), TU
} };
176 using cxtype::MakeCXType
;
178 static inline QualType
GetQualType(CXType CT
) {
179 return QualType::getFromOpaquePtr(CT
.data
[0]);
182 static inline CXTranslationUnit
GetTU(CXType CT
) {
183 return static_cast<CXTranslationUnit
>(CT
.data
[1]);
186 static std::optional
<ArrayRef
<TemplateArgument
>>
187 GetTemplateArguments(QualType Type
) {
188 assert(!Type
.isNull());
189 if (const auto *Specialization
= Type
->getAs
<TemplateSpecializationType
>())
190 return Specialization
->template_arguments();
192 if (const auto *RecordDecl
= Type
->getAsCXXRecordDecl()) {
193 const auto *TemplateDecl
=
194 dyn_cast
<ClassTemplateSpecializationDecl
>(RecordDecl
);
196 return TemplateDecl
->getTemplateArgs().asArray();
202 static std::optional
<QualType
>
203 TemplateArgumentToQualType(const TemplateArgument
&A
) {
204 if (A
.getKind() == TemplateArgument::Type
)
205 return A
.getAsType();
209 static std::optional
<QualType
>
210 FindTemplateArgumentTypeAt(ArrayRef
<TemplateArgument
> TA
, unsigned index
) {
211 unsigned current
= 0;
212 for (const auto &A
: TA
) {
213 if (A
.getKind() == TemplateArgument::Pack
) {
214 if (index
< current
+ A
.pack_size())
215 return TemplateArgumentToQualType(A
.getPackAsArray()[index
- current
]);
216 current
+= A
.pack_size();
219 if (current
== index
)
220 return TemplateArgumentToQualType(A
);
226 CXType
clang_getCursorType(CXCursor C
) {
227 using namespace cxcursor
;
229 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
231 return MakeCXType(QualType(), TU
);
233 ASTContext
&Context
= cxtu::getASTUnit(TU
)->getASTContext();
234 if (clang_isExpression(C
.kind
)) {
235 QualType T
= cxcursor::getCursorExpr(C
)->getType();
236 return MakeCXType(T
, TU
);
239 if (clang_isDeclaration(C
.kind
)) {
240 const Decl
*D
= cxcursor::getCursorDecl(C
);
242 return MakeCXType(QualType(), TU
);
244 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
245 return MakeCXType(Context
.getTypeDeclType(TD
), TU
);
246 if (const ObjCInterfaceDecl
*ID
= dyn_cast
<ObjCInterfaceDecl
>(D
))
247 return MakeCXType(Context
.getObjCInterfaceType(ID
), TU
);
248 if (const DeclaratorDecl
*DD
= dyn_cast
<DeclaratorDecl
>(D
))
249 return MakeCXType(DD
->getType(), TU
);
250 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
251 return MakeCXType(VD
->getType(), TU
);
252 if (const ObjCPropertyDecl
*PD
= dyn_cast
<ObjCPropertyDecl
>(D
))
253 return MakeCXType(PD
->getType(), TU
);
254 if (const FunctionTemplateDecl
*FTD
= dyn_cast
<FunctionTemplateDecl
>(D
))
255 return MakeCXType(FTD
->getTemplatedDecl()->getType(), TU
);
256 return MakeCXType(QualType(), TU
);
259 if (clang_isReference(C
.kind
)) {
261 case CXCursor_ObjCSuperClassRef
: {
263 = Context
.getObjCInterfaceType(getCursorObjCSuperClassRef(C
).first
);
264 return MakeCXType(T
, TU
);
267 case CXCursor_ObjCClassRef
: {
268 QualType T
= Context
.getObjCInterfaceType(getCursorObjCClassRef(C
).first
);
269 return MakeCXType(T
, TU
);
272 case CXCursor_TypeRef
: {
273 QualType T
= Context
.getTypeDeclType(getCursorTypeRef(C
).first
);
274 return MakeCXType(T
, TU
);
278 case CXCursor_CXXBaseSpecifier
:
279 return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C
)->getType(), TU
);
281 case CXCursor_MemberRef
:
282 return cxtype::MakeCXType(getCursorMemberRef(C
).first
->getType(), TU
);
284 case CXCursor_VariableRef
:
285 return cxtype::MakeCXType(getCursorVariableRef(C
).first
->getType(), TU
);
287 case CXCursor_ObjCProtocolRef
:
288 case CXCursor_TemplateRef
:
289 case CXCursor_NamespaceRef
:
290 case CXCursor_OverloadedDeclRef
:
295 return MakeCXType(QualType(), TU
);
298 return MakeCXType(QualType(), TU
);
301 CXString
clang_getTypeSpelling(CXType CT
) {
302 QualType T
= GetQualType(CT
);
304 return cxstring::createEmpty();
306 CXTranslationUnit TU
= GetTU(CT
);
308 llvm::raw_svector_ostream
OS(Str
);
309 PrintingPolicy
PP(cxtu::getASTUnit(TU
)->getASTContext().getLangOpts());
313 return cxstring::createDup(OS
.str());
316 CXType
clang_getTypedefDeclUnderlyingType(CXCursor C
) {
317 using namespace cxcursor
;
318 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
320 if (clang_isDeclaration(C
.kind
)) {
321 const Decl
*D
= cxcursor::getCursorDecl(C
);
323 if (const TypedefNameDecl
*TD
= dyn_cast_or_null
<TypedefNameDecl
>(D
)) {
324 QualType T
= TD
->getUnderlyingType();
325 return MakeCXType(T
, TU
);
329 return MakeCXType(QualType(), TU
);
332 CXType
clang_getEnumDeclIntegerType(CXCursor C
) {
333 using namespace cxcursor
;
334 CXTranslationUnit TU
= cxcursor::getCursorTU(C
);
336 if (clang_isDeclaration(C
.kind
)) {
337 const Decl
*D
= cxcursor::getCursorDecl(C
);
339 if (const EnumDecl
*TD
= dyn_cast_or_null
<EnumDecl
>(D
)) {
340 QualType T
= TD
->getIntegerType();
341 return MakeCXType(T
, 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();
362 unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C
) {
363 using namespace cxcursor
;
365 if (clang_isDeclaration(C
.kind
)) {
366 const Decl
*D
= cxcursor::getCursorDecl(C
);
368 if (const EnumConstantDecl
*TD
= dyn_cast_or_null
<EnumConstantDecl
>(D
)) {
369 return TD
->getInitVal().getZExtValue();
376 int clang_getFieldDeclBitWidth(CXCursor C
) {
377 using namespace cxcursor
;
379 if (clang_isDeclaration(C
.kind
)) {
380 const Decl
*D
= getCursorDecl(C
);
382 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
)) {
383 if (FD
->isBitField() && !FD
->getBitWidth()->isValueDependent())
384 return FD
->getBitWidthValue(getCursorContext(C
));
391 CXType
clang_getCanonicalType(CXType CT
) {
392 if (CT
.kind
== CXType_Invalid
)
395 QualType T
= GetQualType(CT
);
396 CXTranslationUnit TU
= GetTU(CT
);
399 return MakeCXType(QualType(), GetTU(CT
));
401 return MakeCXType(cxtu::getASTUnit(TU
)->getASTContext()
402 .getCanonicalType(T
),
406 unsigned clang_isConstQualifiedType(CXType CT
) {
407 QualType T
= GetQualType(CT
);
408 return T
.isLocalConstQualified();
411 unsigned clang_isVolatileQualifiedType(CXType CT
) {
412 QualType T
= GetQualType(CT
);
413 return T
.isLocalVolatileQualified();
416 unsigned clang_isRestrictQualifiedType(CXType CT
) {
417 QualType T
= GetQualType(CT
);
418 return T
.isLocalRestrictQualified();
421 unsigned clang_getAddressSpace(CXType CT
) {
422 QualType T
= GetQualType(CT
);
424 // For non language-specific address space, use separate helper function.
425 if (T
.getAddressSpace() >= LangAS::FirstTargetAddressSpace
) {
426 return T
.getQualifiers().getAddressSpaceAttributePrintValue();
428 // FIXME: this function returns either a LangAS or a target AS
429 // Those values can overlap which makes this function rather unpredictable
431 return (unsigned)T
.getAddressSpace();
434 CXString
clang_getTypedefName(CXType CT
) {
435 QualType T
= GetQualType(CT
);
436 const TypedefType
*TT
= T
->getAs
<TypedefType
>();
438 TypedefNameDecl
*TD
= TT
->getDecl();
440 return cxstring::createDup(TD
->getNameAsString().c_str());
442 return cxstring::createEmpty();
445 CXType
clang_getPointeeType(CXType CT
) {
446 QualType T
= GetQualType(CT
);
447 const Type
*TP
= T
.getTypePtrOrNull();
450 return MakeCXType(QualType(), GetTU(CT
));
453 switch (TP
->getTypeClass()) {
455 T
= cast
<PointerType
>(TP
)->getPointeeType();
457 case Type::BlockPointer
:
458 T
= cast
<BlockPointerType
>(TP
)->getPointeeType();
460 case Type::LValueReference
:
461 case Type::RValueReference
:
462 T
= cast
<ReferenceType
>(TP
)->getPointeeType();
464 case Type::ObjCObjectPointer
:
465 T
= cast
<ObjCObjectPointerType
>(TP
)->getPointeeType();
467 case Type::MemberPointer
:
468 T
= cast
<MemberPointerType
>(TP
)->getPointeeType();
471 case Type::DeducedTemplateSpecialization
:
472 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
480 return MakeCXType(T
, GetTU(CT
));
483 CXType
clang_getUnqualifiedType(CXType CT
) {
484 return MakeCXType(GetQualType(CT
).getUnqualifiedType(), GetTU(CT
));
487 CXType
clang_getNonReferenceType(CXType CT
) {
488 return MakeCXType(GetQualType(CT
).getNonReferenceType(), GetTU(CT
));
491 CXCursor
clang_getTypeDeclaration(CXType CT
) {
492 if (CT
.kind
== CXType_Invalid
)
493 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
495 QualType T
= GetQualType(CT
);
496 const Type
*TP
= T
.getTypePtrOrNull();
499 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
504 switch (TP
->getTypeClass()) {
506 D
= cast
<TypedefType
>(TP
)->getDecl();
508 case Type::ObjCObject
:
509 D
= cast
<ObjCObjectType
>(TP
)->getInterface();
511 case Type::ObjCInterface
:
512 D
= cast
<ObjCInterfaceType
>(TP
)->getDecl();
516 D
= cast
<TagType
>(TP
)->getDecl();
518 case Type::TemplateSpecialization
:
519 if (const RecordType
*Record
= TP
->getAs
<RecordType
>())
520 D
= Record
->getDecl();
522 D
= cast
<TemplateSpecializationType
>(TP
)->getTemplateName()
523 .getAsTemplateDecl();
527 case Type::DeducedTemplateSpecialization
:
528 TP
= cast
<DeducedType
>(TP
)->getDeducedType().getTypePtrOrNull();
533 case Type::InjectedClassName
:
534 D
= cast
<InjectedClassNameType
>(TP
)->getDecl();
537 // FIXME: Template type parameters!
539 case Type::Elaborated
:
540 TP
= cast
<ElaboratedType
>(TP
)->getNamedType().getTypePtrOrNull();
548 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
550 return cxcursor::MakeCXCursor(D
, GetTU(CT
));
553 CXString
clang_getTypeKindSpelling(enum CXTypeKind K
) {
554 const char *s
= nullptr;
555 #define TKIND(X) case CXType_##X: s = "" #X ""; break
572 case CXType_WChar
: s
= "WChar"; break;
600 TKIND(LValueReference
);
601 TKIND(RValueReference
);
605 TKIND(ObjCInterface
);
607 TKIND(ObjCObjectPointer
);
608 TKIND(ObjCTypeParam
);
609 TKIND(FunctionNoProto
);
610 TKIND(FunctionProto
);
611 TKIND(ConstantArray
);
612 TKIND(IncompleteArray
);
613 TKIND(VariableArray
);
614 TKIND(DependentSizedArray
);
617 TKIND(MemberPointer
);
622 TKIND(BTFTagAttributed
);
623 TKIND(HLSLAttributedResource
);
625 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) TKIND(Id);
626 #include "clang/Basic/OpenCLImageTypes.def"
628 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) TKIND(Id);
629 #include "clang/Basic/OpenCLExtensionTypes.def"
634 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) TKIND(Id);
635 #include "clang/Basic/HLSLIntangibleTypes.def"
639 return cxstring::createRef(s
);
642 unsigned clang_equalTypes(CXType A
, CXType B
) {
643 return A
.data
[0] == B
.data
[0] && A
.data
[1] == B
.data
[1];
646 unsigned clang_isFunctionTypeVariadic(CXType X
) {
647 QualType T
= GetQualType(X
);
651 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>())
652 return (unsigned)FD
->isVariadic();
654 if (T
->getAs
<FunctionNoProtoType
>())
660 CXCallingConv
clang_getFunctionTypeCallingConv(CXType X
) {
661 QualType T
= GetQualType(X
);
663 return CXCallingConv_Invalid
;
665 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>()) {
666 #define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
667 switch (FD
->getCallConv()) {
669 TCALLINGCONV(X86StdCall
);
670 TCALLINGCONV(X86FastCall
);
671 TCALLINGCONV(X86ThisCall
);
672 TCALLINGCONV(X86Pascal
);
673 TCALLINGCONV(X86RegCall
);
674 TCALLINGCONV(X86VectorCall
);
675 TCALLINGCONV(AArch64VectorCall
);
676 TCALLINGCONV(AArch64SVEPCS
);
678 TCALLINGCONV(X86_64SysV
);
680 TCALLINGCONV(AAPCS_VFP
);
681 TCALLINGCONV(IntelOclBicc
);
683 TCALLINGCONV(SwiftAsync
);
684 TCALLINGCONV(PreserveMost
);
685 TCALLINGCONV(PreserveAll
);
686 TCALLINGCONV(M68kRTD
);
687 TCALLINGCONV(PreserveNone
);
688 TCALLINGCONV(RISCVVectorCall
);
689 case CC_SpirFunction
: return CXCallingConv_Unexposed
;
690 case CC_AMDGPUKernelCall
: return CXCallingConv_Unexposed
;
691 case CC_OpenCLKernel
: return CXCallingConv_Unexposed
;
697 return CXCallingConv_Invalid
;
700 int clang_getNumArgTypes(CXType X
) {
701 QualType T
= GetQualType(X
);
705 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
706 return FD
->getNumParams();
709 if (T
->getAs
<FunctionNoProtoType
>()) {
716 CXType
clang_getArgType(CXType X
, unsigned i
) {
717 QualType T
= GetQualType(X
);
719 return MakeCXType(QualType(), GetTU(X
));
721 if (const FunctionProtoType
*FD
= T
->getAs
<FunctionProtoType
>()) {
722 unsigned numParams
= FD
->getNumParams();
724 return MakeCXType(QualType(), GetTU(X
));
726 return MakeCXType(FD
->getParamType(i
), GetTU(X
));
729 return MakeCXType(QualType(), GetTU(X
));
732 CXType
clang_getResultType(CXType X
) {
733 QualType T
= GetQualType(X
);
735 return MakeCXType(QualType(), GetTU(X
));
737 if (const FunctionType
*FD
= T
->getAs
<FunctionType
>())
738 return MakeCXType(FD
->getReturnType(), GetTU(X
));
740 return MakeCXType(QualType(), GetTU(X
));
743 CXType
clang_getCursorResultType(CXCursor C
) {
744 if (clang_isDeclaration(C
.kind
)) {
745 const Decl
*D
= cxcursor::getCursorDecl(C
);
746 if (const ObjCMethodDecl
*MD
= dyn_cast_or_null
<ObjCMethodDecl
>(D
))
747 return MakeCXType(MD
->getReturnType(), cxcursor::getCursorTU(C
));
749 return clang_getResultType(clang_getCursorType(C
));
752 return MakeCXType(QualType(), cxcursor::getCursorTU(C
));
755 // FIXME: We should expose the canThrow(...) result instead of the EST.
756 static CXCursor_ExceptionSpecificationKind
757 getExternalExceptionSpecificationKind(ExceptionSpecificationType EST
) {
760 return CXCursor_ExceptionSpecificationKind_None
;
761 case EST_DynamicNone
:
762 return CXCursor_ExceptionSpecificationKind_DynamicNone
;
764 return CXCursor_ExceptionSpecificationKind_Dynamic
;
766 return CXCursor_ExceptionSpecificationKind_MSAny
;
767 case EST_BasicNoexcept
:
768 return CXCursor_ExceptionSpecificationKind_BasicNoexcept
;
770 return CXCursor_ExceptionSpecificationKind_NoThrow
;
771 case EST_NoexceptFalse
:
772 case EST_NoexceptTrue
:
773 case EST_DependentNoexcept
:
774 return CXCursor_ExceptionSpecificationKind_ComputedNoexcept
;
775 case EST_Unevaluated
:
776 return CXCursor_ExceptionSpecificationKind_Unevaluated
;
777 case EST_Uninstantiated
:
778 return CXCursor_ExceptionSpecificationKind_Uninstantiated
;
780 return CXCursor_ExceptionSpecificationKind_Unparsed
;
782 llvm_unreachable("invalid EST value");
785 int clang_getExceptionSpecificationType(CXType X
) {
786 QualType T
= GetQualType(X
);
790 if (const auto *FD
= T
->getAs
<FunctionProtoType
>())
791 return getExternalExceptionSpecificationKind(FD
->getExceptionSpecType());
796 int clang_getCursorExceptionSpecificationType(CXCursor C
) {
797 if (clang_isDeclaration(C
.kind
))
798 return clang_getExceptionSpecificationType(clang_getCursorType(C
));
803 unsigned clang_isPODType(CXType X
) {
804 QualType T
= GetQualType(X
);
808 CXTranslationUnit TU
= GetTU(X
);
810 return T
.isPODType(cxtu::getASTUnit(TU
)->getASTContext()) ? 1 : 0;
813 CXType
clang_getElementType(CXType CT
) {
814 QualType ET
= QualType();
815 QualType T
= GetQualType(CT
);
816 const Type
*TP
= T
.getTypePtrOrNull();
819 switch (TP
->getTypeClass()) {
820 case Type::ConstantArray
:
821 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
823 case Type::IncompleteArray
:
824 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
826 case Type::VariableArray
:
827 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
829 case Type::DependentSizedArray
:
830 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
833 ET
= cast
<VectorType
> (TP
)->getElementType();
835 case Type::ExtVector
:
836 ET
= cast
<ExtVectorType
>(TP
)->getElementType();
839 ET
= cast
<ComplexType
> (TP
)->getElementType();
845 return MakeCXType(ET
, GetTU(CT
));
848 long long clang_getNumElements(CXType CT
) {
849 long long result
= -1;
850 QualType T
= GetQualType(CT
);
851 const Type
*TP
= T
.getTypePtrOrNull();
854 switch (TP
->getTypeClass()) {
855 case Type::ConstantArray
:
856 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
859 result
= cast
<VectorType
> (TP
)->getNumElements();
861 case Type::ExtVector
:
862 result
= cast
<ExtVectorType
>(TP
)->getNumElements();
871 CXType
clang_getArrayElementType(CXType CT
) {
872 QualType ET
= QualType();
873 QualType T
= GetQualType(CT
);
874 const Type
*TP
= T
.getTypePtrOrNull();
877 switch (TP
->getTypeClass()) {
878 case Type::ConstantArray
:
879 ET
= cast
<ConstantArrayType
> (TP
)->getElementType();
881 case Type::IncompleteArray
:
882 ET
= cast
<IncompleteArrayType
> (TP
)->getElementType();
884 case Type::VariableArray
:
885 ET
= cast
<VariableArrayType
> (TP
)->getElementType();
887 case Type::DependentSizedArray
:
888 ET
= cast
<DependentSizedArrayType
> (TP
)->getElementType();
894 return MakeCXType(ET
, GetTU(CT
));
897 long long clang_getArraySize(CXType CT
) {
898 long long result
= -1;
899 QualType T
= GetQualType(CT
);
900 const Type
*TP
= T
.getTypePtrOrNull();
903 switch (TP
->getTypeClass()) {
904 case Type::ConstantArray
:
905 result
= cast
<ConstantArrayType
> (TP
)->getSize().getSExtValue();
914 static bool isIncompleteTypeWithAlignment(QualType QT
) {
915 return QT
->isIncompleteArrayType() || !QT
->isIncompleteType();
918 long long clang_Type_getAlignOf(CXType T
) {
919 if (T
.kind
== CXType_Invalid
)
920 return CXTypeLayoutError_Invalid
;
921 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
922 QualType QT
= GetQualType(T
);
923 // [expr.alignof] p1: return size_t value for complete object type, reference
925 // [expr.alignof] p3: if reference type, return size of referenced type
926 if (QT
->isReferenceType())
927 QT
= QT
.getNonReferenceType();
928 if (!isIncompleteTypeWithAlignment(QT
))
929 return CXTypeLayoutError_Incomplete
;
930 if (QT
->isDependentType())
931 return CXTypeLayoutError_Dependent
;
932 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
933 if (Deduced
->getDeducedType().isNull())
934 return CXTypeLayoutError_Undeduced
;
935 // Exceptions by GCC extension - see ASTContext.cpp:1313 getTypeInfoImpl
936 // if (QT->isFunctionType()) return 4; // Bug #15511 - should be 1
937 // if (QT->isVoidType()) return 1;
938 return Ctx
.getTypeAlignInChars(QT
).getQuantity();
941 CXType
clang_Type_getClassType(CXType CT
) {
942 QualType ET
= QualType();
943 QualType T
= GetQualType(CT
);
944 const Type
*TP
= T
.getTypePtrOrNull();
946 if (TP
&& TP
->getTypeClass() == Type::MemberPointer
) {
947 ET
= QualType(cast
<MemberPointerType
> (TP
)->getClass(), 0);
949 return MakeCXType(ET
, GetTU(CT
));
952 long long clang_Type_getSizeOf(CXType T
) {
953 if (T
.kind
== CXType_Invalid
)
954 return CXTypeLayoutError_Invalid
;
955 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(T
))->getASTContext();
956 QualType QT
= GetQualType(T
);
957 // [expr.sizeof] p2: if reference type, return size of referenced type
958 if (QT
->isReferenceType())
959 QT
= QT
.getNonReferenceType();
960 // [expr.sizeof] p1: return -1 on: func, incomplete, bitfield, incomplete
962 // Note: We get the cxtype, not the cxcursor, so we can't call
963 // FieldDecl->isBitField()
964 // [expr.sizeof] p3: pointer ok, function not ok.
965 // [gcc extension] lib/AST/ExprConstant.cpp:1372 HandleSizeof : vla == error
966 if (QT
->isIncompleteType())
967 return CXTypeLayoutError_Incomplete
;
968 if (QT
->isDependentType())
969 return CXTypeLayoutError_Dependent
;
970 if (!QT
->isConstantSizeType())
971 return CXTypeLayoutError_NotConstantSize
;
972 if (const auto *Deduced
= dyn_cast
<DeducedType
>(QT
))
973 if (Deduced
->getDeducedType().isNull())
974 return CXTypeLayoutError_Undeduced
;
975 // [gcc extension] lib/AST/ExprConstant.cpp:1372
976 // HandleSizeof : {voidtype,functype} == 1
977 // not handled by ASTContext.cpp:1313 getTypeInfoImpl
978 if (QT
->isVoidType() || QT
->isFunctionType())
980 return Ctx
.getTypeSizeInChars(QT
).getQuantity();
983 static bool isTypeIncompleteForLayout(QualType QT
) {
984 return QT
->isIncompleteType() && !QT
->isIncompleteArrayType();
987 static long long visitRecordForValidation(const RecordDecl
*RD
) {
988 for (const auto *I
: RD
->fields()){
989 QualType FQT
= I
->getType();
990 if (isTypeIncompleteForLayout(FQT
))
991 return CXTypeLayoutError_Incomplete
;
992 if (FQT
->isDependentType())
993 return CXTypeLayoutError_Dependent
;
995 if (const RecordType
*ChildType
= I
->getType()->getAs
<RecordType
>()) {
996 if (const RecordDecl
*Child
= ChildType
->getDecl()) {
997 long long ret
= visitRecordForValidation(Child
);
1002 // else try next field
1007 static long long validateFieldParentType(CXCursor PC
, CXType PT
){
1008 if (clang_isInvalid(PC
.kind
))
1009 return CXTypeLayoutError_Invalid
;
1010 const RecordDecl
*RD
=
1011 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1012 // validate parent declaration
1013 if (!RD
|| RD
->isInvalidDecl())
1014 return CXTypeLayoutError_Invalid
;
1015 RD
= RD
->getDefinition();
1017 return CXTypeLayoutError_Incomplete
;
1018 if (RD
->isInvalidDecl())
1019 return CXTypeLayoutError_Invalid
;
1020 // validate parent type
1021 QualType RT
= GetQualType(PT
);
1022 if (RT
->isIncompleteType())
1023 return CXTypeLayoutError_Incomplete
;
1024 if (RT
->isDependentType())
1025 return CXTypeLayoutError_Dependent
;
1026 // We recurse into all record fields to detect incomplete and dependent types.
1027 long long Error
= visitRecordForValidation(RD
);
1033 long long clang_Type_getOffsetOf(CXType PT
, const char *S
) {
1034 // check that PT is not incomplete/dependent
1035 CXCursor PC
= clang_getTypeDeclaration(PT
);
1036 long long Error
= validateFieldParentType(PC
,PT
);
1040 return CXTypeLayoutError_InvalidFieldName
;
1042 ASTContext
&Ctx
= cxtu::getASTUnit(GetTU(PT
))->getASTContext();
1043 IdentifierInfo
*II
= &Ctx
.Idents
.get(S
);
1044 DeclarationName
FieldName(II
);
1045 const RecordDecl
*RD
=
1046 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1047 // verified in validateFieldParentType
1048 RD
= RD
->getDefinition();
1049 RecordDecl::lookup_result Res
= RD
->lookup(FieldName
);
1050 // If a field of the parent record is incomplete, lookup will fail.
1051 // and we would return InvalidFieldName instead of Incomplete.
1052 // But this erroneous results does protects again a hidden assertion failure
1053 // in the RecordLayoutBuilder
1054 if (!Res
.isSingleResult())
1055 return CXTypeLayoutError_InvalidFieldName
;
1056 if (const FieldDecl
*FD
= dyn_cast
<FieldDecl
>(Res
.front()))
1057 return Ctx
.getFieldOffset(FD
);
1058 if (const IndirectFieldDecl
*IFD
= dyn_cast
<IndirectFieldDecl
>(Res
.front()))
1059 return Ctx
.getFieldOffset(IFD
);
1060 // we don't want any other Decl Type.
1061 return CXTypeLayoutError_InvalidFieldName
;
1064 CXType
clang_Type_getModifiedType(CXType CT
) {
1065 QualType T
= GetQualType(CT
);
1067 return MakeCXType(QualType(), GetTU(CT
));
1069 if (auto *ATT
= T
->getAs
<AttributedType
>())
1070 return MakeCXType(ATT
->getModifiedType(), GetTU(CT
));
1072 if (auto *ATT
= T
->getAs
<BTFTagAttributedType
>())
1073 return MakeCXType(ATT
->getWrappedType(), GetTU(CT
));
1075 return MakeCXType(QualType(), GetTU(CT
));
1078 long long clang_Cursor_getOffsetOfField(CXCursor C
) {
1079 if (clang_isDeclaration(C
.kind
)) {
1080 // we need to validate the parent type
1081 CXCursor PC
= clang_getCursorSemanticParent(C
);
1082 CXType PT
= clang_getCursorType(PC
);
1083 long long Error
= validateFieldParentType(PC
,PT
);
1086 // proceed with the offset calculation
1087 const Decl
*D
= cxcursor::getCursorDecl(C
);
1088 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1089 if (const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(D
))
1090 return Ctx
.getFieldOffset(FD
);
1091 if (const IndirectFieldDecl
*IFD
= dyn_cast_or_null
<IndirectFieldDecl
>(D
))
1092 return Ctx
.getFieldOffset(IFD
);
1097 enum CXRefQualifierKind
clang_Type_getCXXRefQualifier(CXType T
) {
1098 QualType QT
= GetQualType(T
);
1100 return CXRefQualifier_None
;
1101 const FunctionProtoType
*FD
= QT
->getAs
<FunctionProtoType
>();
1103 return CXRefQualifier_None
;
1104 switch (FD
->getRefQualifier()) {
1106 return CXRefQualifier_None
;
1108 return CXRefQualifier_LValue
;
1110 return CXRefQualifier_RValue
;
1112 return CXRefQualifier_None
;
1115 unsigned clang_Cursor_isBitField(CXCursor C
) {
1116 if (!clang_isDeclaration(C
.kind
))
1118 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>(cxcursor::getCursorDecl(C
));
1121 return FD
->isBitField();
1124 CXString
clang_getDeclObjCTypeEncoding(CXCursor C
) {
1125 if (!clang_isDeclaration(C
.kind
))
1126 return cxstring::createEmpty();
1128 const Decl
*D
= cxcursor::getCursorDecl(C
);
1129 ASTContext
&Ctx
= cxcursor::getCursorContext(C
);
1130 std::string encoding
;
1132 if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
1133 encoding
= Ctx
.getObjCEncodingForMethodDecl(OMD
);
1134 } else if (const ObjCPropertyDecl
*OPD
= dyn_cast
<ObjCPropertyDecl
>(D
))
1135 encoding
= Ctx
.getObjCEncodingForPropertyDecl(OPD
, nullptr);
1136 else if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
1137 encoding
= Ctx
.getObjCEncodingForFunctionDecl(FD
);
1140 if (const TypeDecl
*TD
= dyn_cast
<TypeDecl
>(D
))
1141 Ty
= Ctx
.getTypeDeclType(TD
);
1142 if (const ValueDecl
*VD
= dyn_cast
<ValueDecl
>(D
))
1144 else return cxstring::createRef("?");
1145 Ctx
.getObjCEncodingForType(Ty
, encoding
);
1148 return cxstring::createDup(encoding
);
1151 static unsigned GetTemplateArgumentArraySize(ArrayRef
<TemplateArgument
> TA
) {
1152 unsigned size
= TA
.size();
1153 for (const auto &Arg
: TA
)
1154 if (Arg
.getKind() == TemplateArgument::Pack
)
1155 size
+= Arg
.pack_size() - 1;
1159 int clang_Type_getNumTemplateArguments(CXType CT
) {
1160 QualType T
= GetQualType(CT
);
1164 auto TA
= GetTemplateArguments(T
);
1168 return GetTemplateArgumentArraySize(*TA
);
1171 CXType
clang_Type_getTemplateArgumentAsType(CXType CT
, unsigned index
) {
1172 QualType T
= GetQualType(CT
);
1174 return MakeCXType(QualType(), GetTU(CT
));
1176 auto TA
= GetTemplateArguments(T
);
1178 return MakeCXType(QualType(), GetTU(CT
));
1180 std::optional
<QualType
> QT
= FindTemplateArgumentTypeAt(*TA
, index
);
1181 return MakeCXType(QT
.value_or(QualType()), GetTU(CT
));
1184 CXType
clang_Type_getObjCObjectBaseType(CXType CT
) {
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 return MakeCXType(OT
->getBaseType(), GetTU(CT
));
1196 unsigned clang_Type_getNumObjCProtocolRefs(CXType CT
) {
1197 QualType T
= GetQualType(CT
);
1201 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1205 return OT
->getNumProtocols();
1208 CXCursor
clang_Type_getObjCProtocolDecl(CXType CT
, unsigned i
) {
1209 QualType T
= GetQualType(CT
);
1211 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1213 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1215 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1217 const ObjCProtocolDecl
*PD
= OT
->getProtocol(i
);
1219 return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound
);
1221 return cxcursor::MakeCXCursor(PD
, GetTU(CT
));
1224 unsigned clang_Type_getNumObjCTypeArgs(CXType CT
) {
1225 QualType T
= GetQualType(CT
);
1229 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1233 return OT
->getTypeArgs().size();
1236 CXType
clang_Type_getObjCTypeArg(CXType CT
, unsigned i
) {
1237 QualType T
= GetQualType(CT
);
1239 return MakeCXType(QualType(), GetTU(CT
));
1241 const ObjCObjectType
*OT
= dyn_cast
<ObjCObjectType
>(T
);
1243 return MakeCXType(QualType(), GetTU(CT
));
1245 const ArrayRef
<QualType
> TA
= OT
->getTypeArgs();
1246 if ((size_t)i
>= TA
.size())
1247 return MakeCXType(QualType(), GetTU(CT
));
1249 return MakeCXType(TA
[i
], GetTU(CT
));
1252 unsigned clang_Type_visitFields(CXType PT
,
1253 CXFieldVisitor visitor
,
1254 CXClientData client_data
){
1255 CXCursor PC
= clang_getTypeDeclaration(PT
);
1256 if (clang_isInvalid(PC
.kind
))
1258 const RecordDecl
*RD
=
1259 dyn_cast_or_null
<RecordDecl
>(cxcursor::getCursorDecl(PC
));
1260 if (!RD
|| RD
->isInvalidDecl())
1262 RD
= RD
->getDefinition();
1263 if (!RD
|| RD
->isInvalidDecl())
1266 for (RecordDecl::field_iterator I
= RD
->field_begin(), E
= RD
->field_end();
1268 const FieldDecl
*FD
= dyn_cast_or_null
<FieldDecl
>((*I
));
1269 // Callback to the client.
1270 switch (visitor(cxcursor::MakeCXCursor(FD
, GetTU(PT
)), client_data
)){
1273 case CXVisit_Continue
:
1280 unsigned clang_Cursor_isAnonymous(CXCursor C
){
1281 if (!clang_isDeclaration(C
.kind
))
1283 const Decl
*D
= cxcursor::getCursorDecl(C
);
1284 if (const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
)) {
1285 return ND
->isAnonymousNamespace();
1286 } else if (const TagDecl
*TD
= dyn_cast_or_null
<TagDecl
>(D
)) {
1287 return TD
->getTypedefNameForAnonDecl() == nullptr &&
1288 TD
->getIdentifier() == nullptr;
1294 unsigned clang_Cursor_isAnonymousRecordDecl(CXCursor C
){
1295 if (!clang_isDeclaration(C
.kind
))
1297 const Decl
*D
= cxcursor::getCursorDecl(C
);
1298 if (const RecordDecl
*FD
= dyn_cast_or_null
<RecordDecl
>(D
))
1299 return FD
->isAnonymousStructOrUnion();
1303 unsigned clang_Cursor_isInlineNamespace(CXCursor C
) {
1304 if (!clang_isDeclaration(C
.kind
))
1306 const Decl
*D
= cxcursor::getCursorDecl(C
);
1307 const NamespaceDecl
*ND
= dyn_cast_or_null
<NamespaceDecl
>(D
);
1308 return ND
? ND
->isInline() : 0;
1311 CXType
clang_Type_getNamedType(CXType CT
){
1312 QualType T
= GetQualType(CT
);
1313 const Type
*TP
= T
.getTypePtrOrNull();
1315 if (TP
&& TP
->getTypeClass() == Type::Elaborated
)
1316 return MakeCXType(cast
<ElaboratedType
>(TP
)->getNamedType(), GetTU(CT
));
1318 return MakeCXType(QualType(), GetTU(CT
));
1321 unsigned clang_Type_isTransparentTagTypedef(CXType TT
){
1322 QualType T
= GetQualType(TT
);
1323 if (auto *TT
= dyn_cast_or_null
<TypedefType
>(T
.getTypePtrOrNull())) {
1324 if (auto *D
= TT
->getDecl())
1325 return D
->isTransparentTag();
1330 enum CXTypeNullabilityKind
clang_Type_getNullability(CXType CT
) {
1331 QualType T
= GetQualType(CT
);
1333 return CXTypeNullability_Invalid
;
1335 if (auto nullability
= T
->getNullability()) {
1336 switch (*nullability
) {
1337 case NullabilityKind::NonNull
:
1338 return CXTypeNullability_NonNull
;
1339 case NullabilityKind::Nullable
:
1340 return CXTypeNullability_Nullable
;
1341 case NullabilityKind::NullableResult
:
1342 return CXTypeNullability_NullableResult
;
1343 case NullabilityKind::Unspecified
:
1344 return CXTypeNullability_Unspecified
;
1347 return CXTypeNullability_Invalid
;
1350 CXType
clang_Type_getValueType(CXType CT
) {
1351 QualType T
= GetQualType(CT
);
1353 if (T
.isNull() || !T
->isAtomicType())
1354 return MakeCXType(QualType(), GetTU(CT
));
1356 const auto *AT
= T
->castAs
<AtomicType
>();
1357 return MakeCXType(AT
->getValueType(), GetTU(CT
));