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

Reply via email to