Author: Timm Baeder Date: 2026-03-27T06:56:03+01:00 New Revision: 8a49af8752021bbabc6f76e657beaf56a4645624
URL: https://github.com/llvm/llvm-project/commit/8a49af8752021bbabc6f76e657beaf56a4645624 DIFF: https://github.com/llvm/llvm-project/commit/8a49af8752021bbabc6f76e657beaf56a4645624.diff LOG: [clang][bytecode] Pass bitfield width directly to opcodes (#188423) Pass a `FieldOffset` + `FieldBitWidth` pair instead of a `Record::Field` pointer. Added: Modified: clang/lib/AST/ByteCode/Compiler.cpp clang/lib/AST/ByteCode/Interp.h clang/lib/AST/ByteCode/Opcodes.td clang/lib/AST/ByteCode/Record.h Removed: ################################################################################ diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index c38eb0fa93877..217ba3663edb0 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2130,9 +2130,11 @@ bool Compiler<Emitter>::visitInitList(ArrayRef<const Expr *> Inits, bool BitField = FieldToInit->isBitField(); if (BitField && Activate) - return this->emitInitBitFieldActivate(T, FieldToInit, E); + return this->emitInitBitFieldActivate(T, FieldToInit->Offset, + FieldToInit->bitWidth(), E); if (BitField) - return this->emitInitBitField(T, FieldToInit, E); + return this->emitInitBitField(T, FieldToInit->Offset, + FieldToInit->bitWidth(), E); if (Activate) return this->emitInitFieldActivate(T, FieldToInit->Offset, E); return this->emitInitField(T, FieldToInit->Offset, E); @@ -5361,7 +5363,8 @@ bool Compiler<Emitter>::visitAPValueInitializer(const APValue &Val, if (!this->visitAPValue(F, *PT, E)) return false; if (RF->isBitField()) - return this->emitInitBitFieldActivate(*PT, RF, E); + return this->emitInitBitFieldActivate(*PT, RF->Offset, RF->bitWidth(), + E); return this->emitInitFieldActivate(*PT, RF->Offset, E); } @@ -6669,9 +6672,9 @@ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) { if (!this->visit(InitExpr)) return false; - bool BitField = F->isBitField(); - if (BitField) - return this->emitInitThisBitField(*T, F, FieldOffset, InitExpr); + if (F->isBitField()) + return this->emitInitThisBitField(*T, FieldOffset, F->bitWidth(), + InitExpr); return this->emitInitThisField(*T, FieldOffset, InitExpr); } // Non-primitive case. Get a pointer to the field-to-initialize diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index 5b6d1bb18fff4..90dc88c1dbde7 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -1659,9 +1659,9 @@ bool InitThisFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I) { // FIXME: The Field pointer here is too much IMO and we could instead just // pass an Offset + BitWidth pair. template <PrimType Name, class T = typename PrimConv<Name>::T> -bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F, - uint32_t FieldOffset) { - assert(F->isBitField()); +bool InitThisBitField(InterpState &S, CodePtr OpPC, + uint32_t FieldOffset, // const Record::Field *F, + uint32_t FieldBitWidth) { if (S.checkingPotentialConstantExpression() && S.Current->getDepth() == 0) return false; if (!CheckThis(S, OpPC)) @@ -1670,15 +1670,14 @@ bool InitThisBitField(InterpState &S, CodePtr OpPC, const Record::Field *F, const Pointer &Field = This.atField(FieldOffset); assert(Field.canBeInitialized()); const auto &Value = S.Stk.pop<T>(); - Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); + Field.deref<T>() = Value.truncate(FieldBitWidth); Field.initialize(); return true; } template <PrimType Name, class T = typename PrimConv<Name>::T> bool InitThisBitFieldActivate(InterpState &S, CodePtr OpPC, - const Record::Field *F, uint32_t FieldOffset) { - assert(F->isBitField()); + uint32_t FieldOffset, uint32_t FieldBitWidth) { if (S.checkingPotentialConstantExpression() && S.Current->getDepth() == 0) return false; if (!CheckThis(S, OpPC)) @@ -1687,7 +1686,7 @@ bool InitThisBitFieldActivate(InterpState &S, CodePtr OpPC, const Pointer &Field = This.atField(FieldOffset); assert(Field.canBeInitialized()); const auto &Value = S.Stk.pop<T>(); - Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); + Field.deref<T>() = Value.truncate(FieldBitWidth); Field.initialize(); Field.activate(); return true; @@ -1728,8 +1727,8 @@ bool InitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t I) { } template <PrimType Name, class T = typename PrimConv<Name>::T> -bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { - assert(F->isBitField()); +bool InitBitField(InterpState &S, CodePtr OpPC, uint32_t FieldOffset, + uint32_t FieldBitWidth) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckRange(S, OpPC, Ptr, CSK_Field)) @@ -1737,9 +1736,9 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { if (!CheckArray(S, OpPC, Ptr)) return false; - const Pointer &Field = Ptr.atField(F->Offset); + const Pointer &Field = Ptr.atField(FieldOffset); - unsigned BitWidth = std::min(F->Decl->getBitWidthValue(), Value.bitWidth()); + unsigned BitWidth = std::min(FieldBitWidth, Value.bitWidth()); if constexpr (needsAlloc<T>()) { T Result = S.allocAP<T>(Value.bitWidth()); if constexpr (T::isSigned()) @@ -1751,16 +1750,15 @@ bool InitBitField(InterpState &S, CodePtr OpPC, const Record::Field *F) { Field.deref<T>() = Result; } else { - Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); + Field.deref<T>() = Value.truncate(FieldBitWidth); } Field.initialize(); return true; } template <PrimType Name, class T = typename PrimConv<Name>::T> -bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, - const Record::Field *F) { - assert(F->isBitField()); +bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, uint32_t FieldOffset, + uint32_t FieldBitWidth) { const T &Value = S.Stk.pop<T>(); const Pointer &Ptr = S.Stk.peek<Pointer>(); if (!CheckRange(S, OpPC, Ptr, CSK_Field)) @@ -1768,9 +1766,9 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, if (!CheckArray(S, OpPC, Ptr)) return false; - const Pointer &Field = Ptr.atField(F->Offset); + const Pointer &Field = Ptr.atField(FieldOffset); - unsigned BitWidth = std::min(F->Decl->getBitWidthValue(), Value.bitWidth()); + unsigned BitWidth = std::min(FieldBitWidth, Value.bitWidth()); if constexpr (needsAlloc<T>()) { T Result = S.allocAP<T>(Value.bitWidth()); if constexpr (T::isSigned()) @@ -1782,7 +1780,7 @@ bool InitBitFieldActivate(InterpState &S, CodePtr OpPC, Field.deref<T>() = Result; } else { - Field.deref<T>() = Value.truncate(F->Decl->getBitWidthValue()); + Field.deref<T>() = Value.truncate(FieldBitWidth); } Field.activate(); Field.initialize(); diff --git a/clang/lib/AST/ByteCode/Opcodes.td b/clang/lib/AST/ByteCode/Opcodes.td index 5fbd35950c0eb..5e4d0ab2a84af 100644 --- a/clang/lib/AST/ByteCode/Opcodes.td +++ b/clang/lib/AST/ByteCode/Opcodes.td @@ -417,7 +417,8 @@ class AccessOpcode : Opcode { class BitFieldOpcode : Opcode { let Types = [IntegralTypeClass]; - let Args = [ArgRecordField]; + // FieldOffset, FieldBitWidth + let Args = [ArgUint32, ArgUint32]; let HasGroup = 1; } @@ -485,16 +486,7 @@ def SetThisField : AccessOpcode; def InitThisField : AccessOpcode; def InitThisFieldActivate : AccessOpcode; // [Value] -> [] -def InitThisBitField : Opcode { - let Types = [AluTypeClass]; - let Args = [ArgRecordField, ArgUint32]; - let HasGroup = 1; -} -def InitThisBitFieldActivate : Opcode { - let Types = [AluTypeClass]; - let Args = [ArgRecordField, ArgUint32]; - let HasGroup = 1; -} +def InitThisBitField : BitFieldOpcode; // [Pointer, Value] -> [] def InitField : AccessOpcode; def InitFieldActivate : AccessOpcode; diff --git a/clang/lib/AST/ByteCode/Record.h b/clang/lib/AST/ByteCode/Record.h index e43f683364e26..c0c10f72ae3ee 100644 --- a/clang/lib/AST/ByteCode/Record.h +++ b/clang/lib/AST/ByteCode/Record.h @@ -32,6 +32,10 @@ class Record final { bool isBitField() const { return Decl->isBitField(); } bool isUnnamedBitField() const { return Decl->isUnnamedBitField(); } + unsigned bitWidth() const { + assert(isBitField()); + return Decl->getBitWidthValue(); + } Field(const FieldDecl *D, const Descriptor *Desc, unsigned Offset) : Decl(D), Desc(Desc), Offset(Offset) {} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
