summaryrefslogtreecommitdiff
path: root/source/slang/slang-check-stmt.cpp
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-04-07 06:08:29 +0300
committerGitHub <noreply@github.com>2025-04-06 20:08:29 -0700
commit1b82501dd0c74347cda4a2c7fe5a84fd610bb485 (patch)
treef283a491e0545aa6b890a988ac9fb14f192b4663 /source/slang/slang-check-stmt.cpp
parent680fb0b4e9cbb65d46677183a3f68630be1f6179 (diff)
Add defer statement (#6619)
Diffstat (limited to 'source/slang/slang-check-stmt.cpp')
-rw-r--r--source/slang/slang-check-stmt.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/source/slang/slang-check-stmt.cpp b/source/slang/slang-check-stmt.cpp
index db6f00d23..c85eb7593 100644
--- a/source/slang/slang-check-stmt.cpp
+++ b/source/slang/slang-check-stmt.cpp
@@ -119,9 +119,10 @@ void SemanticsStmtVisitor::checkStmt(Stmt* stmt)
}
template<typename T>
-T* SemanticsStmtVisitor::FindOuterStmt()
+T* SemanticsStmtVisitor::FindOuterStmt(Stmt* searchUntil)
{
- for (auto outerStmtInfo = m_outerStmts; outerStmtInfo; outerStmtInfo = outerStmtInfo->next)
+ for (auto outerStmtInfo = m_outerStmts; outerStmtInfo && outerStmtInfo->stmt != searchUntil;
+ outerStmtInfo = outerStmtInfo->next)
{
auto outerStmt = outerStmtInfo->stmt;
auto found = as<T>(outerStmt);
@@ -178,6 +179,14 @@ void SemanticsStmtVisitor::visitBreakStmt(BreakStmt* stmt)
getSink()->diagnose(stmt, Diagnostics::breakOutsideLoop);
}
}
+
+ // If there is a defer statement before the breakable statement, it's
+ // illegal.
+ if (FindOuterStmt<DeferStmt>(targetStmt))
+ {
+ getSink()->diagnose(stmt, Diagnostics::breakInsideDefer);
+ }
+
stmt->parentStmt = targetStmt;
}
@@ -188,6 +197,11 @@ void SemanticsStmtVisitor::visitContinueStmt(ContinueStmt* stmt)
{
getSink()->diagnose(stmt, Diagnostics::continueOutsideLoop);
}
+
+ if (FindOuterStmt<DeferStmt>(outer))
+ {
+ getSink()->diagnose(stmt, Diagnostics::continueInsideDefer);
+ }
stmt->parentStmt = outer;
}
@@ -497,6 +511,11 @@ void SemanticsStmtVisitor::visitReturnStmt(ReturnStmt* stmt)
}
}
}
+
+ if (FindOuterStmt<DeferStmt>())
+ {
+ getSink()->diagnose(stmt, Diagnostics::returnInsideDefer);
+ }
}
void SemanticsStmtVisitor::visitWhileStmt(WhileStmt* stmt)
@@ -508,6 +527,12 @@ void SemanticsStmtVisitor::visitWhileStmt(WhileStmt* stmt)
checkLoopInDifferentiableFunc(stmt);
}
+void SemanticsStmtVisitor::visitDeferStmt(DeferStmt* stmt)
+{
+ WithOuterStmt subContext(this, stmt);
+ subContext.checkStmt(stmt->statement);
+}
+
void SemanticsStmtVisitor::visitExpressionStmt(ExpressionStmt* stmt)
{
stmt->expression = CheckExpr(stmt->expression);