binpac: Improve storage type used for case-type index

The type used to store the index for a case-type now tracks the
type of the index expression rather than always using an "int".

The case fields also now have some checking done at code-gen-time to
ensure the constants used for cases does not exceed the numeric limit
of the type used in the case's index expression.  Then, assuming, it
looks safe, the C++ case labels are generated with casts to the type
of the Binpac case's index expression to ensure compilers accept it
(since all Binpac numbers use "int" for storage/printing internally).
This commit is contained in:
Jon Siwek 2019-05-16 08:44:42 -07:00 committed by Tim Wojtulewicz
parent b4b229acf7
commit 21cf20fc6f
7 changed files with 137 additions and 21 deletions

View file

@ -257,6 +257,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
(*i)->value()->ForceIDEval(out_cc, env);
out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env));
Type* switch_type = operand_[0]->DataType(env);
out_cc->inc_indent();
out_cc->println("{");
@ -274,7 +275,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
}
else
{
GenCaseStr(index, out_cc, env);
GenCaseStr(index, out_cc, env, switch_type);
out_cc->inc_indent();
out_cc->println("%s = %s;",
env->LValue(val_var),
@ -285,7 +286,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
}
// Generate the default case after all other cases
GenCaseStr(0, out_cc, env);
GenCaseStr(0, out_cc, env, switch_type);
out_cc->inc_indent();
if ( default_case )
{
@ -295,7 +296,7 @@ void Expr::GenCaseEval(Output *out_cc, Env *env)
}
else
{
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", %s);",
out_cc->println("throw binpac::ExceptionInvalidCaseIndex(\"%s\", (int64)%s);",
Location(), operand_[0]->EvalExpr(out_cc, env));
}
out_cc->println("break;");