parseerror(parser, "expected for-loop condition");
goto onerr;
}
- }
- else if (!parser_next(parser)) {
+ } else if (!parser_next(parser)) {
parseerror(parser, "expected for-loop condition");
goto onerr;
}
if (!cond)
goto onerr;
}
-
/* move on to incrementor */
if (parser->tok != ';') {
parseerror(parser, "expected semicolon after for-loop initializer");
return false;
}
swcase.m_value = parse_expression_leave(parser, false, false, false);
+
+ if (!operand->compareType(*swcase.m_value)) {
+ char ty1[1024];
+ char ty2[1024];
+
+ ast_type_to_string(swcase.m_value, ty1, sizeof ty1);
+ ast_type_to_string(operand, ty2, sizeof ty2);
+
+ auto fnLiteral = [](ast_expression *expression) -> char* {
+ if (!ast_istype(expression, ast_value))
+ return nullptr;
+ ast_value *value = (ast_value *)expression;
+ if (!value->m_hasvalue)
+ return nullptr;
+ char *string = nullptr;
+ basic_value_t *constval = &value->m_constval;
+ switch (value->m_vtype)
+ {
+ case TYPE_FLOAT:
+ util_asprintf(&string, "%.2f", constval->vfloat);
+ return string;
+ case TYPE_VECTOR:
+ util_asprintf(&string, "'%.2f %.2f %.2f'",
+ constval->vvec.x,
+ constval->vvec.y,
+ constval->vvec.z);
+ return string;
+ case TYPE_STRING:
+ util_asprintf(&string, "\"%s\"", constval->vstring);
+ return string;
+ default:
+ break;
+ }
+ return nullptr;
+ };
+
+ char *literal = fnLiteral(swcase.m_value);
+ if (literal)
+ compile_error(parser_ctx(parser), "incompatible type `%s` for switch case `%s` expected `%s`", ty1, literal, ty2);
+ else
+ compile_error(parser_ctx(parser), "incompatible type `%s` for switch case expected `%s`", ty1, ty2);
+ mem_d(literal);
+ delete switchnode;
+ return false;
+ }
+
if (!swcase.m_value) {
delete switchnode;
parseerror(parser, "expected expression for case");
ast_expression *subtype;
field->m_hasvalue = true;
subtype = field->m_next;
- ifld = ir_builder_create_field(ir, field->m_name, subtype->m_vtype);
+ ifld = ir->createField(field->m_name, subtype->m_vtype);
if (subtype->m_vtype == TYPE_FIELD)
ifld->m_fieldtype = subtype->m_next->m_vtype;
else if (subtype->m_vtype == TYPE_FUNCTION)
ifld->m_outtype = subtype->m_next->m_vtype;
- (void)!ir_value_set_field(field->m_ir_v, ifld);
+ (void)!field->m_ir_v->setField(ifld);
}
}
for (auto &it : parser->globals) {
if (!ast_istype(it, ast_value))
continue;
asvalue = (ast_value*)it;
- if (!asvalue->m_uses && !asvalue->m_hasvalue && asvalue->m_vtype != TYPE_FUNCTION) {
+ if (!asvalue->m_uses && asvalue->m_cvq != CV_CONST && asvalue->m_vtype != TYPE_FUNCTION) {
retval = retval && !compile_warning(asvalue->m_context, WARN_UNUSED_VARIABLE,
"unused global: `%s`", asvalue->m_name);
}
generate_checksum(parser, ir);
if (OPTS_OPTION_BOOL(OPTION_DUMP))
- ir_builder_dump(ir, con_out);
+ ir->dump(con_out);
for (auto &it : parser->functions) {
if (!ir_function_finalize(it->m_ir_func)) {
con_out("failed to finalize function %s\n", it->m_name.c_str());
}
parser_remove_ast(parser);
- if (compile_Werrors) {
- con_out("*** there were warnings treated as errors\n");
- compile_show_werrors();
- retval = false;
- }
+ auto fnCheckWErrors = [&retval]() {
+ if (compile_Werrors) {
+ con_out("*** there were warnings treated as errors\n");
+ compile_show_werrors();
+ retval = false;
+ }
+ };
+
+ fnCheckWErrors();
if (retval) {
if (OPTS_OPTION_BOOL(OPTION_DUMPFIN))
- ir_builder_dump(ir, con_out);
+ ir->dump(con_out);
- if (!ir_builder_generate(ir, output)) {
+ if (!ir->generate(output)) {
con_out("*** failed to generate output file\n");
delete ir;
return false;
}
+
+ // ir->generate can generate compiler warnings
+ fnCheckWErrors();
}
delete ir;
return retval;