17 #ifndef LLVM_CLANG_AST_TYPE_H
18 #define LLVM_CLANG_AST_TYPE_H
33 #include "llvm/ADT/APInt.h"
34 #include "llvm/ADT/APSInt.h"
35 #include "llvm/ADT/ArrayRef.h"
36 #include "llvm/ADT/FoldingSet.h"
37 #include "llvm/ADT/PointerIntPair.h"
38 #include "llvm/ADT/PointerUnion.h"
39 #include "llvm/ADT/StringRef.h"
40 #include "llvm/ADT/Twine.h"
41 #include "llvm/ADT/iterator_range.h"
42 #include "llvm/Support/Casting.h"
43 #include "llvm/Support/Compiler.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/PointerLikeTypeTraits.h"
46 #include "llvm/Support/TrailingObjects.h"
47 #include "llvm/Support/type_traits.h"
54 #include <type_traits>
64 class TemplateParameterList;
72 namespace serialization {
73 template <
class T>
class AbstractTypeReader;
110 template <
typename>
class CanQual;
115 class ExtQualsTypeCommonBase;
117 class IdentifierInfo;
119 class ObjCInterfaceDecl;
120 class ObjCProtocolDecl;
121 class ObjCTypeParamDecl;
122 struct PrintingPolicy;
126 class TemplateArgument;
127 class TemplateArgumentListInfo;
128 class TemplateArgumentLoc;
129 class TemplateTypeParmDecl;
130 class TypedefNameDecl;
131 class UnresolvedUsingTypenameDecl;
132 class UsingShadowDecl;
137 #define TYPE(Class, Base) class Class##Type;
138 #include "clang/AST/TypeNodes.inc"
201 Q.Mask = L.Mask & R.Mask;
298 assert(!(mask & ~
CVRMask) &&
"bitmask contains non-CVR bits");
299 Mask = (Mask & ~
CVRMask) | mask;
302 assert(!(mask & ~
CVRMask) &&
"bitmask contains non-CVR bits");
309 assert(!(mask & ~
CVRMask) &&
"bitmask contains non-CVR bits");
313 assert(!(mask & ~
CVRMask & ~UMask) &&
"bitmask contains non-CVRU bits");
319 Mask = (Mask & ~UMask) | (flag ? UMask : 0);
327 Mask = (Mask & ~GCAttrMask) | (
type << GCAttrShift);
352 return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
355 Mask = (Mask & ~LifetimeMask) | (
type << LifetimeShift);
361 Mask |= (
type << LifetimeShift);
378 return static_cast<LangAS>(Mask >> AddressSpaceShift);
399 Mask = (Mask & ~AddressSpaceMask)
400 | (((uint32_t) space) << AddressSpaceShift);
413 assert(!(mask & ~
FastMask) &&
"bitmask contains non-fast qualifier bits");
417 assert(!(mask & ~
FastMask) &&
"bitmask contains non-fast qualifier bits");
424 assert(!(mask & ~
FastMask) &&
"bitmask contains non-fast qualifier bits");
439 bool empty()
const {
return !Mask; }
604 bool appendSpaceIfNonEmpty =
false)
const;
615 static const uint32_t UMask = 0x8;
616 static const uint32_t UShift = 3;
617 static const uint32_t GCAttrMask = 0x30;
618 static const uint32_t GCAttrShift = 4;
619 static const uint32_t LifetimeMask = 0x1C0;
620 static const uint32_t LifetimeShift = 6;
621 static const uint32_t AddressSpaceMask =
622 ~(
CVRMask | UMask | GCAttrMask | LifetimeMask);
623 static const uint32_t AddressSpaceShift = 9;
633 : Quals(Quals), HasAtomic(HasAtomic) {}
682 std::pair<const Type *,Qualifiers>
asPair()
const {
683 return std::pair<const Type *, Qualifiers>(
Ty,
Quals);
687 return a.
Ty ==
b.Ty && a.
Quals ==
b.Quals;
690 return a.
Ty !=
b.Ty || a.
Quals !=
b.Quals;
740 llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>,
743 const ExtQuals *getExtQualsUnsafe()
const {
747 const Type *getTypePtrUnsafe()
const {
748 return Value.getPointer().get<
const Type*>();
751 const ExtQualsTypeCommonBase *getCommonPtr()
const {
752 assert(!
isNull() &&
"Cannot retrieve a NULL type pointer");
753 auto CommonPtrVal =
reinterpret_cast<uintptr_t>(
Value.getOpaqueValue());
755 return reinterpret_cast<ExtQualsTypeCommonBase*
>(CommonPtrVal);
787 T.Value.setFromOpaqueValue(
const_cast<void*
>(Ptr));
804 return Value.getPointer().isNull();
941 &&
"non-fast qualifier bits set in mask!");
1067 return getSingleStepDesugaredTypeImpl(*
this, Context);
1073 if (isa<ParenType>(*
this))
1080 return LHS.Value == RHS.Value;
1083 return LHS.Value != RHS.Value;
1086 return LHS.Value < RHS.Value;
1100 const Twine &PlaceHolder = Twine(),
1101 unsigned Indentation = 0)
const;
1105 unsigned Indentation = 0) {
1111 const Twine &PlaceHolder,
1112 unsigned Indentation = 0);
1129 const Twine &PlaceHolder;
1130 unsigned Indentation;
1134 const Twine &PlaceHolder,
unsigned Indentation)
1135 : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
1136 Indentation(Indentation) {}
1140 SQT.T.
print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation);
1146 const Twine &PlaceHolder = Twine(),
1147 unsigned Indentation = 0)
const {
1151 void dump(
const char *
s)
const;
1153 void dump(llvm::raw_ostream &OS,
const ASTContext &Context)
const;
1289 return isDestructedTypeImpl(*
this);
1387 raw_ostream &
operator<<(raw_ostream &OS, QualType QT);
1407 return P.getAsOpaquePtr();
1415 static constexpr
int NumLowBitsAvailable = 0;
1435 const Type *
const BaseType;
1441 : BaseType(baseType), CanonicalType(canon) {}
1477 canon.isNull() ?
QualType(this_(), 0) : canon),
1480 &&
"ExtQuals created with no fast qualifiers");
1482 &&
"ExtQuals created with fast qualifiers");
1506 const Type *BaseType,
1509 ID.AddPointer(BaseType);
1569 #define TYPE(Class, Base) Class,
1570 #define LAST_TYPE(Class) TypeLast = Class
1571 #define ABSTRACT_TYPE(Class, Base)
1572 #include "clang/AST/TypeNodes.inc"
1577 class TypeBitfields {
1585 unsigned Dependence : llvm::BitWidth<TypeDependence>;
1589 mutable unsigned CacheValid : 1;
1592 mutable unsigned CachedLinkage : 3;
1595 mutable unsigned CachedLocalOrUnnamed : 1;
1598 mutable unsigned FromAST : 1;
1600 bool isCacheValid()
const {
1605 assert(isCacheValid() &&
"getting linkage from invalid cache");
1606 return static_cast<Linkage>(CachedLinkage);
1609 bool hasLocalOrUnnamedType()
const {
1610 assert(isCacheValid() &&
"getting linkage from invalid cache");
1611 return CachedLocalOrUnnamed;
1614 enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 };
1627 unsigned IndexTypeQuals : 3;
1632 unsigned SizeModifier : 3;
1641 unsigned HasStoredSizeExpr : 1;
1664 unsigned ExtInfo : 13;
1669 unsigned RefQualifier : 2;
1679 unsigned HasExtQuals : 1;
1685 unsigned NumParams : 16;
1688 unsigned ExceptionSpecType : 4;
1691 unsigned HasExtParameterInfos : 1;
1694 unsigned HasExtraBitfields : 1;
1697 unsigned Variadic : 1;
1700 unsigned HasTrailingReturn : 1;
1709 unsigned NumTypeArgs : 7;
1712 unsigned NumProtocols : 6;
1715 unsigned IsKindOf : 1;
1734 unsigned SpelledAsLValue : 1;
1738 unsigned InnerRef : 1;
1747 unsigned Keyword : 8;
1759 unsigned HasOwnedTagDecl : 1;
1770 unsigned VecKind : 3;
1772 uint32_t NumElements;
1781 unsigned AttrKind : 32 - NumTypeBits;
1791 unsigned Keyword : 2;
1808 unsigned IsUnqual : 1;
1817 unsigned hasTypeDifferentFromDecl : 1;
1826 unsigned hasTypeDifferentFromDecl : 1;
1834 unsigned HasNonCanonicalUnderlyingType : 1;
1837 unsigned Index : 15;
1844 unsigned PackIndex : 16;
1853 unsigned Index : 16;
1859 unsigned NumArgs : 16;
1868 unsigned TypeAlias : 1;
1912 unsigned NumExpansions;
1943 void setFromAST(
bool V =
true)
const {
1954 "changing bitfields changed sizeof(Type)!");
1955 static_assert(
alignof(decltype(*
this)) %
sizeof(
void *) == 0,
1956 "Insufficient alignment!");
1960 TypeBits.CachedLocalOrUnnamed =
false;
1969 TypeBits.Dependence =
static_cast<unsigned>(D);
2012 return CanonicalType ==
QualType(
this, 0);
2204 return hasAttr(attr::ObjCInertUnsafeUnretained);
2243 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2244 bool is##Id##Type() const;
2245 #include "clang/Basic/OpenCLImageTypes.def"
2255 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2256 bool is##Id##Type() const;
2257 #include "clang/Basic/OpenCLExtensionTypes.def"
2428 template <
typename T>
const T *
getAs()
const;
2447 template <
typename T>
const T *
castAs()
const;
2579 std::optional<ArrayRef<QualType>>
2589 return CanonicalType;
2594 void dump(llvm::raw_ostream &OS,
const ASTContext &Context)
const;
2599 template <>
const TypedefType *
Type::getAs()
const;
2605 template <>
const TemplateSpecializationType *
Type::getAs()
const;
2609 template <>
const AttributedType *
Type::getAs()
const;
2613 #define TYPE(Class, Base)
2614 #define LEAF_TYPE(Class) \
2615 template <> inline const Class##Type *Type::getAs() const { \
2616 return dyn_cast<Class##Type>(CanonicalType); \
2618 template <> inline const Class##Type *Type::castAs() const { \
2619 return cast<Class##Type>(CanonicalType); \
2621 #include "clang/AST/TypeNodes.inc"
2629 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id,
2630 #include "clang/Basic/OpenCLImageTypes.def"
2632 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
2633 #include "clang/Basic/OpenCLExtensionTypes.def"
2635 #define SVE_TYPE(Name, Id, SingletonId) Id,
2636 #include "clang/Basic/AArch64SVEACLETypes.def"
2638 #define PPC_VECTOR_TYPE(Name, Id, Size) Id,
2639 #include "clang/Basic/PPCTypes.def"
2641 #define RVV_TYPE(Name, Id, SingletonId) Id,
2642 #include "clang/Basic/RISCVVTypes.def"
2644 #define BUILTIN_TYPE(Id, SingletonId) Id,
2645 #define LAST_BUILTIN_TYPE(Id) LastKind = Id
2646 #include "clang/AST/BuiltinTypes.def"
2665 StringRef str =
getName(Policy);
2666 assert(!str.empty() && str.data()[str.size()] ==
'\0');
2693 return K >= Overload;
2728 ElementType(Element) {}
2781 PointeeType(Pointee) {}
2813 OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
2862 PointeeType(Pointee) {}
2890 bool SpelledAsLValue)
2892 PointeeType(Referencee) {
2908 return T->PointeeType;
2917 bool SpelledAsLValue) {
2919 ID.AddBoolean(SpelledAsLValue);
2933 bool SpelledAsLValue)
2975 :
Type(MemberPointer, CanonicalPtr,
2978 PointeeType(Pointee), Class(Cls) {}
3006 const Type *Class) {
3008 ID.AddPointer(Class);
3035 unsigned tq,
const Expr *sz =
nullptr);
3065 private llvm::TrailingObjects<ConstantArrayType, const Expr *> {
3067 friend TrailingObjects;
3073 :
ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) {
3076 assert(!can.
isNull() &&
"canonical constant array should not have size");
3077 *getTrailingObjects<const Expr*>() = sz;
3081 unsigned numTrailingObjects(OverloadToken<const Expr*>)
const {
3089 ? *getTrailingObjects<const Expr *>()
3113 unsigned TypeQuals);
3128 :
ArrayType(IncompleteArray, et, can, sm, tq) {}
3148 ID.AddInteger(SizeMod);
3149 ID.AddInteger(TypeQuals);
3180 :
ArrayType(VariableArray, et, can, sm, tq, e),
3181 SizeExpr((
Stmt*) e), Brackets(brackets) {}
3189 return (
Expr*) SizeExpr;
3204 llvm_unreachable(
"Cannot unique VariableArrayTypes.");
3246 return (
Expr*) SizeExpr;
3267 unsigned TypeQuals,
Expr *E);
3285 Expr *AddrSpaceExpr;
3423 ID.AddInteger(NumElements);
3425 ID.AddInteger(VecKind);
3494 case 'x':
case 'r':
return 0;
3495 case 'y':
case 'g':
return 1;
3496 case 'z':
case 'b':
return 2;
3497 case 'w':
case 'a':
return 3;
3515 case 'a':
return 10;
3517 case 'b':
return 11;
3519 case 'c':
return 12;
3521 case 'd':
return 13;
3523 case 'e':
return 14;
3525 case 'f':
return 15;
3530 if (isNumericAccessor)
3563 const Expr *RowExpr =
nullptr,
const Expr *ColumnExpr =
nullptr);
3600 unsigned NColumns,
QualType CanonElementType);
3603 unsigned NColumns,
QualType CanonElementType);
3710 HasPassObjSize = 0x20,
3713 unsigned char Data = 0;
3722 copy.Data = (copy.Data & ~ABIMask) |
unsigned(
kind);
3732 copy.Data |= IsConsumed;
3734 copy.Data &= ~IsConsumed;
3741 Copy.Data |= HasPassObjSize;
3749 Copy.Data |= IsNoEscape;
3751 Copy.Data &= ~IsNoEscape;
3763 return lhs.Data == rhs.Data;
3767 return lhs.Data != rhs.Data;
3802 enum { CallConvMask = 0x1F };
3803 enum { NoReturnMask = 0x20 };
3804 enum { ProducesResultMask = 0x40 };
3805 enum { NoCallerSavedRegsMask = 0x80 };
3807 RegParmMask = 0x700,
3810 enum { NoCfCheckMask = 0x800 };
3811 enum { CmseNSCallMask = 0x1000 };
3812 uint16_t Bits =
CC_C;
3814 ExtInfo(
unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
3820 bool producesResult,
bool noCallerSavedRegs,
bool NoCfCheck,
3822 assert((!hasRegParm || regParm < 7) &&
"Invalid regparm value");
3823 Bits = ((
unsigned)cc) | (noReturn ? NoReturnMask : 0) |
3824 (producesResult ? ProducesResultMask : 0) |
3825 (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
3826 (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
3827 (NoCfCheck ? NoCfCheckMask : 0) |
3828 (cmseNSCall ? CmseNSCallMask : 0);
3844 bool getHasRegParm()
const {
return ((Bits & RegParmMask) >> RegParmOffset) != 0; }
3847 unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
3856 return Bits == Other.Bits;
3859 return Bits != Other.Bits;
3867 return ExtInfo(Bits | NoReturnMask);
3869 return ExtInfo(Bits & ~NoReturnMask);
3874 return ExtInfo(Bits | ProducesResultMask);
3876 return ExtInfo(Bits & ~ProducesResultMask);
3881 return ExtInfo(Bits | CmseNSCallMask);
3883 return ExtInfo(Bits & ~CmseNSCallMask);
3887 if (noCallerSavedRegs)
3888 return ExtInfo(Bits | NoCallerSavedRegsMask);
3890 return ExtInfo(Bits & ~NoCallerSavedRegsMask);
3895 return ExtInfo(Bits | NoCfCheckMask);
3897 return ExtInfo(Bits & ~NoCfCheckMask);
3901 assert(RegParm < 7 &&
"Invalid regparm value");
3902 return ExtInfo((Bits & ~RegParmMask) |
3903 ((RegParm + 1) << RegParmOffset));
3907 return ExtInfo((Bits & ~CallConvMask) | (
unsigned) cc);
3911 ID.AddInteger(Bits);
3960 "Const, volatile and restrict are assumed to be a subset of "
3961 "the fast qualifiers.");
4023 public llvm::FoldingSetNode,
4024 private llvm::TrailingObjects<
4025 FunctionProtoType, QualType, SourceLocation,
4026 FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
4027 Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
4029 friend TrailingObjects;
4121 Result.ExceptionSpec = ESI;
4131 unsigned numTrailingObjects(OverloadToken<QualType>)
const {
4135 unsigned numTrailingObjects(OverloadToken<SourceLocation>)
const {
4139 unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>)
const {
4140 return hasExtraBitfields();
4143 unsigned numTrailingObjects(OverloadToken<ExceptionType>)
const {
4144 return getExceptionSpecSize().NumExceptionType;
4147 unsigned numTrailingObjects(OverloadToken<Expr *>)
const {
4148 return getExceptionSpecSize().NumExprPtr;
4151 unsigned numTrailingObjects(OverloadToken<FunctionDecl *>)
const {
4152 return getExceptionSpecSize().NumFunctionDeclPtr;
4155 unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>)
const {
4161 static bool containsAnyUnexpandedParameterPack(
const QualType *ArgArray,
4163 for (
unsigned Idx = 0; Idx < numArgs; ++Idx)
4170 FunctionProtoType(
QualType result, ArrayRef<QualType> params,
4171 QualType canonical,
const ExtProtoInfo &epi);
4176 struct ExceptionSpecSizeHolder {
4177 unsigned NumExceptionType;
4178 unsigned NumExprPtr;
4179 unsigned NumFunctionDeclPtr;
4184 static ExceptionSpecSizeHolder
4196 return {NumExceptions, 0, 0};
4209 llvm_unreachable(
"bad exception specification kind");
4214 ExceptionSpecSizeHolder getExceptionSpecSize()
const {
4219 bool hasExtraBitfields()
const {
4222 "ExtraBitfields are required for given ExceptionSpecType");
4227 bool hasExtQualifiers()
const {
4235 assert(i <
getNumParams() &&
"invalid parameter index");
4302 ? getTrailingObjects<FunctionTypeExtraBitfields>()
4318 return *getTrailingObjects<Expr *>();
4329 return getTrailingObjects<FunctionDecl *>()[0];
4339 return getTrailingObjects<FunctionDecl *>()[1];
4357 return isVariadic() ? *getTrailingObjects<SourceLocation>()
4373 if (hasExtQualifiers())
4374 return *getTrailingObjects<Qualifiers>();
4391 return getTrailingObjects<QualType>();
4406 getTrailingObjects<ExceptionType>());
4431 return getTrailingObjects<ExtParameterInfo>();
4435 assert(I <
getNumParams() &&
"parameter index out of range");
4437 return getTrailingObjects<ExtParameterInfo>()[I];
4442 assert(I <
getNumParams() &&
"parameter index out of range");
4444 return getTrailingObjects<ExtParameterInfo>()[I].getABI();
4449 assert(I <
getNumParams() &&
"parameter index out of range");
4451 return getTrailingObjects<ExtParameterInfo>()[I].isConsumed();
4468 const ExtProtoInfo &EPI,
const ASTContext &Context,
4508 public llvm::FoldingSetNode,
4509 private llvm::TrailingObjects<UsingType, QualType> {
4512 friend TrailingObjects;
4533 ID.AddPointer(Found);
4534 if (!Underlying.
isNull())
4541 public llvm::FoldingSetNode,
4542 private llvm::TrailingObjects<TypedefType, QualType> {
4545 friend TrailingObjects;
4567 if (!Underlying.
isNull())
4585 UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
4586 assert(isa<AttributedType>(UnderlyingTy) &&
4587 "Expected a macro qualified type to only wrap attributed types.");
4654 Expr *E,
bool IsUnqual);
4741 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum,
4742 #include "clang/Basic/TransformTypeTraits.def"
4781 public llvm::FoldingSetNode {