tbaeder updated this revision to Diff 509279.
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 visitLoopBody(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,23 @@
}
}
+/// Visits the given statment without creating a variable
+/// scope for it in case it is a compound statement.
+template <class Emitter>
+bool ByteCodeStmtGen<Emitter>::visitLoopBody(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 +323,15 @@
if (!this->jumpFalse(EndLabel))
return false;
- if (!this->visitStmt(Body))
- return false;
+ LocalScope<Emitter> Scope(this);
+ {
+ DestructorScope<Emitter> DS(Scope);
+ if (!this->visitLoopBody(Body))
+ return false;
+ }
+
if (!this->jump(CondLabel))
return false;
-
this->emitLabel(EndLabel);
return true;
@@ -325,15 +346,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->visitLoopBody(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 +377,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 +388,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->visitLoopBody(Body))
+ return false;
+ this->emitLabel(IncLabel);
+ if (Inc && !this->discard(Inc))
+ return false;
+ }
+
if (!this->jump(CondLabel))
return false;
this->emitLabel(EndLabel);
@@ -386,38 +420,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->visitLoopBody(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 +464,7 @@
if (!BreakLabel)
return false;
- this->emitCleanup();
+ this->VarScope->emitDestructors();
return this->jump(*BreakLabel);
}
@@ -437,7 +473,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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits