diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/emit.cpp | 17 | ||||
| -rw-r--r-- | source/slang/lower.cpp | 16 | ||||
| -rw-r--r-- | source/slang/parser.cpp | 33 | ||||
| -rw-r--r-- | source/slang/stmt-defs.h | 5 |
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) |
