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:
parent
a2ce4ecc8b
commit
43581f1fb6
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
Loading…
Reference in New Issue