- make use of new atomic_type_properties in ast2firm
authorMatthias Braun <matze@braunis.de>
Sat, 22 Mar 2008 11:42:19 +0000 (11:42 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 22 Mar 2008 11:42:19 +0000 (11:42 +0000)
- rename base struct member from type to base in all types
- code cleanup

[r19007]

ast2firm.c
lexer.c
main.c
parser.c
symbol_t.h
type.c
type.h
type_hash.c
type_t.h

index be92bc3..aa98938 100644 (file)
@@ -123,150 +123,79 @@ static ident *unique_ident(const char *tag)
        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)
@@ -352,22 +281,19 @@ static unsigned count_parameters(const function_type_t *function_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;
 }
@@ -379,7 +305,7 @@ static ir_type *create_method_type(const function_type_t *function_type)
        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) {
@@ -410,10 +336,10 @@ static ir_type *create_pointer_type(pointer_type_t *type)
         * 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);
@@ -427,7 +353,7 @@ static ir_type *create_array_type(array_type_t *type)
        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);
@@ -524,7 +450,7 @@ static ir_type *get_unsigned_int_type_for_bit_size(ir_type *base_tp,
 
 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);
 
@@ -562,12 +488,12 @@ static ir_type *create_struct_type(compound_type_t *type, ir_type *irtype,
                } 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;
@@ -601,7 +527,7 @@ static ir_type *create_struct_type(compound_type_t *type, ir_type *irtype,
 
                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);
                }
@@ -697,18 +623,18 @@ static ir_type *create_union_type(compound_type_t *type, ir_type *irtype,
                } 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) {
@@ -791,7 +717,7 @@ static ir_type *create_union_type(compound_type_t *type, ir_type *irtype,
 
 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);
@@ -1532,7 +1458,7 @@ static void bitfield_store_to_firm(const unary_expression_t *expression,
        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);
@@ -1785,7 +1711,7 @@ static ir_node *bitfield_extract_to_firm(const unary_expression_t *expression)
 
        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();
@@ -4834,10 +4760,7 @@ static void init_ir_types(void)
        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)
diff --git a/lexer.c b/lexer.c
index 990d285..cba071b 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -957,6 +957,9 @@ static void parse_wide_character_constant(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;
@@ -1373,7 +1376,7 @@ static void parse_preprocessor_directive(void)
 
 #define ELSE_CODE(code)                                    \
                                default:                                   \
-                                       code;                                  \
+                                       code                                   \
                                }                                          \
                        } /* end of while(1) */                        \
                        break;
diff --git a/main.c b/main.c
index 65ec298..25564fb 100644 (file)
--- a/main.c
+++ b/main.c
@@ -362,7 +362,7 @@ int main(int argc, char **argv)
        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);
index 1678418..e2808b0 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -136,7 +136,7 @@ static unsigned char token_anchor_set[T_LAST_TOKEN];
 
 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);
@@ -567,8 +567,7 @@ static void eat_block(void) {
 }
 
 /**
- * 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(';');
@@ -581,7 +580,8 @@ static void eat_statement(void) {
 /**
  * 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);
@@ -607,7 +607,8 @@ static void type_error(const char *msg, const source_position_t *source_position
 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);
 }
 
 /**
@@ -615,16 +616,16 @@ static void type_error_incompatible(const char *msg,
  * 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)
@@ -771,7 +772,7 @@ static void label_pop_to(size_t new_top)
 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
@@ -786,7 +787,7 @@ static int get_rank(const type_t *type)
 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;
@@ -933,7 +934,8 @@ static expression_t *parse_constant_expression(void)
        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;
@@ -1068,10 +1070,12 @@ static int strcmp_underscore(const char *s1, const char *s2) {
  */
 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;
 }
 
