tbaeder updated this revision to Diff 505084. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D145545/new/
https://reviews.llvm.org/D145545 Files: clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/lib/AST/Interp/ByteCodeStmtGen.h
Index: clang/lib/AST/Interp/ByteCodeStmtGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.h +++ clang/lib/AST/Interp/ByteCodeStmtGen.h @@ -54,6 +54,7 @@ // Statement visitors. bool visitStmt(const Stmt *S); bool visitCompoundStmt(const CompoundStmt *S); + bool visitUnscopedCompoundStmt(const Stmt *S); bool visitDeclStmt(const DeclStmt *DS); bool visitReturnStmt(const ReturnStmt *RS); bool visitIfStmt(const IfStmt *IS); Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -194,6 +194,21 @@ } } +template <class Emitter> +bool ByteCodeStmtGen<Emitter>::visitUnscopedCompoundStmt(const Stmt *S) { + if (isa<NullStmt>(S)) + return true; + + if (const auto *CS = dyn_cast<CompoundStmt>(S)) { + for (auto *InnerStmt : CS->body()) + if (!visitStmt(InnerStmt)) + return false; + return true; + } + + return this->visitStmt(S); +} + template <class Emitter> bool ByteCodeStmtGen<Emitter>::visitCompoundStmt( const CompoundStmt *CompoundStmt) { @@ -306,11 +321,13 @@ if (!this->jumpFalse(EndLabel)) return false; - if (!this->visitStmt(Body)) + LocalScope<Emitter> Scope(this); + if (!this->visitUnscopedCompoundStmt(Body)) return false; + + Scope.emitDestructors(); if (!this->jump(CondLabel)) return false; - this->emitLabel(EndLabel); return true; @@ -325,13 +342,16 @@ LabelTy EndLabel = this->getLabel(); LabelTy CondLabel = this->getLabel(); LoopScope<Emitter> LS(this, EndLabel, CondLabel); + LocalScope<Emitter> Scope(this); this->emitLabel(StartLabel); - if (!this->visitStmt(Body)) + if (!this->visitUnscopedCompoundStmt(Body)) return false; this->emitLabel(CondLabel); if (!this->visitBool(Cond)) return false; + + Scope.emitDestructors(); if (!this->jumpTrue(StartLabel)) return false; this->emitLabel(EndLabel); @@ -350,6 +370,7 @@ LabelTy CondLabel = this->getLabel(); LabelTy IncLabel = this->getLabel(); LoopScope<Emitter> LS(this, EndLabel, IncLabel); + LocalScope<Emitter> Scope(this); if (Init && !this->visitStmt(Init)) return false; @@ -360,11 +381,13 @@ if (!this->jumpFalse(EndLabel)) return false; } - if (Body && !this->visitStmt(Body)) + if (Body && !this->visitUnscopedCompoundStmt(Body)) return false; this->emitLabel(IncLabel); if (Inc && !this->discard(Inc)) return false; + + Scope.emitDestructors(); if (!this->jump(CondLabel)) return false; this->emitLabel(EndLabel); @@ -386,38 +409,38 @@ LabelTy CondLabel = this->getLabel(); LabelTy IncLabel = this->getLabel(); LoopScope<Emitter> LS(this, EndLabel, IncLabel); - { - ExprScope<Emitter> ES(this); - // Emit declarations needed in the loop. - if (Init && !this->visitStmt(Init)) - return false; - if (!this->visitStmt(RangeStmt)) - return false; - if (!this->visitStmt(BeginStmt)) - return false; - if (!this->visitStmt(EndStmt)) - return false; + // Emit declarations needed in the loop. + if (Init && !this->visitStmt(Init)) + return false; + if (!this->visitStmt(RangeStmt)) + return false; + if (!this->visitStmt(BeginStmt)) + return false; + if (!this->visitStmt(EndStmt)) + return false; - // Now the condition as well as the loop variable assignment. - this->emitLabel(CondLabel); - if (!this->visitBool(Cond)) - return false; - if (!this->jumpFalse(EndLabel)) - return false; + // Now the condition as well as the loop variable assignment. + this->emitLabel(CondLabel); + if (!this->visitBool(Cond)) + return false; + if (!this->jumpFalse(EndLabel)) + return false; - if (!this->visitVarDecl(LoopVar)) - return false; + if (!this->visitVarDecl(LoopVar)) + return false; - // Body. - if (!this->visitStmt(Body)) - return false; - this->emitLabel(IncLabel); - if (!this->discard(Inc)) - return false; - if (!this->jump(CondLabel)) - return false; - } + // Body. + LocalScope<Emitter> Scope(this); + if (!this->visitUnscopedCompoundStmt(Body)) + return false; + this->emitLabel(IncLabel); + if (!this->discard(Inc)) + return false; + + Scope.emitDestructors(); + if (!this->jump(CondLabel)) + return false; this->emitLabel(EndLabel); return true; @@ -428,7 +451,7 @@ if (!BreakLabel) return false; - this->emitCleanup(); + this->VarScope->emitDestructors(); return this->jump(*BreakLabel); } @@ -437,7 +460,7 @@ if (!ContinueLabel) return false; - this->emitCleanup(); + this->VarScope->emitDestructors(); return this->jump(*ContinueLabel); } Index: clang/lib/AST/Interp/ByteCodeExprGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -306,6 +306,8 @@ } virtual void emitDestruction() {} + /// Emit destructors for local variables in this scope. + virtual void emitDestructors() {} VariableScope *getParent() const { return Parent; } @@ -316,15 +318,25 @@ VariableScope *Parent; }; -/// Scope for local variables. -/// -/// When the scope is destroyed, instructions are emitted to tear down -/// all variables declared in this scope. +/// Generic scope for local variables. template <class Emitter> class LocalScope : public VariableScope<Emitter> { public: LocalScope(ByteCodeExprGen<Emitter> *Ctx) : VariableScope<Emitter>(Ctx) {} - ~LocalScope() override { this->emitDestruction(); } + /// Emit a Destroy op for this scope. + ~LocalScope() override { + if (!Idx) + return; + this->Ctx->emitDestroy(*Idx, SourceInfo{}); + } + + /// Overriden to support explicit destruction. + void emitDestruction() override { + if (!Idx) + return; + this->emitDestructors(); + this->Ctx->emitDestroy(*Idx, SourceInfo{}); + } void addLocal(const Scope::Local &Local) override { if (!Idx) { @@ -335,9 +347,7 @@ this->Ctx->Descriptors[*Idx].emplace_back(Local); } - /// Emit destruction of the local variable. This includes - /// object destructors. - void emitDestruction() override { + void emitDestructors() override { if (!Idx) return; // Emit destructor calls for local variables of record @@ -348,8 +358,6 @@ this->Ctx->emitRecordDestruction(Local.Desc); } } - - this->Ctx->emitDestroy(*Idx, SourceInfo{}); } protected: @@ -357,10 +365,19 @@ std::optional<unsigned> Idx; }; +/// Like a regular LocalScope, except that the destructors of all local +/// variables are automatically emitted when the AutoScope is destroyed. +template <class Emitter> class AutoScope : public LocalScope<Emitter> { +public: + AutoScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} + + ~AutoScope() override { this->emitDestructors(); } +}; + /// Scope for storage declared in a compound statement. -template <class Emitter> class BlockScope final : public LocalScope<Emitter> { +template <class Emitter> class BlockScope final : public AutoScope<Emitter> { public: - BlockScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} + BlockScope(ByteCodeExprGen<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {} void addExtended(const Scope::Local &Local) override { // If we to this point, just add the variable as a normal local @@ -372,9 +389,9 @@ /// Expression scope which tracks potentially lifetime extended /// temporaries which are hoisted to the parent scope on exit. -template <class Emitter> class ExprScope final : public LocalScope<Emitter> { +template <class Emitter> class ExprScope final : public AutoScope<Emitter> { public: - ExprScope(ByteCodeExprGen<Emitter> *Ctx) : LocalScope<Emitter>(Ctx) {} + ExprScope(ByteCodeExprGen<Emitter> *Ctx) : AutoScope<Emitter>(Ctx) {} void addExtended(const Scope::Local &Local) override { if (this->Parent)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits