sem: Replace SwitchCaseBlockStatement with CaseStatement

The SwitchCaseBlockStatement was bound to the BlockStatement of an ast::CaseStatement, but we had nothing that mapped to the actual ast::CaseStatement.
sem::CaseStatement replaces sem::SwitchCaseBlockStatement, and has a Block() accessor, providing a superset of the old behavior.

With this, we can now easily validate the `fallthrough` rules directly, instead of scanning the switch case. This keeps the validation more tigtly coupled to the ast / sem nodes.

Change-Id: I0f22eba37bb164b9e071a6166c7a41fc1a5ac532
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/71460
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton
2021-12-03 15:23:52 +00:00
committed by Tint LUCI CQ
parent 8e39ffd512
commit bf39c8fb19
9 changed files with 103 additions and 55 deletions

View File

@@ -16,8 +16,8 @@
#include "src/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::sem::CaseStatement);
TINT_INSTANTIATE_TYPEINFO(tint::sem::SwitchStatement);
TINT_INSTANTIATE_TYPEINFO(tint::sem::SwitchCaseBlockStatement);
namespace tint {
namespace sem {
@@ -32,15 +32,22 @@ SwitchStatement::SwitchStatement(const ast::SwitchStatement* declaration,
SwitchStatement::~SwitchStatement() = default;
SwitchCaseBlockStatement::SwitchCaseBlockStatement(
const ast::BlockStatement* declaration,
const CompoundStatement* parent,
const sem::Function* function)
const ast::SwitchStatement* SwitchStatement::Declaration() const {
return static_cast<const ast::SwitchStatement*>(Base::Declaration());
}
CaseStatement::CaseStatement(const ast::CaseStatement* declaration,
const CompoundStatement* parent,
const sem::Function* function)
: Base(declaration, parent, function) {
TINT_ASSERT(Semantic, parent);
TINT_ASSERT(Semantic, function);
}
SwitchCaseBlockStatement::~SwitchCaseBlockStatement() = default;
CaseStatement::~CaseStatement() = default;
const ast::CaseStatement* CaseStatement::Declaration() const {
return static_cast<const ast::CaseStatement*>(Base::Declaration());
}
} // namespace sem
} // namespace tint

View File

@@ -20,6 +20,7 @@
// Forward declarations
namespace tint {
namespace ast {
class CaseStatement;
class SwitchStatement;
} // namespace ast
} // namespace tint
@@ -40,22 +41,36 @@ class SwitchStatement : public Castable<SwitchStatement, CompoundStatement> {
/// Destructor
~SwitchStatement() override;
/// @return the AST node for this statement
const ast::SwitchStatement* Declaration() const;
};
/// Holds semantic information about a switch case block
class SwitchCaseBlockStatement
: public Castable<SwitchCaseBlockStatement, BlockStatement> {
/// Holds semantic information about a switch case statement
class CaseStatement : public Castable<CaseStatement, CompoundStatement> {
public:
/// Constructor
/// @param declaration the AST node for this block statement
/// @param declaration the AST node for this case statement
/// @param parent the owning statement
/// @param function the owning function
SwitchCaseBlockStatement(const ast::BlockStatement* declaration,
const CompoundStatement* parent,
const sem::Function* function);
CaseStatement(const ast::CaseStatement* declaration,
const CompoundStatement* parent,
const sem::Function* function);
/// Destructor
~SwitchCaseBlockStatement() override;
~CaseStatement() override;
/// @return the AST node for this statement
const ast::CaseStatement* Declaration() const;
/// @param body the case body block statement
void SetBlock(const BlockStatement* body) { body_ = body; }
/// @returns the case body block statement
const BlockStatement* Body() const { return body_; }
private:
const BlockStatement* body_ = nullptr;
};
} // namespace sem