37 return "switch (" + this->
value()->description() +
") " + this->
caseBlock()->description();
43 bool foundDefault =
false;
45 for (
const std::unique_ptr<Statement>& stmt : cases) {
63 return duplicateCases;
69 bool visitStatementPtr(std::unique_ptr<Statement>& stmt)
override {
77 bool visitExpressionPtr(std::unique_ptr<Expression>& expr)
override {
81 RemoveBreaksWriter{}.visitStatementPtr(stmt);
96 auto iter = cases.
begin();
97 for (; iter != cases.
end(); ++iter) {
99 if (&sc == caseToCapture) {
107 auto startIter = iter;
108 bool removeBreakStatements =
false;
109 for (; iter != cases.
end(); ++iter) {
110 std::unique_ptr<Statement>& stmt = (*iter)->
as<
SwitchCase>().statement();
118 removeBreakStatements =
true;
130 for (
int index = 0; index < numElements; ++index, ++startIter) {
138 if (removeBreakStatements) {
148 std::unique_ptr<Expression>
value,
151 std::unique_ptr<SymbolTable> symbolTable) {
160 for (
int i = 0;
i < caseValues.
size(); ++
i) {
162 Position casePos = caseValues[
i]->fPosition;
164 std::unique_ptr<Expression> caseValue =
value->type().coerceExpression(
165 std::move(caseValues[
i]), context);
171 context.
fErrors->
error(casePos,
"case value must be a constant integer");
182 if (!duplicateCases.
empty()) {
184 if (sc->isDefault()) {
185 context.
fErrors->
error(sc->fPosition,
"duplicate default case");
187 context.
fErrors->
error(sc->fPosition,
"duplicate case value '" +
199 Block::Kind::kBracedScope,
200 std::move(symbolTable)));
205 std::unique_ptr<Expression>
value,
206 std::unique_ptr<Statement> caseBlock) {
210 return stmt->is<SwitchCase>();
222 for (
const std::unique_ptr<Statement>& stmt :
cases) {
229 if (sc.
value() == switchValue) {
243 matchingCase = defaultCase;
254 auto stmt = std::make_unique<SwitchStatement>(
pos, std::move(
value), std::move(
caseBlock));
constexpr int SkToInt(S x)
static std::unique_ptr< Block > MakeBlock(Position pos, StatementArray statements, Kind kind=Kind::kBracedScope, std::unique_ptr< SymbolTable > symbols=nullptr)
const std::unique_ptr< Type > fInt
static bool GetConstantInt(const Expression &value, SKSL_INT *out)
const BuiltinTypes & fTypes
void error(Position position, std::string_view msg)
static std::unique_ptr< Statement > Make()
bool visitStatementPtr(std::unique_ptr< Statement > &s) override
static std::unique_ptr< SwitchCase > MakeDefault(Position pos, std::unique_ptr< Statement > statement)
static std::unique_ptr< SwitchCase > Make(Position pos, SKSL_INT value, std::unique_ptr< Statement > statement)
std::unique_ptr< Statement > & statement()
std::unique_ptr< Expression > & value()
std::string description() const override
std::unique_ptr< Statement > & caseBlock()
static std::unique_ptr< Statement > Make(const Context &context, Position pos, std::unique_ptr< Expression > value, std::unique_ptr< Statement > caseBlock)
static std::unique_ptr< Statement > Convert(const Context &context, Position pos, std::unique_ptr< Expression > value, ExpressionArray caseValues, StatementArray caseStatements, std::unique_ptr< SymbolTable > symbolTable)
bool contains(const T &item) const
EMSCRIPTEN_KEEPALIVE void empty()
bool SwitchCaseContainsUnconditionalExit(const Statement &stmt)
bool SwitchCaseContainsConditionalExit(const Statement &stmt)
static void remove_break_statements(std::unique_ptr< Statement > &stmt)
static TArray< const SwitchCase * > find_duplicate_case_values(const StatementArray &cases)
static bool block_for_case(Statement *caseBlock, SwitchCase *caseToCapture)
static SkString to_string(int n)
ProgramSettings fSettings