Author: Timm Baeder
Date: 2026-08-19T14:18:41+02:00
New Revision: dd53a949dcbb5ac45d3cc3e18e0efb09a5cd598a

URL: 
https://github.com/llvm/llvm-project/commit/dd53a949dcbb5ac45d3cc3e18e0efb09a5cd598a
DIFF: 
https://github.com/llvm/llvm-project/commit/dd53a949dcbb5ac45d3cc3e18e0efb09a5cd598a.diff

LOG: [clang][bytecode] Move `Descriptor` metadata to `Block` (#217280)

The metadata in `Descriptor`s was only ever used for "toplevel"
descriptors, i.e. never for fields or array elements. Those are also the
descriptors we allocate into `Block`s though, so move the metadata there
and save some space in `Descriptor`.

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
    clang/lib/AST/ByteCode/Compiler.cpp
    clang/lib/AST/ByteCode/Context.cpp
    clang/lib/AST/ByteCode/Descriptor.cpp
    clang/lib/AST/ByteCode/Descriptor.h
    clang/lib/AST/ByteCode/Disasm.cpp
    clang/lib/AST/ByteCode/DynamicAllocator.cpp
    clang/lib/AST/ByteCode/EvalEmitter.cpp
    clang/lib/AST/ByteCode/Interp.cpp
    clang/lib/AST/ByteCode/InterpBlock.cpp
    clang/lib/AST/ByteCode/InterpBlock.h
    clang/lib/AST/ByteCode/InterpBuiltin.cpp
    clang/lib/AST/ByteCode/InterpFrame.cpp
    clang/lib/AST/ByteCode/MemberPointer.cpp
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/lib/AST/ByteCode/Pointer.h
    clang/lib/AST/ByteCode/Program.cpp
    clang/lib/AST/ByteCode/Program.h
    clang/unittests/AST/ByteCode/Descriptor.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp 
b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
index 9a2c1c2b496b0..f04478eb6ac16 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.cpp
@@ -92,7 +92,7 @@ void ByteCodeEmitter::compileFunc(const FunctionDecl 
*FuncDecl,
 Scope::Local ByteCodeEmitter::createLocal(Descriptor *D) {
   NextLocalOffset += sizeof(Block);
   unsigned Location = NextLocalOffset;
-  NextLocalOffset += align(D->getAllocSize());
+  NextLocalOffset += align(Block::InlineDescMD + D->getAllocSize());
   return {Location, D};
 }
 

diff  --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index a8e2cb4a3c076..cbfd067bfbdd4 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4218,14 +4218,11 @@ bool Compiler<Emitter>::VisitCXXNewExpr(const 
CXXNewExpr *E) {
       if (E->isArray())
         Desc = nullptr; // We're not going to use it in this case.
       else
-        Desc = P.createDescriptor(E, *ElemT, /*SourceTy=*/nullptr,
-                                  Descriptor::InlineDescMD);
+        Desc = P.createDescriptor(E, *ElemT);
     } else {
-      Desc = P.createDescriptor(
-          E, ElementType.getTypePtr(),
-          E->isArray() ? std::nullopt : Descriptor::InlineDescMD,
-          /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false,
-          /*IsVolatile=*/false, Init);
+      Desc = P.createDescriptor(E, ElementType.getTypePtr(), /*IsConst=*/false,
+                                /*IsTemporary=*/false, /*IsMutable=*/false,
+                                /*IsVolatile=*/false, Init);
     }
   }
 
@@ -5322,8 +5319,7 @@ unsigned 
Compiler<Emitter>::allocateLocalPrimitive(DeclOrExpr &&Src,
   // FIXME: There are cases where Src.isExpr() is wrong, e.g.
   //   (int){12} in C. Consider using Expr::isTemporaryObject() instead
   //   or isa<MaterializeTemporaryExpr>().
-  Descriptor *D = P.createDescriptor(Src, Ty, nullptr, 
Descriptor::InlineDescMD,
-                                     IsConst, Src.isExpr(),
+  Descriptor *D = P.createDescriptor(Src, Ty, nullptr, IsConst, Src.isExpr(),
                                      /*IsMutable=*/false, IsVolatile);
   D->IsConstexprUnknown = this->VariablesAreConstexprUnknown;
   Scope::Local Local = this->createLocal(D);
@@ -5352,9 +5348,8 @@ UnsignedOrNone 
Compiler<Emitter>::allocateLocal(DeclOrExpr &&Src, QualType Ty,
   }
 
   Descriptor *D = P.createDescriptor(
-      Src, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),
-      IsTemporary, /*IsMutable=*/false, 
/*IsVolatile=*/Ty.isVolatileQualified(),
-      Init);
+      Src, Ty.getTypePtr(), Ty.isConstQualified(), IsTemporary,
+      /*IsMutable=*/false, /*IsVolatile=*/Ty.isVolatileQualified(), Init);
   if (!D)
     return std::nullopt;
   D->IsConstexprUnknown = this->VariablesAreConstexprUnknown;
@@ -5371,9 +5366,8 @@ UnsignedOrNone Compiler<Emitter>::allocateTemporary(const 
Expr *E) {
   QualType Ty = E->getType();
   assert(!Ty->isRecordType());
 
-  Descriptor *D = P.createDescriptor(
-      E, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),
-      /*IsTemporary=*/true);
+  Descriptor *D = P.createDescriptor(E, Ty.getTypePtr(), Ty.isConstQualified(),
+                                     /*IsTemporary=*/true);
 
   if (!D)
     return std::nullopt;
@@ -5680,8 +5674,7 @@ bool Compiler<Emitter>::visitDtorCall(const VarDecl *VD, 
const APValue &Value) {
   // Create a local variable to use as the instance.
   QualType Ty = VD->getType();
   Descriptor *D =
-      P.createDescriptor(VD, Ty.getTypePtr(), Descriptor::InlineDescMD,
-                         /*IsConst=*/Ty.isConstQualified(),
+      P.createDescriptor(VD, Ty.getTypePtr(), 
/*IsConst=*/Ty.isConstQualified(),
                          /*IsTemporary=*/false, /*IsMutable=*/false,
                          /*IsVolatile=*/Ty.isVolatileQualified(), nullptr);
   if (!D)

diff  --git a/clang/lib/AST/ByteCode/Context.cpp 
b/clang/lib/AST/ByteCode/Context.cpp
index ce7a95ed49c06..0678b07d0bbf2 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -687,8 +687,8 @@ const Function *Context::getOrCreateFunction(const 
FunctionDecl *FuncDecl) {
 
     OptPrimType T = classify(PD->getType());
     PrimType PT = T.value_or(PT_Ptr);
-    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, std::nullopt,
-                                           IsConst, /*IsTemporary=*/false,
+    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, IsConst,
+                                           /*IsTemporary=*/false,
                                            /*IsMutable=*/false, IsVolatile);
     unsigned PrimTSize = align(primSize(PT));
     ParamDescriptors.emplace_back(Desc, ParamOffset, BlockOffset, PT);
@@ -718,8 +718,8 @@ const Function *Context::getOrCreateObjCBlock(const 
BlockExpr *E) {
 
     OptPrimType T = classify(PD->getType());
     PrimType PT = T.value_or(PT_Ptr);
-    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, std::nullopt,
-                                           IsConst, /*IsTemporary=*/false,
+    Descriptor *Desc = P->createDescriptor(PD, PT, nullptr, IsConst,
+                                           /*IsTemporary=*/false,
                                            /*IsMutable=*/false, IsVolatile);
     ParamDescriptors.emplace_back(Desc, ParamOffset, ~0u, PT);
     ParamOffset += align(primSize(PT));

diff  --git a/clang/lib/AST/ByteCode/Descriptor.cpp 
b/clang/lib/AST/ByteCode/Descriptor.cpp
index 98be3c592f97f..d0435d4684875 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -280,37 +280,33 @@ static BlockDtorFn getDtorArrayPrim(PrimType Type) {
 
 /// Primitives.
 Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
-                       MetadataSize MD, bool IsConst, bool IsTemporary,
-                       bool IsMutable, bool IsVolatile)
+                       bool IsConst, bool IsTemporary, bool IsMutable,
+                       bool IsVolatile)
     : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), 
Size(ElemSize),
-      MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), PrimT(Type),
-      IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
-      IsVolatile(IsVolatile), CtorFn(getCtorPrim(Type)),
-      DtorFn(getDtorPrim(Type)) {
-  assert(AllocSize >= Size);
+      AllocSize(align(ElemSize)), PrimT(Type), IsConst(IsConst),
+      IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
+      CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)) {
   assert(Source && "Missing source");
 }
 
 /// Primitive arrays.
 Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
-                       MetadataSize MD, size_t NumElems, bool IsConst,
-                       bool IsTemporary, bool IsMutable, bool IsVolatile)
+                       size_t NumElems, bool IsConst, bool IsTemporary,
+                       bool IsMutable, bool IsVolatile)
     : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)),
-      Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
-      AllocSize(align(MDSize) + align(Size) + sizeof(InitMapPtr)), PrimT(Type),
-      IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
-      IsVolatile(IsVolatile), IsArray(true), CtorFn(getCtorArrayPrim(Type)),
-      DtorFn(getDtorArrayPrim(Type)) {
+      Size(ElemSize * NumElems), AllocSize(align(Size) + sizeof(InitMapPtr)),
+      PrimT(Type), IsConst(IsConst), IsMutable(IsMutable),
+      IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true),
+      CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)) {
   assert(Source && "Missing source");
   assert(NumElems <= (MaxArrayElemBytes / ElemSize));
 }
 
 /// Primitive unknown-size arrays.
-Descriptor::Descriptor(DeclOrExpr D, PrimType Type, MetadataSize MD,
-                       bool IsTemporary, bool IsConst, UnknownSize)
+Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst,
+                       bool IsTemporary, UnknownSize)
     : Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
-      MDSize(MD.value_or(0)),
-      AllocSize(MDSize + sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
+      AllocSize(sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
       IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary),
       IsArray(true), CtorFn(getCtorArrayPrim(Type)),
       DtorFn(getDtorArrayPrim(Type)) {
@@ -319,47 +315,42 @@ Descriptor::Descriptor(DeclOrExpr D, PrimType Type, 
MetadataSize MD,
 
 /// Arrays of composite elements.
 Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy,
-                       const Descriptor *Elem, MetadataSize MD,
-                       unsigned NumElems, bool IsConst, bool IsTemporary,
-                       bool IsMutable)
+                       const Descriptor *Elem, unsigned NumElems, bool IsConst,
+                       bool IsTemporary, bool IsMutable)
     : Source(D), SourceType(SourceTy),
       ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
-      Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
-      AllocSize(std::max<size_t>(alignof(void *), Size) + MDSize),
-      ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
-      IsTemporary(IsTemporary), IsArray(true), CtorFn(ctorArrayDesc),
+      Size(ElemSize * NumElems),
+      AllocSize(std::max<size_t>(alignof(void *), Size)), ElemDesc(Elem),
+      IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
+      IsArray(true), CtorFn(ctorArrayDesc),
       DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
   assert(Source && "Missing source");
 }
 
 /// Unknown-size arrays of composite elements.
-Descriptor::Descriptor(DeclOrExpr D, const Descriptor *Elem, MetadataSize MD,
-                       bool IsTemporary, UnknownSize)
+Descriptor::Descriptor(DeclOrExpr D, const Descriptor *Elem, bool IsTemporary,
+                       UnknownSize)
     : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
-      Size(UnknownSizeMark), MDSize(MD.value_or(0)),
-      AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(true),
-      IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
+      Size(UnknownSizeMark), AllocSize(alignof(void *)), ElemDesc(Elem),
+      IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
       CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
   assert(Source && "Missing source");
 }
 
 /// Composite records.
-Descriptor::Descriptor(DeclOrExpr D, const Record *R, MetadataSize MD,
-                       bool IsConst, bool IsTemporary, bool IsMutable,
-                       bool IsVolatile)
+Descriptor::Descriptor(DeclOrExpr D, const Record *R, bool IsConst,
+                       bool IsTemporary, bool IsMutable, bool IsVolatile)
     : Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
-      Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
-      ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
-      IsTemporary(IsTemporary), IsVolatile(IsVolatile), CtorFn(ctorRecord),
-      DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) {
+      Size(ElemSize), AllocSize(Size), ElemRecord(R), IsConst(IsConst),
+      IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
+      CtorFn(ctorRecord), DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) {
   assert(Source && "Missing source");
 }
 
 /// Dummy.
-Descriptor::Descriptor(DeclOrExpr D, MetadataSize MD)
-    : Source(D), ElemSize(1), Size(1), MDSize(MD.value_or(0)),
-      AllocSize(MDSize), ElemRecord(nullptr), IsConst(true), IsMutable(false),
-      IsTemporary(false) {
+Descriptor::Descriptor(DeclOrExpr D)
+    : Source(D), ElemSize(1), Size(1), AllocSize(0), ElemDesc(nullptr),
+      IsConst(true), IsMutable(false), IsTemporary(false) {
   assert(Source && "Missing source");
 }
 

diff  --git a/clang/lib/AST/ByteCode/Descriptor.h 
b/clang/lib/AST/ByteCode/Descriptor.h
index 275e2aa594669..ee88b8bad3aee 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -128,9 +128,7 @@ struct Descriptor final {
   const unsigned ElemSize;
   /// Size of the storage, in host bytes.
   const unsigned Size;
-  /// Size of the metadata.
-  const unsigned MDSize;
-  /// Size of the allocation (storage + metadata), in host bytes.
+  /// Size of the allocation (storage), in host bytes.
   const unsigned AllocSize;
 
   /// Value to denote arrays of unknown size.
@@ -140,14 +138,9 @@ struct Descriptor final {
   /// Token to denote structures of unknown size.
   struct UnknownSize {};
 
-  using MetadataSize = std::optional<unsigned>;
-  static constexpr MetadataSize InlineDescMD = sizeof(InlineDescriptor);
-  static constexpr MetadataSize GlobalMD = sizeof(GlobalInlineDescriptor);
-
   /// Maximum number of bytes to be used for array elements.
   static constexpr unsigned MaxArrayElemBytes =
-      std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr) -
-      align(std::max(*InlineDescMD, *GlobalMD));
+      std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr);
 
   /// Pointer to the record, if block contains records.
   const Record *const ElemRecord = nullptr;
@@ -173,33 +166,31 @@ struct Descriptor final {
   const BlockDtorFn DtorFn = nullptr;
 
   /// Allocates a descriptor for a primitive.
-  Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, MetadataSize 
MD,
-             bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile);
+  Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, bool IsConst,
+             bool IsTemporary, bool IsMutable, bool IsVolatile);
 
   /// Allocates a descriptor for an array of primitives.
-  Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, MetadataSize 
MD,
-             size_t NumElems, bool IsConst, bool IsTemporary, bool IsMutable,
-             bool IsVolatile);
+  Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, size_t 
NumElems,
+             bool IsConst, bool IsTemporary, bool IsMutable, bool IsVolatile);
 
   /// Allocates a descriptor for an array of primitives of unknown size.
-  Descriptor(DeclOrExpr D, PrimType Type, MetadataSize MDSize, bool IsConst,
-             bool IsTemporary, UnknownSize);
+  Descriptor(DeclOrExpr D, PrimType Type, bool IsConst, bool IsTemporary,
+             UnknownSize);
 
   /// Allocates a descriptor for an array of composites.
   Descriptor(DeclOrExpr D, const Type *SourceTy, const Descriptor *Elem,
-             MetadataSize MD, unsigned NumElems, bool IsConst, bool 
IsTemporary,
-             bool IsMutable);
+             unsigned NumElems, bool IsConst, bool IsTemporary, bool 
IsMutable);
 
   /// Allocates a descriptor for an array of composites of unknown size.
-  Descriptor(DeclOrExpr D, const Descriptor *Elem, MetadataSize MD,
-             bool IsTemporary, UnknownSize);
+  Descriptor(DeclOrExpr D, const Descriptor *Elem, bool IsTemporary,
+             UnknownSize);
 
   /// Allocates a descriptor for a record.
-  Descriptor(DeclOrExpr D, const Record *R, MetadataSize MD, bool IsConst,
-             bool IsTemporary, bool IsMutable, bool IsVolatile);
+  Descriptor(DeclOrExpr D, const Record *R, bool IsConst, bool IsTemporary,
+             bool IsMutable, bool IsVolatile);
 
   /// Allocates a dummy descriptor.
-  Descriptor(DeclOrExpr D, MetadataSize MD = std::nullopt);
+  Descriptor(DeclOrExpr D);
 
   QualType getType() const;
   QualType getElemQualType() const;
