mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 18:59:21 +00:00
Remove infrastructure for fallthrough
This Cl removes the internal infrastructor and backend code generation for the fallthrough statement. Bug: tint:1644 Change-Id: I2a1de7d527865e5a7221074f4e0fb106599f4c57 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109005 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
bf586f6dfd
commit
267f1748c8
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "src/tint/ast/break_statement.h"
|
||||
#include "src/tint/ast/continue_statement.h"
|
||||
#include "src/tint/ast/fallthrough_statement.h"
|
||||
#include "src/tint/ast/switch_statement.h"
|
||||
#include "src/tint/resolver/resolver_test_helper.h"
|
||||
|
||||
@@ -378,24 +377,6 @@ TEST_F(ResolverControlBlockValidationTest, NonUniqueCaseSelectorValueSint_Fail)
|
||||
"12:34 note: previous case declared here");
|
||||
}
|
||||
|
||||
TEST_F(ResolverControlBlockValidationTest, LastClauseLastStatementIsFallthrough_Fail) {
|
||||
// var a : i32 = 2;
|
||||
// switch (a) {
|
||||
// default: { fallthrough; }
|
||||
// }
|
||||
auto* var = Var("a", ty.i32(), Expr(2_i));
|
||||
auto* fallthrough = create<ast::FallthroughStatement>(Source{{12, 34}});
|
||||
auto* block = Block(Decl(var), //
|
||||
Switch("a", //
|
||||
DefaultCase(Block(fallthrough))));
|
||||
WrapInFunction(block);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: a fallthrough statement must not be used in the last "
|
||||
"switch case");
|
||||
}
|
||||
|
||||
TEST_F(ResolverControlBlockValidationTest, SwitchCase_Pass) {
|
||||
// var a : i32 = 2;
|
||||
// switch (a) {
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "src/tint/ast/external_texture.h"
|
||||
#include "src/tint/ast/f16.h"
|
||||
#include "src/tint/ast/f32.h"
|
||||
#include "src/tint/ast/fallthrough_statement.h"
|
||||
#include "src/tint/ast/for_loop_statement.h"
|
||||
#include "src/tint/ast/i32.h"
|
||||
#include "src/tint/ast/id_attribute.h"
|
||||
@@ -320,7 +319,7 @@ class DependencyScanner {
|
||||
[&](const ast::StaticAssert* assertion) { TraverseExpression(assertion->condition); },
|
||||
[&](Default) {
|
||||
if (!stmt->IsAnyOf<ast::BreakStatement, ast::ContinueStatement,
|
||||
ast::DiscardStatement, ast::FallthroughStatement>()) {
|
||||
ast::DiscardStatement>()) {
|
||||
UnhandledNode(diagnostics_, stmt);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1273,8 +1273,6 @@ TEST_F(ResolverDependencyGraphTraversalTest, SymbolsReached) {
|
||||
Switch(V, //
|
||||
Case(CaseSelector(1_i), //
|
||||
Block(Assign(V, V))), //
|
||||
Case(CaseSelector(2_i), //
|
||||
Block(Fallthrough())), //
|
||||
DefaultCase(Block(Assign(V, V)))), //
|
||||
Return(V), //
|
||||
Break(), //
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "src/tint/ast/depth_texture.h"
|
||||
#include "src/tint/ast/disable_validation_attribute.h"
|
||||
#include "src/tint/ast/discard_statement.h"
|
||||
#include "src/tint/ast/fallthrough_statement.h"
|
||||
#include "src/tint/ast/for_loop_statement.h"
|
||||
#include "src/tint/ast/id_attribute.h"
|
||||
#include "src/tint/ast/if_statement.h"
|
||||
@@ -1217,7 +1216,6 @@ sem::Statement* Resolver::Statement(const ast::Statement* stmt) {
|
||||
[&](const ast::CompoundAssignmentStatement* c) { return CompoundAssignmentStatement(c); },
|
||||
[&](const ast::ContinueStatement* c) { return ContinueStatement(c); },
|
||||
[&](const ast::DiscardStatement* d) { return DiscardStatement(d); },
|
||||
[&](const ast::FallthroughStatement* f) { return FallthroughStatement(f); },
|
||||
[&](const ast::IncrementDecrementStatement* i) { return IncrementDecrementStatement(i); },
|
||||
[&](const ast::ReturnStatement* r) { return ReturnStatement(r); },
|
||||
[&](const ast::VariableDeclStatement* v) { return VariableDeclStatement(v); },
|
||||
@@ -3146,7 +3144,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
|
||||
if (behaviors.Contains(sem::Behavior::kBreak)) {
|
||||
behaviors.Add(sem::Behavior::kNext);
|
||||
}
|
||||
behaviors.Remove(sem::Behavior::kBreak, sem::Behavior::kFallthrough);
|
||||
behaviors.Remove(sem::Behavior::kBreak);
|
||||
|
||||
return validator_.SwitchStatement(stmt);
|
||||
});
|
||||
@@ -3308,16 +3306,6 @@ sem::Statement* Resolver::DiscardStatement(const ast::DiscardStatement* stmt) {
|
||||
});
|
||||
}
|
||||
|
||||
sem::Statement* Resolver::FallthroughStatement(const ast::FallthroughStatement* stmt) {
|
||||
auto* sem =
|
||||
builder_->create<sem::Statement>(stmt, current_compound_statement_, current_function_);
|
||||
return StatementScope(stmt, sem, [&] {
|
||||
sem->Behaviors() = sem::Behavior::kFallthrough;
|
||||
|
||||
return validator_.FallthroughStatement(sem);
|
||||
});
|
||||
}
|
||||
|
||||
sem::Statement* Resolver::IncrementDecrementStatement(
|
||||
const ast::IncrementDecrementStatement* stmt) {
|
||||
auto* sem =
|
||||
|
||||
@@ -212,7 +212,6 @@ class Resolver {
|
||||
sem::Statement* CompoundAssignmentStatement(const ast::CompoundAssignmentStatement*);
|
||||
sem::Statement* ContinueStatement(const ast::ContinueStatement*);
|
||||
sem::Statement* DiscardStatement(const ast::DiscardStatement*);
|
||||
sem::Statement* FallthroughStatement(const ast::FallthroughStatement*);
|
||||
sem::ForLoopStatement* ForLoopStatement(const ast::ForLoopStatement*);
|
||||
sem::WhileStatement* WhileStatement(const ast::WhileStatement*);
|
||||
sem::GlobalVariable* GlobalVariable(const ast::Variable*);
|
||||
|
||||
@@ -477,10 +477,9 @@ class UniformityGraph {
|
||||
}
|
||||
|
||||
// Propagate all variables assignments to the containing scope if the behavior is
|
||||
// either 'Next' or 'Fallthrough'.
|
||||
// 'Next'.
|
||||
auto& behaviors = sem_.Get(b)->Behaviors();
|
||||
if (behaviors.Contains(sem::Behavior::kNext) ||
|
||||
behaviors.Contains(sem::Behavior::kFallthrough)) {
|
||||
if (behaviors.Contains(sem::Behavior::kNext)) {
|
||||
for (auto var : scoped_assignments) {
|
||||
current_function_->variables.Set(var.key, var.value);
|
||||
}
|
||||
@@ -613,8 +612,6 @@ class UniformityGraph {
|
||||
|
||||
[&](const ast::DiscardStatement*) { return cf; },
|
||||
|
||||
[&](const ast::FallthroughStatement*) { return cf; },
|
||||
|
||||
[&](const ast::ForLoopStatement* f) {
|
||||
auto* sem_loop = sem_.Get(f);
|
||||
auto* cfx = CreateNode("loop_start");
|
||||
@@ -937,46 +934,35 @@ class UniformityGraph {
|
||||
info.type = "switch";
|
||||
|
||||
auto* cf_n = v;
|
||||
bool previous_case_has_fallthrough = false;
|
||||
for (auto* c : s->body) {
|
||||
auto* sem_case = sem_.Get(c);
|
||||
|
||||
if (previous_case_has_fallthrough) {
|
||||
cf_n = ProcessStatement(cf_n, c->body);
|
||||
} else {
|
||||
current_function_->variables.Push();
|
||||
cf_n = ProcessStatement(v, c->body);
|
||||
}
|
||||
current_function_->variables.Push();
|
||||
cf_n = ProcessStatement(v, c->body);
|
||||
|
||||
if (cf_end) {
|
||||
cf_end->AddEdge(cf_n);
|
||||
}
|
||||
|
||||
bool has_fallthrough =
|
||||
sem_case->Behaviors().Contains(sem::Behavior::kFallthrough);
|
||||
if (!has_fallthrough) {
|
||||
if (sem_case->Behaviors().Contains(sem::Behavior::kNext)) {
|
||||
// Propagate variable values to the switch exit nodes.
|
||||
for (auto* var : current_function_->local_var_decls) {
|
||||
// Skip variables that were declared inside the switch.
|
||||
if (auto* lv = var->As<sem::LocalVariable>();
|
||||
lv && lv->Statement()->FindFirstParent(
|
||||
[&](auto* st) { return st == sem_switch; })) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add an edge from the variable exit node to its new value.
|
||||
auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() {
|
||||
auto name =
|
||||
builder_->Symbols().NameFor(var->Declaration()->symbol);
|
||||
return CreateNode(name + "_value_" + info.type + "_exit");
|
||||
});
|
||||
exit_node->AddEdge(current_function_->variables.Get(var));
|
||||
if (sem_case->Behaviors().Contains(sem::Behavior::kNext)) {
|
||||
// Propagate variable values to the switch exit nodes.
|
||||
for (auto* var : current_function_->local_var_decls) {
|
||||
// Skip variables that were declared inside the switch.
|
||||
if (auto* lv = var->As<sem::LocalVariable>();
|
||||
lv && lv->Statement()->FindFirstParent(
|
||||
[&](auto* st) { return st == sem_switch; })) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add an edge from the variable exit node to its new value.
|
||||
auto* exit_node = info.var_exit_nodes.GetOrCreate(var, [&]() {
|
||||
auto name = builder_->Symbols().NameFor(var->Declaration()->symbol);
|
||||
return CreateNode(name + "_value_" + info.type + "_exit");
|
||||
});
|
||||
exit_node->AddEdge(current_function_->variables.Get(var));
|
||||
}
|
||||
current_function_->variables.Pop();
|
||||
}
|
||||
previous_case_has_fallthrough = has_fallthrough;
|
||||
current_function_->variables.Pop();
|
||||
}
|
||||
|
||||
// Update nodes for any variables assigned in the switch statement.
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "src/tint/ast/depth_texture.h"
|
||||
#include "src/tint/ast/disable_validation_attribute.h"
|
||||
#include "src/tint/ast/discard_statement.h"
|
||||
#include "src/tint/ast/fallthrough_statement.h"
|
||||
#include "src/tint/ast/for_loop_statement.h"
|
||||
#include "src/tint/ast/id_attribute.h"
|
||||
#include "src/tint/ast/if_statement.h"
|
||||
@@ -1538,26 +1537,6 @@ bool Validator::Call(const sem::Call* call, sem::Statement* current_statement) c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Validator::FallthroughStatement(const sem::Statement* stmt) const {
|
||||
if (auto* block = As<sem::BlockStatement>(stmt->Parent())) {
|
||||
if (auto* c = As<sem::CaseStatement>(block->Parent())) {
|
||||
if (block->Declaration()->Last() == stmt->Declaration()) {
|
||||
if (auto* s = As<sem::SwitchStatement>(c->Parent())) {
|
||||
if (c->Declaration() != s->Declaration()->body.Back()) {
|
||||
return true;
|
||||
}
|
||||
AddError("a fallthrough statement must not be used in the last switch case",
|
||||
stmt->Declaration()->source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
AddError("fallthrough must only be used as the last statement of a case block",
|
||||
stmt->Declaration()->source);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Validator::LoopStatement(const sem::LoopStatement* stmt) const {
|
||||
if (stmt->Behaviors().Empty()) {
|
||||
AddError("loop does not exit", stmt->Declaration()->source.Begin());
|
||||
|
||||
@@ -223,11 +223,6 @@ class Validator {
|
||||
/// @returns true on success, false otherwise
|
||||
bool WhileStatement(const sem::WhileStatement* stmt) const;
|
||||
|
||||
/// Validates a fallthrough statement
|
||||
/// @param stmt the fallthrough to validate
|
||||
/// @returns true on success, false otherwise
|
||||
bool FallthroughStatement(const sem::Statement* stmt) const;
|
||||
|
||||
/// Validates a function
|
||||
/// @param func the function to validate
|
||||
/// @param stage the current pipeline stage
|
||||
|
||||
Reference in New Issue
Block a user