aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/Type.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Type.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/Type.cpp907
1 files changed, 668 insertions, 239 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Type.cpp b/contrib/llvm-project/clang/lib/AST/Type.cpp
index 4a2fc5219ef0..d4103025591e 100644
--- a/contrib/llvm-project/clang/lib/AST/Type.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Type.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DependenceFlags.h"
@@ -42,15 +43,16 @@
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
+#include <optional>
#include <type_traits>
using namespace clang;
@@ -110,6 +112,25 @@ bool QualType::isConstant(QualType T, const ASTContext &Ctx) {
return T.getAddressSpace() == LangAS::opencl_constant;
}
+std::optional<QualType::NonConstantStorageReason>
+QualType::isNonConstantStorage(const ASTContext &Ctx, bool ExcludeCtor,
+ bool ExcludeDtor) {
+ if (!isConstant(Ctx) && !(*this)->isReferenceType())
+ return NonConstantStorageReason::NonConstNonReferenceType;
+ if (!Ctx.getLangOpts().CPlusPlus)
+ return std::nullopt;
+ if (const CXXRecordDecl *Record =
+ Ctx.getBaseElementType(*this)->getAsCXXRecordDecl()) {
+ if (!ExcludeCtor)
+ return NonConstantStorageReason::NonTrivialCtor;
+ if (Record->hasMutableFields())
+ return NonConstantStorageReason::MutableField;
+ if (!Record->hasTrivialDestructor() && !ExcludeDtor)
+ return NonConstantStorageReason::NonTrivialDtor;
+ }
+ return std::nullopt;
+}
+
// C++ [temp.dep.type]p1:
// A type is dependent if it is...
// - an array type constructed from any dependent type or whose
@@ -135,7 +156,7 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can,
: TypeDependence::None)),
ElementType(et) {
ArrayTypeBits.IndexTypeQuals = tq;
- ArrayTypeBits.SizeModifier = sm;
+ ArrayTypeBits.SizeModifier = llvm::to_underlying(sm);
}
unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
@@ -158,7 +179,7 @@ unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
if ((ElementSize >> 32) == 0 && NumElements.getBitWidth() <= 64 &&
(NumElements.getZExtValue() >> 32) == 0) {
uint64_t TotalSize = NumElements.getZExtValue() * ElementSize;
- return 64 - llvm::countLeadingZeros(TotalSize);
+ return llvm::bit_width(TotalSize);
}
// Otherwise, use APSInt to handle arbitrary sized values.
@@ -173,6 +194,11 @@ unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context,
return TotalSize.getActiveBits();
}
+unsigned
+ConstantArrayType::getNumAddressingBits(const ASTContext &Context) const {
+ return getNumAddressingBits(Context, getElementType(), getSize());
+}
+
unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) {
unsigned Bits = Context.getTypeSize(Context.getSizeType());
@@ -192,20 +218,19 @@ void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID,
unsigned TypeQuals) {
ID.AddPointer(ET.getAsOpaquePtr());
ID.AddInteger(ArraySize.getZExtValue());
- ID.AddInteger(SizeMod);
+ ID.AddInteger(llvm::to_underlying(SizeMod));
ID.AddInteger(TypeQuals);
- ID.AddBoolean(SizeExpr != 0);
+ ID.AddBoolean(SizeExpr != nullptr);
if (SizeExpr)
SizeExpr->Profile(ID, Context, true);
}
-DependentSizedArrayType::DependentSizedArrayType(const ASTContext &Context,
- QualType et, QualType can,
+DependentSizedArrayType::DependentSizedArrayType(QualType et, QualType can,
Expr *e, ArraySizeModifier sm,
unsigned tq,
SourceRange brackets)
- : ArrayType(DependentSizedArray, et, can, sm, tq, e),
- Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
+ : ArrayType(DependentSizedArray, et, can, sm, tq, e), SizeExpr((Stmt *)e),
+ Brackets(brackets) {}
void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context,
@@ -214,44 +239,42 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
unsigned TypeQuals,
Expr *E) {
ID.AddPointer(ET.getAsOpaquePtr());
- ID.AddInteger(SizeMod);
+ ID.AddInteger(llvm::to_underlying(SizeMod));
ID.AddInteger(TypeQuals);
E->Profile(ID, Context, true);
}
-DependentVectorType::DependentVectorType(const ASTContext &Context,
- QualType ElementType,
+DependentVectorType::DependentVectorType(QualType ElementType,
QualType CanonType, Expr *SizeExpr,
- SourceLocation Loc,
- VectorType::VectorKind VecKind)
+ SourceLocation Loc, VectorKind VecKind)
: Type(DependentVector, CanonType,
TypeDependence::DependentInstantiation |
ElementType->getDependence() |
(SizeExpr ? toTypeDependence(SizeExpr->getDependence())
: TypeDependence::None)),
- Context(Context), ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) {
- VectorTypeBits.VecKind = VecKind;
+ ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) {
+ VectorTypeBits.VecKind = llvm::to_underlying(VecKind);
}
void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context,
QualType ElementType, const Expr *SizeExpr,
- VectorType::VectorKind VecKind) {
+ VectorKind VecKind) {
ID.AddPointer(ElementType.getAsOpaquePtr());
- ID.AddInteger(VecKind);
+ ID.AddInteger(llvm::to_underlying(VecKind));
SizeExpr->Profile(ID, Context, true);
}
-DependentSizedExtVectorType::DependentSizedExtVectorType(
- const ASTContext &Context, QualType ElementType, QualType can,
- Expr *SizeExpr, SourceLocation loc)
+DependentSizedExtVectorType::DependentSizedExtVectorType(QualType ElementType,
+ QualType can,
+ Expr *SizeExpr,
+ SourceLocation loc)
: Type(DependentSizedExtVector, can,
TypeDependence::DependentInstantiation |
ElementType->getDependence() |
(SizeExpr ? toTypeDependence(SizeExpr->getDependence())
: TypeDependence::None)),
- Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {
-}
+ SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) {}
void
DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
@@ -261,8 +284,7 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
SizeExpr->Profile(ID, Context, true);
}
-DependentAddressSpaceType::DependentAddressSpaceType(const ASTContext &Context,
- QualType PointeeType,
+DependentAddressSpaceType::DependentAddressSpaceType(QualType PointeeType,
QualType can,
Expr *AddrSpaceExpr,
SourceLocation loc)
@@ -271,8 +293,7 @@ DependentAddressSpaceType::DependentAddressSpaceType(const ASTContext &Context,
PointeeType->getDependence() |
(AddrSpaceExpr ? toTypeDependence(AddrSpaceExpr->getDependence())
: TypeDependence::None)),
- Context(Context), AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType),
- loc(loc) {}
+ AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType), loc(loc) {}
void DependentAddressSpaceType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context,
@@ -311,12 +332,14 @@ ConstantMatrixType::ConstantMatrixType(TypeClass tc, QualType matrixType,
: MatrixType(tc, matrixType, canonType), NumRows(nRows),
NumColumns(nColumns) {}
-DependentSizedMatrixType::DependentSizedMatrixType(
- const ASTContext &CTX, QualType ElementType, QualType CanonicalType,
- Expr *RowExpr, Expr *ColumnExpr, SourceLocation loc)
+DependentSizedMatrixType::DependentSizedMatrixType(QualType ElementType,
+ QualType CanonicalType,
+ Expr *RowExpr,
+ Expr *ColumnExpr,
+ SourceLocation loc)
: MatrixType(DependentSizedMatrix, ElementType, CanonicalType, RowExpr,
ColumnExpr),
- Context(CTX), RowExpr(RowExpr), ColumnExpr(ColumnExpr), loc(loc) {}
+ RowExpr(RowExpr), ColumnExpr(ColumnExpr), loc(loc) {}
void DependentSizedMatrixType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &CTX,
@@ -334,29 +357,28 @@ VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType, VectorKind vecKind)
: Type(tc, canonType, vecType->getDependence()), ElementType(vecType) {
- VectorTypeBits.VecKind = vecKind;
+ VectorTypeBits.VecKind = llvm::to_underlying(vecKind);
VectorTypeBits.NumElements = nElements;
}
-ExtIntType::ExtIntType(bool IsUnsigned, unsigned NumBits)
- : Type(ExtInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
+BitIntType::BitIntType(bool IsUnsigned, unsigned NumBits)
+ : Type(BitInt, QualType{}, TypeDependence::None), IsUnsigned(IsUnsigned),
NumBits(NumBits) {}
-DependentExtIntType::DependentExtIntType(const ASTContext &Context,
- bool IsUnsigned, Expr *NumBitsExpr)
- : Type(DependentExtInt, QualType{},
+DependentBitIntType::DependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr)
+ : Type(DependentBitInt, QualType{},
toTypeDependence(NumBitsExpr->getDependence())),
- Context(Context), ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
+ ExprAndUnsigned(NumBitsExpr, IsUnsigned) {}
-bool DependentExtIntType::isUnsigned() const {
+bool DependentBitIntType::isUnsigned() const {
return ExprAndUnsigned.getInt();
}
-clang::Expr *DependentExtIntType::getNumBitsExpr() const {
+clang::Expr *DependentBitIntType::getNumBitsExpr() const {
return ExprAndUnsigned.getPointer();
}
-void DependentExtIntType::Profile(llvm::FoldingSetNodeID &ID,
+void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, bool IsUnsigned,
Expr *NumBitsExpr) {
ID.AddBoolean(IsUnsigned);
@@ -525,6 +547,10 @@ template <> const TypedefType *Type::getAs() const {
return getAsSugar<TypedefType>(this);
}
+template <> const UsingType *Type::getAs() const {
+ return getAsSugar<UsingType>(this);
+}
+
template <> const TemplateSpecializationType *Type::getAs() const {
return getAsSugar<TemplateSpecializationType>(this);
}
@@ -722,8 +748,7 @@ bool Type::isObjCClassOrClassKindOfType() const {
ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can,
ArrayRef<ObjCProtocolDecl *> protocols)
- : Type(ObjCTypeParam, can,
- can->getDependence() & ~TypeDependence::UnexpandedPack),
+ : Type(ObjCTypeParam, can, toSemanticDependence(can->getDependence())),
OTPDecl(const_cast<ObjCTypeParamDecl *>(D)) {
initialize(protocols);
}
@@ -821,6 +846,13 @@ QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
/*isKindOf=*/false);
}
+ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
+ ObjCInterfaceDecl *Canon = Decl->getCanonicalDecl();
+ if (ObjCInterfaceDecl *Def = Canon->getDefinition())
+ return Def;
+ return Canon;
+}
+
const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
const ASTContext &ctx) const {
if (!isKindOfType() && qual_empty())
@@ -1067,7 +1099,7 @@ public:
if (exceptionChanged) {
info.ExceptionSpec.Exceptions =
- llvm::makeArrayRef(exceptionTypes).copy(Ctx);
+ llvm::ArrayRef(exceptionTypes).copy(Ctx);
}
}
@@ -1160,8 +1192,9 @@ public:
== T->getReplacementType().getAsOpaquePtr())
return QualType(T, 0);
- return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),
- replacementType);
+ return Ctx.getSubstTemplateTypeParmType(replacementType,
+ T->getAssociatedDecl(),
+ T->getIndex(), T->getPackIndex());
}
// FIXME: Non-trivial to implement, but important for C++
@@ -1208,10 +1241,10 @@ public:
!typeArgChanged)
return QualType(T, 0);
- return Ctx.getObjCObjectType(baseType, typeArgs,
- llvm::makeArrayRef(T->qual_begin(),
- T->getNumProtocols()),
- T->isKindOfTypeAsWritten());
+ return Ctx.getObjCObjectType(
+ baseType, typeArgs,
+ llvm::ArrayRef(T->qual_begin(), T->getNumProtocols()),
+ T->isKindOfTypeAsWritten());
}
TRIVIAL_TYPE_CLASS(ObjCInterface)
@@ -1363,7 +1396,7 @@ struct SubstObjCTypeArgsVisitor
if (exceptionChanged) {
info.ExceptionSpec.Exceptions =
- llvm::makeArrayRef(exceptionTypes).copy(Ctx);
+ llvm::ArrayRef(exceptionTypes).copy(Ctx);
}
}
@@ -1473,6 +1506,39 @@ struct StripObjCKindOfTypeVisitor
} // namespace
+bool QualType::UseExcessPrecision(const ASTContext &Ctx) {
+ const BuiltinType *BT = getTypePtr()->getAs<BuiltinType>();
+ if (!BT) {
+ const VectorType *VT = getTypePtr()->getAs<VectorType>();
+ if (VT) {
+ QualType ElementType = VT->getElementType();
+ return ElementType.UseExcessPrecision(Ctx);
+ }
+ } else {
+ switch (BT->getKind()) {
+ case BuiltinType::Kind::Float16: {
+ const TargetInfo &TI = Ctx.getTargetInfo();
+ if (TI.hasFloat16Type() && !TI.hasLegalHalfType() &&
+ Ctx.getLangOpts().getFloat16ExcessPrecision() !=
+ Ctx.getLangOpts().ExcessPrecisionKind::FPP_None)
+ return true;
+ break;
+ }
+ case BuiltinType::Kind::BFloat16: {
+ const TargetInfo &TI = Ctx.getTargetInfo();
+ if (TI.hasBFloat16Type() && !TI.hasFullBFloat16Type() &&
+ Ctx.getLangOpts().getBFloat16ExcessPrecision() !=
+ Ctx.getLangOpts().ExcessPrecisionKind::FPP_None)
+ return true;
+ break;
+ }
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
/// Substitute the given type arguments for Objective-C type
/// parameters within the given type, recursively.
QualType QualType::substObjCTypeArgs(ASTContext &ctx,
@@ -1504,8 +1570,8 @@ QualType QualType::getAtomicUnqualifiedType() const {
return getUnqualifiedType();
}
-Optional<ArrayRef<QualType>> Type::getObjCSubstitutions(
- const DeclContext *dc) const {
+std::optional<ArrayRef<QualType>>
+Type::getObjCSubstitutions(const DeclContext *dc) const {
// Look through method scopes.
if (const auto method = dyn_cast<ObjCMethodDecl>(dc))
dc = method->getDeclContext();
@@ -1520,23 +1586,23 @@ Optional<ArrayRef<QualType>> Type::getObjCSubstitutions(
// substitution to do.
dcTypeParams = dcClassDecl->getTypeParamList();
if (!dcTypeParams)
- return None;
+ return std::nullopt;
} else {
// If we are in neither a class nor a category, there's no
// substitution to perform.
dcCategoryDecl = dyn_cast<ObjCCategoryDecl>(dc);
if (!dcCategoryDecl)
- return None;
+ return std::nullopt;
// If the category does not have any type parameters, there's no
// substitution to do.
dcTypeParams = dcCategoryDecl->getTypeParamList();
if (!dcTypeParams)
- return None;
+ return std::nullopt;
dcClassDecl = dcCategoryDecl->getClassInterface();
if (!dcClassDecl)
- return None;
+ return std::nullopt;
}
assert(dcTypeParams && "No substitutions to perform");
assert(dcClassDecl && "No class context");
@@ -1885,15 +1951,26 @@ DeducedType *Type::getContainedDeducedType() const {
}
bool Type::hasAutoForTrailingReturnType() const {
- return dyn_cast_or_null<FunctionType>(
+ return isa_and_nonnull<FunctionType>(
GetContainedDeducedTypeVisitor(true).Visit(this));
}
bool Type::hasIntegerRepresentation() const {
if (const auto *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isIntegerType();
- else
- return isIntegerType();
+ if (CanonicalType->isSveVLSBuiltinType()) {
+ const auto *VT = cast<BuiltinType>(CanonicalType);
+ return VT->getKind() == BuiltinType::SveBool ||
+ (VT->getKind() >= BuiltinType::SveInt8 &&
+ VT->getKind() <= BuiltinType::SveUint64);
+ }
+ if (CanonicalType->isRVVVLSBuiltinType()) {
+ const auto *VT = cast<BuiltinType>(CanonicalType);
+ return (VT->getKind() >= BuiltinType::RvvInt8mf8 &&
+ VT->getKind() <= BuiltinType::RvvUint64m8);
+ }
+
+ return isIntegerType();
}
/// Determine whether this type is an integral type.
@@ -1925,7 +2002,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete();
- return isExtIntType();
+ return isBitIntType();
}
bool Type::isIntegralOrUnscopedEnumerationType() const {
@@ -1933,7 +2010,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128;
- if (isExtIntType())
+ if (isBitIntType())
return true;
return isUnscopedEnumerationType();
@@ -2016,7 +2093,9 @@ bool Type::isSignedIntegerType() const {
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
}
- if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
+ if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
+ return IT->isSigned();
+ if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
return IT->isSigned();
return false;
@@ -2033,9 +2112,10 @@ bool Type::isSignedIntegerOrEnumerationType() const {
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
}
- if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
+ if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
+ return IT->isSigned();
+ if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
return IT->isSigned();
-
return false;
}
@@ -2063,7 +2143,9 @@ bool Type::isUnsignedIntegerType() const {
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
}
- if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
+ if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
+ return IT->isUnsigned();
+ if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
return IT->isUnsigned();
return false;
@@ -2080,7 +2162,9 @@ bool Type::isUnsignedIntegerOrEnumerationType() const {
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
}
- if (const ExtIntType *IT = dyn_cast<ExtIntType>(CanonicalType))
+ if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
+ return IT->isUnsigned();
+ if (const auto *IT = dyn_cast<DependentBitIntType>(CanonicalType))
return IT->isUnsigned();
return false;
@@ -2091,13 +2175,18 @@ bool Type::hasUnsignedIntegerRepresentation() const {
return VT->getElementType()->isUnsignedIntegerOrEnumerationType();
if (const auto *VT = dyn_cast<MatrixType>(CanonicalType))
return VT->getElementType()->isUnsignedIntegerOrEnumerationType();
+ if (CanonicalType->isSveVLSBuiltinType()) {
+ const auto *VT = cast<BuiltinType>(CanonicalType);
+ return VT->getKind() >= BuiltinType::SveUint8 &&
+ VT->getKind() <= BuiltinType::SveUint64;
+ }
return isUnsignedIntegerOrEnumerationType();
}
bool Type::isFloatingType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Half &&
- BT->getKind() <= BuiltinType::Float128;
+ BT->getKind() <= BuiltinType::Ibm128;
if (const auto *CT = dyn_cast<ComplexType>(CanonicalType))
return CT->getElementType()->isFloatingType();
return false;
@@ -2106,8 +2195,9 @@ bool Type::isFloatingType() const {
bool Type::hasFloatingRepresentation() const {
if (const auto *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isFloatingType();
- else
- return isFloatingType();
+ if (const auto *MT = dyn_cast<MatrixType>(CanonicalType))
+ return MT->getElementType()->isFloatingType();
+ return isFloatingType();
}
bool Type::isRealFloatingType() const {
@@ -2119,17 +2209,16 @@ bool Type::isRealFloatingType() const {
bool Type::isRealType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Float128;
+ BT->getKind() <= BuiltinType::Ibm128;
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
- return isExtIntType();
+ return isBitIntType();
}
bool Type::isArithmeticType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Float128 &&
- BT->getKind() != BuiltinType::BFloat16;
+ BT->getKind() <= BuiltinType::Ibm128;
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
// If a body isn't seen by the time we get here, return false.
@@ -2138,7 +2227,7 @@ bool Type::isArithmeticType() const {
// false for scoped enumerations since that will disable any
// unwanted implicit conversions.
return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
- return isa<ComplexType>(CanonicalType) || isExtIntType();
+ return isa<ComplexType>(CanonicalType) || isBitIntType();
}
Type::ScalarTypeKind Type::getScalarTypeKind() const {
@@ -2167,7 +2256,7 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
if (CT->getElementType()->isRealFloatingType())
return STK_FloatingComplex;
return STK_IntegralComplex;
- } else if (isExtIntType()) {
+ } else if (isBitIntType()) {
return STK_Integral;
}
@@ -2279,11 +2368,61 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
}
bool Type::isSizelessBuiltinType() const {
+ if (isSizelessVectorType())
+ return true;
+
+ if (const BuiltinType *BT = getAs<BuiltinType>()) {
+ switch (BT->getKind()) {
+ // WebAssembly reference types
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+bool Type::isWebAssemblyExternrefType() const {
+ if (const auto *BT = getAs<BuiltinType>())
+ return BT->getKind() == BuiltinType::WasmExternRef;
+ return false;
+}
+
+bool Type::isWebAssemblyTableType() const {
+ if (const auto *ATy = dyn_cast<ArrayType>(this))
+ return ATy->getElementType().isWebAssemblyReferenceType();
+
+ if (const auto *PTy = dyn_cast<PointerType>(this))
+ return PTy->getPointeeType().isWebAssemblyReferenceType();
+
+ return false;
+}
+
+bool Type::isSizelessType() const { return isSizelessBuiltinType(); }
+
+bool Type::isSizelessVectorType() const {
+ return isSVESizelessBuiltinType() || isRVVSizelessBuiltinType();
+}
+
+bool Type::isSVESizelessBuiltinType() const {
if (const BuiltinType *BT = getAs<BuiltinType>()) {
switch (BT->getKind()) {
// SVE Types
#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/AArch64SVEACLETypes.def"
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+bool Type::isRVVSizelessBuiltinType() const {
+ if (const BuiltinType *BT = getAs<BuiltinType>()) {
+ switch (BT->getKind()) {
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
return true;
@@ -2294,9 +2433,7 @@ bool Type::isSizelessBuiltinType() const {
return false;
}
-bool Type::isSizelessType() const { return isSizelessBuiltinType(); }
-
-bool Type::isVLSTBuiltinType() const {
+bool Type::isSveVLSBuiltinType() const {
if (const BuiltinType *BT = getAs<BuiltinType>()) {
switch (BT->getKind()) {
case BuiltinType::SveInt8:
@@ -2312,6 +2449,8 @@ bool Type::isVLSTBuiltinType() const {
case BuiltinType::SveFloat64:
case BuiltinType::SveBFloat16:
case BuiltinType::SveBool:
+ case BuiltinType::SveBoolx2:
+ case BuiltinType::SveBoolx4:
return true;
default:
return false;
@@ -2321,9 +2460,9 @@ bool Type::isVLSTBuiltinType() const {
}
QualType Type::getSveEltType(const ASTContext &Ctx) const {
- assert(isVLSTBuiltinType() && "unsupported type!");
+ assert(isSveVLSBuiltinType() && "unsupported type!");
- const BuiltinType *BTy = getAs<BuiltinType>();
+ const BuiltinType *BTy = castAs<BuiltinType>();
if (BTy->getKind() == BuiltinType::SveBool)
// Represent predicates as i8 rather than i1 to avoid any layout issues.
// The type is bitcasted to a scalable predicate type when casting between
@@ -2333,6 +2472,41 @@ QualType Type::getSveEltType(const ASTContext &Ctx) const {
return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType;
}
+bool Type::isRVVVLSBuiltinType() const {
+ if (const BuiltinType *BT = getAs<BuiltinType>()) {
+ switch (BT->getKind()) {
+#define RVV_VECTOR_TYPE(Name, Id, SingletonId, NumEls, ElBits, NF, IsSigned, \
+ IsFP, IsBF) \
+ case BuiltinType::Id: \
+ return NF == 1;
+#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
+ case BuiltinType::Id: \
+ return true;
+#include "clang/Basic/RISCVVTypes.def"
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
+QualType Type::getRVVEltType(const ASTContext &Ctx) const {
+ assert(isRVVVLSBuiltinType() && "unsupported type!");
+
+ const BuiltinType *BTy = castAs<BuiltinType>();
+
+ switch (BTy->getKind()) {
+#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
+ case BuiltinType::Id: \
+ return Ctx.UnsignedCharTy;
+ default:
+ return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType;
+#include "clang/Basic/RISCVVTypes.def"
+ }
+
+ llvm_unreachable("Unhandled type");
+}
+
bool QualType::isPODType(const ASTContext &Context) const {
// C++11 has a more relaxed definition of POD.
if (Context.getLangOpts().CPlusPlus11)
@@ -2374,7 +2548,7 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
case Type::MemberPointer:
case Type::Vector:
case Type::ExtVector:
- case Type::ExtInt:
+ case Type::BitInt:
return true;
case Type::Enum:
@@ -2425,11 +2599,13 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- // C++11 [class]p6:
- // A trivial class is a class that has a default constructor,
- // has no non-trivial default constructors, and is trivially
- // copyable.
- return ClassDecl->hasDefaultConstructor() &&
+ // C++20 [class]p6:
+ // A trivial class is a class that is trivially copyable, and
+ // has one or more eligible default constructors such that each is
+ // trivial.
+ // FIXME: We should merge this definition of triviality into
+ // CXXRecordDecl::isTrivial. Currently it computes the wrong thing.
+ return ClassDecl->hasTrivialDefaultConstructor() &&
!ClassDecl->hasNonTrivialDefaultConstructor() &&
ClassDecl->isTriviallyCopyable();
}
@@ -2441,19 +2617,22 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
return false;
}
-bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
- if ((*this)->isArrayType())
- return Context.getBaseElementType(*this).isTriviallyCopyableType(Context);
+static bool isTriviallyCopyableTypeImpl(const QualType &type,
+ const ASTContext &Context,
+ bool IsCopyConstructible) {
+ if (type->isArrayType())
+ return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
+ Context, IsCopyConstructible);
- if (hasNonTrivialObjCLifetime())
+ if (type.hasNonTrivialObjCLifetime())
return false;
// C++11 [basic.types]p9 - See Core 2094
// Scalar types, trivially copyable class types, arrays of such types, and
// cv-qualified versions of these types are collectively
- // called trivially copyable types.
+ // called trivially copy constructible types.
- QualType CanonicalType = getCanonicalType();
+ QualType CanonicalType = type.getCanonicalType();
if (CanonicalType->isDependentType())
return false;
@@ -2471,16 +2650,110 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- if (!ClassDecl->isTriviallyCopyable()) return false;
+ if (IsCopyConstructible) {
+ return ClassDecl->isTriviallyCopyConstructible();
+ } else {
+ return ClassDecl->isTriviallyCopyable();
+ }
}
-
return true;
}
-
// No other types can match.
return false;
}
+bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
+ return isTriviallyCopyableTypeImpl(*this, Context,
+ /*IsCopyConstructible=*/false);
+}
+
+bool QualType::isTriviallyCopyConstructibleType(
+ const ASTContext &Context) const {
+ return isTriviallyCopyableTypeImpl(*this, Context,
+ /*IsCopyConstructible=*/true);
+}
+
+bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
+ QualType BaseElementType = Context.getBaseElementType(*this);
+
+ if (BaseElementType->isIncompleteType()) {
+ return false;
+ } else if (!BaseElementType->isObjectType()) {
+ return false;
+ } else if (const auto *RD = BaseElementType->getAsRecordDecl()) {
+ return RD->canPassInRegisters();
+ } else {
+ switch (isNonTrivialToPrimitiveDestructiveMove()) {
+ case PCK_Trivial:
+ return !isDestructedType();
+ case PCK_ARCStrong:
+ return true;
+ default:
+ return false;
+ }
+ }
+}
+
+static bool
+HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) {
+ if (Decl->isUnion())
+ return false;
+ if (Decl->isLambda())
+ return Decl->isCapturelessLambda();
+
+ auto IsDefaultedOperatorEqualEqual = [&](const FunctionDecl *Function) {
+ return Function->getOverloadedOperator() ==
+ OverloadedOperatorKind::OO_EqualEqual &&
+ Function->isDefaulted() && Function->getNumParams() > 0 &&
+ (Function->getParamDecl(0)->getType()->isReferenceType() ||
+ Decl->isTriviallyCopyable());
+ };
+
+ if (llvm::none_of(Decl->methods(), IsDefaultedOperatorEqualEqual) &&
+ llvm::none_of(Decl->friends(), [&](const FriendDecl *Friend) {
+ if (NamedDecl *ND = Friend->getFriendDecl()) {
+ return ND->isFunctionOrFunctionTemplate() &&
+ IsDefaultedOperatorEqualEqual(ND->getAsFunction());
+ }
+ return false;
+ }))
+ return false;
+
+ return llvm::all_of(Decl->bases(),
+ [](const CXXBaseSpecifier &BS) {
+ if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
+ return HasNonDeletedDefaultedEqualityComparison(RD);
+ return true;
+ }) &&
+ llvm::all_of(Decl->fields(), [](const FieldDecl *FD) {
+ auto Type = FD->getType();
+ if (Type->isArrayType())
+ Type = Type->getBaseElementTypeUnsafe()->getCanonicalTypeUnqualified();
+
+ if (Type->isReferenceType() || Type->isEnumeralType())
+ return false;
+ if (const auto *RD = Type->getAsCXXRecordDecl())
+ return HasNonDeletedDefaultedEqualityComparison(RD);
+ return true;
+ });
+}
+
+bool QualType::isTriviallyEqualityComparableType(
+ const ASTContext &Context) const {
+ QualType CanonicalType = getCanonicalType();
+ if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
+ CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
+ return false;
+
+ if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
+ if (!HasNonDeletedDefaultedEqualityComparison(RD))
+ return false;
+ }
+
+ return Context.hasUniqueObjectRepresentations(
+ CanonicalType, /*CheckIfTriviallyCopyable=*/false);
+}
+
bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
return !Context.getLangOpts().ObjCAutoRefCount &&
Context.getLangOpts().ObjCWeak &&
@@ -2499,6 +2772,19 @@ bool QualType::hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD) {
return RD->hasNonTrivialToPrimitiveCopyCUnion();
}
+bool QualType::isWebAssemblyReferenceType() const {
+ return isWebAssemblyExternrefType() || isWebAssemblyFuncrefType();
+}
+
+bool QualType::isWebAssemblyExternrefType() const {
+ return getTypePtr()->isWebAssemblyExternrefType();
+}
+
+bool QualType::isWebAssemblyFuncrefType() const {
+ return getTypePtr()->isFunctionPointerType() &&
+ getAddressSpace() == LangAS::wasm_funcref;
+}
+
QualType::PrimitiveDefaultInitializeKind
QualType::isNonTrivialToPrimitiveDefaultInitialize() const {
if (const auto *RT =
@@ -2734,39 +3020,6 @@ bool Type::isStdByteType() const {
return false;
}
-bool Type::isPromotableIntegerType() const {
- if (const auto *BT = getAs<BuiltinType>())
- switch (BT->getKind()) {
- case BuiltinType::Bool:
- case BuiltinType::Char_S:
- case BuiltinType::Char_U:
- case BuiltinType::SChar:
- case BuiltinType::UChar:
- case BuiltinType::Short:
- case BuiltinType::UShort:
- case BuiltinType::WChar_S:
- case BuiltinType::WChar_U:
- case BuiltinType::Char8:
- case BuiltinType::Char16:
- case BuiltinType::Char32:
- return true;
- default:
- return false;
- }
-
- // Enumerated types are promotable to their compatible integer types
- // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
- if (const auto *ET = getAs<EnumType>()){
- if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull()
- || ET->getDecl()->isScoped())
- return false;
-
- return true;
- }
-
- return false;
-}
-
bool Type::isSpecifierType() const {
// Note that this intentionally does not use the canonical type.
switch (getTypeClass()) {
@@ -2785,7 +3038,6 @@ bool Type::isSpecifierType() const {
case DependentTemplateSpecialization:
case ObjCInterface:
case ObjCObject:
- case ObjCObjectPointer: // FIXME: object pointers aren't really specifiers
return true;
default:
return false;
@@ -2795,24 +3047,36 @@ bool Type::isSpecifierType() const {
ElaboratedTypeKeyword
TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
- default: return ETK_None;
- case TST_typename: return ETK_Typename;
- case TST_class: return ETK_Class;
- case TST_struct: return ETK_Struct;
- case TST_interface: return ETK_Interface;
- case TST_union: return ETK_Union;
- case TST_enum: return ETK_Enum;
+ default:
+ return ElaboratedTypeKeyword::None;
+ case TST_typename:
+ return ElaboratedTypeKeyword::Typename;
+ case TST_class:
+ return ElaboratedTypeKeyword::Class;
+ case TST_struct:
+ return ElaboratedTypeKeyword::Struct;
+ case TST_interface:
+ return ElaboratedTypeKeyword::Interface;
+ case TST_union:
+ return ElaboratedTypeKeyword::Union;
+ case TST_enum:
+ return ElaboratedTypeKeyword::Enum;
}
}
TagTypeKind
TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
switch(TypeSpec) {
- case TST_class: return TTK_Class;
- case TST_struct: return TTK_Struct;
- case TST_interface: return TTK_Interface;
- case TST_union: return TTK_Union;
- case TST_enum: return TTK_Enum;
+ case TST_class:
+ return TagTypeKind::Class;
+ case TST_struct:
+ return TagTypeKind::Struct;
+ case TST_interface:
+ return TagTypeKind::Interface;
+ case TST_union:
+ return TagTypeKind::Union;
+ case TST_enum:
+ return TagTypeKind::Enum;
}
llvm_unreachable("Type specifier is not a tag type kind.");
@@ -2821,11 +3085,16 @@ TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
ElaboratedTypeKeyword
TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
switch (Kind) {
- case TTK_Class: return ETK_Class;
- case TTK_Struct: return ETK_Struct;
- case TTK_Interface: return ETK_Interface;
- case TTK_Union: return ETK_Union;
- case TTK_Enum: return ETK_Enum;
+ case TagTypeKind::Class:
+ return ElaboratedTypeKeyword::Class;
+ case TagTypeKind::Struct:
+ return ElaboratedTypeKeyword::Struct;
+ case TagTypeKind::Interface:
+ return ElaboratedTypeKeyword::Interface;
+ case TagTypeKind::Union:
+ return ElaboratedTypeKeyword::Union;
+ case TagTypeKind::Enum:
+ return ElaboratedTypeKeyword::Enum;
}
llvm_unreachable("Unknown tag type kind.");
}
@@ -2833,13 +3102,18 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
TagTypeKind
TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
- case ETK_Class: return TTK_Class;
- case ETK_Struct: return TTK_Struct;
- case ETK_Interface: return TTK_Interface;
- case ETK_Union: return TTK_Union;
- case ETK_Enum: return TTK_Enum;
- case ETK_None: // Fall through.
- case ETK_Typename:
+ case ElaboratedTypeKeyword::Class:
+ return TagTypeKind::Class;
+ case ElaboratedTypeKeyword::Struct:
+ return TagTypeKind::Struct;
+ case ElaboratedTypeKeyword::Interface:
+ return TagTypeKind::Interface;
+ case ElaboratedTypeKeyword::Union:
+ return TagTypeKind::Union;
+ case ElaboratedTypeKeyword::Enum:
+ return TagTypeKind::Enum;
+ case ElaboratedTypeKeyword::None: // Fall through.
+ case ElaboratedTypeKeyword::Typename:
llvm_unreachable("Elaborated type keyword is not a tag type kind.");
}
llvm_unreachable("Unknown elaborated type keyword.");
@@ -2848,14 +3122,14 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
bool
TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
- case ETK_None:
- case ETK_Typename:
+ case ElaboratedTypeKeyword::None:
+ case ElaboratedTypeKeyword::Typename:
return false;
- case ETK_Class:
- case ETK_Struct:
- case ETK_Interface:
- case ETK_Union:
- case ETK_Enum:
+ case ElaboratedTypeKeyword::Class:
+ case ElaboratedTypeKeyword::Struct:
+ case ElaboratedTypeKeyword::Interface:
+ case ElaboratedTypeKeyword::Union:
+ case ElaboratedTypeKeyword::Enum:
return true;
}
llvm_unreachable("Unknown elaborated type keyword.");
@@ -2863,13 +3137,20 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
- case ETK_None: return {};
- case ETK_Typename: return "typename";
- case ETK_Class: return "class";
- case ETK_Struct: return "struct";
- case ETK_Interface: return "__interface";
- case ETK_Union: return "union";
- case ETK_Enum: return "enum";
+ case ElaboratedTypeKeyword::None:
+ return {};
+ case ElaboratedTypeKeyword::Typename:
+ return "typename";
+ case ElaboratedTypeKeyword::Class:
+ return "class";
+ case ElaboratedTypeKeyword::Struct:
+ return "struct";
+ case ElaboratedTypeKeyword::Interface:
+ return "__interface";
+ case ElaboratedTypeKeyword::Union:
+ return "union";
+ case ElaboratedTypeKeyword::Enum:
+ return "enum";
}
llvm_unreachable("Unknown elaborated type keyword.");
@@ -2886,7 +3167,7 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType(
DependentTemplateSpecializationTypeBits.NumArgs = Args.size();
assert((!NNS || NNS->isDependent()) &&
"DependentTemplateSpecializatonType requires dependent qualifier");
- TemplateArgument *ArgBuffer = getArgBuffer();
+ auto *ArgBuffer = const_cast<TemplateArgument *>(template_arguments().data());
for (const TemplateArgument &Arg : Args) {
addDependence(toTypeDependence(Arg.getDependence() &
TemplateArgumentDependence::UnexpandedPack));
@@ -2902,7 +3183,7 @@ DependentTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
NestedNameSpecifier *Qualifier,
const IdentifierInfo *Name,
ArrayRef<TemplateArgument> Args) {
- ID.AddInteger(Keyword);
+ ID.AddInteger(llvm::to_underlying(Keyword));
ID.AddPointer(Qualifier);
ID.AddPointer(Name);
for (const TemplateArgument &Arg : Args)
@@ -3030,6 +3311,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "_Float16";
case Float128:
return "__float128";
+ case Ibm128:
+ return "__ibm128";
case WChar_S:
case WChar_U:
return Policy.MSWChar ? "__wchar_t" : "wchar_t";
@@ -3040,7 +3323,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case Char32:
return "char32_t";
case NullPtr:
- return "nullptr_t";
+ return Policy.NullptrTypeInNamespace ? "std::nullptr_t" : "nullptr_t";
case Overload:
return "<overloaded function type>";
case BoundMember:
@@ -3099,6 +3382,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
case Id: \
return Name;
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) \
+ case Id: \
+ return Name;
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
}
llvm_unreachable("Invalid builtin type.");
@@ -3141,6 +3428,8 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_AAPCS: return "aapcs";
case CC_AAPCS_VFP: return "aapcs-vfp";
case CC_AArch64VectorCall: return "aarch64_vector_pcs";
+ case CC_AArch64SVEPCS: return "aarch64_sve_pcs";
+ case CC_AMDGPUKernelCall: return "amdgpu_kernel";
case CC_IntelOclBicc: return "intel_ocl_bicc";
case CC_SpirFunction: return "spir_function";
case CC_OpenCLKernel: return "opencl_kernel";
@@ -3148,11 +3437,19 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_SwiftAsync: return "swiftasynccall";
case CC_PreserveMost: return "preserve_most";
case CC_PreserveAll: return "preserve_all";
+ case CC_M68kRTD: return "m68k_rtd";
}
llvm_unreachable("Invalid calling convention.");
}
+void FunctionProtoType::ExceptionSpecInfo::instantiate() {
+ assert(Type == EST_Uninstantiated);
+ NoexceptExpr =
+ cast<FunctionProtoType>(SourceTemplate->getType())->getNoexceptExpr();
+ Type = EST_DependentNoexcept;
+}
+
FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
QualType canonical,
const ExtProtoInfo &epi)
@@ -3167,10 +3464,21 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
FunctionTypeBits.Variadic = epi.Variadic;
FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn;
- // Fill in the extra trailing bitfields if present.
- if (hasExtraBitfields(epi.ExceptionSpec.Type)) {
+ if (epi.requiresFunctionProtoTypeExtraBitfields()) {
+ FunctionTypeBits.HasExtraBitfields = true;
auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
- ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size();
+ ExtraBits = FunctionTypeExtraBitfields();
+ } else {
+ FunctionTypeBits.HasExtraBitfields = false;
+ }
+
+ if (epi.requiresFunctionProtoTypeArmAttributes()) {
+ auto &ArmTypeAttrs = *getTrailingObjects<FunctionTypeArmAttributes>();
+ ArmTypeAttrs = FunctionTypeArmAttributes();
+
+ // Also set the bit in FunctionTypeExtraBitfields
+ auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
+ ExtraBits.HasArmTypeAttributes = true;
}
// Fill in the trailing argument array.
@@ -3181,8 +3489,21 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
argSlot[i] = params[i];
}
+ // Propagate the SME ACLE attributes.
+ if (epi.AArch64SMEAttributes != SME_NormalFunction) {
+ auto &ArmTypeAttrs = *getTrailingObjects<FunctionTypeArmAttributes>();
+ assert(epi.AArch64SMEAttributes <= SME_AttributeMask &&
+ "Not enough bits to encode SME attributes");
+ ArmTypeAttrs.AArch64SMEAttributes = epi.AArch64SMEAttributes;
+ }
+
// Fill in the exception type array if present.
if (getExceptionSpecType() == EST_Dynamic) {
+ auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
+ size_t NumExceptions = epi.ExceptionSpec.Exceptions.size();
+ assert(NumExceptions <= 1023 && "Not enough bits to encode exceptions");
+ ExtraBits.NumExceptionType = NumExceptions;
+
assert(hasExtraBitfields() && "missing trailing extra bitfields!");
auto *exnSlot =
reinterpret_cast<QualType *>(getTrailingObjects<ExceptionType>());
@@ -3286,7 +3607,6 @@ CanThrowResult FunctionProtoType::canThrow() const {
switch (getExceptionSpecType()) {
case EST_Unparsed:
case EST_Unevaluated:
- case EST_Uninstantiated:
llvm_unreachable("should not call this with unresolved exception specs");
case EST_DynamicNone:
@@ -3308,6 +3628,7 @@ CanThrowResult FunctionProtoType::canThrow() const {
return CT_Can;
return CT_Dependent;
+ case EST_Uninstantiated:
case EST_DependentNoexcept:
return CT_Dependent;
}
@@ -3337,8 +3658,11 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
// This is followed by an optional "consumed argument" section of the
// same length as the first type sequence:
// bool*
- // Finally, we have the ext info and trailing return type flag:
- // int bool
+ // This is followed by the ext info:
+ // int
+ // Finally we have a trailing return type flag (bool)
+ // combined with AArch64 SME Attributes, to save space:
+ // int
//
// There is no ambiguity between the consumed arguments and an empty EH
// spec because of the leading 'bool' which unambiguously indicates
@@ -3371,8 +3695,9 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
for (unsigned i = 0; i != NumParams; ++i)
ID.AddInteger(epi.ExtParameterInfos[i].getOpaqueValue());
}
+
epi.ExtInfo.Profile(ID);
- ID.AddBoolean(epi.HasTrailingReturn);
+ ID.AddInteger((epi.AArch64SMEAttributes << 1) | epi.HasTrailingReturn);
}
void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
@@ -3382,14 +3707,34 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
}
TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D,
- QualType underlying, QualType can)
- : Type(tc, can, underlying->getDependence()),
+ QualType Underlying, QualType can)
+ : Type(tc, can, toSemanticDependence(can->getDependence())),
Decl(const_cast<TypedefNameDecl *>(D)) {
assert(!isa<TypedefType>(can) && "Invalid canonical type");
+ TypedefBits.hasTypeDifferentFromDecl = !Underlying.isNull();
+ if (!typeMatchesDecl())
+ *getTrailingObjects<QualType>() = Underlying;
}
QualType TypedefType::desugar() const {
- return getDecl()->getUnderlyingType();
+ return typeMatchesDecl() ? Decl->getUnderlyingType()
+ : *getTrailingObjects<QualType>();
+}
+
+UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying,
+ QualType Canon)
+ : Type(Using, Canon, toSemanticDependence(Canon->getDependence())),
+ Found(const_cast<UsingShadowDecl *>(Found)) {
+ UsingBits.hasTypeDifferentFromDecl = !Underlying.isNull();
+ if (!typeMatchesDecl())
+ *getTrailingObjects<QualType>() = Underlying;
+}
+
+QualType UsingType::getUnderlyingType() const {
+ return typeMatchesDecl()
+ ? QualType(
+ cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0)
+ : *getTrailingObjects<QualType>();
}
QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); }
@@ -3406,27 +3751,37 @@ QualType MacroQualifiedType::getModifiedType() const {
return Inner;
}
-TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
- : Type(TypeOfExpr, can,
+TypeOfExprType::TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can)
+ : Type(TypeOfExpr,
+ // We have to protect against 'Can' being invalid through its
+ // default argument.
+ Kind == TypeOfKind::Unqualified && !Can.isNull()
+ ? Can.getAtomicUnqualifiedType()
+ : Can,
toTypeDependence(E->getDependence()) |
(E->getType()->getDependence() &
TypeDependence::VariablyModified)),
- TOExpr(E) {}
+ TOExpr(E) {
+ TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified;
+}
bool TypeOfExprType::isSugared() const {
return !TOExpr->isTypeDependent();
}
QualType TypeOfExprType::desugar() const {
- if (isSugared())
- return getUnderlyingExpr()->getType();
-
+ if (isSugared()) {
+ QualType QT = getUnderlyingExpr()->getType();
+ return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT;
+ }
return QualType(this, 0);
}
void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID,
- const ASTContext &Context, Expr *E) {
+ const ASTContext &Context, Expr *E,
+ bool IsUnqual) {
E->Profile(ID, Context, true);
+ ID.AddBoolean(IsUnqual);
}
DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
@@ -3450,8 +3805,8 @@ QualType DecltypeType::desugar() const {
return QualType(this, 0);
}
-DependentDecltypeType::DependentDecltypeType(const ASTContext &Context, Expr *E)
- : DecltypeType(E, Context.DependentTy), Context(Context) {}
+DependentDecltypeType::DependentDecltypeType(Expr *E, QualType UnderlyingType)
+ : DecltypeType(E, UnderlyingType) {}
void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, Expr *E) {
@@ -3476,7 +3831,7 @@ TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
decl(const_cast<TagDecl *>(D)) {}
static TagDecl *getInterestingTagDecl(TagDecl *decl) {
- for (auto I : decl->redecls()) {
+ for (auto *I : decl->redecls()) {
if (I->isCompleteDefinition() || I->isBeingDefined())
return I;
}
@@ -3505,7 +3860,7 @@ bool RecordType::hasConstFields() const {
return true;
FieldTy = FieldTy.getCanonicalType();
if (const auto *FieldRecTy = FieldTy->getAs<RecordType>()) {
- if (llvm::find(RecordTypeList, FieldRecTy) == RecordTypeList.end())
+ if (!llvm::is_contained(RecordTypeList, FieldRecTy))
RecordTypeList.push_back(FieldRecTy);
}
}
@@ -3551,6 +3906,10 @@ bool AttributedType::isMSTypeSpec() const {
llvm_unreachable("invalid attr kind");
}
+bool AttributedType::isWebAssemblyFuncrefSpec() const {
+ return getAttrKind() == attr::WebAssemblyFuncref;
+}
+
bool AttributedType::isCallingConv() const {
// FIXME: Generate this with TableGen.
switch (getAttrKind()) {
@@ -3565,12 +3924,15 @@ bool AttributedType::isCallingConv() const {
case attr::SwiftAsyncCall:
case attr::VectorCall:
case attr::AArch64VectorPcs:
+ case attr::AArch64SVEPcs:
+ case attr::AMDGPUKernelCall:
case attr::Pascal:
case attr::MSABI:
case attr::SysVABI:
case attr::IntelOclBicc:
case attr::PreserveMost:
case attr::PreserveAll:
+ case attr::M68kRTD:
return true;
}
llvm_unreachable("invalid attr kind");
@@ -3584,28 +3946,80 @@ IdentifierInfo *TemplateTypeParmType::getIdentifier() const {
return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier();
}
+static const TemplateTypeParmDecl *getReplacedParameter(Decl *D,
+ unsigned Index) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D))
+ return TTP;
+ return cast<TemplateTypeParmDecl>(
+ getReplacedTemplateParameterList(D)->getParam(Index));
+}
+
+SubstTemplateTypeParmType::SubstTemplateTypeParmType(
+ QualType Replacement, Decl *AssociatedDecl, unsigned Index,
+ std::optional<unsigned> PackIndex)
+ : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(),
+ Replacement->getDependence()),
+ AssociatedDecl(AssociatedDecl) {
+ SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType =
+ Replacement != getCanonicalTypeInternal();
+ if (SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType)
+ *getTrailingObjects<QualType>() = Replacement;
+
+ SubstTemplateTypeParmTypeBits.Index = Index;
+ SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0;
+ assert(AssociatedDecl != nullptr);
+}
+
+const TemplateTypeParmDecl *
+SubstTemplateTypeParmType::getReplacedParameter() const {
+ return ::getReplacedParameter(getAssociatedDecl(), getIndex());
+}
+
SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType(
- const TemplateTypeParmType *Param, QualType Canon,
+ QualType Canon, Decl *AssociatedDecl, unsigned Index, bool Final,
const TemplateArgument &ArgPack)
: Type(SubstTemplateTypeParmPack, Canon,
TypeDependence::DependentInstantiation |
TypeDependence::UnexpandedPack),
- Replaced(Param), Arguments(ArgPack.pack_begin()) {
+ Arguments(ArgPack.pack_begin()),
+ AssociatedDeclAndFinal(AssociatedDecl, Final) {
+ SubstTemplateTypeParmPackTypeBits.Index = Index;
SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+ assert(AssociatedDecl != nullptr);
+}
+
+Decl *SubstTemplateTypeParmPackType::getAssociatedDecl() const {
+ return AssociatedDeclAndFinal.getPointer();
+}
+
+bool SubstTemplateTypeParmPackType::getFinal() const {
+ return AssociatedDeclAndFinal.getInt();
+}
+
+const TemplateTypeParmDecl *
+SubstTemplateTypeParmPackType::getReplacedParameter() const {
+ return ::getReplacedParameter(getAssociatedDecl(), getIndex());
+}
+
+IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const {
+ return getReplacedParameter()->getIdentifier();
}
TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
- return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs()));
+ return TemplateArgument(llvm::ArrayRef(Arguments, getNumArgs()));
}
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReplacedParameter(), getArgumentPack());
+ Profile(ID, getAssociatedDecl(), getIndex(), getFinal(), getArgumentPack());
}
void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID,
- const TemplateTypeParmType *Replaced,
+ const Decl *AssociatedDecl,
+ unsigned Index, bool Final,
const TemplateArgument &ArgPack) {
- ID.AddPointer(Replaced);
+ ID.AddPointer(AssociatedDecl);
+ ID.AddInteger(Index);
+ ID.AddBoolean(Final);
ID.AddInteger(ArgPack.pack_size());
for (const auto &P : ArgPack.pack_elements())
ID.AddPointer(P.getAsType().getAsOpaquePtr());
@@ -3639,8 +4053,7 @@ TemplateSpecializationType::TemplateSpecializationType(
: Type(TemplateSpecialization, Canon.isNull() ? QualType(this, 0) : Canon,
(Canon.isNull()
? TypeDependence::DependentInstantiation
- : Canon->getDependence() & ~(TypeDependence::VariablyModified |
- TypeDependence::UnexpandedPack)) |
+ : toSemanticDependence(Canon->getDependence())) |
(toTypeDependence(T.getDependence()) &
TypeDependence::UnexpandedPack)),
Template(T) {
@@ -3651,7 +4064,8 @@ TemplateSpecializationType::TemplateSpecializationType(
"Use DependentTemplateSpecializationType for dependent template-name");
assert((T.getKind() == TemplateName::Template ||
T.getKind() == TemplateName::SubstTemplateTemplateParm ||
- T.getKind() == TemplateName::SubstTemplateTemplateParmPack) &&
+ T.getKind() == TemplateName::SubstTemplateTemplateParmPack ||
+ T.getKind() == TemplateName::UsingTemplate) &&
"Unexpected template name for TemplateSpecializationType");
auto *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1);
@@ -3675,10 +4089,22 @@ TemplateSpecializationType::TemplateSpecializationType(
// Store the aliased type if this is a type alias template specialization.
if (isTypeAlias()) {
auto *Begin = reinterpret_cast<TemplateArgument *>(this + 1);
- *reinterpret_cast<QualType*>(Begin + getNumArgs()) = AliasedType;
+ *reinterpret_cast<QualType *>(Begin + Args.size()) = AliasedType;
}
}
+QualType TemplateSpecializationType::getAliasedType() const {
+ assert(isTypeAlias() && "not a type alias template specialization");
+ return *reinterpret_cast<const QualType *>(template_arguments().end());
+}
+
+void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+ const ASTContext &Ctx) {
+ Profile(ID, Template, template_arguments(), Ctx);
+ if (isTypeAlias())
+ getAliasedType().Profile(ID);
+}
+
void
TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
TemplateName T,
@@ -3715,14 +4141,14 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID,
for (auto typeArg : typeArgs)
ID.AddPointer(typeArg.getAsOpaquePtr());
ID.AddInteger(protocols.size());
- for (auto proto : protocols)
+ for (auto *proto : protocols)
ID.AddPointer(proto);
ID.AddBoolean(isKindOf);
}
void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getBaseType(), getTypeArgsAsWritten(),
- llvm::makeArrayRef(qual_begin(), getNumProtocols()),
+ llvm::ArrayRef(qual_begin(), getNumProtocols()),
isKindOfTypeAsWritten());
}
@@ -3733,13 +4159,13 @@ void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID,
ID.AddPointer(OTPDecl);
ID.AddPointer(CanonicalType.getAsOpaquePtr());
ID.AddInteger(protocols.size());
- for (auto proto : protocols)
+ for (auto *proto : protocols)
ID.AddPointer(proto);
}
void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getDecl(), getCanonicalTypeInternal(),
- llvm::makeArrayRef(qual_begin(), getNumProtocols()));
+ llvm::ArrayRef(qual_begin(), getNumProtocols()));
}
namespace {
@@ -3757,8 +4183,8 @@ public:
friend CachedProperties merge(CachedProperties L, CachedProperties R) {
Linkage MergedLinkage = minLinkage(L.L, R.L);
- return CachedProperties(MergedLinkage,
- L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
+ return CachedProperties(MergedLinkage, L.hasLocalOrUnnamedType() ||
+ R.hasLocalOrUnnamedType());
}
};
@@ -3801,7 +4227,7 @@ public:
// Compute the cached properties and then set the cache.
CachedProperties Result = computeCachedProperties(T);
T->TypeBits.CacheValid = true;
- T->TypeBits.CachedLinkage = Result.getLinkage();
+ T->TypeBits.CachedLinkage = llvm::to_underlying(Result.getLinkage());
T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType();
}
};
@@ -3833,20 +4259,20 @@ static CachedProperties computeCachedProperties(const Type *T) {
// Treat instantiation-dependent types as external.
if (!T->isInstantiationDependentType()) T->dump();
assert(T->isInstantiationDependentType());
- return CachedProperties(ExternalLinkage, false);
+ return CachedProperties(Linkage::External, false);
case Type::Auto:
case Type::DeducedTemplateSpecialization:
// Give non-deduced 'auto' types external linkage. We should only see them
// here in error recovery.
- return CachedProperties(ExternalLinkage, false);
+ return CachedProperties(Linkage::External, false);
- case Type::ExtInt:
+ case Type::BitInt:
case Type::Builtin:
// C++ [basic.link]p8:
// A type is said to have linkage if and only if:
// - it is a fundamental type (3.9.1); or
- return CachedProperties(ExternalLinkage, false);
+ return CachedProperties(Linkage::External, false);
case Type::Record:
case Type::Enum: {
@@ -3941,7 +4367,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
assert(T->isInstantiationDependentType());
return LinkageInfo::external();
- case Type::ExtInt:
+ case Type::BitInt:
case Type::Builtin:
return LinkageInfo::external();
@@ -4026,8 +4452,7 @@ LinkageInfo Type::getLinkageAndVisibility() const {
return LinkageComputer{}.getTypeLinkageAndVisibility(this);
}
-Optional<NullabilityKind>
-Type::getNullability(const ASTContext &Context) const {
+std::optional<NullabilityKind> Type::getNullability() const {
QualType Type(this, 0);
while (const auto *AT = Type->getAs<AttributedType>()) {
// Check whether this is an attributed type with nullability
@@ -4037,7 +4462,7 @@ Type::getNullability(const ASTContext &Context) const {
Type = AT->getEquivalentType();
}
- return None;
+ return std::nullopt;
}
bool Type::canHaveNullability(bool ResultIfUnknown) const {
@@ -4125,6 +4550,8 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/RISCVVTypes.def"
+#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
+#include "clang/Basic/WebAssemblyReferenceTypes.def"
case BuiltinType::BuiltinFn:
case BuiltinType::NullPtr:
case BuiltinType::IncompleteMatrixIdx:
@@ -4161,15 +4588,14 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::ObjCInterface:
case Type::Atomic:
case Type::Pipe:
- case Type::ExtInt:
- case Type::DependentExtInt:
+ case Type::BitInt:
+ case Type::DependentBitInt:
return false;
}
llvm_unreachable("bad type kind!");
}
-llvm::Optional<NullabilityKind>
-AttributedType::getImmediateNullability() const {
+std::optional<NullabilityKind> AttributedType::getImmediateNullability() const {
if (getAttrKind() == attr::TypeNonNull)
return NullabilityKind::NonNull;
if (getAttrKind() == attr::TypeNullable)
@@ -4178,10 +4604,11 @@ AttributedType::getImmediateNullability() const {
return NullabilityKind::Unspecified;
if (getAttrKind() == attr::TypeNullableResult)
return NullabilityKind::NullableResult;
- return None;
+ return std::nullopt;
}
-Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) {
+std::optional<NullabilityKind>
+AttributedType::stripOuterNullability(QualType &T) {
QualType AttrTy = T;
if (auto MacroTy = dyn_cast<MacroQualifiedType>(T))
AttrTy = MacroTy->getUnderlyingType();
@@ -4193,7 +4620,7 @@ Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) {
}
}
- return None;
+ return std::nullopt;
}
bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const {
@@ -4255,20 +4682,13 @@ bool Type::isObjCARCImplicitlyUnretainedType() const {
}
bool Type::isObjCNSObjectType() const {
- const Type *cur = this;
- while (true) {
- if (const auto *typedefType = dyn_cast<TypedefType>(cur))
- return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
-
- // Single-step desugar until we run out of sugar.
- QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType();
- if (next.getTypePtr() == cur) return false;
- cur = next.getTypePtr();
- }
+ if (const auto *typedefType = getAs<TypedefType>())
+ return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>();
+ return false;
}
bool Type::isObjCIndependentClassType() const {
- if (const auto *typedefType = dyn_cast<TypedefType>(this))
+ if (const auto *typedefType = getAs<TypedefType>())
return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>();
return false;
}
@@ -4392,16 +4812,20 @@ void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
}
AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
- TypeDependence ExtraDependence,
+ TypeDependence ExtraDependence, QualType Canon,
ConceptDecl *TypeConstraintConcept,
ArrayRef<TemplateArgument> TypeConstraintArgs)
- : DeducedType(Auto, DeducedAsType, ExtraDependence) {
- AutoTypeBits.Keyword = (unsigned)Keyword;
+ : DeducedType(Auto, DeducedAsType, ExtraDependence, Canon) {
+ AutoTypeBits.Keyword = llvm::to_underlying(Keyword);
AutoTypeBits.NumArgs = TypeConstraintArgs.size();
this->TypeConstraintConcept = TypeConstraintConcept;
+ assert(TypeConstraintConcept || AutoTypeBits.NumArgs == 0);
if (TypeConstraintConcept) {
- TemplateArgument *ArgBuffer = getArgBuffer();
+ auto *ArgBuffer =
+ const_cast<TemplateArgument *>(getTypeConstraintArguments().data());
for (const TemplateArgument &Arg : TypeConstraintArgs) {
+ // We only syntactically depend on the constraint arguments. They don't
+ // affect the deduced type, only its validity.
addDependence(
toSyntacticDependence(toTypeDependence(Arg.getDependence())));
@@ -4421,3 +4845,8 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
for (const TemplateArgument &Arg : Arguments)
Arg.Profile(ID, Context);
}
+
+void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
+ Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
+ getTypeConstraintConcept(), getTypeConstraintArguments());
+}