@@ -251,9 +242,6 @@ struct Descriptor final {
   /// E.g., for PT_SInt32, that's 4 bytes.
   unsigned getElemDataSize() const;
 
-  /// Returns the size of the metadata.
-  unsigned getMetadataSize() const { return MDSize; }
-
   /// Returns the number of elements stored in the block.
   unsigned getNumElems() const {
     return Size == UnknownSizeMark ? 0 : (getSize() / getElemSize());

diff  --git a/clang/lib/AST/ByteCode/Disasm.cpp 
b/clang/lib/AST/ByteCode/Disasm.cpp
index 4caf830a0a1b4..9499d3a246706 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -476,16 +476,13 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned 
Offset,
   OS.indent(Spaces);
   dump(OS);
   OS << '\n';
-  OS.indent(Spaces) << "Metadata: " << getMetadataSize() << " bytes\n";
   OS.indent(Spaces) << "Size: " << getSize() << " bytes\n";
   OS.indent(Spaces) << "AllocSize: " << getAllocSize() << " bytes\n";
-  Offset += getMetadataSize();
   if (isCompositeArray()) {
     OS.indent(Spaces) << "Elements: " << getNumElems() << '\n';
     unsigned FO = Offset;
     for (unsigned I = 0; I != getNumElems(); ++I) {
       FO += sizeof(InlineDescriptor);
-      assert(ElemDesc->getMetadataSize() == 0);
       OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n';
       ElemDesc->dumpFull(FO, Indent + 1);
 
@@ -644,6 +641,7 @@ LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) 
const {
   OS << "  Weak: " << isWeak() << "\n";
   OS << "  Dummy: " << isDummy() << '\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 f7909d313eaab..379df235b7fc1 100644
--- a/clang/lib/AST/ByteCode/DynamicAllocator.cpp
+++ b/clang/lib/AST/ByteCode/DynamicAllocator.cpp
@@ -39,8 +39,7 @@ Block *DynamicAllocator::allocate(const Expr *Source, 
PrimType T,
   // Create a new descriptor for an array of the specified size and
   // element type.
   const Descriptor *D =
-      allocateDescriptor(Source, nullptr, T, Descriptor::InlineDescMD,
-                         NumElements, /*IsConst=*/false,
+      allocateDescriptor(Source, nullptr, T, NumElements, /*IsConst=*/false,
                          /*IsTemporary=*/false, /*IsMutable=*/false,
                          /*IsVolatile=*/false);
 
@@ -50,13 +49,11 @@ Block *DynamicAllocator::allocate(const Expr *Source, 
PrimType T,
 Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
                                   size_t NumElements, unsigned EvalID,
                                   Form AllocForm) {
-  assert(ElementDesc->getMetadataSize() == 0);
   // Create a new descriptor for an array of the specified size and
   // element type.
   // FIXME: Pass proper element type.
   const Descriptor *D = allocateDescriptor(
-      ElementDesc->asExpr(), nullptr, ElementDesc, Descriptor::InlineDescMD,
-      NumElements,
+      ElementDesc->asExpr(), nullptr, ElementDesc, NumElements,
       /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
   return allocate(D, EvalID, AllocForm);
 }
@@ -72,12 +69,11 @@ Block *DynamicAllocator::allocate(const Descriptor *D, 
unsigned EvalID,
     return !Alloc.block()->hasPointers();
   });
 
-  auto Memory =
-      std::make_unique<std::byte[]>(sizeof(Block) + D->getAllocSize());
-  auto *B = new (Memory.get()) Block(EvalID, D, /*isStatic=*/false);
+  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);
   B->invokeCtorNoMemset();
-
-  assert(D->getMetadataSize() == sizeof(InlineDescriptor));
   InlineDescriptor *ID = reinterpret_cast<InlineDescriptor *>(B->rawData());
   ID->Desc = D;
   ID->IsActive = true;

diff  --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp 
b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index a54b6d2c18fa9..59eb2731534ce 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -151,8 +151,10 @@ EvalEmitter::LabelTy EvalEmitter::getLabel() { return 
NextLabel++; }
 
 Scope::Local EvalEmitter::createLocal(Descriptor *D) {
   // Allocate memory for a local.
-  auto Memory = std::make_unique<char[]>(sizeof(Block) + D->getAllocSize());
-  auto *B = new (Memory.get()) Block(Ctx.getEvalID(), D, /*IsStatic=*/false);
+  auto Memory = std::make_unique<char[]>(sizeof(Block) + D->getAllocSize() +
+                                         Block::InlineDescMD);
+  auto *B = new (Memory.get()) Block(Ctx.getEvalID(), D, Block::InlineDescMD,
+                                     /*IsStatic=*/false);
   B->invokeCtorNoMemset();
 
   // Initialize local variable inline descriptor.

diff  --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 43020f5ad84c1..7704550a12d82 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -575,7 +575,7 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr,
 
 bool CheckDowncast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
                    uint32_t Offset) {
-  uint32_t MinOffset = Ptr.getDeclDesc()->getMetadataSize();
+  uint32_t MinOffset = Ptr.block()->getMetadataSize();
   uint32_t PtrOffset = Ptr.getByteOffset();
 
   // We subtract Offset from PtrOffset. The result must be at least

diff  --git a/clang/lib/AST/ByteCode/InterpBlock.cpp 
b/clang/lib/AST/ByteCode/InterpBlock.cpp
index 9199cb09687ec..f43b477dff7f9 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.cpp
+++ b/clang/lib/AST/ByteCode/InterpBlock.cpp
@@ -102,8 +102,7 @@ bool Block::hasPointer(const Pointer *P) const {
 
 void Block::movePointersTo(Block *B) {
   assert(B != this);
-  unsigned MDDiff = static_cast<int>(B->Desc->getMetadataSize()) -
-                    static_cast<int>(Desc->getMetadataSize());
+  unsigned MDDiff = static_cast<int>(B->MDSize) - static_cast<int>(MDSize);
 
   while (Pointers) {
     Pointer *P = Pointers;
@@ -135,8 +134,9 @@ void Block::removePointers() {
 }
 
 DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
-    : Root(Root), B(~0u, Blk->Desc, Blk->isExtern(), Blk->IsStatic,
-                    Blk->isWeak(), Blk->isDummy(), /*IsDead=*/true) {
+    : Root(Root), B(~0u, Blk->Desc, Blk->MDSize, Blk->isExtern(), 
Blk->IsStatic,
+                    Blk->isWeak(), Blk->isDummy(),
+                    /*IsDead=*/true) {
   // Add the block to the chain of dead blocks.
   if (Root)
     Root->Prev = this;

diff  --git a/clang/lib/AST/ByteCode/InterpBlock.h 
b/clang/lib/AST/ByteCode/InterpBlock.h
index 0d64439da78ae..ffb4bf2e75654 100644
--- a/clang/lib/AST/ByteCode/InterpBlock.h
+++ b/clang/lib/AST/ByteCode/InterpBlock.h
@@ -29,17 +29,16 @@ enum PrimType : uint8_t;
 /// The storage described by the block is immediately followed by
 /// optional metadata, which is followed by the actual data.
 ///
-/// Block*        rawData()                  data()
-/// │               │                         │
-/// │               │                         │
-/// ▼               ▼                         ▼
-/// ┌───────────────┬─────────────────────────┬─────────────────┐
-/// │ Block         │ Metadata                │ Data            │
-/// │ sizeof(Block) │ Desc->getMetadataSize() │ Desc->getSize() │
-/// └───────────────┴─────────────────────────┴─────────────────┘
+/// Block*        rawData()           data()
+/// │               │                  │
+/// │               │                  │
+/// ▼               ▼                  ▼
+/// ┌───────────────┬──────────────────┬─────────────────┐
+/// │ Block         │ Metadata         │ Data            │
+/// │ sizeof(Block) │ MDSize           │ Desc->getSize() │
+/// └───────────────┴──────────────────┴─────────────────┘
 ///
-/// Desc->getAllocSize() describes the size after the Block, i.e.
-/// the data size and the metadata size.
+/// getSize() returns MDSize + Desc->getAllocSize().
 ///
 class Block final {
 private:
@@ -49,20 +48,25 @@ class Block final {
   static constexpr uint8_t DummyFlag = 1 << 3;
 
 public:
+  static constexpr uint8_t InlineDescMD = sizeof(InlineDescriptor);
+  static constexpr uint8_t GlobalMD = sizeof(GlobalInlineDescriptor);
+
   /// Creates a new block.
   Block(unsigned EvalID, UnsignedOrNone DeclID, const Descriptor *Desc,
-        bool IsStatic = false, bool IsExtern = false, bool IsWeak = false,
-        bool IsDummy = false)
-      : Desc(Desc), DeclID(DeclID), EvalID(EvalID), IsStatic(IsStatic) {
+        unsigned MDSize = 0, bool IsStatic = false, bool IsExtern = false,
+        bool IsWeak = false, bool IsDummy = false)
+      : Desc(Desc), DeclID(DeclID), EvalID(EvalID), MDSize(MDSize),
+        IsStatic(IsStatic) {
     assert(Desc);
     AccessFlags |= (ExternFlag * IsExtern);
     AccessFlags |= (WeakFlag * IsWeak);
     AccessFlags |= (DummyFlag * IsDummy);
   }
 
-  Block(unsigned EvalID, const Descriptor *Desc, bool IsStatic = false,
-        bool IsExtern = false, bool IsWeak = false, bool IsDummy = false)
-      : Desc(Desc), EvalID(EvalID), IsStatic(IsStatic) {
+  Block(unsigned EvalID, const Descriptor *Desc, unsigned MDSize = 0,
+        bool IsStatic = false, bool IsExtern = false, bool IsWeak = false,
+        bool IsDummy = false)
+      : Desc(Desc), EvalID(EvalID), MDSize(MDSize), IsStatic(IsStatic) {
     assert(Desc);
     AccessFlags |= (ExternFlag * IsExtern);
     AccessFlags |= (WeakFlag * IsWeak);
@@ -83,8 +87,10 @@ class Block final {
   bool isDynamic() const { return (DynAllocId != std::nullopt); }
   bool isDummy() const { return AccessFlags & DummyFlag; }
   bool isDead() const { return AccessFlags & DeadFlag; }
-  /// Returns the size of the block.
-  unsigned getSize() const { return Desc->getAllocSize(); }
+  /// Returns the size of the block, including metadata.
+  unsigned getSize() const { return Desc->getAllocSize() + MDSize; }
+  /// Returns the size of the metadata.
+  unsigned getMetadataSize() const { return MDSize; }
   /// Returns the declaration ID.
   UnsignedOrNone getDeclID() const { return DeclID; }
   /// Returns whether the data of this block has been initialized via
@@ -99,16 +105,8 @@ class Block final {
 
   /// Returns a pointer to the stored data.
   /// You are allowed to read Desc->getSize() bytes from this address.
-  std::byte *data() {
-    // rawData might contain metadata as well.
-    size_t DataOffset = Desc->getMetadataSize();
-    return rawData() + DataOffset;
-  }
-  const std::byte *data() const {
-    // rawData might contain metadata as well.
-    size_t DataOffset = Desc->getMetadataSize();
-    return rawData() + DataOffset;
-  }
+  std::byte *data() { return rawData() + MDSize; }
+  const std::byte *data() const { return rawData() + MDSize; }
 
   /// Returns a pointer to the raw data, including metadata.
   /// You are allowed to read Desc->getAllocSize() bytes from this address.
@@ -125,7 +123,7 @@ class Block final {
   template <typename T> T &deref() { return *reinterpret_cast<T *>(data()); }
 
   template <typename T> T &getBlockDesc() {
-    assert(sizeof(T) == getDescriptor()->getMetadataSize());
+    assert(sizeof(T) == MDSize);
     return *reinterpret_cast<T *>(rawData());
   }
   template <typename T> const T &getBlockDesc() const {
@@ -135,7 +133,7 @@ class Block final {
   /// Invokes the constructor.
   void invokeCtor() {
     assert(!IsInitialized);
-    std::memset(rawData(), 0, Desc->getAllocSize());
+    std::memset(rawData(), 0, getSize());
     invokeCtorNoMemset();
   }
   /// The same, but won't memset() the memory first to zero.
@@ -169,9 +167,9 @@ class Block final {
   friend class DynamicAllocator;
   friend class Program;
 
-  Block(unsigned EvalID, const Descriptor *Desc, bool IsExtern, bool IsStatic,
-        bool IsWeak, bool IsDummy, bool IsDead)
-      : Desc(Desc), EvalID(EvalID), IsStatic(IsStatic) {
+  Block(unsigned EvalID, const Descriptor *Desc, unsigned MDSize, bool 
IsExtern,
+        bool IsStatic, bool IsWeak, bool IsDummy, bool IsDead)
+      : Desc(Desc), EvalID(EvalID), MDSize(MDSize), IsStatic(IsStatic) {
     assert(Desc);
     AccessFlags |= (ExternFlag * IsExtern);
     AccessFlags |= (DeadFlag * IsDead);
@@ -200,15 +198,17 @@ class Block final {
   /// Unique identifier of the declaration.
   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, IsWeak, and IsDummy 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;
   /// Flag indicating if the block contents have been initialized
   /// via invokeCtor.
   bool IsInitialized = false;
-  /// Allocation ID for this dynamic allocation, if it is one.
-  UnsignedOrNone DynAllocId = std::nullopt;
-  /// AccessFlags containing IsExtern, IsDead, IsWeak, and IsDummy bits.
-  uint8_t AccessFlags = 0;
 };
 
 /// Descriptor for a dead block.

diff  --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 9386a12ac13c2..54b2b4bb1b16d 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -1608,7 +1608,7 @@ static bool interp__builtin_operator_new(InterpState &S, 
CodePtr OpPC,
   // Composite arrays
   if (IsArray) {
     const Descriptor *Desc =
-        S.P.createDescriptor(NewCall, ElemType.getTypePtr(), std::nullopt);
+        S.P.createDescriptor(NewCall, ElemType.getTypePtr());
     Block *B =
         Allocator.allocate(Desc, NumElems.getZExtValue(), S.Ctx.getEvalID(),
                            DynamicAllocator::Form::Operator);
@@ -1621,8 +1621,8 @@ static bool interp__builtin_operator_new(InterpState &S, 
CodePtr OpPC,
   QualType AllocType = S.getASTContext().getConstantArrayType(
       ElemType, NumElems, nullptr, ArraySizeModifier::Normal, 0);
 
-  const Descriptor *Desc = S.P.createDescriptor(NewCall, 
AllocType.getTypePtr(),
-                                                Descriptor::InlineDescMD);
+  const Descriptor *Desc =
+      S.P.createDescriptor(NewCall, AllocType.getTypePtr());
   Block *B = Allocator.allocate(Desc, S.getContext().getEvalID(),
                                 DynamicAllocator::Form::Operator);
   assert(B);

diff  --git a/clang/lib/AST/ByteCode/InterpFrame.cpp 
b/clang/lib/AST/ByteCode/InterpFrame.cpp
index a91f6172ca9ca..a12836403c386 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.cpp
+++ b/clang/lib/AST/ByteCode/InterpFrame.cpp
@@ -50,7 +50,8 @@ InterpFrame::InterpFrame(InterpState &S, const Function *Func,
 
   for (auto &Scope : Func->scopes()) {
     for (auto &Local : Scope.locals()) {
-      new (localBlock(Local.Offset)) Block(S.EvalID, Local.Desc);
+      new (localBlock(Local.Offset))
+          Block(S.EvalID, Local.Desc, Block::InlineDescMD);
       // Note that we are NOT calling invokeCtor() here, since that is done
       // via the InitScope op.
       new (localInlineDesc(Local.Offset)) InlineDescriptor(Local.Desc);

diff  --git a/clang/lib/AST/ByteCode/MemberPointer.cpp 
b/clang/lib/AST/ByteCode/MemberPointer.cpp
index bccadc4d4fc8f..ea6963e66d85c 100644
--- a/clang/lib/AST/ByteCode/MemberPointer.cpp
+++ b/clang/lib/AST/ByteCode/MemberPointer.cpp
@@ -22,7 +22,7 @@ std::optional<Pointer> MemberPointer::toPointer(const Context 
&Ctx) const {
   if (!Base.isBlockPointer())
     return std::nullopt;
 
-  unsigned BlockMDSize = Base.block()->getDescriptor()->getMetadataSize();
+  unsigned BlockMDSize = Base.block()->getMetadataSize();
 
   if (PtrOffset >= 0) {
     // If the resulting base would be too small, return nullopt.

diff  --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 55903c4cff70c..46f658f7cef64 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -26,8 +26,8 @@ using namespace clang;
 using namespace clang::interp;
 
 Pointer::Pointer(Block *Pointee)
-    : Pointer(Pointee, Pointee->getDescriptor()->getMetadataSize(),
-              Pointee->getDescriptor()->getMetadataSize()) {}
+    : Pointer(Pointee, Pointee->getMetadataSize(), Pointee->getMetadataSize()) 
{
+}
 
 Pointer::Pointer(Block *Pointee, uint64_t BaseAndOffset)
     : Pointer(Pointee, BaseAndOffset, BaseAndOffset) {}
@@ -36,7 +36,7 @@ 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->getDescriptor()->getMetadataSize());
+  assert(Base >= Pointee->getMetadataSize());
 
   BS = {Pointee, Base, nullptr, nullptr};
   Pointee->addPointer(this);

diff  --git a/clang/lib/AST/ByteCode/Pointer.h 
b/clang/lib/AST/ByteCode/Pointer.h
index fa16c28712ac5..78768929f3487 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -57,9 +57,7 @@ struct PtrView {
 
   unsigned getEvalID() { return Pointee->getEvalID(); }
 
-  bool isRoot() const {
-    return Base == Pointee->getDescriptor()->getMetadataSize();
-  }
+  bool isRoot() const { return Base == Pointee->getMetadataSize(); }
 
   bool isConst() const {
     return isRoot() ? getDeclDesc()->IsConst : getInlineDesc()->IsConst;
@@ -132,10 +130,9 @@ struct PtrView {
 
     // Step into the containing array, if inside one.
     unsigned Next = Base - getInlineDesc()->Offset;
-    const Descriptor *Desc =
-        (Next == Pointee->getDescriptor()->getMetadataSize())
-            ? getDeclDesc()
-            : getDescriptor(Next)->Desc;
+    const Descriptor *Desc = (Next == Pointee->getMetadataSize())
+                                 ? getDeclDesc()
+                                 : getDescriptor(Next)->Desc;
     if (!Desc->IsArray)
       return *this;
     return PtrView{Pointee, Next, Offset};
@@ -251,7 +248,7 @@ struct PtrView {
 
     unsigned ElemByteOffset = I * getFieldDesc()->getElemSize();
     unsigned ReadOffset = Base + sizeof(InitMapPtr) + ElemByteOffset;
-    assert(ReadOffset + sizeof(T) <= Pointee->getDescriptor()->getAllocSize());
+    assert(ReadOffset + sizeof(T) <= Pointee->getSize());
 
     return *reinterpret_cast<T *>(Pointee->rawData() + ReadOffset);
   }
@@ -878,7 +875,7 @@ class Pointer {
     assert(isBlockPointer());
     assert(BS.Pointee);
     assert(isDereferencable());
-    assert(Offset + sizeof(T) <= BS.Pointee->getDescriptor()->getAllocSize());
+    assert(Offset + sizeof(T) <= BS.Pointee->getSize());
 
     return view().deref<T>();
   }

diff  --git a/clang/lib/AST/ByteCode/Program.cpp 
b/clang/lib/AST/ByteCode/Program.cpp
index 564d2d8fc422d..c838729fb599d 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -45,20 +45,19 @@ unsigned Program::createGlobalString(const StringLiteral 
*S, const Expr *Base) {
     Base = S;
 
   // Create a descriptor for the string.
-  Descriptor *Desc =
-      allocateDescriptor(Base, S->getType().getTypePtr(), *CharType,
-                         Descriptor::GlobalMD, StringLength + 1,
-                         /*IsConst=*/true,
-                         /*isTemporary=*/false,
-                         /*isMutable=*/false,
-                         /*IsVolatile=*/false);
+  Descriptor *Desc = allocateDescriptor(Base, S->getType().getTypePtr(),
+                                        *CharType, StringLength + 1,
+                                        /*IsConst=*/true,
+                                        /*isTemporary=*/false,
+                                        /*isMutable=*/false,
+                                        /*IsVolatile=*/false);
 
   // Allocate storage for the string.
   // The byte length does not include the null terminator.
   unsigned GlobalIndex = Globals.size();
-  unsigned Sz = Desc->getAllocSize();
-  auto *G = new (Allocator, Sz) Global(Ctx.getEvalID(), Desc, 
/*IsStatic=*/true,
-                                       /*IsExtern=*/false);
+  unsigned Sz = Desc->getAllocSize() + Block::GlobalMD;
+  auto *G = new (Allocator, Sz) Global(Ctx.getEvalID(), Desc, Block::GlobalMD,
+                                       /*IsStatic=*/true, /*IsExtern=*/false);
   G->block()->invokeCtor();
 
   new (G->block()->rawData())
@@ -150,10 +149,10 @@ unsigned Program::getOrCreateDummy(DeclOrExpr D, bool 
IsConstexprUnknown) {
 
   Descriptor *Desc;
   if (OptPrimType T = Ctx.classify(QT))
-    Desc = createDescriptor(D, *T, /*SourceTy=*/nullptr, std::nullopt,
+    Desc = createDescriptor(D, *T, /*SourceTy=*/nullptr,
                             /*IsConst=*/QT.isConstQualified());
   else
-    Desc = createDescriptor(D, QT.getTypePtr(), std::nullopt,
+    Desc = createDescriptor(D, QT.getTypePtr(),
                             /*IsConst=*/QT.isConstQualified());
   if (!Desc)
     Desc = allocateDescriptor(D);
@@ -166,8 +165,8 @@ unsigned Program::getOrCreateDummy(DeclOrExpr D, bool 
IsConstexprUnknown) {
   unsigned I = Globals.size();
 
   auto *G = new (Allocator, Desc->getAllocSize())
-      Global(Ctx.getEvalID(), getCurrentDecl(), Desc, /*IsStatic=*/true,
-             /*IsExtern=*/false, IsWeak, /*IsDummy=*/true);
+      Global(Ctx.getEvalID(), getCurrentDecl(), Desc, /*MDSize=*/0u,
+             /*IsStatic=*/true, /*IsExtern=*/false, IsWeak, /*IsDummy=*/true);
   G->block()->invokeCtor();
   assert(G->block()->isDummy());
 
@@ -266,11 +265,11 @@ UnsignedOrNone Program::createGlobal(DeclOrExpr D, 
QualType Ty, bool IsStatic,
   const bool IsTemporary = D.isExpr();
   const bool IsVolatile = Ty.isVolatileQualified();
   if (OptPrimType T = Ctx.classify(Ty))
-    Desc = createDescriptor(D, *T, nullptr, Descriptor::GlobalMD, IsConst,
-                            IsTemporary, /*IsMutable=*/false, IsVolatile);
+    Desc = createDescriptor(D, *T, nullptr, IsConst, IsTemporary,
+                            /*IsMutable=*/false, IsVolatile);
   else
-    Desc = createDescriptor(D, Ty.getTypePtr(), Descriptor::GlobalMD, IsConst,
-                            IsTemporary, /*IsMutable=*/false, IsVolatile);
+    Desc = createDescriptor(D, Ty.getTypePtr(), IsConst, IsTemporary,
+                            /*IsMutable=*/false, IsVolatile);
 
   if (!Desc)
     return std::nullopt;
@@ -279,8 +278,9 @@ UnsignedOrNone Program::createGlobal(DeclOrExpr D, QualType 
Ty, bool IsStatic,
   // Allocate a block for storage.
   unsigned I = Globals.size();
 
-  auto *G = new (Allocator, Desc->getAllocSize()) Global(
-      Ctx.getEvalID(), getCurrentDecl(), Desc, IsStatic, IsExtern, IsWeak);
+  auto *G = new (Allocator, Desc->getAllocSize() + Block::GlobalMD)
+      Global(Ctx.getEvalID(), getCurrentDecl(), Desc, Block::GlobalMD, 
IsStatic,
+             IsExtern, IsWeak);
   G->block()->invokeCtor();
 
   // Initialize GlobalInlineDescriptor fields.
@@ -325,8 +325,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
                             const Record *BR) -> const Descriptor * {
     if (!BR)
       return nullptr;
-    return allocateDescriptor(BD, BR, std::nullopt, /*IsConst=*/false,
-                              /*IsTemporary=*/false,
+    return allocateDescriptor(BD, BR, /*IsConst=*/false, /*IsTemporary=*/false,
                               /*IsMutable=*/false, /*IsVolatile=*/false);
   };
 
@@ -388,12 +387,12 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
     const bool IsVolatile = FT.isVolatileQualified();
     const Descriptor *Desc;
     if (OptPrimType T = Ctx.classify(FT)) {
-      Desc = createDescriptor(FD, *T, nullptr, std::nullopt, IsConst,
+      Desc = createDescriptor(FD, *T, nullptr, IsConst,
                               /*IsTemporary=*/false, IsMutable, IsVolatile);
       HasPtrField = HasPtrField || (T == PT_Ptr);
-    } else if ((Desc = createDescriptor(
-                    FD, FT.getTypePtr(), std::nullopt, IsConst,
-                    /*IsTemporary=*/false, IsMutable, IsVolatile))) {
+    } else if ((Desc = createDescriptor(FD, FT.getTypePtr(), IsConst,
+                                        /*IsTemporary=*/false, IsMutable,
+                                        IsVolatile))) {
       HasPtrField =
           HasPtrField ||
           (Desc->isPrimitiveArray() && Desc->getPrimType() == PT_Ptr) ||
@@ -413,16 +412,15 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
 }
 
 Descriptor *Program::createDescriptor(DeclOrExpr D, const Type *Ty,
-                                      Descriptor::MetadataSize MDSize,
                                       bool IsConst, bool IsTemporary,
                                       bool IsMutable, bool IsVolatile,
                                       const Expr *Init) {
   // Classes and structures.
   if (const auto *RD = Ty->getAsRecordDecl()) {
     if (const auto *Record = getOrCreateRecord(RD))
-      return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary,
-                                IsMutable, IsVolatile);
-    return allocateDescriptor(D, MDSize);
+      return allocateDescriptor(D, Record, IsConst, IsTemporary, IsMutable,
+                                IsVolatile);
+    return allocateDescriptor(D);
   }
 
   // Arrays.
@@ -437,20 +435,20 @@ Descriptor *Program::createDescriptor(DeclOrExpr D, const 
Type *Ty,
         if ((Descriptor::MaxArrayElemBytes / ElemSize) < NumElems) {
           return nullptr;
         }
-        return allocateDescriptor(D, CAT, *T, MDSize, NumElems, IsConst,
-                                  IsTemporary, IsMutable, IsVolatile);
+        return allocateDescriptor(D, CAT, *T, NumElems, IsConst, IsTemporary,
+                                  IsMutable, IsVolatile);
       }
         // Arrays of composites. In this case, the array is a list of pointers,
         // followed by the actual elements.
-        const Descriptor *ElemDesc = createDescriptor(
-            D, ElemTy.getTypePtr(), std::nullopt, IsConst, IsTemporary);
-        if (!ElemDesc)
-          return nullptr;
-        unsigned ElemSize = ElemDesc->getAllocSize() + 
sizeof(InlineDescriptor);
-        if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
-          return nullptr;
-        return allocateDescriptor(D, Ty, ElemDesc, MDSize, NumElems, IsConst,
-                                  IsTemporary, IsMutable);
+      const Descriptor *ElemDesc =
+          createDescriptor(D, ElemTy.getTypePtr(), IsConst, IsTemporary);
+      if (!ElemDesc)
+        return nullptr;
+      unsigned ElemSize = ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
+      if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
+        return nullptr;
+      return allocateDescriptor(D, Ty, ElemDesc, NumElems, IsConst, 
IsTemporary,
+                                IsMutable);
     }
 
     // Array of unknown bounds - cannot be accessed and pointer arithmetic
@@ -458,23 +456,22 @@ Descriptor *Program::createDescriptor(DeclOrExpr D, const 
Type *Ty,
     if (isa<IncompleteArrayType>(ArrayType) ||
         isa<VariableArrayType>(ArrayType)) {
       if (OptPrimType T = Ctx.classify(ElemTy)) {
-        return allocateDescriptor(D, *T, MDSize, IsConst, IsTemporary,
+        return allocateDescriptor(D, *T, IsConst, IsTemporary,
                                   Descriptor::UnknownSize{});
       }
-        const Descriptor *Desc = createDescriptor(
-            D, ElemTy.getTypePtr(), std::nullopt, IsConst, IsTemporary);
-        if (!Desc)
-          return nullptr;
-        return allocateDescriptor(D, Desc, MDSize, IsTemporary,
-                                  Descriptor::UnknownSize{});
+      const Descriptor *Desc =
+          createDescriptor(D, ElemTy.getTypePtr(), IsConst, IsTemporary);
+      if (!Desc)
+        return nullptr;
+      return allocateDescriptor(D, Desc, IsTemporary,
+                                Descriptor::UnknownSize{});
     }
   }
 
   // Atomic types.
   if (const auto *AT = Ty->getAs<AtomicType>()) {
     const Type *InnerTy = AT->getValueType().getTypePtr();
-    return createDescriptor(D, InnerTy, MDSize, IsConst, IsTemporary,
-                            IsMutable);
+    return createDescriptor(D, InnerTy, IsConst, IsTemporary, IsMutable);
   }
 
   // Complex types - represented as arrays of elements.
@@ -483,7 +480,7 @@ Descriptor *Program::createDescriptor(DeclOrExpr D, const 
Type *Ty,
     if (!ElemTy)
       return nullptr;
 
-    return allocateDescriptor(D, CT, *ElemTy, MDSize, 2, IsConst, IsTemporary,
+    return allocateDescriptor(D, CT, *ElemTy, 2, IsConst, IsTemporary,
                               IsMutable, IsVolatile);
   }
 
@@ -493,8 +490,8 @@ Descriptor *Program::createDescriptor(DeclOrExpr D, const 
Type *Ty,
     if (!ElemTy)
       return nullptr;
 
-    return allocateDescriptor(D, VT, *ElemTy, MDSize, VT->getNumElements(),
-                              IsConst, IsTemporary, IsMutable, IsVolatile);
+    return allocateDescriptor(D, VT, *ElemTy, VT->getNumElements(), IsConst,
+                              IsTemporary, IsMutable, IsVolatile);
   }
 
   // Same with constant matrix types.
@@ -503,9 +500,8 @@ Descriptor *Program::createDescriptor(DeclOrExpr D, const 
Type *Ty,
     if (!ElemTy)
       return nullptr;
 
-    return allocateDescriptor(D, MT, *ElemTy, MDSize,
-                              MT->getNumElementsFlattened(), IsConst,
-                              IsTemporary, IsMutable, IsVolatile);
+    return allocateDescriptor(D, MT, *ElemTy, MT->getNumElementsFlattened(),
+                              IsConst, IsTemporary, IsMutable, IsVolatile);
   }
 
   return nullptr;

diff  --git a/clang/lib/AST/ByteCode/Program.h 
b/clang/lib/AST/ByteCode/Program.h
index c2299a1e10191..cbddbcd28ba3f 100644
--- a/clang/lib/AST/ByteCode/Program.h
+++ b/clang/lib/AST/ByteCode/Program.h
@@ -122,17 +122,15 @@ class Program final {
   /// Creates a descriptor for a primitive type.
   Descriptor *createDescriptor(DeclOrExpr D, PrimType T,
                                const Type *SourceTy = nullptr,
-                               Descriptor::MetadataSize MDSize = std::nullopt,
                                bool IsConst = false, bool IsTemporary = false,
                                bool IsMutable = false,
                                bool IsVolatile = false) {
-    return allocateDescriptor(D, SourceTy, T, MDSize, IsConst, IsTemporary,
-                              IsMutable, IsVolatile);
+    return allocateDescriptor(D, SourceTy, T, IsConst, IsTemporary, IsMutable,
+                              IsVolatile);
   }
 
   /// Creates a descriptor for a composite type.
   Descriptor *createDescriptor(DeclOrExpr D, const Type *Ty,
-                               Descriptor::MetadataSize MDSize = std::nullopt,
                                bool IsConst = false, bool IsTemporary = false,
                                bool IsMutable = false, bool IsVolatile = false,
                                const Expr *Init = nullptr);

diff  --git a/clang/unittests/AST/ByteCode/Descriptor.cpp 
b/clang/unittests/AST/ByteCode/Descriptor.cpp
index 3ce97f339ed29..a6b72422db846 100644
--- a/clang/unittests/AST/ByteCode/Descriptor.cpp
+++ b/clang/unittests/AST/ByteCode/Descriptor.cpp
@@ -54,7 +54,6 @@ TEST(Descriptor, Primitives) {
   ASSERT_FALSE(GlobalDesc->asRecordDecl());
 
   // Still true because this is a global variable.
-  ASSERT_TRUE(GlobalDesc->getMetadataSize() == sizeof(GlobalInlineDescriptor));
   ASSERT_FALSE(GlobalDesc->isPrimitiveArray());
   ASSERT_FALSE(GlobalDesc->isCompositeArray());
   ASSERT_FALSE(GlobalDesc->isZeroSizeArray());


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to