================ @@ -3182,34 +3182,100 @@ class ArrayType : public Type, public llvm::FoldingSetNode { /// 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<ConstantArrayType, const Expr *> { + : 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; + }; + struct InlineSize { + InlineSize(uint64_t TSz, uint64_t Sz) : ByteWidth(TSz), Size(Sz) {} + uint64_t ByteWidth : 4; + uint64_t Size : 60; + }; + union { + struct InlineSize I; + ExternalSize *SizePtr; + }; - 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<const Expr*>() = sz; - } + ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz, + ArraySizeModifier SM, unsigned TQ) + : ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), I(Width / 8, Sz) { + ConstantArrayTypeBits.HasExternalSize = false; + assert(Sz < 0x0FFFFFFFFFFFFFFF && "Size must fit in 60 bits"); + // The in-structure size stores the size in bytes rather than bits so we + // drop the four least significant bits since they're always zero anyways. + assert(Width < 0xFF && "Type width must fit in 8 bits"); } - unsigned numTrailingObjects(OverloadToken<const Expr*>) 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; + + 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(I.ByteWidth * 8, I.Size); + } + + /// Return the bit width of the size type. + unsigned getSizeBitWidth() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getBitWidth() + : static_cast<unsigned>(I.ByteWidth * 8); + } + + /// Return true if the size is zero. + bool isZeroSize() const { + return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero() + : 0 == I.Size; + } + + /// Return the size zero-extended as a uint64_t. + uint64_t getZExtSize() const { + return ConstantArrayTypeBits.HasExternalSize + ? SizePtr->Size.getZExtValue() + : I.Size; + } + + /// Return the size zero-extended as a uint64_t. ---------------- efriedma-quic wrote:
Sign-extended https://github.com/llvm/llvm-project/pull/85716 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits