diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 10916053cdfbf..5f7c5b86892d0 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1689,7 +1689,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { /// Whether we have a stored size expression. LLVM_PREFERRED_TYPE(bool) - unsigned HasStoredSizeExpr : 1; + unsigned HasExternalSize : 1; + + LLVM_PREFERRED_TYPE(unsigned) + unsigned SizeWidth : 5; }; class BuiltinTypeBitfields { @@ -3181,35 +3184,93 @@ class ArrayType : public Type, public llvm::FoldingSetNode { /// Represents the canonical version of C arrays with a specified constant size. /// For example, the canonical type for 'int A[4 + 4*100]' is a /// ConstantArrayType where the element type is 'int' and the size is 404. -class ConstantArrayType final - : public ArrayType, - private llvm::TrailingObjects { +class ConstantArrayType final : public ArrayType { friend class ASTContext; // ASTContext creates these. - friend TrailingObjects; - llvm::APInt Size; // Allows us to unique the type. + struct ExternalSize { + ExternalSize(const llvm::APInt &Sz, const Expr *SE) + : Size(Sz), SizeExpr(SE) {} + llvm::APInt Size; // Allows us to unique the type. + const Expr *SizeExpr; + }; - ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, - const Expr *sz, ArraySizeModifier sm, unsigned tq) - : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) { - ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr; - if (ConstantArrayTypeBits.HasStoredSizeExpr) { - assert(!can.isNull() && "canonical constant array should not have size"); - *getTrailingObjects() = sz; - } + union { + uint64_t Size; + ExternalSize *SizePtr; + }; + + ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz, + ArraySizeModifier SM, unsigned TQ) + : ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) { + ConstantArrayTypeBits.HasExternalSize = false; + ConstantArrayTypeBits.SizeWidth = Width / 8; + // The in-structure size stores the size in bytes rather than bits so we + // drop the three least significant bits since they're always zero anyways. + assert(Width < 0xFF && "Type width in bits must be less than 8 bits"); } - unsigned numTrailingObjects(OverloadToken) const { - return ConstantArrayTypeBits.HasStoredSizeExpr; + ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr, + ArraySizeModifier SM, unsigned TQ) + : ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr), + SizePtr(SzPtr) { + ConstantArrayTypeBits.HasExternalSize = true; + ConstantArrayTypeBits.SizeWidth = 0; + + assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) && + "canonical constant array should not have size expression"); } + static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET, + QualType Can, const llvm::APInt &Sz, + const Expr *SzExpr, ArraySizeModifier SzMod, + unsigned Qual); + public: - const llvm::APInt &getSize() const { return Size; } + /// Return the constant array size as an APInt. + llvm::APInt getSize() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size + : llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size); + } + + /// Return the bit width of the size type. + unsigned getSizeBitWidth() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getBitWidth() + : static_cast(ConstantArrayTypeBits.SizeWidth * 8); + } + + /// Return true if the size is zero. + bool isZeroSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero() + : 0 == Size; + } + + /// Return the size zero-extended as a uint64_t. + uint64_t getZExtSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue() + : Size; + } + + /// Return the size sign-extended as a uint64_t. + int64_t getSExtSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue() + : static_cast(Size); + } + + /// Return the size zero-extended to uint64_t or UINT64_MAX if the value is + /// larger than UINT64_MAX. + uint64_t getLimitedSize() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getLimitedValue() + : Size; + } + + /// Return a pointer to the size expression. const Expr *getSizeExpr() const { - return ConstantArrayTypeBits.HasStoredSizeExpr - ? *getTrailingObjects() - : nullptr; + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr; } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -3226,14 +3287,13 @@ class ConstantArrayType final static unsigned getMaxSizeBits(const ASTContext &Context); void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { - Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(), + Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(), getSizeModifier(), getIndexTypeCVRQualifiers()); } static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, - QualType ET, const llvm::APInt &ArraySize, - const Expr *SizeExpr, ArraySizeModifier SizeMod, - unsigned TypeQuals); + QualType ET, uint64_t ArraySize, const Expr *SizeExpr, + ArraySizeModifier SizeMod, unsigned TypeQuals); static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5a8fae76a43a4..7ca341c6cfc32 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1766,7 +1766,7 @@ TypeInfoChars static getConstantArrayInfoInChars(const ASTContext &Context, const ConstantArrayType *CAT) { TypeInfoChars EltInfo = Context.getTypeInfoInChars(CAT->getElementType()); - uint64_t Size = CAT->getSize().getZExtValue(); + uint64_t Size = CAT->getZExtSize(); assert((Size == 0 || static_cast(EltInfo.Width.getQuantity()) <= (uint64_t)(-1)/Size) && "Overflow in array type char size evaluation"); @@ -1910,7 +1910,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { // Model non-constant sized arrays as size zero, but track the alignment. uint64_t Size = 0; if (const auto *CAT = dyn_cast(T)) - Size = CAT->getSize().getZExtValue(); + Size = CAT->getZExtSize(); TypeInfo EltInfo = getTypeInfo(cast(T)->getElementType()); assert((Size == 0 || EltInfo.Width <= (uint64_t)(-1) / Size) && @@ -3531,8 +3531,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, ArySize = ArySize.zextOrTrunc(Target->getMaxPointerWidth()); llvm::FoldingSetNodeID ID; - ConstantArrayType::Profile(ID, *this, EltTy, ArySize, SizeExpr, ASM, - IndexTypeQuals); + ConstantArrayType::Profile(ID, *this, EltTy, ArySize.getZExtValue(), SizeExpr, + ASM, IndexTypeQuals); void *InsertPos = nullptr; if (ConstantArrayType *ATP = @@ -3556,11 +3556,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP; } - void *Mem = Allocate( - ConstantArrayType::totalSizeToAlloc(SizeExpr ? 1 : 0), - alignof(ConstantArrayType)); - auto *New = new (Mem) - ConstantArrayType(EltTy, Canon, ArySize, SizeExpr, ASM, IndexTypeQuals); + auto *New = ConstantArrayType::Create(*this, EltTy, Canon, ArySize, SizeExpr, + ASM, IndexTypeQuals); ConstantArrayTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -7022,7 +7019,7 @@ uint64_t ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const { uint64_t ElementCount = 1; do { - ElementCount *= CA->getSize().getZExtValue(); + ElementCount *= CA->getZExtSize(); CA = dyn_cast_or_null( CA->getElementType()->getAsArrayTypeUnsafe()); } while (CA); @@ -8345,7 +8342,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, S += '['; if (const auto *CAT = dyn_cast(AT)) - S += llvm::utostr(CAT->getSize().getZExtValue()); + S += llvm::utostr(CAT->getZExtSize()); else { //Variable length arrays are encoded as a regular array with 0 elements. assert((isa(AT) || isa(AT)) && @@ -10779,7 +10776,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer, { const ConstantArrayType* LCAT = getAsConstantArrayType(LHS); const ConstantArrayType* RCAT = getAsConstantArrayType(RHS); - if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize()) + if (LCAT && RCAT && RCAT->getZExtSize() != LCAT->getZExtSize()) return {}; QualType LHSElem = getAsArrayType(LHS)->getElementType(); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 95900afdd2c5d..131f82985e903 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2840,7 +2840,7 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const { auto InitTy = Ctx.getAsConstantArrayType(FlexibleInit->getType()); if (!InitTy) return false; - return InitTy->getSize() != 0; + return !InitTy->isZeroSize(); } CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const { diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 592d43597dc1b..c5bdff0df06b4 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -209,7 +209,7 @@ namespace { IsArray = true; if (auto *CAT = dyn_cast(AT)) { - ArraySize = CAT->getSize().getZExtValue(); + ArraySize = CAT->getZExtSize(); } else { assert(I == 0 && "unexpected unsized array designator"); FirstEntryIsUnsizedArray = true; @@ -401,7 +401,7 @@ namespace { // This is a most-derived object. MostDerivedType = CAT->getElementType(); MostDerivedIsArrayElement = true; - MostDerivedArraySize = CAT->getSize().getZExtValue(); + MostDerivedArraySize = CAT->getZExtSize(); MostDerivedPathLength = Entries.size(); } /// Update this designator to refer to the first element within the array of @@ -3476,7 +3476,7 @@ static void expandStringLiteral(EvalInfo &Info, const StringLiteral *S, QualType CharType = CAT->getElementType(); assert(CharType->isIntegerType() && "unexpected character type"); - unsigned Elts = CAT->getSize().getZExtValue(); + unsigned Elts = CAT->getZExtSize(); Result = APValue(APValue::UninitArray(), std::min(S->getLength(), Elts), Elts); APSInt Value(Info.Ctx.getTypeSize(CharType), @@ -3619,7 +3619,7 @@ static bool CheckArraySize(EvalInfo &Info, const ConstantArrayType *CAT, SourceLocation CallLoc = {}) { return Info.CheckArraySize( CAT->getSizeExpr() ? CAT->getSizeExpr()->getBeginLoc() : CallLoc, - CAT->getNumAddressingBits(Info.Ctx), CAT->getSize().getZExtValue(), + CAT->getNumAddressingBits(Info.Ctx), CAT->getZExtSize(), /*Diag=*/true); } @@ -4908,7 +4908,7 @@ static bool handleDefaultInitValue(QualType T, APValue &Result) { if (auto *AT = dyn_cast_or_null(T->getAsArrayTypeUnsafe())) { - Result = APValue(APValue::UninitArray(), 0, AT->getSize().getZExtValue()); + Result = APValue(APValue::UninitArray(), 0, AT->getZExtSize()); if (Result.hasArrayFiller()) Success &= handleDefaultInitValue(AT->getElementType(), Result.getArrayFiller()); @@ -6595,7 +6595,7 @@ static bool HandleDestructionImpl(EvalInfo &Info, SourceRange CallRange, // For arrays, destroy elements right-to-left. if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(T)) { - uint64_t Size = CAT->getSize().getZExtValue(); + uint64_t Size = CAT->getZExtSize(); QualType ElemT = CAT->getElementType(); if (!CheckArraySize(Info, CAT, CallRange.getBegin())) @@ -7396,7 +7396,7 @@ class BufferToAPValueConverter { } std::optional visit(const ConstantArrayType *Ty, CharUnits Offset) { - size_t Size = Ty->getSize().getLimitedValue(); + size_t Size = Ty->getLimitedSize(); CharUnits ElementWidth = Info.Ctx.getTypeSizeInChars(Ty->getElementType()); APValue ArrayValue(APValue::UninitArray(), Size, Size); @@ -9951,7 +9951,7 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { assert(CAT && "unexpected type for array initializer"); unsigned Bits = - std::max(CAT->getSize().getBitWidth(), ArrayBound.getBitWidth()); + std::max(CAT->getSizeBitWidth(), ArrayBound.getBitWidth()); llvm::APInt InitBound = CAT->getSize().zext(Bits); llvm::APInt AllocBound = ArrayBound.zext(Bits); if (InitBound.ugt(AllocBound)) { @@ -10410,7 +10410,7 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr( if (Field->getType()->isIncompleteArrayType()) { if (auto *CAT = Info.Ctx.getAsConstantArrayType(Init->getType())) { - if (!CAT->getSize().isZero()) { + if (!CAT->isZeroSize()) { // Bail out for now. This might sort of "work", but the rest of the // code isn't really prepared to handle it. Info.FFDiag(Init, diag::note_constexpr_unsupported_flexible_array); @@ -10554,7 +10554,7 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr( // End pointer. if (!HandleLValueArrayAdjustment(Info, E, Array, ArrayType->getElementType(), - ArrayType->getSize().getZExtValue())) + ArrayType->getZExtSize())) return false; Array.moveInto(Result.getStructField(1)); } else if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType())) @@ -10996,8 +10996,7 @@ namespace { return Error(E); } - Result = APValue(APValue::UninitArray(), 0, - CAT->getSize().getZExtValue()); + Result = APValue(APValue::UninitArray(), 0, CAT->getZExtSize()); if (!Result.hasArrayFiller()) return true; @@ -11122,7 +11121,7 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr( Filler = Result.getArrayFiller(); unsigned NumEltsToInit = Args.size(); - unsigned NumElts = CAT->getSize().getZExtValue(); + unsigned NumElts = CAT->getZExtSize(); // If the initializer might depend on the array index, run it for each // array element. @@ -11180,7 +11179,7 @@ bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { auto *CAT = cast(E->getType()->castAsArrayTypeUnsafe()); - uint64_t Elements = CAT->getSize().getZExtValue(); + uint64_t Elements = CAT->getZExtSize(); Result = APValue(APValue::UninitArray(), Elements, Elements); LValue Subobject = This; @@ -11225,7 +11224,7 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E, bool HadZeroInit = Value->hasValue(); if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) { - unsigned FinalSize = CAT->getSize().getZExtValue(); + unsigned FinalSize = CAT->getZExtSize(); // Preserve the array filler if we had prior zero-initialization. APValue Filler = @@ -11940,7 +11939,7 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) { return true; const auto *CAT = cast(Ctx.getAsArrayType(BaseType)); uint64_t Index = Entry.getAsArrayIndex(); - if (Index + 1 != CAT->getSize()) + if (Index + 1 != CAT->getZExtSize()) return false; BaseType = CAT->getElementType(); } else if (BaseType->isAnyComplexType()) { diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index af214d4a8577c..6b19d6a620f32 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -819,7 +819,7 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni const ArrayType *AT = QT->getAsArrayTypeUnsafe(); assert(AT); const auto *CAT = cast(AT); - size_t NumElems = CAT->getSize().getZExtValue(); + size_t NumElems = CAT->getZExtSize(); PrimType ElemT = classifyPrim(CAT->getElementType()); for (size_t I = 0; I != NumElems; ++I) { @@ -992,7 +992,7 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { if (const Expr *Filler = E->getArrayFiller()) { const ConstantArrayType *CAT = Ctx.getASTContext().getAsConstantArrayType(E->getType()); - uint64_t NumElems = CAT->getSize().getZExtValue(); + uint64_t NumElems = CAT->getZExtSize(); for (; ElementIndex != NumElems; ++ElementIndex) { if (!this->visitArrayElemInit(ElementIndex, Filler)) @@ -1318,7 +1318,7 @@ bool ByteCodeExprGen::VisitStringLiteral(const StringLiteral *E) { // If the initializer string is too long, a diagnostic has already been // emitted. Read only the array length from the string literal. - unsigned ArraySize = CAT->getSize().getZExtValue(); + unsigned ArraySize = CAT->getZExtSize(); unsigned N = std::min(ArraySize, E->getLength()); size_t CharWidth = E->getCharByteWidth(); @@ -1919,7 +1919,7 @@ bool ByteCodeExprGen::VisitCXXConstructExpr( const ConstantArrayType *CAT = Ctx.getASTContext().getAsConstantArrayType(E->getType()); assert(CAT); - size_t NumElems = CAT->getSize().getZExtValue(); + size_t NumElems = CAT->getZExtSize(); const Function *Func = getFunction(E->getConstructor()); if (!Func || !Func->isConstexpr()) return false; diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 07b28d07326f9..d567b551f7f6f 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -66,7 +66,7 @@ static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc, const Pointer &BasePtr, const ConstantArrayType *CAT) { bool Result = true; - size_t NumElems = CAT->getSize().getZExtValue(); + size_t NumElems = CAT->getZExtSize(); QualType ElemType = CAT->getElementType(); if (ElemType->isRecordType()) { diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index da6f72c62115d..25e938e015032 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -355,7 +355,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty, QualType ElemTy = ArrayType->getElementType(); // Array of well-known bounds. if (auto CAT = dyn_cast(ArrayType)) { - size_t NumElems = CAT->getSize().getZExtValue(); + size_t NumElems = CAT->getZExtSize(); if (std::optional T = Ctx.classify(ElemTy)) { // Arrays of primitives. unsigned ElemSize = primSize(*T); diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index e27d44fc2ffe6..5861d5a7ea0dd 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -695,7 +695,7 @@ void JSONNodeDumper::VisitArrayType(const ArrayType *AT) { void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) { // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a // narrowing conversion to int64_t so it cannot be expressed. - JOS.attribute("size", CAT->getSize().getSExtValue()); + JOS.attribute("size", CAT->getSExtSize()); VisitArrayType(CAT); } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index aa26bb7ed46f4..12c44f8fa028e 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -4022,10 +4022,8 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, // char bar[42] = "foobar"; // Where it is truncated or zero-padded to fit the array. This is the length // used for mangling, and any trailing null-bytes also need to be mangled. - unsigned StringLength = getASTContext() - .getAsConstantArrayType(SL->getType()) - ->getSize() - .getZExtValue(); + unsigned StringLength = + getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize(); unsigned StringByteLength = StringLength * SL->getCharByteWidth(); // : The "kind" of string literal is encoded into the mangled name. diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp index 64c430e623b57..7ee21c8c61954 100644 --- a/clang/lib/AST/ScanfFormatString.cpp +++ b/clang/lib/AST/ScanfFormatString.cpp @@ -448,9 +448,7 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(RawQT)) { if (CAT->getSizeModifier() == ArraySizeModifier::Normal) FieldWidth = OptionalAmount(OptionalAmount::Constant, - CAT->getSize().getZExtValue() - 1, - "", 0, false); - + CAT->getZExtSize() - 1, "", 0, false); } return true; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 22666184c56cc..9a00b9ab83b38 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -159,6 +159,22 @@ ArrayType::ArrayType(TypeClass tc, QualType et, QualType can, ArrayTypeBits.SizeModifier = llvm::to_underlying(sm); } +ConstantArrayType * +ConstantArrayType::Create(const ASTContext &Ctx, QualType ET, QualType Can, + const llvm::APInt &Sz, const Expr *SzExpr, + ArraySizeModifier SzMod, unsigned Qual) { + bool NeedsExternalSize = SzExpr != nullptr || Sz.ugt(0x0FFFFFFFFFFFFFFF) || + Sz.getBitWidth() > 0xFF; + if (!NeedsExternalSize) + return new (Ctx, alignof(ConstantArrayType)) ConstantArrayType( + ET, Can, Sz.getBitWidth(), Sz.getZExtValue(), SzMod, Qual); + + auto *SzPtr = new (Ctx, alignof(ConstantArrayType::ExternalSize)) + ConstantArrayType::ExternalSize(Sz, SzExpr); + return new (Ctx, alignof(ConstantArrayType)) + ConstantArrayType(ET, Can, SzPtr, SzMod, Qual); +} + unsigned ConstantArrayType::getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements) { @@ -213,11 +229,10 @@ unsigned ConstantArrayType::getMaxSizeBits(const ASTContext &Context) { void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, QualType ET, - const llvm::APInt &ArraySize, - const Expr *SizeExpr, ArraySizeModifier SizeMod, - unsigned TypeQuals) { + uint64_t ArraySize, const Expr *SizeExpr, + ArraySizeModifier SizeMod, unsigned TypeQuals) { ID.AddPointer(ET.getAsOpaquePtr()); - ID.AddInteger(ArraySize.getZExtValue()); + ID.AddInteger(ArraySize); ID.AddInteger(llvm::to_underlying(SizeMod)); ID.AddInteger(TypeQuals); ID.AddBoolean(SizeExpr != nullptr); @@ -432,12 +447,8 @@ QualType QualType::getSingleStepDesugaredTypeImpl(QualType type, // Check that no type class has a non-trival destructor. Types are // allocated with the BumpPtrAllocator from ASTContext and therefore // their destructor is not executed. -// -// FIXME: ConstantArrayType is not trivially destructible because of its -// APInt member. It should be replaced in favor of ASTContext allocation. #define TYPE(CLASS, BASE) \ - static_assert(std::is_trivially_destructible::value || \ - std::is_same::value, \ + static_assert(std::is_trivially_destructible::value, \ #CLASS "Type should be trivially destructible!"); #include "clang/AST/TypeNodes.inc" diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 7dcc4348f8e03..458452f3e880e 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -537,7 +537,7 @@ void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T, if (T->getSizeModifier() == ArraySizeModifier::Static) OS << "static "; - OS << T->getSize().getZExtValue() << ']'; + OS << T->getZExtSize() << ']'; printAfter(T->getElementType(), OS); } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index de70cbbf6cdb3..64e6155de090c 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2039,7 +2039,7 @@ void CFGBuilder::addImplicitDtorsForDestructor(const CXXDestructorDecl *DD) { QualType QT = FI->getType(); // It may be a multidimensional array. while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { - if (AT->getSize() == 0) + if (AT->isZeroSize()) break; QT = AT->getElementType(); } @@ -2133,7 +2133,7 @@ bool CFGBuilder::hasTrivialDestructor(const VarDecl *VD) const { // Check for constant size array. Set type to array element type. while (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) { - if (AT->getSize() == 0) + if (AT->isZeroSize()) return true; QT = AT->getElementType(); } diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index e1ff0d92f6b2f..e03fe1b683004 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -403,10 +403,11 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) { QualType Arg0Ty = Arg0->IgnoreImplicit()->getType(); if (Arg0Ty->isConstantArrayType()) { - const APInt &ConstArrSize = cast(Arg0Ty)->getSize(); + const APSInt ConstArrSize = + APSInt(cast(Arg0Ty)->getSize()); // Check form 4: - return Arg1CV && APSInt::compareValues(APSInt(ConstArrSize), *Arg1CV) == 0; + return Arg1CV && APSInt::compareValues(ConstArrSize, *Arg1CV) == 0; } return false; } @@ -429,14 +430,13 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { BaseDRE->getDecl()->getType()); if (!CATy) return false; - const APInt ArrSize = CATy->getSize(); if (const auto *IdxLit = dyn_cast(Node.getIdx())) { const APInt ArrIdx = IdxLit->getValue(); // FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a // bug if (ArrIdx.isNonNegative() && - ArrIdx.getLimitedValue() < ArrSize.getLimitedValue()) + ArrIdx.getLimitedValue() < CATy->getLimitedSize()) return true; } diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp index efcff958ce545..acaae9f8c3d84 100644 --- a/clang/lib/CodeGen/ABIInfo.cpp +++ b/clang/lib/CodeGen/ABIInfo.cpp @@ -61,7 +61,7 @@ bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const { bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const { if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { - uint64_t NElements = AT->getSize().getZExtValue(); + uint64_t NElements = AT->getZExtSize(); if (NElements == 0) return false; if (!isHomogeneousAggregate(AT->getElementType(), Base, Members)) @@ -98,7 +98,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, QualType FT = FD->getType(); while (const ConstantArrayType *AT = getContext().getAsConstantArrayType(FT)) { - if (AT->getSize().getZExtValue() == 0) + if (AT->isZeroSize()) return false; FT = AT->getElementType(); } diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp index 2b20d5a13346d..dd59101ecc81b 100644 --- a/clang/lib/CodeGen/ABIInfoImpl.cpp +++ b/clang/lib/CodeGen/ABIInfoImpl.cpp @@ -257,7 +257,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD, bool WasArray = false; if (AllowArrays) while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { - if (AT->getSize() == 0) + if (AT->isZeroSize()) return true; FT = AT->getElementType(); // The [[no_unique_address]] special case below does not apply to @@ -352,7 +352,7 @@ const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) { // Treat single element arrays as the element. while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { - if (AT->getSize().getZExtValue() != 1) + if (AT->getZExtSize() != 1) break; FT = AT->getElementType(); } diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a28d7888715d8..475d96b0e87d7 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -933,8 +933,8 @@ struct NoExpansion : TypeExpansion { static std::unique_ptr getTypeExpansion(QualType Ty, const ASTContext &Context) { if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { - return std::make_unique( - AT->getElementType(), AT->getSize().getZExtValue()); + return std::make_unique(AT->getElementType(), + AT->getZExtSize()); } if (const RecordType *RT = Ty->getAs()) { SmallVector Bases; @@ -3086,7 +3086,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Align Alignment = CGM.getNaturalTypeAlignment(ETy).getAsAlign(); AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment)); - uint64_t ArrSize = ArrTy->getSize().getZExtValue(); + uint64_t ArrSize = ArrTy->getZExtSize(); if (!ETy->isIncompleteType() && ETy->isConstantSizeType() && ArrSize) { llvm::AttrBuilder Attrs(getLLVMContext()); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c2c01439f2dc9..7a64f793f4b07 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -3239,7 +3239,7 @@ llvm::DIType *CGDebugInfo::CreateType(const ArrayType *Ty, llvm::DIFile *Unit) { // }; int64_t Count = -1; // Count == -1 is an unbounded array. if (const auto *CAT = dyn_cast(Ty)) - Count = CAT->getSize().getZExtValue(); + Count = CAT->getZExtSize(); else if (const auto *VAT = dyn_cast(Ty)) { if (Expr *Size = VAT->getSizeExpr()) { Expr::EvalResult Result; diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 2adbef6d55122..35da0f1a89bc3 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1073,8 +1073,7 @@ void CodeGenFunction::EmitNewArrayInitializer( // Move past these elements. InitListElements = cast(Init->getType()->getAsArrayTypeUnsafe()) - ->getSize() - .getZExtValue(); + ->getZExtSize(); CurPtr = Builder.CreateConstInBoundsGEP( CurPtr, InitListElements, "string.init.end"); @@ -1591,8 +1590,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) { isa(IgnoreParen) || isa(IgnoreParen)) { minElements = cast(Init->getType()->getAsArrayTypeUnsafe()) - ->getSize() - .getZExtValue(); + ->getZExtSize(); } else if (ILE || CPLIE) { minElements = ILE ? ILE->getNumInits() : CPLIE->getInitExprs().size(); } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 75286dceb13a7..67a3cdc770426 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -656,7 +656,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, } unsigned NumElementsToUpdate = - FillC ? CAT->getSize().getZExtValue() : Updater->getNumInits(); + FillC ? CAT->getZExtSize() : Updater->getNumInits(); for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) { Expr *Init = nullptr; if (I < Updater->getNumInits()) @@ -1249,7 +1249,7 @@ class ConstExprEmitter : auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType()); assert(CAT && "can't emit array init for non-constant-bound array"); unsigned NumInitElements = ILE->getNumInits(); - unsigned NumElements = CAT->getSize().getZExtValue(); + unsigned NumElements = CAT->getZExtSize(); // Initialising an array requires us to automatically // initialise any elements that have not been initialised explicitly @@ -1374,7 +1374,7 @@ class ConstExprEmitter : // Resize the string to the right size, adding zeros at the end, or // truncating as needed. - Str.resize(CAT->getSize().getZExtValue(), '\0'); + Str.resize(CAT->getZExtSize(), '\0'); return llvm::ConstantDataArray::getString(VMContext, Str, false); } @@ -2382,7 +2382,7 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) { llvm::Constant *Element = ConstantEmitter::emitNullForMemory(*this, ElementTy); - unsigned NumElements = CAT->getSize().getZExtValue(); + unsigned NumElements = CAT->getZExtSize(); SmallVector Array(NumElements, Element); return llvm::ConstantArray::get(ATy, Array); } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index e815e097e1fb4..ed8d7b9a065d7 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2501,12 +2501,12 @@ void CGObjCCommonMac::BuildRCRecordLayout(const llvm::StructLayout *RecLayout, if (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { auto *CArray = cast(Array); - uint64_t ElCount = CArray->getSize().getZExtValue(); + uint64_t ElCount = CArray->getZExtSize(); assert(CArray && "only array with known element size is supported"); FQT = CArray->getElementType(); while (const ArrayType *Array = CGM.getContext().getAsArrayType(FQT)) { auto *CArray = cast(Array); - ElCount *= CArray->getSize().getZExtValue(); + ElCount *= CArray->getZExtSize(); FQT = CArray->getElementType(); } if (FQT->isRecordType() && ElCount) { @@ -5326,7 +5326,7 @@ void IvarLayoutBuilder::visitField(const FieldDecl *field, } // Unlike incomplete arrays, constant arrays can be nested. while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) { - numElts *= arrayType->getSize().getZExtValue(); + numElts *= arrayType->getZExtSize(); fieldType = arrayType->getElementType(); } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index e8a68dbcc6870..00e395c2a207f 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -6796,7 +6796,7 @@ class MappableExprsHandler { OASE->getBase()->IgnoreParenImpCasts()) .getCanonicalType(); if (const auto *ATy = dyn_cast(BaseQTy.getTypePtr())) - return ATy->getSize().getSExtValue() != 1; + return ATy->getSExtSize() != 1; // If we don't have a constant dimension length, we have to consider // the current section as having any size, so it is not necessarily // unitary. If it happen to be unity size, that's user fault. @@ -7546,8 +7546,8 @@ class MappableExprsHandler { // it. if (DimSizes.size() < Components.size() - 1) { if (CAT) - DimSizes.push_back(llvm::ConstantInt::get( - CGF.Int64Ty, CAT->getSize().getZExtValue())); + DimSizes.push_back( + llvm::ConstantInt::get(CGF.Int64Ty, CAT->getZExtSize())); else if (VAT) DimSizes.push_back(CGF.Builder.CreateIntCast( CGF.EmitScalarExpr(VAT->getSizeExpr()), CGF.Int64Ty, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4a3ff49b0007a..32a235b3fd057 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2187,8 +2187,8 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, dyn_cast(addr.getElementType()); while (llvmArrayType) { assert(isa(arrayType)); - assert(cast(arrayType)->getSize().getZExtValue() - == llvmArrayType->getNumElements()); + assert(cast(arrayType)->getZExtSize() == + llvmArrayType->getNumElements()); gepIndices.push_back(zero); countFromCLAs *= llvmArrayType->getNumElements(); @@ -2206,8 +2206,7 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, // as some other type (probably a packed struct). Compute the array // size, and just emit the 'begin' expression as a bitcast. while (arrayType) { - countFromCLAs *= - cast(arrayType)->getSize().getZExtValue(); + countFromCLAs *= cast(arrayType)->getZExtSize(); eltType = arrayType->getElementType(); arrayType = getContext().getAsArrayType(eltType); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8ceecff28cbc6..d79156c12a29f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -6244,7 +6244,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) { // Resize the string to the right size, which is indicated by its type. const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType()); assert(CAT && "String literal not of constant array type!"); - Str.resize(CAT->getSize().getZExtValue()); + Str.resize(CAT->getZExtSize()); return llvm::ConstantDataArray::getString(VMContext, Str, false); } diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index a6b51bfef8765..afadc29ab1b02 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -601,7 +601,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { EltTy = llvm::Type::getInt8Ty(getLLVMContext()); } - ResultType = llvm::ArrayType::get(EltTy, A->getSize().getZExtValue()); + ResultType = llvm::ArrayType::get(EltTy, A->getZExtSize()); break; } case Type::ExtVector: diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp index 16fbf52a517db..ab2e2bd0b3064 100644 --- a/clang/lib/CodeGen/SwiftCallingConv.cpp +++ b/clang/lib/CodeGen/SwiftCallingConv.cpp @@ -78,7 +78,7 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) { QualType eltType = arrayType->getElementType(); auto eltSize = CGM.getContext().getTypeSizeInChars(eltType); - for (uint64_t i = 0, e = arrayType->getSize().getZExtValue(); i != e; ++i) { + for (uint64_t i = 0, e = arrayType->getZExtSize(); i != e; ++i) { addTypedData(eltType, begin + i * eltSize); } diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp index 5d42e6286e525..885d9c77d0e76 100644 --- a/clang/lib/CodeGen/Targets/ARM.cpp +++ b/clang/lib/CodeGen/Targets/ARM.cpp @@ -671,7 +671,7 @@ bool ARMABIInfo::isIllegalVectorType(QualType Ty) const { /// Return true if a type contains any 16-bit floating point vectors bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const { if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { - uint64_t NElements = AT->getSize().getZExtValue(); + uint64_t NElements = AT->getZExtSize(); if (NElements == 0) return false; return containsAnyFP16Vectors(AT->getElementType()); diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp index 63b9a1fdb988c..3f01d9ad90f13 100644 --- a/clang/lib/CodeGen/Targets/LoongArch.cpp +++ b/clang/lib/CodeGen/Targets/LoongArch.cpp @@ -146,7 +146,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper( } if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) { - uint64_t ArraySize = ATy->getSize().getZExtValue(); + uint64_t ArraySize = ATy->getZExtSize(); QualType EltTy = ATy->getElementType(); // Non-zero-length arrays of empty records make the struct ineligible to be // passed via FARs in C++. diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 9a79424c4612c..7b32c79723562 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -152,7 +152,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff, } if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) { - uint64_t ArraySize = ATy->getSize().getZExtValue(); + uint64_t ArraySize = ATy->getZExtSize(); QualType EltTy = ATy->getElementType(); // Non-zero-length arrays of empty records make the struct ineligible for // the FP calling convention in C++. diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 2291c991fb110..1679e7776ee20 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -1993,7 +1993,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, // this, but it isn't worth it and would be harder to verify. Current = NoClass; uint64_t EltSize = getContext().getTypeSize(AT->getElementType()); - uint64_t ArraySize = AT->getSize().getZExtValue(); + uint64_t ArraySize = AT->getZExtSize(); // The only case a 256-bit wide vector could be used is when the array // contains a single 256-bit element. Since Lo and Hi logic isn't extended @@ -2295,7 +2295,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType()); - unsigned NumElts = (unsigned)AT->getSize().getZExtValue(); + unsigned NumElts = (unsigned)AT->getZExtSize(); // Check each element to see if the element overlaps with the queried range. for (unsigned i = 0; i != NumElts; ++i) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a0b256ab5579e..5044f8f7736dc 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1098,7 +1098,7 @@ static bool ProcessFormatStringLiteral(const Expr *FormatExpr, const ConstantArrayType *T = Context.getAsConstantArrayType(Format->getType()); assert(T && "String literal not of constant array type!"); - size_t TypeSize = T->getSize().getZExtValue(); + size_t TypeSize = T->getZExtSize(); // In case there's a null byte somewhere. StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, FormatStrRef.find(0)); return true; @@ -12970,7 +12970,7 @@ static void CheckFormatString( const ConstantArrayType *T = S.Context.getAsConstantArrayType(FExpr->getType()); assert(T && "String literal not of constant array type!"); - size_t TypeSize = T->getSize().getZExtValue(); + size_t TypeSize = T->getZExtSize(); size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size()); const unsigned numDataArgs = Args.size() - firstDataArg; @@ -13030,7 +13030,7 @@ bool Sema::FormatStringHasSArg(const StringLiteral *FExpr) { // Account for cases where the string literal is truncated in a declaration. const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType()); assert(T && "String literal not of constant array type!"); - size_t TypeSize = T->getSize().getZExtValue(); + size_t TypeSize = T->getZExtSize(); size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size()); return analyze_format_string::ParseFormatStringHasSArg(Str, Str + StrLen, getLangOpts(), @@ -13993,7 +13993,7 @@ static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, // Only handle constant-sized or VLAs, but not flexible members. if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(Ty)) { // Only issue the FIXIT for arrays of size > 1. - if (CAT->getSize().getSExtValue() <= 1) + if (CAT->getZExtSize() <= 1) return false; } else if (!Ty->isVariableArrayType()) { return false; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5850cd0ab6b9a..13ca830789417 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -8843,7 +8843,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { return; } const auto *ATy = dyn_cast(T.getTypePtr()); - if (!ATy || ATy->getSize().getSExtValue() != 0) { + if (!ATy || ATy->getZExtSize() != 0) { Diag(NewVD->getLocation(), diag::err_typecheck_wasm_table_must_have_zero_length); NewVD->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index e258a4f7c8941..bef7e9636a68d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5282,7 +5282,7 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { return true; while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) { - if (!ArrayT->getSize()) + if (ArrayT->isZeroSize()) return true; T = ArrayT->getElementType(); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8725b09f8546c..a5af65ff775a1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6833,9 +6833,8 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc, ArgCAT->getElementType())) { if (ArgCAT->getSize().ult(CAT->getSize())) { Diag(CallLoc, diag::warn_static_array_too_small) - << ArgExpr->getSourceRange() - << (unsigned)ArgCAT->getSize().getZExtValue() - << (unsigned)CAT->getSize().getZExtValue() << 0; + << ArgExpr->getSourceRange() << (unsigned)ArgCAT->getZExtSize() + << (unsigned)CAT->getZExtSize() << 0; DiagnoseCalleeStaticArrayParam(*this, Param); } return; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index c34a40fa7c81a..51c8e04bee8c3 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6083,7 +6083,7 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT, if (Matched && T->isArrayType()) { if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T)) - return CAT->getSize().getLimitedValue(); + return CAT->getLimitedSize(); } } return 0; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index aa470adb30b47..2b4805d62d07d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -213,7 +213,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, // Get the length of the string as parsed. auto *ConstantArrayTy = cast(Str->getType()->getAsArrayTypeUnsafe()); - uint64_t StrLength = ConstantArrayTy->getSize().getZExtValue(); + uint64_t StrLength = ConstantArrayTy->getZExtSize(); if (CheckC23ConstexprInit) if (const StringLiteral *SL = dyn_cast(Str->IgnoreParens())) @@ -246,14 +246,13 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, } // [dcl.init.string]p2 - if (StrLength > CAT->getSize().getZExtValue()) + if (StrLength > CAT->getZExtSize()) S.Diag(Str->getBeginLoc(), diag::err_initializer_string_for_char_array_too_long) - << CAT->getSize().getZExtValue() << StrLength - << Str->getSourceRange(); + << CAT->getZExtSize() << StrLength << Str->getSourceRange(); } else { // C99 6.7.8p14. - if (StrLength-1 > CAT->getSize().getZExtValue()) + if (StrLength - 1 > CAT->getZExtSize()) S.Diag(Str->getBeginLoc(), diag::ext_initializer_string_for_char_array_too_long) << Str->getSourceRange(); @@ -879,7 +878,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity, if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) { ElementType = AType->getElementType(); if (const auto *CAType = dyn_cast(AType)) - NumElements = CAType->getSize().getZExtValue(); + NumElements = CAType->getZExtSize(); // For an array new with an unknown bound, ask for one additional element // in order to populate the array filler. if (Entity.isVariableLengthArrayNew()) @@ -1016,7 +1015,7 @@ int InitListChecker::numArrayElements(QualType DeclType) { int maxElements = 0x7FFFFFFF; if (const ConstantArrayType *CAT = SemaRef.Context.getAsConstantArrayType(DeclType)) { - maxElements = static_cast(CAT->getSize().getZExtValue()); + maxElements = static_cast(CAT->getZExtSize()); } return maxElements; } @@ -3101,7 +3100,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Get the length of the string. uint64_t StrLen = SL->getLength(); if (cast(AT)->getSize().ult(StrLen)) - StrLen = cast(AT)->getSize().getZExtValue(); + StrLen = cast(AT)->getZExtSize(); StructuredList->resizeInits(Context, StrLen); // Build a literal for each character in the string, and put them into @@ -3124,7 +3123,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Get the length of the string. uint64_t StrLen = Str.size(); if (cast(AT)->getSize().ult(StrLen)) - StrLen = cast(AT)->getSize().getZExtValue(); + StrLen = cast(AT)->getZExtSize(); StructuredList->resizeInits(Context, StrLen); // Build a literal for each character in the string, and put them into @@ -3283,7 +3282,7 @@ InitListChecker::createInitListExpr(QualType CurrentObjectType, if (const ArrayType *AType = SemaRef.Context.getAsArrayType(CurrentObjectType)) { if (const ConstantArrayType *CAType = dyn_cast(AType)) { - NumElements = CAType->getSize().getZExtValue(); + NumElements = CAType->getZExtSize(); // Simple heuristic so that we don't allocate a very large // initializer with many empty entries at the end. if (NumElements > ExpectedNumInits) @@ -5492,7 +5491,7 @@ static void TryOrBuildParenListInitialization( // having k elements. if (const ConstantArrayType *CAT = S.getASTContext().getAsConstantArrayType(Entity.getType())) { - ArrayLength = CAT->getSize().getZExtValue(); + ArrayLength = CAT->getZExtSize(); ResultType = Entity.getType(); } else if (const VariableArrayType *VAT = S.getASTContext().getAsVariableArrayType(Entity.getType())) { diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index e9ad7bbde0f9b..0ba54a3a9cae3 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -21284,7 +21284,7 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, if (isa(E) || (OASE && OASE->getColonLocFirst().isInvalid())) { if (const auto *ATy = dyn_cast(BaseQTy.getTypePtr())) - return ATy->getSize().getSExtValue() != 1; + return ATy->getSExtSize() != 1; // Size can't be evaluated statically. return false; } @@ -21325,7 +21325,7 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, return false; // Can't get the integer value as a constant. llvm::APSInt ConstLength = Result.Val.getInt(); - return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); + return CATy->getSExtSize() != ConstLength.getSExtValue(); } // Return true if it can be proven that the provided array expression (array @@ -21350,7 +21350,7 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, // is pointer. if (!Length) { if (const auto *ATy = dyn_cast(BaseQTy.getTypePtr())) - return ATy->getSize().getSExtValue() != 1; + return ATy->getSExtSize() != 1; // We cannot assume anything. return false; } diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index ca0254d29e7f4..18ebaa13346a4 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -35,7 +35,7 @@ Sema::SemaDiagnosticBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc, static bool isZeroSizedArray(Sema &SemaRef, QualType Ty) { if (const auto *CAT = SemaRef.getASTContext().getAsConstantArrayType(Ty)) - return CAT->getSize() == 0; + return CAT->isZeroSize(); return false; } diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp index a50772f881f7d..2cff97a591b8c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp @@ -68,7 +68,7 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize, FlexSize = Ctx.getTypeSizeInChars(ElemType); if (ArrayTy->getSize() == 1 && TypeSize > FlexSize) TypeSize -= FlexSize; - else if (ArrayTy->getSize() != 0) + else if (!ArrayTy->isZeroSize()) return false; } else if (RD->hasFlexibleArrayMember()) { FlexSize = Ctx.getTypeSizeInChars(ElemType); diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index eee9449f31805..4f35d9442ad98 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -117,7 +117,7 @@ class PaddingChecker : public Checker> { return; uint64_t Elts = 0; if (const ConstantArrayType *CArrTy = dyn_cast(ArrTy)) - Elts = CArrTy->getSize().getZExtValue(); + Elts = CArrTy->getZExtSize(); if (Elts == 0) return; const RecordType *RT = ArrTy->getElementType()->getAs(); diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 16db6b249dc92..a98e32ec4c6f0 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -817,7 +817,7 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR, }; auto IsArrayOfZero = [](const ArrayType *AT) { const auto *CAT = dyn_cast(AT); - return CAT && CAT->getSize() == 0; + return CAT && CAT->isZeroSize(); }; auto IsArrayOfOne = [](const ArrayType *AT) { const auto *CAT = dyn_cast(AT); diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index da9a1a1a4d1f6..755a8c4b22fd9 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1166,7 +1166,7 @@ void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR, // Compute lower and upper offsets for region within array. if (const ConstantArrayType *CAT = dyn_cast(AT)) - NumElements = CAT->getSize().getZExtValue(); + NumElements = CAT->getZExtSize(); if (!NumElements) // We are not dealing with a constant size array goto conjure_default; QualType ElementTy = AT->getElementType(); @@ -1613,7 +1613,7 @@ getConstantArrayExtents(const ConstantArrayType *CAT) { CAT = cast(CAT->getCanonicalTypeInternal()); SmallVector Extents; do { - Extents.push_back(CAT->getSize().getZExtValue()); + Extents.push_back(CAT->getZExtSize()); } while ((CAT = dyn_cast(CAT->getElementType()))); return Extents; } @@ -2436,7 +2436,7 @@ std::optional RegionStoreManager::tryBindSmallArray( return std::nullopt; // If the array is too big, create a LCV instead. - uint64_t ArrSize = CAT->getSize().getLimitedValue(); + uint64_t ArrSize = CAT->getLimitedSize(); if (ArrSize > SmallArrayLimit) return std::nullopt; @@ -2465,7 +2465,7 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B, std::optional Size; if (const ConstantArrayType* CAT = dyn_cast(AT)) - Size = CAT->getSize().getZExtValue(); + Size = CAT->getZExtSize(); // Check if the init expr is a literal. If so, bind the rvalue instead. // FIXME: It's not responsibility of the Store to transform this lvalue