diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Descriptor.cpp')
| -rw-r--r-- | clang/lib/AST/ByteCode/Descriptor.cpp | 108 |
1 files changed, 52 insertions, 56 deletions
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp index 9ecc7b673cf2..0a819599287e 100644 --- a/clang/lib/AST/ByteCode/Descriptor.cpp +++ b/clang/lib/AST/ByteCode/Descriptor.cpp @@ -50,14 +50,6 @@ static void dtorTy(Block *, std::byte *Ptr, const Descriptor *) { } template <typename T> -static void moveTy(Block *, std::byte *Src, std::byte *Dst, - const Descriptor *) { - auto *SrcPtr = reinterpret_cast<T *>(Src); - auto *DstPtr = reinterpret_cast<T *>(Dst); - new (DstPtr) T(std::move(*SrcPtr)); -} - -template <typename T> static void ctorArrayTy(Block *, std::byte *Ptr, bool, bool, bool, bool, bool, const Descriptor *D) { new (Ptr) InitMapPtr(std::nullopt); @@ -85,28 +77,6 @@ static void dtorArrayTy(Block *, std::byte *Ptr, const Descriptor *D) { } } -template <typename T> -static void moveArrayTy(Block *, std::byte *Src, std::byte *Dst, - const Descriptor *D) { - InitMapPtr &SrcIMP = *reinterpret_cast<InitMapPtr *>(Src); - if (SrcIMP) { - // We only ever invoke the moveFunc when moving block contents to a - // DeadBlock. DeadBlocks don't need InitMaps, so we destroy them here. - SrcIMP = std::nullopt; - } - Src += sizeof(InitMapPtr); - Dst += sizeof(InitMapPtr); - if constexpr (!needsCtor<T>()) { - std::memcpy(Dst, Src, D->getNumElems() * D->getElemSize()); - } else { - for (unsigned I = 0, NE = D->getNumElems(); I < NE; ++I) { - auto *SrcPtr = &reinterpret_cast<T *>(Src)[I]; - auto *DstPtr = &reinterpret_cast<T *>(Dst)[I]; - new (DstPtr) T(std::move(*SrcPtr)); - } - } -} - static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsVolatile, bool IsActive, bool InUnion, const Descriptor *D) { @@ -144,12 +114,14 @@ static void dtorArrayDesc(Block *B, std::byte *Ptr, const Descriptor *D) { D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor); unsigned ElemOffset = 0; - for (unsigned I = 0; I < NumElems; ++I, ElemOffset += ElemSize) { + auto Dtor = D->ElemDesc->DtorFn; + assert(Dtor && + "a composite array without an elem dtor shouldn't have a dtor itself"); + for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) { auto *ElemPtr = Ptr + ElemOffset; auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr); auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1); - if (auto Fn = D->ElemDesc->DtorFn) - Fn(B, ElemLoc, D->ElemDesc); + Dtor(B, ElemLoc, D->ElemDesc); } } @@ -246,34 +218,59 @@ static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) { destroyBase(B, Ptr, F.Desc, F.Offset); } -static BlockCtorFn getCtorPrim(PrimType Type) { - // Floating types are special. They are primitives, but need their - // constructor called. - if (Type == PT_Float) +/// Whether a record needs its descriptor dtor function called. +static bool needsRecordDtor(const Record *R) { + for (const auto &B : R->bases()) { + if (B.Desc->DtorFn) + return true; + } + + for (const auto &F : R->fields()) { + if (F.Desc->DtorFn) + return true; + } + + for (const auto &V : R->virtual_bases()) { + if (V.Desc->DtorFn) + return true; + } + return false; +} + +static BlockCtorFn getCtorPrim(PrimType T) { + switch (T) { + case PT_Float: return ctorTy<PrimConv<PT_Float>::T>; - if (Type == PT_IntAP) + case PT_IntAP: return ctorTy<PrimConv<PT_IntAP>::T>; - if (Type == PT_IntAPS) + case PT_IntAPS: return ctorTy<PrimConv<PT_IntAPS>::T>; - if (Type == PT_MemberPtr) + case PT_Ptr: + return ctorTy<PrimConv<PT_Ptr>::T>; + case PT_MemberPtr: return ctorTy<PrimConv<PT_MemberPtr>::T>; - - COMPOSITE_TYPE_SWITCH(Type, return ctorTy<T>, return nullptr); + default: + return nullptr; + } + llvm_unreachable("Unhandled PrimType"); } -static BlockDtorFn getDtorPrim(PrimType Type) { - // Floating types are special. They are primitives, but need their - // destructor called, since they might allocate memory. - if (Type == PT_Float) +static BlockDtorFn getDtorPrim(PrimType T) { + switch (T) { + case PT_Float: return dtorTy<PrimConv<PT_Float>::T>; - if (Type == PT_IntAP) + case PT_IntAP: return dtorTy<PrimConv<PT_IntAP>::T>; - if (Type == PT_IntAPS) + case PT_IntAPS: return dtorTy<PrimConv<PT_IntAPS>::T>; - if (Type == PT_MemberPtr) + case PT_Ptr: + return dtorTy<PrimConv<PT_Ptr>::T>; + case PT_MemberPtr: return dtorTy<PrimConv<PT_MemberPtr>::T>; - - COMPOSITE_TYPE_SWITCH(Type, return dtorTy<T>, return nullptr); + default: + return nullptr; + } + llvm_unreachable("Unhandled PrimType"); } static BlockCtorFn getCtorArrayPrim(PrimType Type) { @@ -336,7 +333,7 @@ Descriptor::Descriptor(const DeclTy &D, const Type *SourceTy, AllocSize(std::max<size_t>(alignof(void *), Size) + MDSize), ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(true), CtorFn(ctorArrayDesc), - DtorFn(dtorArrayDesc) { + DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) { assert(Source && "Missing source"); } @@ -347,7 +344,7 @@ Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD, Size(UnknownSizeMark), MDSize(MD.value_or(0)), AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true), - CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc) { + CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) { assert(Source && "Missing source"); } @@ -359,7 +356,7 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize), ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile), CtorFn(ctorRecord), - DtorFn(dtorRecord) { + DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) { assert(Source && "Missing source"); } @@ -460,8 +457,7 @@ bool Descriptor::hasTrivialDtor() const { if (isRecord()) { assert(ElemRecord); - const CXXDestructorDecl *Dtor = ElemRecord->getDestructor(); - return !Dtor || Dtor->isTrivial(); + return ElemRecord->hasTrivialDtor(); } if (!ElemDesc) |
