From 267f1748c8287ee6ef27ed0bf65a7ede9f8afc31 Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Tue, 15 Nov 2022 00:30:33 +0000 Subject: [PATCH] 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 Reviewed-by: Ben Clayton Commit-Queue: Dan Sinclair --- src/tint/BUILD.gn | 6 +- src/tint/CMakeLists.txt | 4 - src/tint/ast/fallthrough_statement.cc | 36 --------- src/tint/ast/fallthrough_statement.h | 43 ----------- src/tint/ast/fallthrough_statement_test.cc | 45 ----------- src/tint/ast/statement.cc | 4 - src/tint/ir/builder_impl.cc | 25 +------ src/tint/ir/builder_impl.h | 7 -- src/tint/ir/builder_impl_test.cc | 59 --------------- src/tint/program_builder.h | 12 --- .../resolver/control_block_validation_test.cc | 19 ----- src/tint/resolver/dependency_graph.cc | 3 +- src/tint/resolver/dependency_graph_test.cc | 2 - src/tint/resolver/resolver.cc | 14 +--- src/tint/resolver/resolver.h | 1 - src/tint/resolver/uniformity.cc | 54 +++++--------- src/tint/resolver/validator.cc | 21 ------ src/tint/resolver/validator.h | 5 -- src/tint/sem/behavior.cc | 2 - src/tint/sem/behavior.h | 1 - src/tint/writer/glsl/generator_impl.cc | 11 +-- .../writer/glsl/generator_impl_case_test.cc | 17 ----- src/tint/writer/hlsl/generator_impl.cc | 18 +---- .../writer/hlsl/generator_impl_case_test.cc | 23 ------ src/tint/writer/msl/generator_impl.cc | 11 +-- .../writer/msl/generator_impl_case_test.cc | 17 ----- src/tint/writer/spirv/builder.cc | 25 +------ .../spirv/builder_static_assert_test.cc | 1 - src/tint/writer/spirv/builder_switch_test.cc | 74 ++----------------- src/tint/writer/wgsl/generator_impl.cc | 6 -- src/tint/writer/wgsl/generator_impl.h | 5 -- .../wgsl/generator_impl_fallthrough_test.cc | 39 ---------- 32 files changed, 39 insertions(+), 571 deletions(-) delete mode 100644 src/tint/ast/fallthrough_statement.cc delete mode 100644 src/tint/ast/fallthrough_statement.h delete mode 100644 src/tint/ast/fallthrough_statement_test.cc delete mode 100644 src/tint/writer/wgsl/generator_impl_fallthrough_test.cc diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index fbbfe5a3b1..36fd66b062 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -247,8 +247,6 @@ libtint_source_set("libtint_core_all_src") { "ast/f16.h", "ast/f32.cc", "ast/f32.h", - "ast/fallthrough_statement.cc", - "ast/fallthrough_statement.h", "ast/float_literal_expression.cc", "ast/float_literal_expression.h", "ast/for_loop_statement.cc", @@ -1047,7 +1045,6 @@ if (tint_build_unittests) { "ast/external_texture_test.cc", "ast/f16_test.cc", "ast/f32_test.cc", - "ast/fallthrough_statement_test.cc", "ast/float_literal_expression_test.cc", "ast/for_loop_statement_test.cc", "ast/function_test.cc", @@ -1159,8 +1156,8 @@ if (tint_build_unittests) { "resolver/resolver_test.cc", "resolver/resolver_test_helper.cc", "resolver/resolver_test_helper.h", - "resolver/side_effects_test.cc", "resolver/root_identifier_test.cc", + "resolver/side_effects_test.cc", "resolver/static_assert_test.cc", "resolver/struct_address_space_use_test.cc", "resolver/struct_layout_test.cc", @@ -1480,7 +1477,6 @@ if (tint_build_unittests) { "writer/wgsl/generator_impl_continue_test.cc", "writer/wgsl/generator_impl_discard_test.cc", "writer/wgsl/generator_impl_enable_test.cc", - "writer/wgsl/generator_impl_fallthrough_test.cc", "writer/wgsl/generator_impl_function_test.cc", "writer/wgsl/generator_impl_global_decl_test.cc", "writer/wgsl/generator_impl_identifier_test.cc", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index cbf23dbbf9..978986ee3b 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -139,8 +139,6 @@ list(APPEND TINT_LIB_SRCS ast/f16.h ast/f32.cc ast/f32.h - ast/fallthrough_statement.cc - ast/fallthrough_statement.h ast/float_literal_expression.cc ast/float_literal_expression.h ast/for_loop_statement.cc @@ -786,7 +784,6 @@ if(TINT_BUILD_TESTS) ast/external_texture_test.cc ast/f16_test.cc ast/f32_test.cc - ast/fallthrough_statement_test.cc ast/float_literal_expression_test.cc ast/for_loop_statement_test.cc ast/function_test.cc @@ -1150,7 +1147,6 @@ if(TINT_BUILD_TESTS) writer/wgsl/generator_impl_continue_test.cc writer/wgsl/generator_impl_discard_test.cc writer/wgsl/generator_impl_enable_test.cc - writer/wgsl/generator_impl_fallthrough_test.cc writer/wgsl/generator_impl_function_test.cc writer/wgsl/generator_impl_global_decl_test.cc writer/wgsl/generator_impl_identifier_test.cc diff --git a/src/tint/ast/fallthrough_statement.cc b/src/tint/ast/fallthrough_statement.cc deleted file mode 100644 index 0d30ae3ec2..0000000000 --- a/src/tint/ast/fallthrough_statement.cc +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/tint/ast/fallthrough_statement.h" - -#include "src/tint/program_builder.h" - -TINT_INSTANTIATE_TYPEINFO(tint::ast::FallthroughStatement); - -namespace tint::ast { - -FallthroughStatement::FallthroughStatement(ProgramID pid, NodeID nid, const Source& src) - : Base(pid, nid, src) {} - -FallthroughStatement::FallthroughStatement(FallthroughStatement&&) = default; - -FallthroughStatement::~FallthroughStatement() = default; - -const FallthroughStatement* FallthroughStatement::Clone(CloneContext* ctx) const { - // Clone arguments outside of create() call to have deterministic ordering - auto src = ctx->Clone(source); - return ctx->dst->create(src); -} - -} // namespace tint::ast diff --git a/src/tint/ast/fallthrough_statement.h b/src/tint/ast/fallthrough_statement.h deleted file mode 100644 index da2fd3d88b..0000000000 --- a/src/tint/ast/fallthrough_statement.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef SRC_TINT_AST_FALLTHROUGH_STATEMENT_H_ -#define SRC_TINT_AST_FALLTHROUGH_STATEMENT_H_ - -#include "src/tint/ast/statement.h" - -namespace tint::ast { - -/// An fallthrough statement -class FallthroughStatement final : public Castable { - public: - /// Constructor - /// @param pid the identifier of the program that owns this node - /// @param nid the unique node identifier - /// @param src the source of this node - FallthroughStatement(ProgramID pid, NodeID nid, const Source& src); - /// Move constructor - FallthroughStatement(FallthroughStatement&&); - ~FallthroughStatement() override; - - /// Clones this node and all transitive child nodes using the `CloneContext` - /// `ctx`. - /// @param ctx the clone context - /// @return the newly cloned node - const FallthroughStatement* Clone(CloneContext* ctx) const override; -}; - -} // namespace tint::ast - -#endif // SRC_TINT_AST_FALLTHROUGH_STATEMENT_H_ diff --git a/src/tint/ast/fallthrough_statement_test.cc b/src/tint/ast/fallthrough_statement_test.cc deleted file mode 100644 index f823e91700..0000000000 --- a/src/tint/ast/fallthrough_statement_test.cc +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/tint/ast/fallthrough_statement.h" - -#include "src/tint/ast/test_helper.h" - -namespace tint::ast { -namespace { - -using FallthroughStatementTest = TestHelper; - -TEST_F(FallthroughStatementTest, Creation) { - auto* stmt = create(); - EXPECT_EQ(stmt->source.range.begin.line, 0u); - EXPECT_EQ(stmt->source.range.begin.column, 0u); - EXPECT_EQ(stmt->source.range.end.line, 0u); - EXPECT_EQ(stmt->source.range.end.column, 0u); -} - -TEST_F(FallthroughStatementTest, Creation_WithSource) { - auto* stmt = create(Source{Source::Location{20, 2}}); - auto src = stmt->source; - EXPECT_EQ(src.range.begin.line, 20u); - EXPECT_EQ(src.range.begin.column, 2u); -} - -TEST_F(FallthroughStatementTest, IsFallthrough) { - auto* stmt = create(); - EXPECT_TRUE(stmt->Is()); -} - -} // namespace -} // namespace tint::ast diff --git a/src/tint/ast/statement.cc b/src/tint/ast/statement.cc index 6acfff31a4..7b9ca5deaf 100644 --- a/src/tint/ast/statement.cc +++ b/src/tint/ast/statement.cc @@ -19,7 +19,6 @@ #include "src/tint/ast/call_statement.h" #include "src/tint/ast/continue_statement.h" #include "src/tint/ast/discard_statement.h" -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/ast/if_statement.h" #include "src/tint/ast/loop_statement.h" #include "src/tint/ast/return_statement.h" @@ -58,9 +57,6 @@ const char* Statement::Name() const { if (Is()) { return "discard statement"; } - if (Is()) { - return "fallthrough statement"; - } if (Is()) { return "if statement"; } diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc index 6bbcf6db89..423559d2a2 100644 --- a/src/tint/ir/builder_impl.cc +++ b/src/tint/ir/builder_impl.cc @@ -19,7 +19,6 @@ #include "src/tint/ast/break_if_statement.h" #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/for_loop_statement.h" #include "src/tint/ast/function.h" #include "src/tint/ast/if_statement.h" @@ -210,7 +209,6 @@ bool BuilderImpl::EmitStatement(const ast::Statement* stmt) { // [&](const ast::CallStatement* c) { }, [&](const ast::ContinueStatement* c) { return EmitContinue(c); }, // [&](const ast::DiscardStatement* d) { }, - [&](const ast::FallthroughStatement*) { return EmitFallthrough(); }, [&](const ast::IfStatement* i) { return EmitIf(i); }, [&](const ast::LoopStatement* l) { return EmitLoop(l); }, [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); }, @@ -415,25 +413,12 @@ bool BuilderImpl::EmitSwitch(const ast::SwitchStatement* stmt) { { FlowStackScope scope(this, switch_node); - // TODO(crbug.com/tint/1644): This can be simplifed when fallthrough is removed, a single - // loop can be used to iterate each body statement and emit for the case. Two loops are - // needed in order to have the target for a fallthrough. for (const auto* c : stmt->body) { - builder_.CreateCase(switch_node, c->selectors); - } - - for (size_t i = 0; i < stmt->body.Length(); ++i) { - current_flow_block_ = switch_node->cases[i].start_target; - if (i < (stmt->body.Length() - 1)) { - fallthrough_target_ = switch_node->cases[i + 1].start_target; - } - - if (!EmitStatement(stmt->body[i]->body)) { + current_flow_block_ = builder_.CreateCase(switch_node, c->selectors); + if (!EmitStatement(c->body)) { return false; } BranchToIfNeeded(switch_node->merge_target); - - fallthrough_target_ = nullptr; } } current_flow_block_ = nullptr; @@ -514,10 +499,4 @@ bool BuilderImpl::EmitBreakIf(const ast::BreakIfStatement* stmt) { return true; } -bool BuilderImpl::EmitFallthrough() { - TINT_ASSERT(IR, fallthrough_target_ != nullptr); - BranchTo(fallthrough_target_); - return true; -} - } // namespace tint::ir diff --git a/src/tint/ir/builder_impl.h b/src/tint/ir/builder_impl.h index d6c4bc480d..8f24dc6f9d 100644 --- a/src/tint/ir/builder_impl.h +++ b/src/tint/ir/builder_impl.h @@ -134,10 +134,6 @@ class BuilderImpl { /// @returns true if successful, false otherwise. bool EmitBreakIf(const ast::BreakIfStatement* stmt); - /// Emits a fallthrough statement - /// @returns true if successful, false otherwise - bool EmitFallthrough(); - /// Retrieve the IR Flow node for a given AST node. /// @param n the node to lookup /// @returns the FlowNode for the given ast::Node or nullptr if it doesn't exist. @@ -166,9 +162,6 @@ class BuilderImpl { Block* current_flow_block_ = nullptr; Function* current_function_ = nullptr; - // TODO(crbug.com/tint/1644): Remove this when fallthrough is removed. - Block* fallthrough_target_ = nullptr; - /// Map from ast nodes to flow nodes, used to retrieve the flow node for a given AST node. /// Used for testing purposes. std::unordered_map ast_to_flow_; diff --git a/src/tint/ir/builder_impl_test.cc b/src/tint/ir/builder_impl_test.cc index 1ee66e57f1..14f01ba4eb 100644 --- a/src/tint/ir/builder_impl_test.cc +++ b/src/tint/ir/builder_impl_test.cc @@ -1313,64 +1313,5 @@ TEST_F(IRBuilderImplTest, Switch_AllReturn) { EXPECT_EQ(flow->merge_target->branch_target, nullptr); } -// TODO(crbug.com/tint/1644): Remove when fallthrough is removed. -TEST_F(IRBuilderImplTest, Switch_Fallthrough) { - // func -> switch -> case 1 - // -> case 2 - // -> default - // - // [case 1] -> switch merge - // [case 2] -> default - // [default] -> switch merge - // [switch merge] -> func end - // - auto* ast_switch = - Switch(1_i, utils::Vector{Case(utils::Vector{CaseSelector(0_i)}, Block()), - Case(utils::Vector{CaseSelector(1_i)}, Block(Fallthrough())), - DefaultCase(Block())}); - - WrapInFunction(ast_switch); - auto& b = Build(); - - auto r = b.Build(); - ASSERT_TRUE(r) << b.error(); - auto m = r.Move(); - - auto* ir_switch = b.FlowNodeForAstNode(ast_switch); - ASSERT_NE(ir_switch, nullptr); - ASSERT_TRUE(ir_switch->Is()); - - auto* flow = ir_switch->As(); - ASSERT_NE(flow->merge_target, nullptr); - ASSERT_EQ(3u, flow->cases.Length()); - - ASSERT_EQ(1u, m.functions.Length()); - auto* func = m.functions[0]; - - ASSERT_EQ(1u, flow->cases[0].selectors.Length()); - ASSERT_TRUE(flow->cases[0].selectors[0]->expr->Is()); - EXPECT_EQ(0_i, flow->cases[0].selectors[0]->expr->As()->value); - - ASSERT_EQ(1u, flow->cases[1].selectors.Length()); - ASSERT_TRUE(flow->cases[1].selectors[0]->expr->Is()); - EXPECT_EQ(1_i, flow->cases[1].selectors[0]->expr->As()->value); - - ASSERT_EQ(1u, flow->cases[2].selectors.Length()); - EXPECT_TRUE(flow->cases[2].selectors[0]->IsDefault()); - - EXPECT_EQ(1u, flow->inbound_branches.Length()); - EXPECT_EQ(1u, flow->cases[0].start_target->inbound_branches.Length()); - EXPECT_EQ(1u, flow->cases[1].start_target->inbound_branches.Length()); - EXPECT_EQ(2u, flow->cases[2].start_target->inbound_branches.Length()); - EXPECT_EQ(2u, flow->merge_target->inbound_branches.Length()); - EXPECT_EQ(1u, func->end_target->inbound_branches.Length()); - - EXPECT_EQ(func->start_target->branch_target, ir_switch); - EXPECT_EQ(flow->cases[0].start_target->branch_target, flow->merge_target); - EXPECT_EQ(flow->cases[1].start_target->branch_target, flow->cases[2].start_target); - EXPECT_EQ(flow->cases[2].start_target->branch_target, flow->merge_target); - EXPECT_EQ(flow->merge_target->branch_target, func->end_target); -} - } // namespace } // namespace tint::ir diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index 3d1f40e389..d6d1f0059a 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -47,7 +47,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/float_literal_expression.h" #include "src/tint/ast/for_loop_statement.h" #include "src/tint/ast/i32.h" @@ -2932,17 +2931,6 @@ class ProgramBuilder { /// @returns the selector pointer const ast::CaseSelector* DefaultCaseSelector() { return create(nullptr); } - /// Creates an ast::FallthroughStatement - /// @param source the source information - /// @returns the fallthrough statement pointer - const ast::FallthroughStatement* Fallthrough(const Source& source) { - return create(source); - } - - /// Creates an ast::FallthroughStatement - /// @returns the fallthrough statement pointer - const ast::FallthroughStatement* Fallthrough() { return create(); } - /// Creates an ast::BuiltinAttribute /// @param source the source information /// @param builtin the builtin value diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc index 8cbf506969..2104321a18 100644 --- a/src/tint/resolver/control_block_validation_test.cc +++ b/src/tint/resolver/control_block_validation_test.cc @@ -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(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) { diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc index 4dbf1c0f52..1fda54fdee 100644 --- a/src/tint/resolver/dependency_graph.cc +++ b/src/tint/resolver/dependency_graph.cc @@ -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::DiscardStatement>()) { UnhandledNode(diagnostics_, stmt); } }); diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc index c02a5613eb..2cc4a3ab52 100644 --- a/src/tint/resolver/dependency_graph_test.cc +++ b/src/tint/resolver/dependency_graph_test.cc @@ -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(), // diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index e3b2d63e14..3dc054ce88 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -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(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 = diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h index bfb95b3b21..38e624cc24 100644 --- a/src/tint/resolver/resolver.h +++ b/src/tint/resolver/resolver.h @@ -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*); diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc index 8c4f4782b7..afdbdfb1b6 100644 --- a/src/tint/resolver/uniformity.cc +++ b/src/tint/resolver/uniformity.cc @@ -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(); - 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(); + 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. diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 42bee0dba6..df720a1c43 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -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(stmt->Parent())) { - if (auto* c = As(block->Parent())) { - if (block->Declaration()->Last() == stmt->Declaration()) { - if (auto* s = As(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()); diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h index 577b688f04..500d056e79 100644 --- a/src/tint/resolver/validator.h +++ b/src/tint/resolver/validator.h @@ -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 diff --git a/src/tint/sem/behavior.cc b/src/tint/sem/behavior.cc index 4746104370..670cc1db65 100644 --- a/src/tint/sem/behavior.cc +++ b/src/tint/sem/behavior.cc @@ -24,8 +24,6 @@ std::ostream& operator<<(std::ostream& out, Behavior behavior) { return out << "Break"; case Behavior::kContinue: return out << "Continue"; - case Behavior::kFallthrough: - return out << "Fallthrough"; case Behavior::kNext: return out << "Next"; } diff --git a/src/tint/sem/behavior.h b/src/tint/sem/behavior.h index 25572523cf..011ca72a51 100644 --- a/src/tint/sem/behavior.h +++ b/src/tint/sem/behavior.h @@ -25,7 +25,6 @@ enum class Behavior { kReturn, kBreak, kContinue, - kFallthrough, kNext, }; diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index 290629e636..e716b1d3c7 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc @@ -22,7 +22,6 @@ #include #include "src/tint/ast/call_statement.h" -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/ast/id_attribute.h" #include "src/tint/ast/internal_attribute.h" #include "src/tint/ast/interpolate_attribute.h" @@ -104,8 +103,8 @@ namespace { const char kTempNamePrefix[] = "tint_tmp"; -bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) { - return IsAnyOf(stmts->Last()); +bool last_is_break(const ast::BlockStatement* stmts) { + return IsAnyOf(stmts->Last()); } const char* convert_texel_format_to_glsl(const ast::TexelFormat format) { @@ -1821,7 +1820,7 @@ bool GeneratorImpl::EmitCase(const ast::CaseStatement* stmt) { if (!EmitStatements(stmt->body->statements)) { return false; } - if (!last_is_break_or_fallthrough(stmt->body)) { + if (!last_is_break(stmt->body)) { line() << "break;"; } } @@ -2748,10 +2747,6 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) { }, [&](const ast::ContinueStatement* c) { return EmitContinue(c); }, [&](const ast::DiscardStatement* d) { return EmitDiscard(d); }, - [&](const ast::FallthroughStatement*) { - line() << "/* fallthrough */"; - return true; - }, [&](const ast::IfStatement* i) { return EmitIf(i); }, [&](const ast::LoopStatement* l) { return EmitLoop(l); }, [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); }, diff --git a/src/tint/writer/glsl/generator_impl_case_test.cc b/src/tint/writer/glsl/generator_impl_case_test.cc index 4f1c6f310b..f12defd865 100644 --- a/src/tint/writer/glsl/generator_impl_case_test.cc +++ b/src/tint/writer/glsl/generator_impl_case_test.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/writer/glsl/test_helper.h" using namespace tint::number_suffixes; // NOLINT @@ -53,22 +52,6 @@ TEST_F(GlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) { )"); } -TEST_F(GlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) { - auto* s = Switch(1_i, Case(CaseSelector(5_i), Block(create())), - DefaultCase()); - WrapInFunction(s); - - GeneratorImpl& gen = Build(); - - gen.increment_indent(); - - ASSERT_TRUE(gen.EmitCase(s->body[0])) << gen.error(); - EXPECT_EQ(gen.result(), R"( case 5: { - /* fallthrough */ - } -)"); -} - TEST_F(GlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) { auto* s = Switch(1_i, Case( diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index 4c2ac48904..9cfe5d7dae 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -23,7 +23,6 @@ #include #include "src/tint/ast/call_statement.h" -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/ast/id_attribute.h" #include "src/tint/ast/internal_attribute.h" #include "src/tint/ast/interpolate_attribute.h" @@ -2506,18 +2505,7 @@ bool GeneratorImpl::EmitCase(const ast::SwitchStatement* s, size_t case_idx) { return false; } - // Inline all fallthrough case statements. FXC cannot handle fallthroughs. - while (tint::Is(stmt->body->Last())) { - case_idx++; - stmt = s->body[case_idx]; - // Generate each fallthrough case statement in a new block. This is done to - // prevent symbol collision of variables declared in these cases statements. - if (!EmitBlock(stmt->body)) { - return false; - } - } - - if (!tint::IsAnyOf(stmt->body->Last())) { + if (!tint::IsAnyOf(stmt->body->Last())) { line() << "break;"; } @@ -3534,10 +3522,6 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) { [&](const ast::DiscardStatement* d) { // return EmitDiscard(d); }, - [&](const ast::FallthroughStatement*) { // - line() << "/* fallthrough */"; - return true; - }, [&](const ast::IfStatement* i) { // return EmitIf(i); }, diff --git a/src/tint/writer/hlsl/generator_impl_case_test.cc b/src/tint/writer/hlsl/generator_impl_case_test.cc index bfcbcafdb8..2352bbca64 100644 --- a/src/tint/writer/hlsl/generator_impl_case_test.cc +++ b/src/tint/writer/hlsl/generator_impl_case_test.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/writer/hlsl/test_helper.h" using namespace tint::number_suffixes; // NOLINT @@ -53,28 +52,6 @@ TEST_F(HlslGeneratorImplTest_Case, Emit_Case_BreaksByDefault) { )"); } -TEST_F(HlslGeneratorImplTest_Case, Emit_Case_WithFallthrough) { - auto* s = Switch(1_i, // - Case(CaseSelector(4_i), Block(create())), // - Case(CaseSelector(5_i), Block(create())), // - DefaultCase()); - WrapInFunction(s); - - GeneratorImpl& gen = Build(); - - gen.increment_indent(); - - ASSERT_TRUE(gen.EmitCase(s, 0)) << gen.error(); - EXPECT_EQ(gen.result(), R"( case 4: { - /* fallthrough */ - { - return; - } - break; - } -)"); -} - TEST_F(HlslGeneratorImplTest_Case, Emit_Case_MultipleSelectors) { auto* s = Switch(1_i, Case(utils::Vector{CaseSelector(5_i), CaseSelector(6_i)}, diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc index 1342ac9c28..534742e674 100644 --- a/src/tint/writer/msl/generator_impl.cc +++ b/src/tint/writer/msl/generator_impl.cc @@ -25,7 +25,6 @@ #include "src/tint/ast/bool_literal_expression.h" #include "src/tint/ast/call_statement.h" #include "src/tint/ast/disable_validation_attribute.h" -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/ast/float_literal_expression.h" #include "src/tint/ast/id_attribute.h" #include "src/tint/ast/interpolate_attribute.h" @@ -85,8 +84,8 @@ namespace tint::writer::msl { namespace { -bool last_is_break_or_fallthrough(const ast::BlockStatement* stmts) { - return IsAnyOf(stmts->Last()); +bool last_is_break(const ast::BlockStatement* stmts) { + return IsAnyOf(stmts->Last()); } void PrintF32(std::ostream& out, float value) { @@ -1587,7 +1586,7 @@ bool GeneratorImpl::EmitCase(const ast::CaseStatement* stmt) { } } - if (!last_is_break_or_fallthrough(stmt->body)) { + if (!last_is_break(stmt->body)) { line() << "break;"; } } @@ -2426,10 +2425,6 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) { [&](const ast::DiscardStatement* d) { // return EmitDiscard(d); }, - [&](const ast::FallthroughStatement*) { // - line() << "/* fallthrough */"; - return true; - }, [&](const ast::IfStatement* i) { // return EmitIf(i); }, diff --git a/src/tint/writer/msl/generator_impl_case_test.cc b/src/tint/writer/msl/generator_impl_case_test.cc index 8aae4fe2c1..c21800011e 100644 --- a/src/tint/writer/msl/generator_impl_case_test.cc +++ b/src/tint/writer/msl/generator_impl_case_test.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/writer/msl/test_helper.h" using namespace tint::number_suffixes; // NOLINT @@ -53,22 +52,6 @@ TEST_F(MslGeneratorImplTest, Emit_Case_BreaksByDefault) { )"); } -TEST_F(MslGeneratorImplTest, Emit_Case_WithFallthrough) { - auto* s = Switch(1_i, Case(CaseSelector(5_i), Block(create())), - DefaultCase()); - WrapInFunction(s); - - GeneratorImpl& gen = Build(); - - gen.increment_indent(); - - ASSERT_TRUE(gen.EmitCase(s->body[0])) << gen.error(); - EXPECT_EQ(gen.result(), R"( case 5: { - /* fallthrough */ - } -)"); -} - TEST_F(MslGeneratorImplTest, Emit_Case_MultipleSelectors) { auto* s = Switch(1_i, Case( diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index 6342f7151a..3c28de3cca 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc @@ -19,7 +19,6 @@ #include "spirv/unified1/GLSL.std.450.h" #include "src/tint/ast/call_statement.h" -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/ast/id_attribute.h" #include "src/tint/ast/internal_attribute.h" #include "src/tint/ast/traverse_expressions.h" @@ -86,10 +85,6 @@ uint32_t pipeline_stage_to_execution_model(ast::PipelineStage stage) { return model; } -bool LastIsFallthrough(const ast::BlockStatement* stmts) { - return !stmts->Empty() && stmts->Last()->Is(); -} - /// Returns the matrix type that is `type` or that is wrapped by /// one or more levels of an arrays inside of `type`. /// @param type the given type, which must not be null @@ -3515,9 +3510,7 @@ bool Builder::GenerateSwitchStatement(const ast::SwitchStatement* stmt) { bool generated_default = false; auto& body = stmt->body; // We output the case statements in order they were entered in the original - // source. Each fallthrough goes to the next case entry, so is a forward - // branch, otherwise the branch is to the merge block which comes after - // the switch statement. + // source. The branch is to the merge block which comes after the switch statement. for (uint32_t i = 0; i < body.Length(); i++) { auto* item = body[i]; @@ -3531,17 +3524,7 @@ bool Builder::GenerateSwitchStatement(const ast::SwitchStatement* stmt) { if (!GenerateBlockStatement(item->body)) { return false; } - - if (LastIsFallthrough(item->body)) { - if (i == (body.Length() - 1)) { - // This case is caught by Resolver validation - TINT_UNREACHABLE(Writer, builder_.Diagnostics()); - return false; - } - if (!push_function_inst(spv::Op::OpBranch, {Operand(case_ids[i + 1])})) { - return false; - } - } else if (InsideBasicBlock()) { + if (InsideBasicBlock()) { if (!push_function_inst(spv::Op::OpBranch, {Operand(merge_block_id)})) { return false; } @@ -3671,10 +3654,6 @@ bool Builder::GenerateStatement(const ast::Statement* stmt) { [&](const ast::CallStatement* c) { return GenerateCallExpression(c->expr) != 0; }, [&](const ast::ContinueStatement* c) { return GenerateContinueStatement(c); }, [&](const ast::DiscardStatement* d) { return GenerateDiscardStatement(d); }, - [&](const ast::FallthroughStatement*) { - // Do nothing here, the fallthrough gets handled by the switch code. - return true; - }, [&](const ast::IfStatement* i) { return GenerateIfStatement(i); }, [&](const ast::LoopStatement* l) { return GenerateLoopStatement(l); }, [&](const ast::ReturnStatement* r) { return GenerateReturnStatement(r); }, diff --git a/src/tint/writer/spirv/builder_static_assert_test.cc b/src/tint/writer/spirv/builder_static_assert_test.cc index c6d6a51ec0..6e5092d9fa 100644 --- a/src/tint/writer/spirv/builder_static_assert_test.cc +++ b/src/tint/writer/spirv/builder_static_assert_test.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/writer/spirv/spv_dump.h" #include "src/tint/writer/spirv/test_helper.h" diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc index c59c640316..6cf8fad535 100644 --- a/src/tint/writer/spirv/builder_switch_test.cc +++ b/src/tint/writer/spirv/builder_switch_test.cc @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "src/tint/ast/fallthrough_statement.h" #include "src/tint/writer/spirv/spv_dump.h" #include "src/tint/writer/spirv/test_helper.h" @@ -328,69 +327,6 @@ OpFunctionEnd )"); } -TEST_F(BuilderTest, Switch_CaseWithFallthrough) { - // switch(a) { - // case 1i: - // v = 1i; - // fallthrough; - // case 2i: - // v = 2i; - // default: {} - // v = 3i; - // } - - auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate); - auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate); - - auto* func = Func("a_func", utils::Empty, ty.void_(), - utils::Vector{ - Switch(Expr("a"), // - Case(CaseSelector(1_i), // - Block(Assign("v", 1_i), Fallthrough())), // - Case(CaseSelector(2_i), // - Block(Assign("v", 2_i))), // - DefaultCase(Block(Assign("v", 3_i)))), - }); - - spirv::Builder& b = Build(); - - ASSERT_TRUE(b.GenerateGlobalVariable(v)) << b.error(); - ASSERT_TRUE(b.GenerateGlobalVariable(a)) << b.error(); - ASSERT_TRUE(b.GenerateFunction(func)) << b.error(); - - EXPECT_EQ(DumpBuilder(b), R"(OpName %1 "v" -OpName %5 "a" -OpName %8 "a_func" -%3 = OpTypeInt 32 1 -%2 = OpTypePointer Private %3 -%4 = OpConstantNull %3 -%1 = OpVariable %2 Private %4 -%5 = OpVariable %2 Private %4 -%7 = OpTypeVoid -%6 = OpTypeFunction %7 -%15 = OpConstant %3 1 -%16 = OpConstant %3 2 -%17 = OpConstant %3 3 -%8 = OpFunction %7 None %6 -%9 = OpLabel -%11 = OpLoad %3 %5 -OpSelectionMerge %10 None -OpSwitch %11 %12 1 %13 2 %14 -%13 = OpLabel -OpStore %1 %15 -OpBranch %14 -%14 = OpLabel -OpStore %1 %16 -OpBranch %10 -%12 = OpLabel -OpStore %1 %17 -OpBranch %10 -%10 = OpLabel -OpReturn -OpFunctionEnd -)"); -} - TEST_F(BuilderTest, Switch_WithNestedBreak) { // switch (a) { // case 1: @@ -460,7 +396,7 @@ TEST_F(BuilderTest, Switch_AllReturn) { // return 1i; // } // case 2i: { - // fallthrough; + // return 1i; // } // default: { // return 3i; @@ -469,9 +405,9 @@ TEST_F(BuilderTest, Switch_AllReturn) { auto* fn = Func("f", utils::Empty, ty.i32(), utils::Vector{ - Switch(1_i, // - Case(CaseSelector(1_i), Block(Return(1_i))), // - Case(CaseSelector(2_i), Block(Fallthrough())), // + Switch(1_i, // + Case(CaseSelector(1_i), Block(Return(1_i))), // + Case(CaseSelector(2_i), Block(Return(1_i))), // DefaultCase(Block(Return(3_i)))), }); @@ -491,7 +427,7 @@ OpSwitch %6 %7 1 %8 2 %9 %8 = OpLabel OpReturnValue %6 %9 = OpLabel -OpBranch %7 +OpReturnValue %6 %7 = OpLabel OpReturnValue %10 %5 = OpLabel diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc index bf7ebd7262..6327c6c976 100644 --- a/src/tint/writer/wgsl/generator_impl.cc +++ b/src/tint/writer/wgsl/generator_impl.cc @@ -970,7 +970,6 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) { [&](const ast::CompoundAssignmentStatement* c) { return EmitCompoundAssign(c); }, [&](const ast::ContinueStatement* c) { return EmitContinue(c); }, [&](const ast::DiscardStatement* d) { return EmitDiscard(d); }, - [&](const ast::FallthroughStatement* f) { return EmitFallthrough(f); }, [&](const ast::IfStatement* i) { return EmitIf(i); }, [&](const ast::IncrementDecrementStatement* l) { return EmitIncrementDecrement(l); }, [&](const ast::LoopStatement* l) { return EmitLoop(l); }, @@ -1093,11 +1092,6 @@ bool GeneratorImpl::EmitContinue(const ast::ContinueStatement*) { return true; } -bool GeneratorImpl::EmitFallthrough(const ast::FallthroughStatement*) { - line() << "fallthrough;"; - return true; -} - bool GeneratorImpl::EmitIf(const ast::IfStatement* stmt) { { auto out = line(); diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h index 2b7f1c9760..7c76cbd364 100644 --- a/src/tint/writer/wgsl/generator_impl.h +++ b/src/tint/writer/wgsl/generator_impl.h @@ -25,7 +25,6 @@ #include "src/tint/ast/compound_assignment_statement.h" #include "src/tint/ast/continue_statement.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/if_statement.h" #include "src/tint/ast/index_accessor_expression.h" @@ -124,10 +123,6 @@ class GeneratorImpl : public TextGenerator { /// @param expr the expression /// @returns true if the expression was emitted bool EmitExpression(std::ostream& out, const ast::Expression* expr); - /// Handles generating a fallthrough statement - /// @param stmt the fallthrough statement - /// @returns true if the statement was successfully emitted - bool EmitFallthrough(const ast::FallthroughStatement* stmt); /// Handles generating a function /// @param func the function to generate /// @returns true if the function was emitted diff --git a/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc b/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc deleted file mode 100644 index 093fba114a..0000000000 --- a/src/tint/writer/wgsl/generator_impl_fallthrough_test.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 The Tint Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/tint/writer/wgsl/test_helper.h" - -using namespace tint::number_suffixes; // NOLINT - -namespace tint::writer::wgsl { -namespace { - -using WgslGeneratorImplTest = TestHelper; - -TEST_F(WgslGeneratorImplTest, Emit_Fallthrough) { - auto* f = create(); - WrapInFunction(Switch(1_i, // - Case(CaseSelector(1_i), Block(f)), // - DefaultCase())); - - GeneratorImpl& gen = Build(); - - gen.increment_indent(); - - ASSERT_TRUE(gen.EmitStatement(f)) << gen.error(); - EXPECT_EQ(gen.result(), " fallthrough;\n"); -} - -} // namespace -} // namespace tint::writer::wgsl