https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/234203

>From 353b2b9d5b4da90a391ef5447e159006b96a0336 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                | 81 +++++++++++++------
 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              | 56 ++++++-------
 clang/lib/AST/ByteCode/Program.cpp            | 39 +++++----
 clang/lib/AST/ByteCode/Program.h              |  5 +-
 16 files changed, 169 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..642dd97fd88b6d 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,10 @@ class Block final {
     return Result;
   }
   bool isDead() const { return AccessFlags & DeadFlag; }
+  /// Returns the size of the block, excluding metadata.
+  unsigned getSize() const { return DescSize; }
   /// Returns the size of the block, including metadata.
-  unsigned getSize() const { return Desc->getAllocSize() + MDSize; }
+  unsigned getAllocSize() const { return DescSize + MDSize; }
   /// Returns the size of the metadata.
   unsigned getMetadataSize() const { return MDSize; }
   /// Returns the declaration ID.
@@ -123,7 +144,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 +163,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.
@@ -142,7 +172,7 @@ class Block final {
     if (Desc->CtorFn)
       Desc->CtorFn(this, data(), Desc->IsConst, Desc->IsMutable,
                    Desc->IsVolatile,
-                   /*isActive=*/true, /*InUnion=*/false, Desc);
+                   /*IsActive=*/true, /*InUnion=*/false, Desc);
 
     IsInitialized = true;
   }
@@ -167,9 +197,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);
@@ -191,20 +222,22 @@ class Block final {
 #endif
 
   /// Pointer to the stack slot descriptor.
-  const Descriptor *Desc;
+  const Descriptor *const Desc;
   /// Start of the chain of pointers.
   Pointer *Pointers = nullptr;
+  /// Size of the data(), excluding block-level metadata.
+  const unsigned DescSize;
   /// Unique identifier of the declaration.
-  UnsignedOrNone DeclID = std::nullopt;
+  const UnsignedOrNone DeclID = std::nullopt;
   const unsigned EvalID = ~0u;
   /// Allocation ID for this dynamic allocation, if it is one.
   UnsignedOrNone DynAllocId = std::nullopt;
   /// 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;
+  /// 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..0e1544baa97de6 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());
+  assert(aligned(Block::getMetadataSize(Block::Local) + D->getAllocSize()));
+  NextLocalOffset += 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..4ee3a2da2bfab9 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};
@@ -223,7 +220,7 @@ struct PtrView {
     if (isZero())
       return 0;
     // narrow()ed element in a composite array.
-    if (Base > sizeof(InlineDescriptor) && Base == Offset)
+    if (Base != 0 && Base == Offset)
       return 0;
 
     if (auto ElemSize = elemSize())
@@ -239,7 +236,7 @@ struct PtrView {
 
     // Might be a narrow()'ed element in a composite array.
     // Check the inline descriptor.
-    if (Base >= sizeof(InlineDescriptor) && getInlineDesc()->IsArrayElement)
+    if (Base != 0 && getInlineDesc()->IsArrayElement)
       return true;
 
     return false;
@@ -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,18 @@ 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 +323,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 +530,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
@@ -788,7 +790,7 @@ class Pointer {
     return false;
   }
   bool inUnion() const {
-    if (isBlockPointer() && BS.Base >= sizeof(InlineDescriptor))
+    if (isBlockPointer() && BS.Base != 0)
       return view().inUnion();
     return false;
   };
@@ -828,8 +830,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 +891,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 +1019,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 +1333,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..343edf88ee352e 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,21 @@ 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);
     IsExtern = Var->hasExternalStorage();
-  } else if (isa<UnnamedGlobalConstantDecl, MSGuidDecl,
-                 TemplateParamObjectDecl>(VD)) {
-    IsStatic = true;
-    IsExtern = false;
   } else {
-    IsStatic = false;
-    IsExtern = true;
+    assert((isa<UnnamedGlobalConstantDecl, MSGuidDecl, 
TemplateParamObjectDecl>(
+        VD)));
+    IsExtern = false;
   }
 
   // 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 +132,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 +141,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 +169,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

Reply via email to