@@ -6284,26 +6284,21 @@ bool Compiler<Emitter>::compileDestructor(const CXXDestructorDecl *Dtor) {
62846284 // First, destroy all fields.
62856285 for (const Record::Field &Field : llvm::reverse (R->fields ())) {
62866286 const Descriptor *D = Field.Desc ;
6287- if (!D->isPrimitive () && !D->isPrimitiveArray ()) {
6288- if (!this ->emitGetPtrField (Field.Offset , SourceInfo{}))
6289- return false ;
6290- if (!this ->emitDestruction (D, SourceInfo{}))
6291- return false ;
6292- if (!this ->emitPopPtr (SourceInfo{}))
6293- return false ;
6294- }
6287+ if (D->hasTrivialDtor ())
6288+ continue ;
6289+ if (!this ->emitGetPtrField (Field.Offset , SourceInfo{}))
6290+ return false ;
6291+ if (!this ->emitDestructionPop (D, SourceInfo{}))
6292+ return false ;
62956293 }
62966294 }
62976295
62986296 for (const Record::Base &Base : llvm::reverse (R->bases ())) {
6299- if (Base.R ->isAnonymousUnion ())
6297+ if (Base.R ->hasTrivialDtor ())
63006298 continue ;
6301-
63026299 if (!this ->emitGetPtrBase (Base.Offset , SourceInfo{}))
63036300 return false ;
6304- if (!this ->emitRecordDestruction (Base.R , {}))
6305- return false ;
6306- if (!this ->emitPopPtr (SourceInfo{}))
6301+ if (!this ->emitRecordDestructionPop (Base.R , {}))
63076302 return false ;
63086303 }
63096304
@@ -7200,71 +7195,56 @@ bool Compiler<Emitter>::emitComplexComparison(const Expr *LHS, const Expr *RHS,
72007195// / on the stack.
72017196// / Emit destruction of record types (or arrays of record types).
72027197template <class Emitter >
7203- bool Compiler<Emitter>::emitRecordDestruction(const Record *R, SourceInfo Loc) {
7198+ bool Compiler<Emitter>::emitRecordDestructionPop(const Record *R,
7199+ SourceInfo Loc) {
72047200 assert (R);
7205- assert (!R->isAnonymousUnion ());
7201+ assert (!R->hasTrivialDtor ());
72067202 const CXXDestructorDecl *Dtor = R->getDestructor ();
7207- if (!Dtor || Dtor->isTrivial ())
7208- return true ;
7209-
72107203 assert (Dtor);
72117204 const Function *DtorFunc = getFunction (Dtor);
72127205 if (!DtorFunc)
72137206 return false ;
72147207 assert (DtorFunc->hasThisPointer ());
72157208 assert (DtorFunc->getNumParams () == 1 );
7216- if (!this ->emitDupPtr (Loc))
7217- return false ;
72187209 return this ->emitCall (DtorFunc, 0 , Loc);
72197210}
72207211// / When calling this, we have a pointer of the local-to-destroy
72217212// / on the stack.
72227213// / Emit destruction of record types (or arrays of record types).
72237214template <class Emitter >
7224- bool Compiler<Emitter>::emitDestruction (const Descriptor *Desc,
7225- SourceInfo Loc) {
7215+ bool Compiler<Emitter>::emitDestructionPop (const Descriptor *Desc,
7216+ SourceInfo Loc) {
72267217 assert (Desc);
7227- assert (!Desc->isPrimitive ());
7228- assert (!Desc->isPrimitiveArray ());
7218+ assert (!Desc->hasTrivialDtor ());
72297219
72307220 // Arrays.
72317221 if (Desc->isArray ()) {
72327222 const Descriptor *ElemDesc = Desc->ElemDesc ;
72337223 assert (ElemDesc);
72347224
7235- // Don't need to do anything for these.
7236- if (ElemDesc-> isPrimitiveArray () )
7237- return true ;
7225+ unsigned N = Desc-> getNumElems ();
7226+ if (N == 0 )
7227+ return this -> emitPopPtr (Loc) ;
72387228
7239- // If this is an array of record types, check if we need
7240- // to call the element destructors at all. If not, try
7241- // to save the work.
7242- if (const Record *ElemRecord = ElemDesc->ElemRecord ) {
7243- if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor ();
7244- !Dtor || Dtor->isTrivial ())
7245- return true ;
7246- }
7247-
7248- if (unsigned N = Desc->getNumElems ()) {
7249- for (ssize_t I = N - 1 ; I >= 0 ; --I) {
7250- if (!this ->emitConstUint64 (I, Loc))
7251- return false ;
7252- if (!this ->emitArrayElemPtrUint64 (Loc))
7253- return false ;
7254- if (!this ->emitDestruction (ElemDesc, Loc))
7255- return false ;
7256- if (!this ->emitPopPtr (Loc))
7257- return false ;
7258- }
7229+ for (ssize_t I = N - 1 ; I >= 1 ; --I) {
7230+ if (!this ->emitConstUint64 (I, Loc))
7231+ return false ;
7232+ if (!this ->emitArrayElemPtrUint64 (Loc))
7233+ return false ;
7234+ if (!this ->emitDestructionPop (ElemDesc, Loc))
7235+ return false ;
72597236 }
7260- return true ;
7237+ // Last iteration, removes the instance pointer from the stack.
7238+ if (!this ->emitConstUint64 (0 , Loc))
7239+ return false ;
7240+ if (!this ->emitArrayElemPtrPopUint64 (Loc))
7241+ return false ;
7242+ return this ->emitDestructionPop (ElemDesc, Loc);
72617243 }
72627244
72637245 assert (Desc->ElemRecord );
7264- if (Desc->ElemRecord ->isAnonymousUnion ())
7265- return true ;
7266-
7267- return this ->emitRecordDestruction (Desc->ElemRecord , Loc);
7246+ assert (!Desc->ElemRecord ->hasTrivialDtor ());
7247+ return this ->emitRecordDestructionPop (Desc->ElemRecord , Loc);
72687248}
72697249
72707250// / Create a dummy pointer for the given decl (or expr) and
0 commit comments