tint: Add new methods to semantic Switch nodes

• Add sem::SwitchStatement::Cases()
• Add sem::CaseStatement::Selectors()
• Add ast::SwitchStatement -> sem::SwitchStatement mapping

Removes a bunch of hopping between the AST and SEM to get at this data.

Change-Id: If48d78e7a386aa0b34c6d00ad9af1d53cb236f12
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91024
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2022-05-20 12:28:00 +00:00 committed by Dawn LUCI CQ
parent a2ce4ecc8b
commit 43581f1fb6
5 changed files with 43 additions and 5 deletions

View File

@ -870,10 +870,13 @@ sem::CaseStatement* Resolver::CaseStatement(const ast::CaseStatement* stmt) {
auto* sem = auto* sem =
builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_); builder_->create<sem::CaseStatement>(stmt, current_compound_statement_, current_function_);
return StatementScope(stmt, sem, [&] { return StatementScope(stmt, sem, [&] {
sem->Selectors().reserve(stmt->selectors.size());
for (auto* sel : stmt->selectors) { for (auto* sel : stmt->selectors) {
if (!Expression(sel)) { auto* expr = Expression(sel);
if (!expr) {
return false; return false;
} }
sem->Selectors().emplace_back(expr);
} }
Mark(stmt->body); Mark(stmt->body);
auto* body = BlockStatement(stmt->body); auto* body = BlockStatement(stmt->body);
@ -2140,6 +2143,7 @@ sem::SwitchStatement* Resolver::SwitchStatement(const ast::SwitchStatement* stmt
return false; return false;
} }
behaviors.Add(c->Behaviors()); behaviors.Add(c->Behaviors());
sem->Cases().emplace_back(c);
} }
if (behaviors.Contains(sem::Behavior::kBreak)) { if (behaviors.Contains(sem::Behavior::kBreak)) {

View File

@ -19,6 +19,7 @@
#include "src/tint/sem/expression.h" #include "src/tint/sem/expression.h"
#include "src/tint/sem/for_loop_statement.h" #include "src/tint/sem/for_loop_statement.h"
#include "src/tint/sem/if_statement.h" #include "src/tint/sem/if_statement.h"
#include "src/tint/sem/switch_statement.h"
using namespace tint::number_suffixes; // NOLINT using namespace tint::number_suffixes; // NOLINT

View File

@ -42,6 +42,7 @@
#include "src/tint/sem/reference.h" #include "src/tint/sem/reference.h"
#include "src/tint/sem/sampled_texture.h" #include "src/tint/sem/sampled_texture.h"
#include "src/tint/sem/statement.h" #include "src/tint/sem/statement.h"
#include "src/tint/sem/switch_statement.h"
#include "src/tint/sem/variable.h" #include "src/tint/sem/variable.h"
using ::testing::ElementsAre; using ::testing::ElementsAre;
@ -111,11 +112,11 @@ TEST_F(ResolverTest, Stmt_Case) {
auto* assign = Assign(lhs, rhs); auto* assign = Assign(lhs, rhs);
auto* block = Block(assign); auto* block = Block(assign);
ast::CaseSelectorList lit; auto* sel = Expr(3_i);
lit.push_back(Expr(3_i)); auto* cse = Case(sel, block);
auto* cse = create<ast::CaseStatement>(lit, block); auto* def = DefaultCase();
auto* cond_var = Var("c", ty.i32()); auto* cond_var = Var("c", ty.i32());
auto* sw = Switch(cond_var, cse, DefaultCase()); auto* sw = Switch(cond_var, cse, def);
WrapInFunction(v, cond_var, sw); WrapInFunction(v, cond_var, sw);
EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(r()->Resolve()) << r()->error();
@ -127,6 +128,13 @@ TEST_F(ResolverTest, Stmt_Case) {
EXPECT_EQ(StmtOf(lhs), assign); EXPECT_EQ(StmtOf(lhs), assign);
EXPECT_EQ(StmtOf(rhs), assign); EXPECT_EQ(StmtOf(rhs), assign);
EXPECT_EQ(BlockOf(assign), block); EXPECT_EQ(BlockOf(assign), block);
auto* sem = Sem().Get(sw);
ASSERT_EQ(sem->Cases().size(), 2u);
EXPECT_EQ(sem->Cases()[0]->Declaration(), cse);
ASSERT_EQ(sem->Cases()[0]->Selectors().size(), 1u);
EXPECT_EQ(sem->Cases()[0]->Selectors()[0]->Declaration(), sel);
EXPECT_EQ(sem->Cases()[1]->Declaration(), def);
EXPECT_EQ(sem->Cases()[1]->Selectors().size(), 0u);
} }
TEST_F(ResolverTest, Stmt_Block) { TEST_F(ResolverTest, Stmt_Block) {

View File

@ -15,6 +15,8 @@
#ifndef SRC_TINT_SEM_SWITCH_STATEMENT_H_ #ifndef SRC_TINT_SEM_SWITCH_STATEMENT_H_
#define SRC_TINT_SEM_SWITCH_STATEMENT_H_ #define SRC_TINT_SEM_SWITCH_STATEMENT_H_
#include <vector>
#include "src/tint/sem/block_statement.h" #include "src/tint/sem/block_statement.h"
// Forward declarations // Forward declarations
@ -22,6 +24,10 @@ namespace tint::ast {
class CaseStatement; class CaseStatement;
class SwitchStatement; class SwitchStatement;
} // namespace tint::ast } // namespace tint::ast
namespace tint::sem {
class CaseStatement;
class Expression;
} // namespace tint::sem
namespace tint::sem { namespace tint::sem {
@ -41,6 +47,15 @@ class SwitchStatement final : public Castable<SwitchStatement, CompoundStatement
/// @return the AST node for this statement /// @return the AST node for this statement
const ast::SwitchStatement* Declaration() const; const ast::SwitchStatement* Declaration() const;
/// @returns the case statements for this switch
std::vector<const CaseStatement*>& Cases() { return cases_; }
/// @returns the case statements for this switch
const std::vector<const CaseStatement*>& Cases() const { return cases_; }
private:
std::vector<const CaseStatement*> cases_;
}; };
/// Holds semantic information about a switch case statement /// Holds semantic information about a switch case statement
@ -66,8 +81,15 @@ class CaseStatement final : public Castable<CaseStatement, CompoundStatement> {
/// @returns the case body block statement /// @returns the case body block statement
const BlockStatement* Body() const { return body_; } const BlockStatement* Body() const { return body_; }
/// @returns the selectors for the case
std::vector<const Expression*>& Selectors() { return selectors_; }
/// @returns the selectors for the case
const std::vector<const Expression*>& Selectors() const { return selectors_; }
private: private:
const BlockStatement* body_ = nullptr; const BlockStatement* body_ = nullptr;
std::vector<const Expression*> selectors_;
}; };
} // namespace tint::sem } // namespace tint::sem

View File

@ -30,6 +30,7 @@ class Node;
class Statement; class Statement;
class Struct; class Struct;
class StructMember; class StructMember;
class SwitchStatement;
class Type; class Type;
class TypeDecl; class TypeDecl;
class Variable; class Variable;
@ -46,6 +47,7 @@ class Node;
class Statement; class Statement;
class Struct; class Struct;
class StructMember; class StructMember;
class SwitchStatement;
class Type; class Type;
class Variable; class Variable;
} // namespace tint::sem } // namespace tint::sem
@ -68,6 +70,7 @@ struct TypeMappings {
Statement* operator()(ast::Statement*); Statement* operator()(ast::Statement*);
Struct* operator()(ast::Struct*); Struct* operator()(ast::Struct*);
StructMember* operator()(ast::StructMember*); StructMember* operator()(ast::StructMember*);
SwitchStatement* operator()(ast::SwitchStatement*);
Type* operator()(ast::Type*); Type* operator()(ast::Type*);
Type* operator()(ast::TypeDecl*); Type* operator()(ast::TypeDecl*);
Variable* operator()(ast::Variable*); Variable* operator()(ast::Variable*);