https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/234203
>From ae40b70c224f1248aa40dabed186b50b8c04646e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]> Date: Tue, 20 Oct 2026 15:40:43 +0200 Subject: [PATCH] asdf --- clang/lib/AST/ByteCode/Block.cpp | 3 +- clang/lib/AST/ByteCode/Block.h | 75 ++++++++++++------ clang/lib/AST/ByteCode/ByteCodeEmitter.cpp | 3 +- clang/lib/AST/ByteCode/Compiler.cpp | 6 +- clang/lib/AST/ByteCode/Disasm.cpp | 2 - clang/lib/AST/ByteCode/DynamicAllocator.cpp | 7 +- clang/lib/AST/ByteCode/EvalEmitter.cpp | 9 +-- clang/lib/AST/ByteCode/Interp.cpp | 12 +-- .../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 2 +- clang/lib/AST/ByteCode/InterpFrame.cpp | 5 +- clang/lib/AST/ByteCode/InterpState.cpp | 4 +- clang/lib/AST/ByteCode/MemberPointer.cpp | 6 +- clang/lib/AST/ByteCode/Pointer.cpp | 78 +++++++++---------- clang/lib/AST/ByteCode/Pointer.h | 53 ++++++------- clang/lib/AST/ByteCode/Program.cpp | 42 +++++----- clang/lib/AST/ByteCode/Program.h | 5 +- 16 files changed, 163 insertions(+), 149 deletions(-) diff --git a/clang/lib/AST/ByteCode/Block.cpp b/clang/lib/AST/ByteCode/Block.cpp index 92019f3a754479..30597f2a081cec 100644 --- a/clang/lib/AST/ByteCode/Block.cpp +++ b/clang/lib/AST/ByteCode/Block.cpp @@ -125,8 +125,7 @@ void Block::removePointers() { } DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk) - : Root(Root), B(~0u, Blk->Desc, Blk->MDSize, Blk->isExtern(), Blk->IsStatic, - Blk->isWeak(), + : Root(Root), B(~0u, Blk->Desc, Blk->Kind, Blk->isExtern(), Blk->isWeak(), /*IsDead=*/true) { // Add the block to the chain of dead blocks. if (Root) diff --git a/clang/lib/AST/ByteCode/Block.h b/clang/lib/AST/ByteCode/Block.h index cac9d683bc1395..a00a332a4c8b7c 100644 --- a/clang/lib/AST/ByteCode/Block.h +++ b/clang/lib/AST/ByteCode/Block.h @@ -38,7 +38,8 @@ enum PrimType : uint8_t; /// │ sizeof(Block) │ MDSize │ Desc->getSize() │ /// └───────────────┴──────────────────┴─────────────────┘ /// -/// getSize() returns MDSize + Desc->getAllocSize(). +/// getSize() returns Desc->getAllocSize(). +/// getAllocSize() returns getMetadataSize() + Desc->getAllocSize(). /// class Block final { private: @@ -47,36 +48,54 @@ class Block final { static constexpr uint8_t WeakFlag = 1 << 2; public: - static constexpr uint8_t InlineDescMD = sizeof(InlineDescriptor); - static constexpr uint8_t GlobalMD = sizeof(GlobalInlineDescriptor); + enum BlockKind : uint8_t { None, Local, Global }; /// Creates a new block. Block(unsigned EvalID, UnsignedOrNone DeclID, const Descriptor *Desc, - unsigned MDSize = 0, bool IsStatic = false, bool IsExtern = false, - bool IsWeak = false) - : Desc(Desc), DeclID(DeclID), EvalID(EvalID), MDSize(MDSize), - IsStatic(IsStatic) { + BlockKind K, bool IsExtern, bool IsWeak) + + : Desc(Desc), DescSize(Desc->getAllocSize()), DeclID(DeclID), + EvalID(EvalID), Kind(K), MDSize(getMetadataSize(K)) { assert(Desc); AccessFlags |= (ExternFlag * IsExtern); AccessFlags |= (WeakFlag * IsWeak); } - Block(unsigned EvalID, const Descriptor *Desc, unsigned MDSize = 0, - bool IsStatic = false, bool IsExtern = false, bool IsWeak = false) - : Desc(Desc), EvalID(EvalID), MDSize(MDSize), IsStatic(IsStatic) { + Block(unsigned EvalID, const Descriptor *Desc, BlockKind K, + bool IsExtern = false, bool IsWeak = false) + : Desc(Desc), DescSize(Desc->getAllocSize()), EvalID(EvalID), Kind(K), + MDSize(getMetadataSize(K)) { assert(Desc); AccessFlags |= (ExternFlag * IsExtern); AccessFlags |= (WeakFlag * IsWeak); } + /// Number of bytes needed to allocate the block. + static constexpr unsigned allocSize(const Descriptor *D, BlockKind K) { + return sizeof(Block) + getMetadataSize(K) + D->getAllocSize(); + } + + static constexpr unsigned getMetadataSize(BlockKind K) { + switch (K) { + case None: + return 0; + case Global: + return sizeof(GlobalInlineDescriptor); + case Local: + return sizeof(InlineDescriptor); + } + llvm_unreachable("Unhandled Block kind"); + } + + bool isGlobal() const { return Kind == Global; } + bool isLocal() const { return Kind == Local; } + /// Returns the block's descriptor. const Descriptor *getDescriptor() const { return Desc; } /// Checks if the block has any live pointers. bool hasPointers() const { return Pointers; } /// Checks if the block is extern. bool isExtern() const { return AccessFlags & ExternFlag; } - /// Checks if the block has static storage duration. - bool isStatic() const { return IsStatic; } /// Checks if the block is temporary. bool isTemporary() const { return Desc->IsTemporary; } bool isWeak() const { return AccessFlags & WeakFlag; } @@ -87,8 +106,9 @@ class Block final { return Result; } bool isDead() const { return AccessFlags & DeadFlag; } - /// Returns the size of the block, including metadata. - unsigned getSize() const { return Desc->getAllocSize() + MDSize; } + /// Returns the size of the block, excluding metadata. + unsigned getSize() const { return DescSize; } + unsigned getAllocSize() const { return DescSize + MDSize; } /// Returns the size of the metadata. unsigned getMetadataSize() const { return MDSize; } /// Returns the declaration ID. @@ -123,7 +143,16 @@ class Block final { template <typename T> T &deref() { return *reinterpret_cast<T *>(data()); } template <typename T> T &getBlockDesc() { - assert(sizeof(T) == MDSize); + assert(sizeof(T) == getMetadataSize()); + + if constexpr (std::is_same_v<T, GlobalInlineDescriptor>) { + assert(Kind == Global); + } else if constexpr (std::is_same_v<T, InlineDescriptor>) { + assert(Kind == Local); + } else { + assert(Kind == None); + } + return *reinterpret_cast<T *>(rawData()); } template <typename T> const T &getBlockDesc() const { @@ -133,7 +162,7 @@ class Block final { /// Invokes the constructor. void invokeCtor() { assert(!IsInitialized); - std::memset(rawData(), 0, getSize()); + std::memset(rawData(), 0, getAllocSize()); invokeCtorNoMemset(); } /// The same, but won't memset() the memory first to zero. @@ -167,9 +196,10 @@ class Block final { friend class DynamicAllocator; friend class Program; - Block(unsigned EvalID, const Descriptor *Desc, unsigned MDSize, bool IsExtern, - bool IsStatic, bool IsWeak, bool IsDead) - : Desc(Desc), EvalID(EvalID), MDSize(MDSize), IsStatic(IsStatic) { + Block(unsigned EvalID, const Descriptor *Desc, BlockKind K, bool IsExtern, + bool IsWeak, bool IsDead) + : Desc(Desc), DescSize(Desc->getAllocSize()), EvalID(EvalID), Kind(K), + MDSize(getMetadataSize(K)) { assert(Desc); AccessFlags |= (ExternFlag * IsExtern); AccessFlags |= (DeadFlag * IsDead); @@ -194,6 +224,7 @@ class Block final { const Descriptor *Desc; /// Start of the chain of pointers. Pointer *Pointers = nullptr; + const unsigned DescSize; /// Unique identifier of the declaration. UnsignedOrNone DeclID = std::nullopt; const unsigned EvalID = ~0u; @@ -202,9 +233,9 @@ class Block final { /// AccessFlags containing IsExtern, IsDead and IsWeak bits. uint8_t AccessFlags = 0; /// Size of the metadata. - const uint8_t MDSize = 0; - /// Flag indicating if the block has static storage duration. - bool IsStatic = false; + const BlockKind Kind = Block::None; + /// Size of block-level metadata. + const uint8_t MDSize; /// Flag indicating if the block contents have been initialized /// via invokeCtor. bool IsInitialized = false; diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp index e55bfb586fb7b2..908f2515264b76 100644 --- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp +++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp @@ -91,7 +91,8 @@ void ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl, Scope::Local ByteCodeEmitter::createLocal(const Descriptor *D) { NextLocalOffset += sizeof(Block); unsigned Location = NextLocalOffset; - NextLocalOffset += align(Block::InlineDescMD + D->getAllocSize()); + NextLocalOffset += + align(Block::getMetadataSize(Block::Local) + D->getAllocSize()); return {D, Location}; } diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index e20e54837e9260..389e359b2c3eb4 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -1310,7 +1310,9 @@ bool Compiler<Emitter>::VisitImaginaryLiteral(const ImaginaryLiteral *E) { return false; if (!this->emitInitElem(SubExprT, 0, SubExpr)) return false; - return this->visitArrayElemInit(1, SubExpr, SubExprT); + if (!this->visitArrayElemInit(1, SubExpr, SubExprT)) + return false; + return this->emitFinishInit(E); } template <class Emitter> @@ -1884,7 +1886,7 @@ bool Compiler<Emitter>::VisitComplexBinOp(const BinaryOperator *E) { return this->emitPopPtr(E); } } - return true; + return this->emitFinishInit(E); } template <class Emitter> diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp index 380c4ca326dcb7..af115e8bdc0b04 100644 --- a/clang/lib/AST/ByteCode/Disasm.cpp +++ b/clang/lib/AST/ByteCode/Disasm.cpp @@ -627,12 +627,10 @@ LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const { OS << "-\n"; OS << " Pointers: " << NPointers << "\n"; OS << " Dead: " << isDead() << "\n"; - OS << " Static: " << IsStatic << "\n"; OS << " Extern: " << isExtern() << "\n"; OS << " Initialized: " << IsInitialized << "\n"; OS << " Weak: " << isWeak() << "\n"; OS << " Dynamic: " << isDynamic() << "\n"; - OS << " Metadata: " << MDSize << '\n'; } LLVM_DUMP_METHOD void EvaluationResult::dump() const { diff --git a/clang/lib/AST/ByteCode/DynamicAllocator.cpp b/clang/lib/AST/ByteCode/DynamicAllocator.cpp index f213316dfe7a04..b2f5260483d89d 100644 --- a/clang/lib/AST/ByteCode/DynamicAllocator.cpp +++ b/clang/lib/AST/ByteCode/DynamicAllocator.cpp @@ -68,10 +68,9 @@ Block *DynamicAllocator::allocate(const Descriptor *D, unsigned EvalID, return !Alloc.block()->hasPointers(); }); - auto Memory = std::make_unique<std::byte[]>( - sizeof(Block) + D->getAllocSize() + Block::InlineDescMD); - auto *B = new (Memory.get()) Block(EvalID, D, Block::InlineDescMD, - /*isStatic=*/false); + auto Memory = + std::make_unique<std::byte[]>(Block::allocSize(D, Block::Local)); + auto *B = new (Memory.get()) Block(EvalID, D, Block::Local); B->invokeCtorNoMemset(); InlineDescriptor *ID = reinterpret_cast<InlineDescriptor *>(B->rawData()); ID->Desc = D; diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp index a1fce467dcd203..6a18c8cfee71ed 100644 --- a/clang/lib/AST/ByteCode/EvalEmitter.cpp +++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp @@ -149,10 +149,9 @@ EvalEmitter::LabelTy EvalEmitter::getLabel() { return NextLabel++; } Scope::Local EvalEmitter::createLocal(const Descriptor *D) { // Allocate memory for a local. - char *Memory = reinterpret_cast<char *>( - S.allocate(sizeof(Block) + D->getAllocSize() + Block::InlineDescMD)); - auto *B = new (Memory) Block(Ctx.getEvalID(), D, Block::InlineDescMD, - /*IsStatic=*/false); + char *Memory = + reinterpret_cast<char *>(S.allocate(Block::allocSize(D, Block::Local))); + auto *B = new (Memory) Block(Ctx.getEvalID(), D, Block::Local); B->invokeCtor(); // Initialize local variable inline descriptor. @@ -345,7 +344,7 @@ bool EvalEmitter::emitGetPtrLocal(uint32_t I, SourceInfo Info) { return true; Block *B = getLocal(I); - S.Stk.push<Pointer>(B, sizeof(InlineDescriptor)); + S.Stk.push<Pointer>(B); return true; } diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 3586f5c62ed6f4..53dbdb9df33d54 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -243,7 +243,7 @@ void noteValueLocation(InterpState &S, const Pointer &Ptr) { static bool CheckTemporary(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK) { if (B->getDeclID()) { - if (!(B->isStatic() && B->isTemporary())) + if (!(B->isGlobal() && B->isTemporary())) return true; const auto *MTE = dyn_cast_if_present<MaterializeTemporaryExpr>( @@ -595,7 +595,7 @@ static bool CheckConstant(InterpState &S, CodePtr OpPC, PtrView Ptr, if (S.checkingConstantDestruction(Ptr.getDeclDesc()->asVarDecl())) return CheckConstant(S, OpPC, Ptr.getDeclDesc(), AK); - if (!Ptr.block()->isStatic()) + if (!Ptr.block()->isGlobal()) return true; if (!Ptr.block()->getDeclID()) return true; @@ -899,7 +899,7 @@ bool CheckGlobalLoad(InterpState &S, CodePtr OpPC, const Block *B) { // Similarly, for local loads. bool CheckLocalLoad(InterpState &S, CodePtr OpPC, const Block *B) { assert(!B->isExtern()); - const auto &Desc = *reinterpret_cast<const InlineDescriptor *>(B->rawData()); + const auto &Desc = B->getBlockDesc<InlineDescriptor>(); const Descriptor *BlockDesc = B->getDescriptor(); if (!Desc.IsInitialized) return diagnoseUninitialized(S, OpPC, /*Extern=*/false, B, Desc.LifeState); @@ -1939,7 +1939,7 @@ bool checkDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { } // Can't call a dtor on a global variable. - if (Ptr.isOpaquePointer() || Ptr.block()->isStatic()) { + if (Ptr.isOpaquePointer() || Ptr.block()->isGlobal()) { const SourceInfo &E = S.Current->getSource(OpPC); S.FFDiag(E, diag::note_constexpr_modify_global); return false; @@ -2241,7 +2241,7 @@ static bool getDynamicDecl(InterpState &S, CodePtr OpPC, const Pointer &Ptr, } QualType DynamicType = TypePtr.getType(); - if (TypePtr.Pointee->isStatic() || TypePtr.isConst()) { + if (TypePtr.Pointee->isGlobal() || TypePtr.isConst()) { if (const VarDecl *VD = Pointer(TypePtr).getRootVarDecl(); VD && !VD->isConstexpr()) return diagUnknownDynamicType(Pointer(TypePtr)); @@ -3054,7 +3054,7 @@ bool handleReference(InterpState &S, CodePtr OpPC, Block *B) { return true; } - const auto &ID = B->getBlockDesc<const InlineDescriptor>(); + const auto &ID = B->getBlockDesc<InlineDescriptor>(); if (!ID.IsInitialized) { if (!S.checkingPotentialConstantExpression()) S.FFDiag(S.Current->getSource(OpPC), diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp index 3bec4f3bf1396b..88b2736bce4440 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp @@ -104,7 +104,7 @@ convertToBlockPointer(const Context &Ctx, const StringPointer &SP) { // The byte length does not include the null terminator. // unsigned GlobalIndex = Globals.size(); auto *Memory = new std::byte[sizeof(Block) + Desc->getAllocSize()]; - auto *B = new (Memory) Block(Ctx.getEvalID(), Desc.get()); + auto *B = new (Memory) Block(Ctx.getEvalID(), Desc.get(), Block::None); B->invokeCtor(); new (B->rawData()) GlobalInlineDescriptor{GlobalInitState::Initialized}; diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp index 5aafa0f2ceecaf..52486444820498 100644 --- a/clang/lib/AST/ByteCode/InterpFrame.cpp +++ b/clang/lib/AST/ByteCode/InterpFrame.cpp @@ -40,7 +40,8 @@ InterpFrame::InterpFrame(InterpState &S, const Function *Func, // Initialize argument blocks. for (unsigned I = 0, N = Func->getNumWrittenParams(); I != N; ++I) - new (argBlock(I)) Block(S.EvalID, Func->getParamDescriptor(I).Desc); + new (argBlock(I)) + Block(S.EvalID, Func->getParamDescriptor(I).Desc, Block::None); if (Func->getFrameSize() == 0) return; @@ -48,7 +49,7 @@ InterpFrame::InterpFrame(InterpState &S, const Function *Func, for (auto &Scope : Func->scopes()) { for (auto &Local : Scope.locals()) { Block *B = localBlock(Local.Offset); - new (B) Block(S.EvalID, Local.Desc, Block::InlineDescMD); + new (B) Block(S.EvalID, Local.Desc, Block::Local); // Note that we are NOT calling invokeCtor() here, since that is done // lazily when accessing the local. } diff --git a/clang/lib/AST/ByteCode/InterpState.cpp b/clang/lib/AST/ByteCode/InterpState.cpp index 44f6fb3216b779..8e7c021c6020fa 100644 --- a/clang/lib/AST/ByteCode/InterpState.cpp +++ b/clang/lib/AST/ByteCode/InterpState.cpp @@ -95,7 +95,7 @@ const Frame *InterpState::getCurrentFrame() { return Current; } void InterpState::deallocate(Block *B) { assert(B); assert(!B->isDynamic()); - assert(!B->isStatic()); + assert(!B->isGlobal()); assert(!B->isDead()); // The block might have a pointer saved in a field in its data @@ -108,7 +108,7 @@ void InterpState::deallocate(Block *B) { assert(!B->isInitialized()); if (B->hasPointers()) { - size_t Size = B->getSize(); + size_t Size = B->getAllocSize(); // Allocate a new block, transferring over pointers. char *Memory = reinterpret_cast<char *>(std::malloc(sizeof(DeadBlock) + Size)); diff --git a/clang/lib/AST/ByteCode/MemberPointer.cpp b/clang/lib/AST/ByteCode/MemberPointer.cpp index ea6963e66d85cc..1f906f579d68da 100644 --- a/clang/lib/AST/ByteCode/MemberPointer.cpp +++ b/clang/lib/AST/ByteCode/MemberPointer.cpp @@ -22,12 +22,9 @@ std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const { if (!Base.isBlockPointer()) return std::nullopt; - unsigned BlockMDSize = Base.block()->getMetadataSize(); - if (PtrOffset >= 0) { // If the resulting base would be too small, return nullopt. - if (Base.BS.Base < static_cast<unsigned>(PtrOffset) || - (Base.BS.Base - PtrOffset < BlockMDSize)) + if (Base.BS.Base < static_cast<unsigned>(PtrOffset) || PtrOffset < 0) return std::nullopt; } @@ -39,7 +36,6 @@ std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const { return std::nullopt; unsigned Offset = 0; - Offset += BlockMDSize; if (const auto *FD = dyn_cast<FieldDecl>(getDecl())) { if (FD->getParent() == BaseRecord->getDecl()) diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp index 3890f2ed2f91de..288081c2facc18 100644 --- a/clang/lib/AST/ByteCode/Pointer.cpp +++ b/clang/lib/AST/ByteCode/Pointer.cpp @@ -34,9 +34,7 @@ static bool validType(QualType T) { !T->isIncompleteType(); } -Pointer::Pointer(Block *Pointee) - : Pointer(Pointee, Pointee->getMetadataSize(), Pointee->getMetadataSize()) { -} +Pointer::Pointer(Block *Pointee) : Pointer(Pointee, 0, 0) {} Pointer::Pointer(Block *Pointee, uint64_t BaseAndOffset) : Pointer(Pointee, BaseAndOffset, BaseAndOffset) {} @@ -45,7 +43,6 @@ Pointer::Pointer(Block *Pointee, unsigned Base, uint64_t Offset) : Offset(Offset), StorageKind(Storage::Block) { assert(Pointee); assert(Base % alignof(void *) == 0 && "wrong base"); - assert(Base >= Pointee->getMetadataSize()); BS = {Pointee, Base, nullptr, nullptr}; Pointee->addPointer(this); @@ -730,12 +727,11 @@ bool PtrView::isElementInitialized(unsigned Index) const { const Descriptor *Desc = getFieldDesc(); assert(Desc); - if (Pointee->isStatic() && Base == 0) - return true; - - if (isRoot() && Base == sizeof(GlobalInlineDescriptor) && Offset == Base) { - const auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); - return GD.InitState == GlobalInitState::Initialized; + if (Offset == 0) { + if (Pointee->isGlobal()) { + const auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); + return GD.InitState == GlobalInitState::Initialized; + } } if (Desc->isPrimitiveArray()) { @@ -765,8 +761,13 @@ bool Pointer::isElementAlive(unsigned Index) const { } Lifetime PtrView::getLifetime() const { - if (Base < sizeof(InlineDescriptor)) + if (Offset == 0) { + if (Pointee->isLocal()) { + auto &LD = Pointee->getBlockDesc<InlineDescriptor>(); + return LD.LifeState; + } return Lifetime::Started; + } if (inPrimitiveArray() && !isArrayRoot()) { InitMapPtr &IM = getInitMap(); @@ -780,14 +781,20 @@ Lifetime PtrView::getLifetime() const { return IM->isElementAlive(getIndex()) ? Lifetime::Started : Lifetime::Ended; } - return getInlineDesc()->LifeState; + return getDescriptor(Offset)->LifeState; } void PtrView::setLifeState(Lifetime L) const { - if (Base < sizeof(InlineDescriptor)) + + if (Offset == 0) { + if (Pointee->isLocal()) { + auto &LD = Pointee->getBlockDesc<InlineDescriptor>(); + LD.LifeState = L; + } return; + } - if (inArray() && !isArrayRoot()) { + if (inPrimitiveArray() && !isArrayRoot()) { assert(L == Lifetime::Started || L == Lifetime::Ended); const Descriptor *Desc = getFieldDesc(); InitMapPtr &IM = getInitMap(); @@ -802,13 +809,18 @@ void PtrView::setLifeState(Lifetime L) const { return; } - getInlineDesc()->LifeState = L; + getDescriptor(Offset)->LifeState = L; } void PtrView::initialize() const { - if (isRoot() && Base == sizeof(GlobalInlineDescriptor) && Offset == Base) { - auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); - GD.InitState = GlobalInitState::Initialized; + if (Offset == 0) { + if (Pointee->isGlobal()) { + auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); + GD.InitState = GlobalInitState::Initialized; + } else if (Pointee->isLocal()) { + auto &LD = Pointee->getBlockDesc<InlineDescriptor>(); + LD.IsInitialized = true; + } return; } @@ -821,16 +833,12 @@ void PtrView::initialize() const { } // Field has its bit in an inline descriptor. - assert(Base != 0 && "Only composite fields can be initialised"); - getInlineDesc()->IsInitialized = true; - getInlineDesc()->LifeState = Lifetime::Started; + assert(Offset != 0 && "Only composite fields can be initialised"); + getDescriptor(Offset)->IsInitialized = true; + getDescriptor(Offset)->LifeState = Lifetime::Started; } void PtrView::initializeElement(unsigned Index) const { - // Primitive global arrays don't have an initmap. - if (Pointee->isStatic() && Base == 0) - return; - assert(Index < getFieldDesc()->getNumElems()); InitMapPtr &IM = getInitMap(); @@ -858,13 +866,8 @@ bool PtrView::allElementsInitialized() const { assert(getFieldDesc()->isPrimitiveArray()); assert(isArrayRoot()); - if (Pointee->isStatic() && Base == 0) - return true; - - if (isRoot() && Base == sizeof(GlobalInlineDescriptor) && Offset == Base) { - const auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); - return GD.InitState == GlobalInitState::Initialized; - } + if (Offset == 0) + return isInitialized(); InitMapPtr IM = getInitMap(); return IM.allInitialized(); @@ -874,11 +877,7 @@ bool Pointer::allElementsAlive() const { assert(getFieldDesc()->isPrimitiveArray()); assert(isArrayRoot()); - if (isStatic() && BS.Base == 0) - return true; - - if (isRoot() && BS.Base == sizeof(GlobalInlineDescriptor) && - Offset == BS.Base) { + if (Offset == 0) { const auto &GD = block()->getBlockDesc<GlobalInlineDescriptor>(); return GD.InitState == GlobalInitState::Initialized; } @@ -888,10 +887,7 @@ bool Pointer::allElementsAlive() const { } void PtrView::activate() const { - // Field has its bit in an inline descriptor. - assert(Base != 0 && "Only composite fields can be activated"); - - if (isRoot() && Base == sizeof(GlobalInlineDescriptor)) + if (isRoot()) return; if (!getInlineDesc()->InUnion) return; diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h index 6c8ac0066f5977..131a43beeae769 100644 --- a/clang/lib/AST/ByteCode/Pointer.h +++ b/clang/lib/AST/ByteCode/Pointer.h @@ -56,28 +56,26 @@ struct PtrView { bool inUnion() const { return getInlineDesc()->InUnion; }; bool inArray() const { return getFieldDesc()->IsArray; } bool inPrimitiveArray() const { return getFieldDesc()->isPrimitiveArray(); } - bool canBeInitialized() const { return Pointee && Base > 0; } + bool canBeInitialized() const { return Pointee; } const Block *block() const { return Pointee; } unsigned getEvalID() { return Pointee->getEvalID(); } - bool isRoot() const { return Base == Pointee->getMetadataSize(); } + bool isRoot() const { return Base == 0; } bool isConst() const { return isRoot() ? getDeclDesc()->IsConst : getInlineDesc()->IsConst; } InlineDescriptor *getInlineDesc() const { - assert(Base != sizeof(GlobalInlineDescriptor)); assert(Base <= Pointee->getSize()); - assert(Base >= sizeof(InlineDescriptor)); + assert(Base != 0); return getDescriptor(Base); } InlineDescriptor *getDescriptor(unsigned Offset) const { assert(Offset != 0 && "Not a nested pointer"); - return reinterpret_cast<InlineDescriptor *>(Pointee->rawData() + Offset) - - 1; + return reinterpret_cast<InlineDescriptor *>(Pointee->data() + Offset) - 1; } const Descriptor *getFieldDesc() const { @@ -134,9 +132,8 @@ struct PtrView { // Step into the containing array, if inside one. unsigned Next = Base - getInlineDesc()->Offset; - const Descriptor *Desc = (Next == Pointee->getMetadataSize()) - ? getDeclDesc() - : getDescriptor(Next)->Desc; + const Descriptor *Desc = + (Next == 0) ? getDeclDesc() : getDescriptor(Next)->Desc; if (!Desc->IsArray) return *this; return PtrView{Pointee, Next, Offset}; @@ -250,10 +247,10 @@ struct PtrView { assert(Pointee); if (isArrayRoot()) - return *reinterpret_cast<T *>(Pointee->rawData() + Base + + return *reinterpret_cast<T *>(Pointee->data() + Base + sizeof(InitMapPtr)); - return *reinterpret_cast<T *>(Pointee->rawData() + Offset); + return *reinterpret_cast<T *>(Pointee->data() + Offset); } template <typename T> T &elem(unsigned I) const { @@ -266,7 +263,7 @@ struct PtrView { unsigned ReadOffset = Base + sizeof(InitMapPtr) + ElemByteOffset; assert(ReadOffset + sizeof(T) <= Pointee->getSize()); - return *reinterpret_cast<T *>(Pointee->rawData() + ReadOffset); + return *reinterpret_cast<T *>(Pointee->data() + ReadOffset); } [[nodiscard]] PtrView getBase() const { @@ -303,13 +300,15 @@ struct PtrView { } bool isInitialized() const { - - if (!Pointee->isInitialized()) - return false; - - if (isRoot() && Base == sizeof(GlobalInlineDescriptor) && Offset == Base) { - const auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); - return GD.InitState == GlobalInitState::Initialized; + if (Offset == 0) { + if (Pointee->isGlobal()) { + const auto &GD = Pointee->getBlockDesc<GlobalInlineDescriptor>(); + return GD.InitState == GlobalInitState::Initialized; + } + if (Pointee->isLocal()) { + const auto &LD = Pointee->getBlockDesc<InlineDescriptor>(); + return LD.IsInitialized; + } } assert(Pointee && "Cannot check if null pointer was initialized"); @@ -321,14 +320,14 @@ struct PtrView { if (Base == 0) return true; // Field has its bit in an inline descriptor. - return getInlineDesc()->IsInitialized; + return getDescriptor(Offset)->IsInitialized; } void initializeElement(unsigned Index) const; bool allElementsInitialized() const; bool isElementInitialized(unsigned Index) const; InitMapPtr &getInitMap() const { - return *reinterpret_cast<InitMapPtr *>(Pointee->rawData() + Base); + return *reinterpret_cast<InitMapPtr *>(Pointee->data() + Base); } void initialize() const; void activate() const; @@ -528,7 +527,7 @@ enum class Storage { Int, Block, Fn, Typeid, String, Opaque }; /// /// The Offset field is used to access the actual data. In other words, the /// data the pointer decribes can be found at -/// Pointee->rawData() + Pointer.Offset. +/// Pointee->data() + Pointer.Offset. /// /// \verbatim /// Pointee Offset @@ -828,8 +827,7 @@ class Pointer { bool canBeInitialized() const { if (!isBlockPointer()) return false; - - return BS.Pointee && BS.Base > 0; + return view().canBeInitialized(); } [[nodiscard]] const BlockPointer &asBlockPointer() const { @@ -890,7 +888,7 @@ class Pointer { if (!isBlockPointer()) return true; assert(BS.Pointee); - return BS.Pointee->isStatic(); + return BS.Pointee->isGlobal(); } /// Checks if the storage is temporary. bool isTemporary() const { @@ -1018,7 +1016,7 @@ class Pointer { Lit->getBytes().data() + (Offset * Lit->getCharByteWidth())); } assert(isBlockPointer()); - return BS.Pointee->rawData() + Offset; + return BS.Pointee->data() + Offset; } /// Returns the index into an array. @@ -1332,9 +1330,8 @@ class Pointer { /// Returns the embedded descriptor preceding a field. InlineDescriptor *getInlineDesc() const { assert(isBlockPointer()); - assert(BS.Base != sizeof(GlobalInlineDescriptor)); assert(BS.Base <= BS.Pointee->getSize()); - assert(BS.Base >= sizeof(InlineDescriptor)); + assert(BS.Base != 0); return getDescriptor(BS.Base); } diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 94eca237cd3d87..1205ff1cabd36a 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -25,9 +25,8 @@ Pointer Program::getPtrGlobal(unsigned Idx) const { // Force de-serialization of a redeclaration that might initialize this // global. - if (B->getMetadataSize() != 0 && - B->getBlockDesc<GlobalInlineDescriptor>().InitState != - GlobalInitState::Initialized) { + if (B->isGlobal() && B->getBlockDesc<GlobalInlineDescriptor>().InitState != + GlobalInitState::Initialized) { if (const VarDecl *VD = B->getDescriptor()->asVarDecl()) { const VarDecl *MD = VD->getMostRecentDecl(); if (MD != VD && MD->hasInit() && !MD->getInit()->isValueDependent()) { @@ -82,24 +81,20 @@ UnsignedOrNone Program::getOrCreateGlobal(const ValueDecl *VD, UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init, bool IsConstexprUnknown) { - bool IsStatic, IsExtern; + bool IsExtern; bool IsWeak = VD->isWeak(); - if (const auto *Var = dyn_cast<VarDecl>(VD)) { - IsStatic = Context::shouldBeGloballyIndexed(VD); + if (const auto *Var = dyn_cast<VarDecl>(VD)) IsExtern = Var->hasExternalStorage(); - } else if (isa<UnnamedGlobalConstantDecl, MSGuidDecl, - TemplateParamObjectDecl>(VD)) { - IsStatic = true; + else if (isa<UnnamedGlobalConstantDecl, MSGuidDecl, TemplateParamObjectDecl>( + VD)) IsExtern = false; - } else { - IsStatic = false; - IsExtern = true; - } + else + llvm_unreachable("The conditions above should cover all cases"); // Register all previous declarations as well. For extern blocks, just replace // the index with the new variable. - UnsignedOrNone Idx = createGlobal(VD, VD->getType(), IsStatic, IsExtern, - IsWeak, IsConstexprUnknown, Init); + UnsignedOrNone Idx = createGlobal(VD, VD->getType(), IsExtern, IsWeak, + IsConstexprUnknown, Init); if (!Idx) return std::nullopt; @@ -136,7 +131,7 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init, UnsignedOrNone Program::createGlobal(const Expr *E, QualType ExprType) { if (auto Idx = getGlobal(E)) return Idx; - if (auto Idx = createGlobal(E, ExprType, /*IsStatic=*/true, + if (auto Idx = createGlobal(E, ExprType, /*IsExtern=*/false, /*IsWeak=*/false, /*IsConstexprUnknown=*/false)) { GlobalIndices[E] = *Idx; @@ -145,9 +140,8 @@ UnsignedOrNone Program::createGlobal(const Expr *E, QualType ExprType) { return std::nullopt; } -UnsignedOrNone Program::createGlobal(DeclOrExpr D, QualType Ty, bool IsStatic, - bool IsExtern, bool IsWeak, - bool IsConstexprUnknown, +UnsignedOrNone Program::createGlobal(DeclOrExpr D, QualType Ty, bool IsExtern, + bool IsWeak, bool IsConstexprUnknown, const Expr *Init) { // Since this global variable is constexpr-unknown and a reference, register // the pointee type instead. When referencing the variable, the pointer will @@ -174,13 +168,15 @@ UnsignedOrNone Program::createGlobal(DeclOrExpr D, QualType Ty, bool IsStatic, // Allocate a block for storage. unsigned I = Globals.size(); - auto *G = new (Allocator, Desc->getAllocSize() + Block::GlobalMD) - Global(Ctx.getEvalID(), getCurrentDecl(), Desc, Block::GlobalMD, IsStatic, - IsExtern, IsWeak); + auto *G = new (Allocator, + Desc->getAllocSize() + Block::getMetadataSize(Block::Global)) + Global(Ctx.getEvalID(), getCurrentDecl(), Desc, Block::Global, IsExtern, + IsWeak); G->block()->invokeCtor(); // Initialize GlobalInlineDescriptor fields. - auto *GD = new (G->block()->rawData()) GlobalInlineDescriptor(); + auto *GD = new (&G->block()->getBlockDesc<GlobalInlineDescriptor>()) + GlobalInlineDescriptor(); if (!Init) GD->InitState = GlobalInitState::NoInitializer; Globals.push_back(G); diff --git a/clang/lib/AST/ByteCode/Program.h b/clang/lib/AST/ByteCode/Program.h index 5d7803543aff85..3cae337a6bc765 100644 --- a/clang/lib/AST/ByteCode/Program.h +++ b/clang/lib/AST/ByteCode/Program.h @@ -159,9 +159,8 @@ class Program final { private: friend class DeclScope; - UnsignedOrNone createGlobal(DeclOrExpr D, QualType Ty, bool IsStatic, - bool IsExtern, bool IsWeak, - bool IsConstexprUnknown, + UnsignedOrNone createGlobal(DeclOrExpr D, QualType Ty, bool IsExtern, + bool IsWeak, bool IsConstexprUnknown, const Expr *Init = nullptr); /// Reference to the VM context. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
