if (parenthesized)
print_string("(");
switch (expression->kind) {
- case EXPR_INVALID:
- print_string("$invalid expression$");
+ case EXPR_ERROR:
+ print_string("$error$");
break;
case EXPR_WIDE_STRING_LITERAL:
case EXPR_STRING_LITERAL:
case EXPR_STATEMENT:
print_statement_expression(&expression->statement);
break;
+ case EXPR_INVALID:
+ panic("invalid expression found");
#if 0
default:
return EXPR_CLASS_VARIABLE;
}
- case EXPR_INVALID:
+ case EXPR_ERROR:
return EXPR_CLASS_ERROR;
+ case EXPR_INVALID:
+ panic("invalid expression found");
default:
return EXPR_CLASS_VARIABLE;
return EXPR_CLASS_VARIABLE;
}
- case EXPR_INVALID:
+ case EXPR_ERROR:
return EXPR_CLASS_ERROR;
+ case EXPR_INVALID:
+ panic("invalid expression found");
default:
return EXPR_CLASS_VARIABLE;
case EXPR_UNARY_DEREFERENCE:
return is_constant_pointer(expression->unary.value);
- case EXPR_INVALID:
+ case EXPR_ERROR:
return EXPR_CLASS_ERROR;
+ case EXPR_INVALID:
+ panic("invalid expression found");
default:
return EXPR_CLASS_VARIABLE;
}
}
- case EXPR_INVALID:
+ case EXPR_ERROR:
return EXPR_CLASS_ERROR;
+ case EXPR_INVALID:
+ break;
}
panic("invalid expression found (is constant expression)");
}
long fold_constant_to_int(const expression_t *expression)
{
- if (expression->kind == EXPR_INVALID)
+ if (expression->kind == EXPR_ERROR)
return 0;
ir_tarval *tv = fold_constant_to_tarval(expression);
bool fold_constant_to_bool(const expression_t *expression)
{
- if (expression->kind == EXPR_INVALID)
+ if (expression->kind == EXPR_ERROR)
return false;
ir_tarval *tv = fold_constant_to_tarval(expression);
return !tarval_is_null(tv);
return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
}
+static ir_node *error_to_firm(const expression_t *expression)
+{
+ ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
+ return new_Bad(mode);
+}
+
/**
* creates firm nodes for an expression. The difference between this function
* and expression_to_firm is, that this version might produce mode_b nodes
case EXPR_LABEL_ADDRESS:
return label_address_to_firm(&expression->label_address);
+ case EXPR_ERROR:
+ return error_to_firm(expression);
case EXPR_INVALID:
break;
}
{
static const size_t sizes[] = {
[EXPR_INVALID] = sizeof(expression_base_t),
+ [EXPR_ERROR] = sizeof(expression_base_t),
[EXPR_REFERENCE] = sizeof(reference_expression_t),
[EXPR_REFERENCE_ENUM_VALUE] = sizeof(reference_expression_t),
[EXPR_LITERAL_BOOLEAN] = sizeof(literal_expression_t),
* Creates a new invalid expression at the source position
* of the current token.
*/
-static expression_t *create_invalid_expression(void)
+static expression_t *create_error_expression(void)
{
- return allocate_expression_zero(EXPR_INVALID);
+ expression_t *expression = allocate_expression_zero(EXPR_ERROR);
+ expression->base.type = type_error_type;
+ return expression;
}
/**
EXPR_LITERAL_CASES
case EXPR_INVALID:
+ case EXPR_ERROR:
case EXPR_STRING_LITERAL:
case EXPR_WIDE_STRING_LITERAL:
case EXPR_COMPOUND_LITERAL: // TODO init?
case EXPR_BUILTIN_TYPES_COMPATIBLE_P:
case EXPR_OFFSETOF:
case EXPR_INVALID:
+ case EXPR_ERROR:
return true;
case EXPR_STATEMENT: {
}
next_token();
- return create_invalid_expression();
+ return create_error_expression();
}
static type_t *get_string_type(void)
return cast;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
descend_into_subtype(&path);
if (!walk_designator(&path, designator, true)) {
- return create_invalid_expression();
+ return create_error_expression();
}
DEL_ARR_F(path.path);
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
}
expect(')', end_error);
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
expression->base.type = type_void;
return expression;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
eat(T_ANDAND);
if (token.kind != T_IDENTIFIER) {
parse_error_expected("while parsing label address", T_IDENTIFIER, NULL);
- return create_invalid_expression();
+ return create_error_expression();
}
label_t *const label = get_label();
parse_declaration_specifiers(&specifiers);
type_t const *const type = parse_abstract_declarator(specifiers.type);
errorf(&pos, "encountered type '%T' while parsing expression", type);
- return create_invalid_expression();
+ return create_error_expression();
}
}
errorf(HERE, "unexpected token %K, expected an expression", &token);
eat_until_anchor();
- return create_invalid_expression();
+ return create_error_expression();
}
static expression_t *parse_array_expression(expression_t *left)
if (token.kind != T_IDENTIFIER) {
parse_error_expected("while parsing select", T_IDENTIFIER, NULL);
- return create_invalid_expression();
+ return create_error_expression();
}
symbol_t *symbol = token.identifier.symbol;
next_token();
"request for member '%Y' in something not a struct or union, but '%T'",
symbol, type_left);
}
- return create_invalid_expression();
+ return create_error_expression();
}
compound_t *compound = type_left->compound.compound;
if (!compound->complete) {
errorf(&pos, "request for member '%Y' in incomplete type '%T'",
symbol, type_left);
- return create_invalid_expression();
+ return create_error_expression();
}
type_qualifiers_t qualifiers = type_left->base.qualifiers;
if (result == NULL) {
errorf(&pos, "'%T' has no member named '%Y'", orig_type, symbol);
- return create_invalid_expression();
+ return create_error_expression();
}
return result;
return result;
end_error:
- return create_invalid_expression();
+ return create_error_expression();
}
/**
static bool expression_has_effect(const expression_t *const expr)
{
switch (expr->kind) {
+ case EXPR_ERROR:
case EXPR_INVALID: return true; /* do NOT warn */
case EXPR_REFERENCE: return false;
case EXPR_REFERENCE_ENUM_VALUE: return false;