https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/226115
>From 8498665ba05c046e8696b8678ce9c31a42b4f454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Thu, 24 Sep 2026 12:05:26 +0200 Subject: [PATCH] Copy CharUnits parameters --- clang/include/clang/AST/APValue.h | 28 +-- clang/include/clang/AST/CharUnits.h | 374 +++++++++++++--------------- clang/lib/AST/APValue.cpp | 7 +- clang/lib/AST/ASTContext.cpp | 2 +- clang/lib/AST/ExprConstant.cpp | 10 +- 5 files changed, 192 insertions(+), 229 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index ef25f99b48544..45a08e4d614ef 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_APVALUE_H #define LLVM_CLANG_AST_APVALUE_H +#include "clang/AST/CharUnits.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/APFixedPoint.h" #include "llvm/ADT/APFloat.h" @@ -30,7 +31,6 @@ template <typename T> class BasicReaderBase; class AddrLabelExpr; class ASTContext; - class CharUnits; class CXXRecordDecl; class Decl; class DiagnosticBuilder; @@ -376,7 +376,7 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { /// \param Base The base of the lvalue. /// \param Offset The offset of the lvalue. /// \param IsNullPtr Whether this lvalue is a null pointer. - APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath, + APValue(LValueBase Base, CharUnits Offset, NoLValuePath, bool IsNullPtr = false) : Kind(None), AllowConstexprUnknown(false) { MakeLValue(); @@ -389,9 +389,8 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { /// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the /// subobject it points to. /// \param IsNullPtr Whether this lvalue is a null pointer. - APValue(LValueBase Base, const CharUnits &Offset, - ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, - bool IsNullPtr = false) + APValue(LValueBase Base, CharUnits Offset, ArrayRef<LValuePathEntry> Path, + bool OnePastTheEnd, bool IsNullPtr = false) : Kind(None), AllowConstexprUnknown(false) { MakeLValue(); setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr); @@ -400,7 +399,7 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { /// \param Base The base of the lvalue. /// \param Offset The offset of the lvalue. /// \param IsNullPtr Whether this lvalue is a null pointer. - APValue(LValueBase Base, const CharUnits &Offset, ConstexprUnknown, + APValue(LValueBase Base, CharUnits Offset, ConstexprUnknown, bool IsNullPtr = false) : Kind(None), AllowConstexprUnknown(true) { MakeLValue(); @@ -573,7 +572,7 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { const LValueBase getLValueBase() const; CharUnits &getLValueOffset(); - const CharUnits &getLValueOffset() const { + CharUnits getLValueOffset() const { return const_cast<APValue*>(this)->getLValueOffset(); } bool isLValueOnePastTheEnd() const; @@ -754,11 +753,9 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { ((ComplexAPFloat *)(char *)&Data)->Real = std::move(R); ((ComplexAPFloat *)(char *)&Data)->Imag = std::move(I); } - void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, - bool IsNullPtr); - void setLValue(LValueBase B, const CharUnits &O, - ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd, - bool IsNullPtr); + void setLValue(LValueBase B, CharUnits O, NoLValuePath, bool IsNullPtr); + void setLValue(LValueBase B, CharUnits O, ArrayRef<LValuePathEntry> Path, + bool OnePastTheEnd, bool IsNullPtr); void setUnion(const FieldDecl *Field, const APValue &Value); void setAddrLabelDiff(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr) { @@ -853,9 +850,10 @@ class LLVM_ATTRIBUTE_WARN_UNUSED APValue { M->NumCols = NumCols; return {M->Elts, NumElts}; } - MutableArrayRef<LValuePathEntry> - setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, - bool OnePastTheEnd, bool IsNullPtr); + MutableArrayRef<LValuePathEntry> setLValueUninit(LValueBase B, CharUnits O, + unsigned Size, + bool OnePastTheEnd, + bool IsNullPtr); MutableArrayRef<const CXXRecordDecl *> setMemberPointerUninit(const ValueDecl *Member, bool IsDerivedMember, unsigned Size); diff --git a/clang/include/clang/AST/CharUnits.h b/clang/include/clang/AST/CharUnits.h index aee838e60f948..e432570128e6f 100644 --- a/clang/include/clang/AST/CharUnits.h +++ b/clang/include/clang/AST/CharUnits.h @@ -20,223 +20,189 @@ namespace clang { - /// CharUnits - This is an opaque type for sizes expressed in character units. - /// Instances of this type represent a quantity as a multiple of the size - /// of the standard C type, char, on the target architecture. As an opaque - /// type, CharUnits protects you from accidentally combining operations on - /// quantities in bit units and character units. - /// - /// In both C and C++, an object of type 'char', 'signed char', or 'unsigned - /// char' occupies exactly one byte, so 'character unit' and 'byte' refer to - /// the same quantity of storage. However, we use the term 'character unit' - /// rather than 'byte' to avoid an implication that a character unit is - /// exactly 8 bits. +/// This is an opaque type for sizes expressed in character units. +/// Instances of this type represent a quantity as a multiple of the size +/// of the standard C type, char, on the target architecture. As an opaque +/// type, CharUnits protects you from accidentally combining operations on +/// quantities in bit units and character units. +/// +/// In both C and C++, an object of type 'char', 'signed char', or 'unsigned +/// char' occupies exactly one byte, so 'character unit' and 'byte' refer to +/// the same quantity of storage. However, we use the term 'character unit' +/// rather than 'byte' to avoid an implication that a character unit is +/// exactly 8 bits. +/// +/// For portability, never assume that a target character is 8 bits wide. Use +/// CharUnit values wherever you calculate sizes, offsets, or alignments +/// in character units. +class CharUnits { +public: + typedef int64_t QuantityType; + +private: + QuantityType Quantity = 0; + + explicit CharUnits(QuantityType C) : Quantity(C) {} + +public: + /// A default constructor. + CharUnits() = default; + + /// Construct a CharUnits quantity of zero. + static CharUnits Zero() { return CharUnits(0); } + + /// Construct a CharUnits quantity of one. + static CharUnits One() { return CharUnits(1); } + + /// Construct a CharUnits quantity from a raw integer type. + static CharUnits fromQuantity(QuantityType Quantity) { + return CharUnits(Quantity); + } + + /// Construct a CharUnits quantity from an llvm::Align + /// quantity. + static CharUnits fromQuantity(llvm::Align Quantity) { + return CharUnits(Quantity.value()); + } + + // Compound assignment. + CharUnits &operator+=(CharUnits Other) { + Quantity += Other.Quantity; + return *this; + } + CharUnits &operator++() { + ++Quantity; + return *this; + } + CharUnits operator++(int) { return CharUnits(Quantity++); } + CharUnits &operator-=(CharUnits Other) { + Quantity -= Other.Quantity; + return *this; + } + CharUnits &operator--() { + --Quantity; + return *this; + } + CharUnits operator--(int) { return CharUnits(Quantity--); } + + // Comparison operators. + bool operator==(CharUnits Other) const { return Quantity == Other.Quantity; } + bool operator!=(CharUnits Other) const { return Quantity != Other.Quantity; } + + // Relational operators. + bool operator<(CharUnits Other) const { return Quantity < Other.Quantity; } + bool operator<=(CharUnits Other) const { return Quantity <= Other.Quantity; } + bool operator>(CharUnits Other) const { return Quantity > Other.Quantity; } + bool operator>=(CharUnits Other) const { return Quantity >= Other.Quantity; } + + // Other predicates. + + /// Test whether the quantity equals zero. + bool isZero() const { return Quantity == 0; } + + /// Test whether the quantity equals one. + bool isOne() const { return Quantity == 1; } + + /// Test whether the quantity is greater than zero. + bool isPositive() const { return Quantity > 0; } + + /// Test whether the quantity is less than zero. + bool isNegative() const { return Quantity < 0; } + + /// Test whether the quantity is a power of two. + /// Zero is not a power of two. + bool isPowerOfTwo() const { return (Quantity & -Quantity) == Quantity; } + + /// Test whether this is a multiple of the other value. /// - /// For portability, never assume that a target character is 8 bits wide. Use - /// CharUnit values wherever you calculate sizes, offsets, or alignments - /// in character units. - class CharUnits { - public: - typedef int64_t QuantityType; - - private: - QuantityType Quantity = 0; - - explicit CharUnits(QuantityType C) : Quantity(C) {} - - public: - - /// CharUnits - A default constructor. - CharUnits() = default; - - /// Zero - Construct a CharUnits quantity of zero. - static CharUnits Zero() { - return CharUnits(0); - } - - /// One - Construct a CharUnits quantity of one. - static CharUnits One() { - return CharUnits(1); - } - - /// fromQuantity - Construct a CharUnits quantity from a raw integer type. - static CharUnits fromQuantity(QuantityType Quantity) { - return CharUnits(Quantity); - } - - /// fromQuantity - Construct a CharUnits quantity from an llvm::Align - /// quantity. - static CharUnits fromQuantity(llvm::Align Quantity) { - return CharUnits(Quantity.value()); - } - - // Compound assignment. - CharUnits& operator+= (const CharUnits &Other) { - Quantity += Other.Quantity; - return *this; - } - CharUnits& operator++ () { - ++Quantity; - return *this; - } - CharUnits operator++ (int) { - return CharUnits(Quantity++); - } - CharUnits& operator-= (const CharUnits &Other) { - Quantity -= Other.Quantity; - return *this; - } - CharUnits& operator-- () { - --Quantity; - return *this; - } - CharUnits operator-- (int) { - return CharUnits(Quantity--); - } - - // Comparison operators. - bool operator== (const CharUnits &Other) const { - return Quantity == Other.Quantity; - } - bool operator!= (const CharUnits &Other) const { - return Quantity != Other.Quantity; - } - - // Relational operators. - bool operator< (const CharUnits &Other) const { - return Quantity < Other.Quantity; - } - bool operator<= (const CharUnits &Other) const { - return Quantity <= Other.Quantity; - } - bool operator> (const CharUnits &Other) const { - return Quantity > Other.Quantity; - } - bool operator>= (const CharUnits &Other) const { - return Quantity >= Other.Quantity; - } - - // Other predicates. - - /// isZero - Test whether the quantity equals zero. - bool isZero() const { return Quantity == 0; } - - /// isOne - Test whether the quantity equals one. - bool isOne() const { return Quantity == 1; } - - /// isPositive - Test whether the quantity is greater than zero. - bool isPositive() const { return Quantity > 0; } - - /// isNegative - Test whether the quantity is less than zero. - bool isNegative() const { return Quantity < 0; } - - /// isPowerOfTwo - Test whether the quantity is a power of two. - /// Zero is not a power of two. - bool isPowerOfTwo() const { - return (Quantity & -Quantity) == Quantity; - } - - /// Test whether this is a multiple of the other value. - /// - /// Among other things, this promises that - /// self.alignTo(N) will just return self. - bool isMultipleOf(CharUnits N) const { - return (*this % N) == CharUnits::Zero(); - } - - // Arithmetic operators. - CharUnits operator* (QuantityType N) const { - return CharUnits(Quantity * N); - } - CharUnits &operator*= (QuantityType N) { - Quantity *= N; - return *this; - } - CharUnits operator/ (QuantityType N) const { - return CharUnits(Quantity / N); - } - CharUnits &operator/= (QuantityType N) { - Quantity /= N; - return *this; - } - QuantityType operator/ (const CharUnits &Other) const { - return Quantity / Other.Quantity; - } - CharUnits operator% (QuantityType N) const { - return CharUnits(Quantity % N); - } - CharUnits operator%(const CharUnits &Other) const { - return CharUnits(Quantity % Other.Quantity); - } - CharUnits operator+ (const CharUnits &Other) const { - return CharUnits(Quantity + Other.Quantity); - } - CharUnits operator- (const CharUnits &Other) const { - return CharUnits(Quantity - Other.Quantity); - } - CharUnits operator- () const { - return CharUnits(-Quantity); - } - - - // Conversions. - - /// getQuantity - Get the raw integer representation of this quantity. - QuantityType getQuantity() const { return Quantity; } - - /// getAsAlign - Returns Quantity as a valid llvm::Align, - /// Beware llvm::Align assumes power of two 8-bit bytes. - llvm::Align getAsAlign() const { return llvm::Align(Quantity); } - - /// getAsMaybeAlign - Returns Quantity as a valid llvm::Align or - /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit - /// bytes. - llvm::MaybeAlign getAsMaybeAlign() const { - return llvm::MaybeAlign(Quantity); - } - - /// alignTo - Returns the next integer (mod 2**64) that is - /// greater than or equal to this quantity and is a multiple of \p Align. - /// Align must be non-zero. - CharUnits alignTo(const CharUnits &Align) const { - return CharUnits(llvm::alignTo(Quantity, Align.Quantity)); - } - - /// Given that this is a non-zero alignment value, what is the - /// alignment at the given offset? - CharUnits alignmentAtOffset(CharUnits offset) const { - assert(Quantity != 0 && "offsetting from unknown alignment?"); - return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); - } - - /// Given that this is the alignment of the first element of an - /// array, return the minimum alignment of any element in the array. - CharUnits alignmentOfArrayElement(CharUnits elementSize) const { - // Since we don't track offsetted alignments, the alignment of - // the second element (or any odd element) will be minimally - // aligned. - return alignmentAtOffset(elementSize); - } - - - }; // class CharUnit + /// Among other things, this promises that + /// self.alignTo(N) will just return self. + bool isMultipleOf(CharUnits N) const { + return (*this % N) == CharUnits::Zero(); + } + + // Arithmetic operators. + CharUnits operator*(QuantityType N) const { return CharUnits(Quantity * N); } + CharUnits &operator*=(QuantityType N) { + Quantity *= N; + return *this; + } + CharUnits operator/(QuantityType N) const { return CharUnits(Quantity / N); } + CharUnits &operator/=(QuantityType N) { + Quantity /= N; + return *this; + } + QuantityType operator/(CharUnits Other) const { + return Quantity / Other.Quantity; + } + CharUnits operator%(QuantityType N) const { return CharUnits(Quantity % N); } + CharUnits operator%(CharUnits Other) const { + return CharUnits(Quantity % Other.Quantity); + } + CharUnits operator+(CharUnits Other) const { + return CharUnits(Quantity + Other.Quantity); + } + CharUnits operator-(CharUnits Other) const { + return CharUnits(Quantity - Other.Quantity); + } + CharUnits operator-() const { return CharUnits(-Quantity); } + + // Conversions. + + /// Get the raw integer representation of this quantity. + QuantityType getQuantity() const { return Quantity; } + + /// Returns Quantity as a valid llvm::Align, + /// Beware llvm::Align assumes power of two 8-bit bytes. + llvm::Align getAsAlign() const { return llvm::Align(Quantity); } + + /// Returns Quantity as a valid llvm::Align or + /// std::nullopt, Beware llvm::MaybeAlign assumes power of two 8-bit + /// bytes. + llvm::MaybeAlign getAsMaybeAlign() const { + return llvm::MaybeAlign(Quantity); + } + + /// Returns the next integer (mod 2**64) that is + /// greater than or equal to this quantity and is a multiple of \p Align. + /// Align must be non-zero. + CharUnits alignTo(CharUnits Align) const { + return CharUnits(llvm::alignTo(Quantity, Align.Quantity)); + } + + /// Given that this is a non-zero alignment value, what is the + /// alignment at the given offset? + CharUnits alignmentAtOffset(CharUnits offset) const { + assert(Quantity != 0 && "offsetting from unknown alignment?"); + return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); + } + + /// Given that this is the alignment of the first element of an + /// array, return the minimum alignment of any element in the array. + CharUnits alignmentOfArrayElement(CharUnits elementSize) const { + // Since we don't track offsetted alignments, the alignment of + // the second element (or any odd element) will be minimally + // aligned. + return alignmentAtOffset(elementSize); + } + +}; // class CharUnit } // namespace clang -inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, - const clang::CharUnits &CU) { +inline clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, + clang::CharUnits CU) { return CU * Scale; } namespace llvm { template<> struct DenseMapInfo<clang::CharUnits> { - static unsigned getHashValue(const clang::CharUnits &CU) { + static unsigned getHashValue(clang::CharUnits CU) { clang::CharUnits::QuantityType Quantity = CU.getQuantity(); return DenseMapInfo<clang::CharUnits::QuantityType>::getHashValue(Quantity); } - static bool isEqual(const clang::CharUnits &LHS, - const clang::CharUnits &RHS) { + static bool isEqual(clang::CharUnits LHS, clang::CharUnits RHS) { return LHS == RHS; } }; diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp index 3e61281fabd3f..4f42b7f5f037b 100644 --- a/clang/lib/AST/APValue.cpp +++ b/clang/lib/AST/APValue.cpp @@ -13,7 +13,6 @@ #include "clang/AST/APValue.h" #include "Linkage.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/CharUnits.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -1050,7 +1049,7 @@ bool APValue::isNullPointer() const { return ((const LV *)(const char *)&Data)->IsNullPtr; } -void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, +void APValue::setLValue(LValueBase B, CharUnits O, NoLValuePath, bool IsNullPtr) { assert(isLValue() && "Invalid accessor"); LV &LVal = *((LV *)(char *)&Data); @@ -1062,7 +1061,7 @@ void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, } MutableArrayRef<APValue::LValuePathEntry> -APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, +APValue::setLValueUninit(LValueBase B, CharUnits O, unsigned Size, bool IsOnePastTheEnd, bool IsNullPtr) { assert(isLValue() && "Invalid accessor"); LV &LVal = *((LV *)(char *)&Data); @@ -1074,7 +1073,7 @@ APValue::setLValueUninit(LValueBase B, const CharUnits &O, unsigned Size, return {LVal.getPath(), Size}; } -void APValue::setLValue(LValueBase B, const CharUnits &O, +void APValue::setLValue(LValueBase B, CharUnits O, ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, bool IsNullPtr) { MutableArrayRef<APValue::LValuePathEntry> InternalPath = diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5e3296a418c90..2c0db63d1fcfd 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8878,7 +8878,7 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const { return InlineVariableDefinitionKind::WeakUnknown; } -static std::string charUnitsToString(const CharUnits &CU) { +static std::string charUnitsToString(CharUnits CU) { return llvm::itostr(CU.getQuantity()); } diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 72baa9406cdde..9e21d35ea2145 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1448,7 +1448,7 @@ namespace { const APValue::LValueBase getLValueBase() const { return Base; } bool allowConstexprUnknown() const { return AllowConstexprUnknown; } CharUnits &getLValueOffset() { return Offset; } - const CharUnits &getLValueOffset() const { return Offset; } + CharUnits getLValueOffset() const { return Offset; } SubobjectDesignator &getLValueDesignator() { return Designator; } const SubobjectDesignator &getLValueDesignator() const { return Designator;} bool isNullPointer() const { return IsNullPtr;} @@ -19386,8 +19386,8 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E, return Success(CmpResult::Unequal, E); } - const CharUnits &LHSOffset = LHSValue.getLValueOffset(); - const CharUnits &RHSOffset = RHSValue.getLValueOffset(); + CharUnits LHSOffset = LHSValue.getLValueOffset(); + CharUnits RHSOffset = RHSValue.getLValueOffset(); SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator(); SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator(); @@ -19692,8 +19692,8 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { return Error(E); return Success(APValue(LHSAddrExpr, RHSAddrExpr), E); } - const CharUnits &LHSOffset = LHSValue.getLValueOffset(); - const CharUnits &RHSOffset = RHSValue.getLValueOffset(); + CharUnits LHSOffset = LHSValue.getLValueOffset(); + CharUnits RHSOffset = RHSValue.getLValueOffset(); SubobjectDesignator &LHSDesignator = LHSValue.getLValueDesignator(); SubobjectDesignator &RHSDesignator = RHSValue.getLValueDesignator(); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
