tbaeder updated this revision to Diff 509264. 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,15 @@ if (!this->jumpFalse(EndLabel)) return false; - if (!this->visitStmt(Body)) - return false; + LocalScope<Emitter> Scope(this); + { + DestructorScope<Emitter> DS(Scope); + if (!this->visitUnscopedCompoundStmt(Body)) + return false; + } + if (!this->jump(CondLabel)) return false; - this->emitLabel(EndLabel); return true; @@ -325,15 +344,21 @@ 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)) - return false; - this->emitLabel(CondLabel); - if (!this->visitBool(Cond)) - return false; + { + DestructorScope<Emitter> DS(Scope); + + if (!this->visitUnscopedCompoundStmt(Body)) + return false; + this->emitLabel(CondLabel); + if (!this->visitBool(Cond)) + return false; + } if (!this->jumpTrue(StartLabel)) return false; + this->emitLabel(EndLabel); return true; } @@ -350,6 +375,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 +386,17 @@ if (!this->jumpFalse(EndLabel)) return false; } - if (Body && !this->visitStmt(Body)) - return false; - this->emitLabel(IncLabel); - if (Inc && !this->discard(Inc)) - return false; + + { + DestructorScope<Emitter> DS(Scope); + + if (Body && !this->visitUnscopedCompoundStmt(Body)) + return false; + this->emitLabel(IncLabel); + if (Inc && !this->discard(Inc)) + return false; + } + if (!this->jump(CondLabel)) return false; this->emitLabel(EndLabel); @@ -386,38 +418,40 @@ 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. + LocalScope<Emitter> Scope(this); + { + DestructorScope<Emitter> DS(Scope); - // Body. - if (!this->visitStmt(Body)) + if (!this->visitUnscopedCompoundStmt(Body)) return false; this->emitLabel(IncLabel); if (!this->discard(Inc)) return false; - if (!this->jump(CondLabel)) - return false; } + if (!this->jump(CondLabel)) + return false; this->emitLabel(EndLabel); return true; @@ -428,7 +462,7 @@ if (!BreakLabel) return false; - this->emitCleanup(); + this->VarScope->emitDestructors(); return this->jump(*BreakLabel); } @@ -437,7 +471,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 @@ -29,6 +29,7 @@ namespace interp { template <class Emitter> class LocalScope; +template <class Emitter> class DestructorScope; template <class Emitter> class RecordScope; template <class Emitter> class VariableScope; template <class Emitter> class DeclScope; @@ -189,6 +190,7 @@ private: friend class VariableScope<Emitter>; friend class LocalScope<Emitter>; + friend class DestructorScope<Emitter>; friend class RecordScope<Emitter>; friend class DeclScope<Emitter>; friend class OptionScope<Emitter>; @@ -306,7 +308,7 @@ } virtual void emitDestruction() {} - + virtual void emitDestructors() {} VariableScope *getParent() const { return Parent; } protected: @@ -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,19 +358,40 @@ this->Ctx->emitRecordDestruction(Local.Desc); } } - - this->Ctx->emitDestroy(*Idx, SourceInfo{}); } -protected: /// Index of the scope in the chain. std::optional<unsigned> Idx; }; +/// Emits the destructors of the variables of \param OtherScope +/// when this scope is destroyed. Does not create a Scope in the bytecode at +/// all, this is just a RAII object to emit destructors. +template <class Emitter> class DestructorScope final { +public: + DestructorScope(LocalScope<Emitter> &OtherScope) : OtherScope(OtherScope) {} + + ~DestructorScope() { OtherScope.emitDestructors(); } + +private: + LocalScope<Emitter> &OtherScope; +}; + +/// 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), DS(*this) {} + +private: + DestructorScope<Emitter> DS; +}; + /// 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 +403,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