summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp17
-rw-r--r--source/slang/lower.cpp16
-rw-r--r--source/slang/parser.cpp33
-rw-r--r--source/slang/stmt-defs.h5
4 files changed, 48 insertions, 23 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index a8c0083c1..24b0dd717 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -57,10 +57,6 @@ struct EmitContext
{
// The shared context that is in effect
SharedEmitContext* shared;
-
- // Are we in "rewrite" mode, where we are trying to reproduce the input
- // code as closely as posible?
- bool isRewrite;
};
//
@@ -2196,12 +2192,10 @@ struct EmitVisitor
// The one wrinkle is that HLSL implements the
// bad approach to scoping a `for` loop variable,
// so we need to avoid those outer `{...}` when
- // we are generating HLSL via "rewrite" (that is,
- // without our semantic checks).
+ // we are emitting code that was written in HLSL.
//
bool brokenScoping = false;
- if (context->shared->target == CodeGenTarget::HLSL
- && context->isRewrite)
+ if (forStmt.As<UnscopedForStmt>())
{
brokenScoping = true;
}
@@ -3406,10 +3400,6 @@ struct EmitVisitor
}
};
-bool isRewriteRequest(
- SourceLanguage sourceLanguage,
- CodeGenTarget target);
-
String emitEntryPoint(
EntryPointRequest* entryPoint,
ProgramLayout* programLayout,
@@ -3465,9 +3455,6 @@ String emitEntryPoint(
EmitContext context;
context.shared = &sharedContext;
- context.isRewrite = isRewriteRequest(
- translationUnit->sourceLanguage,
- target);
EmitVisitor visitor(&context);
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index c154c96c8..8a4b7a4b1 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -723,10 +723,10 @@ struct LoweringVisitor
addStmt(loweredStmt);
}
-
- void visitForStatementSyntaxNode(ForStatementSyntaxNode* stmt)
+ void lowerForStmtCommon(
+ RefPtr<ForStatementSyntaxNode> loweredStmt,
+ ForStatementSyntaxNode* stmt)
{
- RefPtr<ForStatementSyntaxNode> loweredStmt = new ForStatementSyntaxNode();
lowerScopeStmtFields(loweredStmt, stmt);
LoweringVisitor subVisitor = pushScope(loweredStmt, stmt);
@@ -739,6 +739,16 @@ struct LoweringVisitor
addStmt(loweredStmt);
}
+ void visitForStatementSyntaxNode(ForStatementSyntaxNode* stmt)
+ {
+ lowerForStmtCommon(new ForStatementSyntaxNode(), stmt);
+ }
+
+ void visitUnscopedForStmt(UnscopedForStmt* stmt)
+ {
+ lowerForStmtCommon(new UnscopedForStmt(), stmt);
+ }
+
void visitWhileStatementSyntaxNode(WhileStatementSyntaxNode* stmt)
{
RefPtr<WhileStatementSyntaxNode> loweredStmt = new WhileStatementSyntaxNode();
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 0efc8cd77..199275a2d 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -2673,12 +2673,32 @@ namespace Slang
RefPtr<ForStatementSyntaxNode> Parser::ParseForStatement()
{
RefPtr<ScopeDecl> scopeDecl = new ScopeDecl();
- RefPtr<ForStatementSyntaxNode> stmt = new ForStatementSyntaxNode();
+
+ // HLSL implements the bad approach to scoping a `for` loop
+ // variable, and we want to respect that, but *only* when
+ // parsing HLSL code.
+ //
+
+ bool brokenScoping = translationUnit->sourceLanguage == SourceLanguage::HLSL;
+
+ // We will create a distinct syntax node class for the unscoped
+ // case, just so that we can correctly handle it in downstream
+ // logic.
+ //
+ RefPtr<ForStatementSyntaxNode> stmt;
+ if (brokenScoping)
+ {
+ stmt = new UnscopedForStmt();
+ }
+ else
+ {
+ stmt = new ForStatementSyntaxNode();
+ }
+
stmt->scopeDecl = scopeDecl;
- // Note(tfoley): HLSL implements `for` with incorrect scoping.
- // We need an option to turn on this behavior in a kind of "legacy" mode
-// PushScope(scopeDecl.Ptr());
+ if(!brokenScoping)
+ PushScope(scopeDecl.Ptr());
FillPosition(stmt.Ptr());
ReadToken("for");
ReadToken(TokenType::LParent);
@@ -2704,7 +2724,10 @@ namespace Slang
stmt->SideEffectExpression = ParseExpression();
ReadToken(TokenType::RParent);
stmt->Statement = ParseStatement();
-// PopScope();
+
+ if (!brokenScoping)
+ PopScope();
+
return stmt;
}
diff --git a/source/slang/stmt-defs.h b/source/slang/stmt-defs.h
index 165ffea83..15826abc4 100644
--- a/source/slang/stmt-defs.h
+++ b/source/slang/stmt-defs.h
@@ -66,6 +66,7 @@ SIMPLE_SYNTAX_CLASS(DefaultStmt, CaseStmtBase)
ABSTRACT_SYNTAX_CLASS(LoopStmt, BreakableStmt)
END_SYNTAX_CLASS()
+// A `for` statement
SYNTAX_CLASS(ForStatementSyntaxNode, LoopStmt)
SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, InitialStatement)
SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, SideEffectExpression)
@@ -73,6 +74,10 @@ SYNTAX_CLASS(ForStatementSyntaxNode, LoopStmt)
SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, Statement)
END_SYNTAX_CLASS()
+// A `for` statement in a language that doesn't restrict the scope
+// of the loop variable to the body.
+SYNTAX_CLASS(UnscopedForStmt, ForStatementSyntaxNode);
+END_SYNTAX_CLASS()
SYNTAX_CLASS(WhileStatementSyntaxNode, LoopStmt)
SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Predicate)