return new_id_from_str(buf);
}
-/**
- * Return the signed integer mode of size bytes.
- *
- * @param size the size
- */
-static ir_mode *get_smode(unsigned size)
-{
- static ir_mode *s_modes[16 + 1] = {0, };
- ir_mode *res;
-
- if (size <= 0 || size > 16)
- return NULL;
+static ir_mode *_atomic_modes[ATOMIC_TYPE_LAST+1];
- res = s_modes[size];
- if (res == NULL) {
- unsigned bits;
- char name[32];
+static ir_mode *mode_int, *mode_uint;
- bits = size * 8;
- snprintf(name, sizeof(name), "i%u", bits);
- res = new_ir_mode(name, irms_int_number, bits, 1, irma_twos_complement,
- bits <= machine_size ? machine_size : bits );
+static ir_node *expression_to_firm(const expression_t *expression);
+static inline ir_mode *get_ir_mode(type_t *type);
- s_modes[size] = res;
+static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
+{
+ unsigned flags = get_atomic_type_flags(kind);
+ unsigned size = get_atomic_type_size(kind);
+ if( (flags & (ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_FLOAT))
+ && !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) {
+ char name[64];
+ mode_sort sort;
+ unsigned bit_size = size * 8;
+ bool is_signed = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0;
+ mode_arithmetic arithmetic;
+ unsigned modulo_shift;
+
+ if(flags & ATOMIC_TYPE_FLAG_INTEGER) {
+ assert(! (flags & ATOMIC_TYPE_FLAG_FLOAT));
+ snprintf(name, sizeof(name), "i%s%d", is_signed?"":"u", bit_size);
+ sort = irms_int_number;
+ arithmetic = irma_twos_complement;
+ modulo_shift = bit_size < machine_size ? machine_size : bit_size;
+ } else {
+ assert(flags & ATOMIC_TYPE_FLAG_FLOAT);
+ snprintf(name, sizeof(name), "f%d", bit_size);
+ sort = irms_float_number;
+ arithmetic = irma_ieee754;
+ modulo_shift = 0;
+ }
+ return new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
+ modulo_shift);
}
- return res;
-}
-/**
- * Return the unsigned integer mode of size bytes.
- *
- * @param size the size
- */
-static ir_mode *get_umode(unsigned size)
-{
- static ir_mode *u_modes[16 + 1] = {0, };
- ir_mode *res;
-
- if (size <= 0 || size > 16)
- return NULL;
-
- res = u_modes[size];
- if (res == NULL) {
- unsigned bits;
- char name[32];
-
- bits = size * 8;
- snprintf(name, sizeof(name), "u%u", bits);
- res = new_ir_mode(name, irms_int_number, bits, 0, irma_twos_complement,
- bits <= machine_size ? machine_size : bits );
-
- u_modes[size] = res;
- }
- return res;
+ return NULL;
}
/**
- * Return the pointer mode of size bytes.
- *
- * @param size the size
+ * Initialises the atomic modes depending on the machine size.
*/
-static ir_mode *get_ptrmode(unsigned size, char *name)
+static void init_atomic_modes(void)
{
- static ir_mode *p_modes[16 + 1] = {0, };
- ir_mode *res;
-
- if (size <= 0 || size > 16)
- return NULL;
-
- res = p_modes[size];
- if (res == NULL) {
- unsigned bits;
- char buf[32];
-
- bits = size * 8;
- if (name == NULL) {
- snprintf(buf, sizeof(buf), "p%u", bits);
- name = buf;
- }
- res = new_ir_mode(name, irms_reference, bits, 0, irma_twos_complement,
- bits <= machine_size ? machine_size : bits);
-
- p_modes[size] = res;
-
- set_reference_mode_signed_eq(res, get_smode(size));
- set_reference_mode_unsigned_eq(res, get_umode(size));
+ for(int i = 0; i <= ATOMIC_TYPE_LAST; ++i) {
+ _atomic_modes[i] = init_atomic_ir_mode((atomic_type_kind_t) i);
}
- return res;
-}
+ mode_int = _atomic_modes[ATOMIC_TYPE_INT];
+ mode_uint = _atomic_modes[ATOMIC_TYPE_UINT];
-static ir_mode *_atomic_modes[ATOMIC_TYPE_LAST+1];
+ /* there's no real void type in firm */
+ _atomic_modes[ATOMIC_TYPE_VOID] = mode_int;
-static ir_mode *mode_int, *mode_uint;
+ /* initialize pointer modes */
+ char name[64];
+ mode_sort sort = irms_reference;
+ unsigned bit_size = machine_size;
+ bool is_signed = 0;
+ mode_arithmetic arithmetic = irma_twos_complement;
+ unsigned modulo_shift
+ = bit_size < machine_size ? machine_size : bit_size;
-static ir_node *expression_to_firm(const expression_t *expression);
-static inline ir_mode *get_ir_mode(type_t *type);
+ snprintf(name, sizeof(name), "p%d", machine_size);
+ ir_mode *ptr_mode = new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
+ modulo_shift);
-/**
- * Initialises the atomic modes depending on the machine size.
- */
-static void init_atomic_modes(void) {
- unsigned int_size = machine_size < 32 ? 2 : 4;
- unsigned long_size = machine_size < 64 ? 4 : 8;
- unsigned llong_size = machine_size < 32 ? 4 : 8;
-
- /* firm has no real void... */
- _atomic_modes[ATOMIC_TYPE_VOID] = mode_T;
- _atomic_modes[ATOMIC_TYPE_CHAR] = char_is_signed ? get_smode(1) : get_umode(1);
- _atomic_modes[ATOMIC_TYPE_SCHAR] = get_smode(1);
- _atomic_modes[ATOMIC_TYPE_UCHAR] = get_umode(1);
- _atomic_modes[ATOMIC_TYPE_SHORT] = get_smode(2);
- _atomic_modes[ATOMIC_TYPE_USHORT] = get_umode(2);
- _atomic_modes[ATOMIC_TYPE_INT] = get_smode(int_size);
- _atomic_modes[ATOMIC_TYPE_UINT] = get_umode(int_size);
- _atomic_modes[ATOMIC_TYPE_LONG] = get_smode(long_size);
- _atomic_modes[ATOMIC_TYPE_ULONG] = get_umode(long_size);
- _atomic_modes[ATOMIC_TYPE_LONGLONG] = get_smode(llong_size);
- _atomic_modes[ATOMIC_TYPE_ULONGLONG] = get_umode(llong_size);
- _atomic_modes[ATOMIC_TYPE_FLOAT] = mode_F;
- _atomic_modes[ATOMIC_TYPE_DOUBLE] = mode_D;
- _atomic_modes[ATOMIC_TYPE_LONG_DOUBLE] = mode_E;
- _atomic_modes[ATOMIC_TYPE_BOOL] = get_umode(int_size);
-
- _atomic_modes[ATOMIC_TYPE_BOOL] = _atomic_modes[ATOMIC_TYPE_INT];
- _atomic_modes[ATOMIC_TYPE_FLOAT_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_FLOAT];
- _atomic_modes[ATOMIC_TYPE_DOUBLE_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_DOUBLE];
- _atomic_modes[ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY] = _atomic_modes[ATOMIC_TYPE_LONG_DOUBLE];
+ set_reference_mode_signed_eq(ptr_mode, _atomic_modes[get_intptr_kind()]);
+ set_reference_mode_unsigned_eq(ptr_mode, _atomic_modes[get_uintptr_kind()]);
/* Hmm, pointers should be machine size */
- set_modeP_data(get_ptrmode(machine_size >> 3, NULL));
- set_modeP_code(get_ptrmode(machine_size >> 3, NULL));
-
- mode_int = _atomic_modes[ATOMIC_TYPE_INT];
- mode_uint = _atomic_modes[ATOMIC_TYPE_UINT];
-}
-
-static ir_mode *get_atomic_mode(const atomic_type_t* atomic_type)
-{
- ir_mode *res = NULL;
- if ((unsigned)atomic_type->akind <= (unsigned)ATOMIC_TYPE_LAST)
- res = _atomic_modes[(unsigned)atomic_type->akind];
- if (res == NULL)
- panic("Encountered unknown atomic type");
- return res;
+ set_modeP_data(ptr_mode);
+ set_modeP_code(ptr_mode);
}
static unsigned get_compound_type_size(compound_type_t *type)
return count;
}
-
static ir_type *create_atomic_type(const atomic_type_t *type)
{
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
- ir_mode *mode = get_atomic_mode(type);
- ident *id = get_mode_ident(mode);
- ir_type *irtype = new_d_type_primitive(id, mode, dbgi);
+ dbg_info *dbgi = get_dbg_info(&type->base.source_position);
+ atomic_type_kind_t kind = type->akind;
+ ir_mode *mode = _atomic_modes[kind];
+ unsigned alignment = get_atomic_type_alignment(kind);
+ ident *id = get_mode_ident(mode);
+ ir_type *irtype = new_d_type_primitive(id, mode, dbgi);
- /* TODO: this is x86 specific, we should fiddle this into
- * lang_features.h somehow... */
- if(type->akind == ATOMIC_TYPE_LONG_DOUBLE
- || type->akind == ATOMIC_TYPE_DOUBLE
- || type->akind == ATOMIC_TYPE_LONGLONG
- || type->akind == ATOMIC_TYPE_ULONGLONG) {
- set_type_alignment_bytes(irtype, 4);
- }
+ if(type->base.alignment > alignment)
+ alignment = type->base.alignment;
+
+ set_type_alignment_bytes(irtype, alignment);
return irtype;
}
ident *id = unique_ident("functiontype");
int n_parameters = count_parameters(function_type);
int n_results = return_type == type_void ? 0 : 1;
- dbg_info *dbgi = get_dbg_info(&function_type->type.source_position);
+ dbg_info *dbgi = get_dbg_info(&function_type->base.source_position);
ir_type *irtype = new_d_type_method(id, n_parameters, n_results, dbgi);
if(return_type != type_void) {
* again (might be a struct). We therefore first create a void* pointer
* and then set the real points_to type
*/
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
- ir_type *ir_type = new_d_type_pointer(unique_ident("pointer"),
+ dbg_info *dbgi = get_dbg_info(&type->base.source_position);
+ ir_type *ir_type = new_d_type_pointer(unique_ident("pointer"),
ir_type_void, mode_P_data, dbgi);
- type->type.firm_type = ir_type;
+ type->base.firm_type = ir_type;
ir_points_to = get_ir_type(points_to);
set_pointer_points_to_type(ir_type, ir_points_to);
ir_type *ir_element_type = get_ir_type(element_type);
ident *id = unique_ident("array");
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
+ dbg_info *dbgi = get_dbg_info(&type->base.source_position);
ir_type *ir_type = new_d_type_array(id, 1, ir_element_type, dbgi);
const int align = get_type_alignment_bytes(ir_element_type);
static ir_type *create_bitfield_type(bitfield_type_t *const type)
{
- type_t *base = skip_typeref(type->base);
+ type_t *base = skip_typeref(type->base_type);
assert(base->kind == TYPE_ATOMIC);
ir_type *irbase = get_ir_type(base);
} else {
id = unique_ident("__anonymous_struct");
}
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
+ dbg_info *dbgi = get_dbg_info(&type->base.source_position);
irtype = new_d_type_struct(id, dbgi);
declaration->v.irtype = irtype;
- type->type.firm_type = irtype;
+ type->base.firm_type = irtype;
} else {
offset = *outer_offset;
align_all = *outer_align;
ir_type *base_irtype;
if(entry_type->kind == TYPE_BITFIELD) {
- base_irtype = get_ir_type(entry_type->bitfield.base);
+ base_irtype = get_ir_type(entry_type->bitfield.base_type);
} else {
base_irtype = get_ir_type(entry_type);
}
} else {
id = unique_ident("__anonymous_union");
}
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
+ dbg_info *dbgi = get_dbg_info(&type->base.source_position);
irtype = new_d_type_union(id, dbgi);
declaration->v.irtype = irtype;
- type->type.firm_type = irtype;
+ type->base.firm_type = irtype;
} else {
offset = *outer_offset;
align_all = *outer_align;
}
- type->type.firm_type = irtype;
+ type->base.firm_type = irtype;
declaration_t *entry = declaration->scope.declarations;
for( ; entry != NULL; entry = entry->next) {
static ir_type *create_enum_type(enum_type_t *const type)
{
- type->type.firm_type = ir_type_int;
+ type->base.firm_type = ir_type_int;
ir_mode *const mode = mode_int;
tarval *const one = get_mode_one(mode);
assert(select->kind == EXPR_SELECT);
type_t *type = select->base.type;
assert(type->kind == TYPE_BITFIELD);
- ir_mode *mode = get_ir_mode(type->bitfield.base);
+ ir_mode *mode = get_ir_mode(type->bitfield.base_type);
ir_node *addr = expression_to_addr(select);
assert(get_irn_mode(value) == mode);
type_t *type = select->base.type;
assert(type->kind == TYPE_BITFIELD);
- ir_mode *mode = get_ir_mode(type->bitfield.base);
+ ir_mode *mode = get_ir_mode(type->bitfield.base_type);
dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
ir_node *addr = expression_to_addr(select);
ir_node *mem = get_store();
ir_type_int = get_ir_type(type_int);
ir_type_const_char = get_ir_type(type_const_char);
ir_type_wchar_t = get_ir_type(type_wchar_t);
- ir_type_void = get_ir_type(type_int); /* we don't have a real void
- type in firm */
-
- type_void->base.firm_type = ir_type_void;
+ ir_type_void = get_ir_type(type_void);
}
void exit_ast2firm(void)
end_of_wide_char_constant:;
size_t size = (size_t) obstack_object_size(&symbol_obstack);
+ assert(size % sizeof(wchar_rep_t) == 0);
+ size /= sizeof(wchar_rep_t);
+
const wchar_rep_t *string = obstack_finish(&symbol_obstack);
lexer_token.type = T_WIDE_CHARACTER_CONSTANT;
#define ELSE_CODE(code) \
default: \
- code; \
+ code \
} \
} /* end of while(1) */ \
break;
const char *dumpfunction = NULL;
compile_mode_t mode = CompileAssembleLink;
int opt_level = 1;
- int result = EXIT_SUCCESS;
+ int result = EXIT_SUCCESS;
obstack_init(&cppflags_obst);
obstack_init(&ldflags_obst);
static type_t *type_valist;
-static statement_t *parse_compound_statement(void);
+static statement_t *parse_compound_statement(bool inside_expression_statement);
static statement_t *parse_statement(void);
static expression_t *parse_sub_expression(unsigned precedence);
}
/**
- * eat all token until a ';' is reached
- * or a stop token is found.
+ * eat all token until a ';' is reached or a stop token is found.
*/
static void eat_statement(void) {
eat_until_matching_token(';');
/**
* Report a parse error because an expected token was not found.
*/
-static void parse_error_expected(const char *message, ...)
+static __attribute__((sentinel))
+void parse_error_expected(const char *message, ...)
{
if(message != NULL) {
errorf(HERE, "%s", message);
static void type_error_incompatible(const char *msg,
const source_position_t *source_position, type_t *type1, type_t *type2)
{
- errorf(source_position, "%s, incompatible types: '%T' - '%T'", msg, type1, type2);
+ errorf(source_position, "%s, incompatible types: '%T' - '%T'",
+ msg, type1, type2);
}
/**
* If not, generate an error, eat the current statement,
* and goto the end_error label.
*/
-#define expect(expected) \
- do { \
- if(UNLIKELY(token.type != (expected))) { \
- parse_error_expected(NULL, (expected), 0); \
- add_anchor_token(expected); \
- eat_until_anchor(); \
- rem_anchor_token(expected); \
- goto end_error; \
- } \
- next_token(); \
+#define expect(expected) \
+ do { \
+ if(UNLIKELY(token.type != (expected))) { \
+ parse_error_expected(NULL, (expected), NULL); \
+ add_anchor_token(expected); \
+ eat_until_anchor(); \
+ rem_anchor_token(expected); \
+ goto end_error; \
+ } \
+ next_token(); \
} while(0)
static void set_scope(scope_t *new_scope)
static int get_rank(const type_t *type)
{
assert(!is_typeref(type));
- /* The C-standard allows promoting to int or unsigned int (see § 7.2.2
+ /* The C-standard allows promoting enums to int or unsigned int (see § 7.2.2
* and esp. footnote 108). However we can't fold constants (yet), so we
* can't decide whether unsigned int is possible, while int always works.
* (unsigned int would be preferable when possible... for stuff like
static type_t *promote_integer(type_t *type)
{
if(type->kind == TYPE_BITFIELD)
- type = type->bitfield.base;
+ type = type->bitfield.base_type;
if(get_rank(type) < ATOMIC_TYPE_INT)
type = type_int;
expression_t *result = parse_sub_expression(7);
if(!is_constant_expression(result)) {
- errorf(&result->base.source_position, "expression '%E' is not constant\n", result);
+ errorf(&result->base.source_position,
+ "expression '%E' is not constant\n", result);
}
return result;
*/
static gnu_attribute_t *allocate_gnu_attribute(gnu_attribute_kind_t kind) {
gnu_attribute_t *attribute = obstack_alloc(&temp_obst, sizeof(*attribute));
- attribute->kind = kind;
- attribute->next = NULL;
- attribute->invalid = false;
- attribute->have_arguments = false;
+ attribute->kind = kind;
+ attribute->next = NULL;
+ attribute->invalid = false;
+ attribute->have_arguments = false;
+
+ return attribute;
return attribute;
}
/**
* parse one string literal argument.
*/
-static void parse_gnu_attribute_string_arg(gnu_attribute_t *attribute, string_t *string) {
+static void parse_gnu_attribute_string_arg(gnu_attribute_t *attribute,
+ string_t *string)
+{
add_anchor_token('(');
if(token.type != T_STRING_LITERAL) {
- parse_error_expected("while parsing attribute directive", T_STRING_LITERAL, 0);
+ parse_error_expected("while parsing attribute directive",
+ T_STRING_LITERAL, NULL);
goto end_error;
}
*string = parse_string_literals();
int i;
if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing format attribute directive", T_IDENTIFIER, 0);
+ parse_error_expected("while parsing format attribute directive", T_IDENTIFIER, NULL);
goto end_error;
}
const char *name = token.v.symbol->string;
/* __attribute__((cdecl)), WITH ms mode */
name = "cdecl";
} else if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing GNU attribute", T_IDENTIFIER, 0);
+ parse_error_expected("while parsing GNU attribute", T_IDENTIFIER, NULL);
break;
}
const symbol_t *sym = token.v.symbol;
expect('(');
if(token.type != T_STRING_LITERAL) {
parse_error_expected("while parsing assembler attribute",
- T_STRING_LITERAL, 0);
+ T_STRING_LITERAL, NULL);
eat_until_matching_token('(');
break;
} else {
next_token();
if(token.type != T_IDENTIFIER) {
parse_error_expected("while parsing designator",
- T_IDENTIFIER, 0);
+ T_IDENTIFIER, NULL);
return NULL;
}
designator->symbol = token.v.symbol;
} else if(token.type != '{') {
if(is_struct) {
parse_error_expected("while parsing struct type specifier",
- T_IDENTIFIER, '{', 0);
+ T_IDENTIFIER, '{', NULL);
} else {
parse_error_expected("while parsing union type specifier",
- T_IDENTIFIER, '{', 0);
+ T_IDENTIFIER, '{', NULL);
}
return NULL;
add_anchor_token('}');
do {
if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing enum entry", T_IDENTIFIER, 0);
+ parse_error_expected("while parsing enum entry", T_IDENTIFIER, NULL);
eat_block();
rem_anchor_token('}');
return;
declaration = get_declaration(symbol, NAMESPACE_ENUM);
} else if(token.type != '{') {
parse_error_expected("while parsing enum type specifier",
- T_IDENTIFIER, '{', 0);
+ T_IDENTIFIER, '{', NULL);
return NULL;
} else {
declaration = NULL;
default:
if(may_be_abstract)
break;
- parse_error_expected("while parsing declarator", T_IDENTIFIER, '(', 0);
+ parse_error_expected("while parsing declarator", T_IDENTIFIER, '(', NULL);
/* avoid a loop in the outermost scope, because eat_statement doesn't
* eat '}' */
if(token.type == '}' && current_function == NULL) {
parse_kr_declaration_list(ndeclaration);
if(token.type != '{') {
- parse_error_expected("while parsing function definition", '{', 0);
+ parse_error_expected("while parsing function definition", '{', NULL);
eat_until_matching_token(';');
return;
}
declaration_t *old_current_function = current_function;
current_function = declaration;
- declaration->init.statement = parse_compound_statement();
+ declaration->init.statement = parse_compound_statement(false);
first_err = true;
check_labels();
check_declarations();
environment_pop_to(top);
}
-static type_t *make_bitfield_type(type_t *base, expression_t *size,
+static type_t *make_bitfield_type(type_t *base_type, expression_t *size,
source_position_t *source_position)
{
- type_t *type = allocate_type_zero(TYPE_BITFIELD, source_position);
- type->bitfield.base = base;
- type->bitfield.size = size;
+ type_t *type = allocate_type_zero(TYPE_BITFIELD, source_position);
+
+ type->bitfield.base_type = base_type;
+ type->bitfield.size = size;
return type;
}
if(is_type_array(type)) {
array_type_t *array_type = &type->array;
type_t *element_type = array_type->element_type;
- unsigned qualifiers = array_type->type.qualifiers;
+ unsigned qualifiers = array_type->base.qualifiers;
return make_pointer_type(element_type, qualifiers);
}
{
expression_t *expression = allocate_expression_zero(EXPR_STATEMENT);
- statement_t *statement = parse_compound_statement();
+ statement_t *statement = parse_compound_statement(true);
expression->statement.statement = statement;
expression->base.source_position = statement->base.source_position;
if(token.type != T_IDENTIFIER) {
parse_error_expected("while parsing member designator",
- T_IDENTIFIER, 0);
+ T_IDENTIFIER, NULL);
return NULL;
}
result->symbol = token.v.symbol;
next_token();
if(token.type != T_IDENTIFIER) {
parse_error_expected("while parsing member designator",
- T_IDENTIFIER, 0);
+ T_IDENTIFIER, NULL);
return NULL;
}
designator_t *designator = allocate_ast_zero(sizeof(result[0]));
rem_anchor_token(']');
if(token.type != ']') {
- parse_error_expected("Problem while parsing array access", ']', 0);
+ parse_error_expected("Problem while parsing array access", ']', NULL);
return expression;
}
next_token();
select->select.compound = compound;
if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing select", T_IDENTIFIER, 0);
+ parse_error_expected("while parsing select", T_IDENTIFIER, NULL);
return select;
}
symbol_t *symbol = token.v.symbol;
expression_t *extract
= allocate_expression_zero(EXPR_UNARY_BITFIELD_EXTRACT);
extract->unary.value = select;
- extract->base.type = expression_type->bitfield.base;
+ extract->base.type = expression_type->bitfield.base_type;
return extract;
}
/* TODO non-arithmetic types */
if(is_type_arithmetic(type_left) && is_type_arithmetic(type_right)) {
+ /* test for signed vs unsigned compares */
if (warning.sign_compare &&
(expression->base.kind != EXPR_BINARY_EQUAL &&
expression->base.kind != EXPR_BINARY_NOTEQUAL) &&
(is_type_signed(type_left) != is_type_signed(type_right))) {
+
+ /* check if 1 of the operands is a constant, in this case we just
+ * check wether we can safely represent the resulting constant in
+ * the type of the other operand. */
+ expression_t *const_expr = NULL;
+ expression_t *other_expr = NULL;
+
+ if(is_constant_expression(left)) {
+ const_expr = left;
+ other_expr = right;
+ } else if(is_constant_expression(right)) {
+ const_expr = right;
+ other_expr = left;
+ }
+
+ type_t *other_type = skip_typeref(other_expr->base.type);
+ if(const_expr != NULL) {
+ long val = fold_constant(const_expr);
+ /* TODO: check if val can be represented by other_type */
+ (void) other_type;
+ (void) val;
+ }
warningf(&expression->base.source_position,
"comparison between signed and unsigned");
}
eat('[');
if(token.type != T_IDENTIFIER) {
parse_error_expected("while parsing asm constraint",
- T_IDENTIFIER, 0);
+ T_IDENTIFIER, NULL);
return NULL;
}
constraint->symbol = token.v.symbol;
eat(T_goto);
if(token.type != T_IDENTIFIER) {
- parse_error_expected("while parsing goto", T_IDENTIFIER, 0);
+ parse_error_expected("while parsing goto", T_IDENTIFIER, NULL);
eat_statement();
return NULL;
}
expression_t *const expr = parse_expression();
statement->expression.expression = expr;
- if (warning.unused_value && !expression_has_effect(expr)) {
- warningf(&expr->base.source_position, "statement has no effect");
- }
-
expect(';');
return statement;
ms_try_statement_t *rem = current_try;
current_try = &statement->ms_try;
- statement->ms_try.try_statement = parse_compound_statement();
+ statement->ms_try.try_statement = parse_compound_statement(false);
current_try = rem;
if(token.type == T___except) {
statement->ms_try.except_expression = create_implicit_cast(expr, type);
rem_anchor_token(')');
expect(')');
- statement->ms_try.final_statement = parse_compound_statement();
+ statement->ms_try.final_statement = parse_compound_statement(false);
} else if(token.type == T__finally) {
eat(T___finally);
- statement->ms_try.final_statement = parse_compound_statement();
+ statement->ms_try.final_statement = parse_compound_statement(false);
} else {
- parse_error_expected("while parsing __try statement", T___except, T___finally, 0);
+ parse_error_expected("while parsing __try statement", T___except, T___finally, NULL);
return create_invalid_statement();
}
return statement;
/**
* Parse a statement.
+ * There's also parse_statement() which additionally checks for
+ * "statement has no effect" warnings
*/
-static statement_t *parse_statement(void)
+static statement_t *intern_parse_statement(void)
{
- statement_t *statement = NULL;
+ statement_t *statement = NULL;
/* declaration or statement */
add_anchor_token(';');
break;
case '{':
- statement = parse_compound_statement();
+ statement = parse_compound_statement(false);
break;
case T_if:
return statement;
}
+/**
+ * parse a statement and emits "statement has no effect" warning if needed
+ * (This is really a wrapper around intern_parse_statement with check for 1
+ * single warning. It is needed, because for statement expressions we have
+ * to avoid the warning on the last statement)
+ */
+static statement_t *parse_statement(void)
+{
+ statement_t *statement = intern_parse_statement();
+
+ if(statement->kind == STATEMENT_EXPRESSION && warning.unused_value) {
+ expression_t *expression = statement->expression.expression;
+ if(!expression_has_effect(expression)) {
+ warningf(&expression->base.source_position,
+ "statement has no effect");
+ }
+ }
+
+ return statement;
+}
+
/**
* Parse a compound statement.
*/
-static statement_t *parse_compound_statement(void)
+static statement_t *parse_compound_statement(bool inside_expression_statement)
{
statement_t *statement = allocate_statement_zero(STATEMENT_COMPOUND);
statement_t *last_statement = NULL;
while(token.type != '}' && token.type != T_EOF) {
- statement_t *sub_statement = parse_statement();
+ statement_t *sub_statement = intern_parse_statement();
if(is_invalid_statement(sub_statement)) {
/* an error occurred. if we are at an anchor, return */
if(at_anchor())
"end of file while looking for closing '}'");
}
+ /* look over all statements again to produce no effect warnings */
+ if(warning.unused_value) {
+ statement_t *sub_statement = statement->compound.statements;
+ for( ; sub_statement != NULL; sub_statement = sub_statement->base.next) {
+ if(sub_statement->kind != STATEMENT_EXPRESSION)
+ continue;
+ /* don't emit a warning for the last expression in an expression
+ * statement as it has always an effect */
+ if(inside_expression_statement && sub_statement->base.next == NULL)
+ continue;
+
+ expression_t *expression = sub_statement->expression.expression;
+ if(!expression_has_effect(expression)) {
+ warningf(&expression->base.source_position,
+ "statement has no effect");
+ }
+ }
+ }
+
end_error:
rem_anchor_token('}');
assert(scope == &statement->compound.scope);
source_position_t source_position;
pp_definition_t *parent_expansion;
size_t expand_pos;
+ bool is_variadic;
+ size_t argument_count;
+ token_t *arguments;
size_t list_len;
- token_t replacement_list[];
+ token_t *replacement_list;
};
struct symbol_t {
[ATOMIC_TYPE_FLOAT] = {
.size = 4,
.alignment = 4,
- .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
+ .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC
| ATOMIC_TYPE_FLAG_SIGNED,
},
[ATOMIC_TYPE_DOUBLE] = {
.size = 8,
.alignment = 8,
- .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
+ .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC
| ATOMIC_TYPE_FLAG_SIGNED,
},
[ATOMIC_TYPE_LONG_DOUBLE] = {
.size = 12,
.alignment = 12,
- .flags = ATOMIC_TYPE_FLAG_INTEGER | ATOMIC_TYPE_FLAG_ARITHMETIC
+ .flags = ATOMIC_TYPE_FLAG_FLOAT | ATOMIC_TYPE_FLAG_ARITHMETIC
| ATOMIC_TYPE_FLAG_SIGNED,
},
/* complex and imaginary types are set in init_types */
static
void print_atomic_type(const atomic_type_t *type)
{
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
const char *s = "INVALIDATOMIC";
switch((atomic_type_kind_t) type->akind) {
*/
static void print_function_type_pre(const function_type_t *type, bool top)
{
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
intern_print_type_pre(type->return_type, false);
{
intern_print_type_pre(type->points_to, false);
fputs("*", out);
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
}
/**
if(type->is_static) {
fputs("static ", out);
}
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
if(type->size_expression != NULL
&& (print_implicit_array_size || !type->has_implicit_size)) {
print_expression(type->size_expression);
{
fputs(" : ", out);
print_expression(type->size);
- intern_print_type_post(type->base, false);
+ intern_print_type_post(type->base_type, false);
}
/**
*/
static void print_type_enum(const enum_type_t *type)
{
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
fputs("enum ", out);
declaration_t *declaration = type->declaration;
*/
static void print_compound_type(const compound_type_t *type)
{
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
- if(type->type.kind == TYPE_COMPOUND_STRUCT) {
+ if(type->base.kind == TYPE_COMPOUND_STRUCT) {
fputs("struct ", out);
} else {
- assert(type->type.kind == TYPE_COMPOUND_UNION);
+ assert(type->base.kind == TYPE_COMPOUND_UNION);
fputs("union ", out);
}
*/
static void print_typedef_type_pre(const typedef_type_t *const type)
{
- print_type_qualifiers(type->type.qualifiers);
+ print_type_qualifiers(type->base.qualifiers);
fputs(type->declaration->symbol->string, out);
}
print_pointer_type_pre(&type->pointer);
return;
case TYPE_BITFIELD:
- intern_print_type_pre(type->bitfield.base, top);
+ intern_print_type_pre(type->bitfield.base_type, top);
return;
case TYPE_ARRAY:
print_array_type_pre(&type->array);
return atomic_type_properties[kind].flags;
}
+atomic_type_kind_t get_intptr_kind(void)
+{
+ if(machine_size <= 32)
+ return ATOMIC_TYPE_INT;
+ else if(machine_size <= 64)
+ return ATOMIC_TYPE_LONG;
+ else
+ return ATOMIC_TYPE_LONGLONG;
+}
+
+atomic_type_kind_t get_uintptr_kind(void)
+{
+ if(machine_size <= 32)
+ return ATOMIC_TYPE_UINT;
+ else if(machine_size <= 64)
+ return ATOMIC_TYPE_ULONG;
+ else
+ return ATOMIC_TYPE_ULONGLONG;
+}
+
/**
* Find the atomic type kind representing a given size (signed).
*/
*/
unsigned get_atomic_type_flags(atomic_type_kind_t kind);
+atomic_type_kind_t get_intptr_kind(void);
+atomic_type_kind_t get_uintptr_kind(void);
+
/**
* Find the atomic type kind representing a given size (signed).
*/
static unsigned hash_bitfield_type(const bitfield_type_t *type)
{
- unsigned result = hash_ptr(type->base);
+ unsigned result = hash_ptr(type->base_type);
result ^= 27172145;
return result;
static bool bitfield_types_equal(const bitfield_type_t *type1,
const bitfield_type_t *type2)
{
- if(type1->base != type2->base)
+ if(type1->base_type != type2->base_type)
return false;
/* TODO: compare size expression */
return false;
};
struct atomic_type_t {
- type_base_t type;
+ type_base_t base;
atomic_type_kind_t akind;
};
struct builtin_type_t {
- type_base_t type;
+ type_base_t base;
symbol_t *symbol;
type_t *real_type;
};
struct pointer_type_t {
- type_base_t type;
+ type_base_t base;
type_t *points_to;
};
struct array_type_t {
- type_base_t type;
+ type_base_t base;
type_t *element_type;
expression_t *size_expression;
size_t size;
};
struct function_type_t {
- type_base_t type;
+ type_base_t base;
type_t *return_type;
function_parameter_t *parameters;
unsigned variadic : 1;
};
struct compound_type_t {
- type_base_t type;
+ type_base_t base;
/** the declaration of the compound type, the scope of the declaration
* contains the compound entries. */
declaration_t *declaration;
};
struct enum_type_t {
- type_base_t type;
+ type_base_t base;
/** the declaration of the enum type. You can find the enum entries by
* walking the declaration->next list until you don't find
* STORAGE_CLASS_ENUM_ENTRY declarations anymore */
};
struct typedef_type_t {
- type_base_t type;
+ type_base_t base;
declaration_t *declaration;
type_t *resolved_type;
};
struct typeof_type_t {
- type_base_t type;
+ type_base_t base;
expression_t *expression;
type_t *typeof_type;
type_t *resolved_type;
};
struct bitfield_type_t {
- type_base_t type;
- type_t *base;
+ type_base_t base;
+ type_t *base_type;
expression_t *size;
};