@@ -1115,10 +1119,13 @@ end_error:
 /**
  * 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();
@@ -1238,7 +1245,7 @@ static void parse_gnu_attribute_format_args(gnu_attribute_t *attribute) {
        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;
@@ -1373,7 +1380,7 @@ static void parse_gnu_attribute(gnu_attribute_t **attributes)
                                /* __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;
@@ -1577,7 +1584,7 @@ static void parse_attributes(gnu_attribute_t **attributes)
                        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 {
@@ -1618,7 +1625,7 @@ static designator_t *parse_designation(void)
                        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;
@@ -2389,10 +2396,10 @@ static declaration_t *parse_compound_type_specifier(bool is_struct)
        } 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;
@@ -2440,7 +2447,7 @@ static void parse_enum_entries(type_t *const enum_type)
        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;
@@ -2491,7 +2498,7 @@ static type_t *parse_enum_specifier(void)
                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;
@@ -3479,7 +3486,7 @@ static construct_type_t *parse_inner_declarator(declaration_t *declaration,
        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) {
@@ -4282,7 +4289,7 @@ static void parse_external_declaration(void)
        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;
        }
@@ -4345,7 +4352,7 @@ static void parse_external_declaration(void)
                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();
@@ -4361,12 +4368,13 @@ end_of_parse_external_declaration:
        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;
 }
@@ -4785,7 +4793,7 @@ static type_t *automatic_type_conversion(type_t *orig_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);
        }
@@ -4968,7 +4976,7 @@ static expression_t *parse_statement_expression(void)
 {
        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;
 
@@ -5093,7 +5101,7 @@ static designator_t *parse_designator(void)
 
        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;
@@ -5105,7 +5113,7 @@ static designator_t *parse_designator(void)
                        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]));
@@ -5544,7 +5552,7 @@ static expression_t *parse_array_expression(unsigned precedence,
 
        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();
@@ -5604,7 +5612,7 @@ static expression_t *parse_select_expression(unsigned precedence,
        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;
@@ -5660,7 +5668,7 @@ static expression_t *parse_select_expression(unsigned precedence,
                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;
        }
@@ -6259,10 +6267,33 @@ static void semantic_comparison(binary_expression_t *expression)
 
        /* 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");
                }
@@ -6825,7 +6856,7 @@ static asm_constraint_t *parse_asm_constraints(void)
                        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;
@@ -7323,7 +7354,7 @@ static statement_t *parse_goto(void)
        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;
        }
@@ -7571,10 +7602,6 @@ static statement_t *parse_expression_statement(void)
        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;
@@ -7594,7 +7621,7 @@ static statement_t *parse_ms_try_statment(void) {
 
        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) {
@@ -7613,12 +7640,12 @@ static statement_t *parse_ms_try_statment(void) {
                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;
@@ -7628,10 +7655,12 @@ end_error:
 
 /**
  * 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(';');
@@ -7649,7 +7678,7 @@ static statement_t *parse_statement(void)
                break;
 
        case '{':
-               statement = parse_compound_statement();
+               statement = parse_compound_statement(false);
                break;
 
        case T_if:
@@ -7743,10 +7772,31 @@ static statement_t *parse_statement(void)
        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);
 
@@ -7762,7 +7812,7 @@ static statement_t *parse_compound_statement(void)
        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())
@@ -7789,6 +7839,25 @@ static statement_t *parse_compound_statement(void)
                       "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);
index df2f226..1fe4054 100644 (file)
@@ -30,8 +30,11 @@ struct pp_definition_t {
        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 {
diff --git a/type.c b/type.c
index 3257dc5..aac602a 100644 (file)
--- a/type.c
+++ b/type.c
@@ -120,19 +120,19 @@ static atomic_type_properties_t atomic_type_properties[ATOMIC_TYPE_LAST+1] = {
        [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 */
@@ -221,7 +221,7 @@ void print_type_qualifiers(type_qualifiers_t qualifiers)
 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) {
@@ -260,7 +260,7 @@ void print_atomic_type(const atomic_type_t *type)
  */
 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);
 
@@ -331,7 +331,7 @@ static void print_pointer_type_pre(const pointer_type_t *type)
 {
        intern_print_type_pre(type->points_to, false);
        fputs("*", out);
-       print_type_qualifiers(type->type.qualifiers);
+       print_type_qualifiers(type->base.qualifiers);
 }
 
 /**
@@ -365,7 +365,7 @@ static void print_array_type_post(const array_type_t *type)
        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);
@@ -383,7 +383,7 @@ static void print_bitfield_type_post(const bitfield_type_t *type)
 {
        fputs(" : ", out);
        print_expression(type->size);
-       intern_print_type_post(type->base, false);
+       intern_print_type_post(type->base_type, false);
 }
 
 /**
@@ -428,7 +428,7 @@ void print_enum_definition(const declaration_t *declaration)
  */
 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;
@@ -469,12 +469,12 @@ void print_compound_definition(const declaration_t *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);
        }
 
@@ -494,7 +494,7 @@ static void print_compound_type(const compound_type_t *type)
  */
 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);
 }
 
@@ -549,7 +549,7 @@ static void intern_print_type_pre(const type_t *const type, const bool top)
                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);
@@ -1048,6 +1048,26 @@ unsigned get_atomic_type_flags(atomic_type_kind_t kind)
        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).
  */
diff --git a/type.h b/type.h
index 5d51b88..e9fcb5e 100644 (file)
--- a/type.h
+++ b/type.h
@@ -158,6 +158,9 @@ unsigned get_atomic_type_alignment(atomic_type_kind_t kind);
  */
 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).
  */
index 03b9f02..8ec4171 100644 (file)
@@ -98,7 +98,7 @@ static unsigned hash_typeof_type(const typeof_type_t *type)
 
 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;
@@ -251,7 +251,7 @@ static bool typeof_types_equal(const typeof_type_t *type1,
 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;
index 2824b96..3536fad 100644 (file)
--- a/type_t.h
+++ b/type_t.h
@@ -74,23 +74,23 @@ struct type_base_t {
 };
 
 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;
@@ -110,7 +110,7 @@ struct function_parameter_t {
 };
 
 struct function_type_t {
-       type_base_t           type;
+       type_base_t           base;
        type_t               *return_type;
        function_parameter_t *parameters;
        unsigned              variadic : 1;
@@ -119,14 +119,14 @@ struct function_type_t {
 };
 
 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 */
@@ -134,21 +134,21 @@ struct enum_type_t {
 };
 
 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;
 };