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
