implement array intiailizers
authorMatthias Braun <matze@braunis.de>
Tue, 20 Nov 2007 21:25:18 +0000 (21:25 +0000)
committerMatthias Braun <matze@braunis.de>
Tue, 20 Nov 2007 21:25:18 +0000 (21:25 +0000)
[r18500]

ast2firm.c
ast_t.h
parser.c
type.c
type_t.h

index f7d715a..721c92d 100644 (file)
@@ -1419,9 +1419,6 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
                                case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
                                        tc = complex_type_class;
                                        break;
-#endif
-
-#ifdef PROVIDE_IMAGINARY
                                case ATOMIC_TYPE_FLOAT_IMAGINARY:
                                case ATOMIC_TYPE_DOUBLE_IMAGINARY:
                                case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
@@ -1962,8 +1959,8 @@ static void create_initializer_compound(initializer_list_t *initializer,
        declaration_t *compound_entry = compound_declaration->context.declarations;
 
        compound_graph_path_entry_t entry;
-       entry.type     = COMPOUND_GRAPH_ENTRY_COMPOUND;
-       entry.prev     = last_entry;
+       entry.type = COMPOUND_GRAPH_ENTRY_COMPOUND;
+       entry.prev = last_entry;
        ++len;
 
        size_t i = 0;
@@ -1997,12 +1994,41 @@ static void create_initializer_compound(initializer_list_t *initializer,
        }
 }
 
+static void create_initializer_array(initializer_list_t *initializer,
+                                     array_type_t *type, ir_entity *entity,
+                                     compound_graph_path_entry_t *last_entry,
+                                     int len)
+{
+       type_t *element_type = type->element_type;
+
+       compound_graph_path_entry_t entry;
+       entry.type = COMPOUND_GRAPH_ENTRY_ARRAY;
+       entry.prev = last_entry;
+       ++len;
+
+       for(size_t i = 0; i < initializer->len; ++i) {
+               entry.v.array_index = i;
+
+               initializer_t *sub_initializer = initializer->initializers[i];
+
+               if(sub_initializer->type == INITIALIZER_VALUE) {
+                       create_initializer_value((initializer_value_t*) sub_initializer,
+                                                entity, &entry, len);
+               } else {
+                       assert(sub_initializer->type == INITIALIZER_LIST);
+                       create_initializer_list((initializer_list_t*) sub_initializer,
+                                               element_type, entity, &entry, len);
+               }
+       }
+}
+
 static void create_initializer_list(initializer_list_t *initializer,
                                     type_t *type, ir_entity *entity,
                                     compound_graph_path_entry_t *entry, int len)
 {
        if(type->type == TYPE_ARRAY) {
-               /* TODO */
+               create_initializer_array(initializer, (array_type_t*) type,
+                                        entity, entry, len);
        } else {
                assert(type->type == TYPE_COMPOUND_STRUCT
                                || type->type == TYPE_COMPOUND_UNION);
diff --git a/ast_t.h b/ast_t.h
index ccb2cea..b893982 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -221,7 +221,6 @@ typedef enum {
 
 struct initializer_t {
        initializer_type_t  type;
-       initializer_t      *next;
 };
 
 struct initializer_value_t {
index 3f73c1d..16410fd 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -71,14 +71,10 @@ static type_t       *parse_typename(void);
 #ifdef PROVIDE_COMPLEX
 #define COMPLEX_SPECIFIERS  \
        case T__Complex:
-#else
-#define COMPLEX_SPECIFIERS
-#endif
-
-#ifdef PROVIDE_IMAGINARY
 #define IMAGINARY_SPECIFIERS \
        case T__Imaginary:
 #else
+#define COMPLEX_SPECIFIERS
 #define IMAGINARY_SPECIFIERS
 #endif
 
@@ -980,15 +976,15 @@ static initializer_t *parse_sub_initializer(type_t *type,
        /* TODO: ignore qualifiers, comparing pointers is probably
         * not correct */
        if(expression != NULL && expression_type == type) {
-               initializer_t *result = allocate_ast_zero(sizeof(result[0]));
-               result->type          = INITIALIZER_VALUE;
+               initializer_value_t *result = allocate_ast_zero(sizeof(result[0]));
+               result->initializer.type    = INITIALIZER_VALUE;
 
                if(type != NULL) {
                        semantic_assign(type, &expression, "initializer");
                }
-               //result->v.value = expression;
+               result->value = expression;
 
-               return result;
+               return (initializer_t*) result;
        }
 
        bool read_paren = false;
@@ -998,14 +994,46 @@ static initializer_t *parse_sub_initializer(type_t *type,
        }
 
        /* descend into subtype */
-       initializer_t *result = NULL;
+       initializer_t  *result = NULL;
+       initializer_t **elems;
        if(type->type == TYPE_ARRAY) {
                array_type_t *array_type   = (array_type_t*) type;
                type_t       *element_type = array_type->element_type;
                element_type               = skip_typeref(element_type);
 
-               result
-                       = parse_sub_initializer(element_type, expression, expression_type);
+               initializer_t *sub;
+               had_initializer_brace_warning = false;
+               if(expression == NULL) {
+                       sub = parse_sub_initializer_elem(element_type);
+               } else {
+                       sub = parse_sub_initializer(element_type, expression,
+                                                   expression_type);
+               }
+
+               /* didn't match the subtypes -> try the parent type */
+               if(sub == NULL) {
+                       assert(!read_paren);
+                       return NULL;
+               }
+
+               elems = NEW_ARR_F(initializer_t*, 0);
+               ARR_APP1(initializer_t*, elems, sub);
+
+               while(true) {
+                       if(token.type == '}')
+                               break;
+                       expect_block(',');
+
+                       initializer_t *sub
+                               = parse_sub_initializer(element_type, NULL, NULL);
+                       if(sub == NULL) {
+                               /* TODO error, do nicer cleanup */
+                               parse_error("member initializer didn't match");
+                               DEL_ARR_F(elems);
+                               return NULL;
+                       }
+                       ARR_APP1(initializer_t*, elems, sub);
+               }
        } else {
                assert(type->type == TYPE_COMPOUND_STRUCT
                                || type->type == TYPE_COMPOUND_UNION);
@@ -1032,7 +1060,7 @@ static initializer_t *parse_sub_initializer(type_t *type,
                        return NULL;
                }
 
-               initializer_t **elems = NEW_ARR_F(initializer_t*, 0);
+               elems = NEW_ARR_F(initializer_t*, 0);
                ARR_APP1(initializer_t*, elems, sub);
 
                declaration_t *iter  = first->next;
@@ -1049,7 +1077,6 @@ static initializer_t *parse_sub_initializer(type_t *type,
                        type_t *iter_type = iter->type;
                        iter_type         = skip_typeref(iter_type);
 
-                       /* read next token */
                        initializer_t *sub = parse_sub_initializer(iter_type, NULL, NULL);
                        if(sub == NULL) {
                                /* TODO error, do nicer cleanup*/
@@ -1059,20 +1086,19 @@ static initializer_t *parse_sub_initializer(type_t *type,
                        }
                        ARR_APP1(initializer_t*, elems, sub);
                }
+       }
 
-               int    len        = ARR_LEN(elems);
-               size_t elems_size = sizeof(initializer_t*) * len;
+       int    len        = ARR_LEN(elems);
+       size_t elems_size = sizeof(initializer_t*) * len;
 
-               initializer_list_t *init
-                       = allocate_ast_zero(sizeof(init[0]) + elems_size);
+       initializer_list_t *init = allocate_ast_zero(sizeof(init[0]) + elems_size);
 
-               init->initializer.type = INITIALIZER_LIST;
-               init->len              = len;
-               memcpy(init->initializers, elems, elems_size);
-               DEL_ARR_F(elems);
+       init->initializer.type = INITIALIZER_LIST;
+       init->len              = len;
+       memcpy(init->initializers, elems, elems_size);
+       DEL_ARR_F(elems);
 
-               result = (initializer_t*) init;
-       }
+       result = (initializer_t*) init;
 
        if(read_paren) {
                if(token.type == ',')
@@ -1347,8 +1373,6 @@ typedef enum {
        SPECIFIER_VOID      = 1 << 10,
 #ifdef PROVIDE_COMPLEX
        SPECIFIER_COMPLEX   = 1 << 11,
-#endif
-#ifdef PROVIDE_IMAGINARY
        SPECIFIER_IMAGINARY = 1 << 12,
 #endif
 } specifiers_t;
@@ -1443,8 +1467,6 @@ static void parse_declaration_specifiers(declaration_specifiers_t *specifiers)
                MATCH_SPECIFIER(T__Bool,      SPECIFIER_BOOL,      "_Bool")
 #ifdef PROVIDE_COMPLEX
                MATCH_SPECIFIER(T__Complex,   SPECIFIER_COMPLEX,   "_Complex")
-#endif
-#ifdef PROVIDE_IMAGINARY
                MATCH_SPECIFIER(T__Imaginary, SPECIFIER_IMAGINARY, "_Imaginary")
 #endif
                case T_inline:
@@ -1603,8 +1625,6 @@ finish_specifiers:
                case SPECIFIER_LONG | SPECIFIER_DOUBLE | SPECIFIER_COMPLEX:
                        atomic_type = ATOMIC_TYPE_LONG_DOUBLE_COMPLEX;
                        break;
-#endif
-#ifdef PROVIDE_IMAGINARY
                case SPECIFIER_FLOAT | SPECIFIER_IMAGINARY:
                        atomic_type = ATOMIC_TYPE_FLOAT_IMAGINARY;
                        break;
@@ -1722,7 +1742,7 @@ static declaration_t *parse_parameters(function_type_t *type)
        if(token.type == T_IDENTIFIER) {
                symbol_t      *symbol = token.v.symbol;
                if(!is_typedef_symbol(symbol)) {
-                       /* TODO */
+                       /* TODO: K&R style C parameters */
                        parse_identifier_list();
                        return NULL;
                }
@@ -2118,7 +2138,8 @@ static void parse_init_declarators(const declaration_specifiers_t *specifiers)
                                parser_error_multiple_definition(declaration, ndeclaration);
                        }
 
-                       ndeclaration->init.initializer = parse_initializer(declaration->type);
+                       ndeclaration->init.initializer
+                               = parse_initializer(declaration->type);
                } else if(token.type == '{') {
                        if(declaration->type->type != TYPE_FUNCTION) {
                                parser_print_error_prefix();
diff --git a/type.c b/type.c
index bcc1b25..1276df2 100644 (file)
--- a/type.c
+++ b/type.c
@@ -384,8 +384,6 @@ bool is_type_floating(const type_t *type)
        case ATOMIC_TYPE_FLOAT_COMPLEX:
        case ATOMIC_TYPE_DOUBLE_COMPLEX:
        case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
-#endif
-#ifdef PROVIDE_IMAGINARY
        case ATOMIC_TYPE_FLOAT_IMAGINARY:
        case ATOMIC_TYPE_DOUBLE_IMAGINARY:
        case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
@@ -420,8 +418,6 @@ bool is_type_signed(const type_t *type)
        case ATOMIC_TYPE_FLOAT_COMPLEX:
        case ATOMIC_TYPE_DOUBLE_COMPLEX:
        case ATOMIC_TYPE_LONG_DOUBLE_COMPLEX:
-#endif
-#ifdef PROVIDE_IMAGINARY
        case ATOMIC_TYPE_FLOAT_IMAGINARY:
        case ATOMIC_TYPE_DOUBLE_IMAGINARY:
        case ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY:
index 67a23b9..dd7fcfd 100644 (file)
--- a/type_t.h
+++ b/type_t.h
@@ -51,8 +51,6 @@ typedef enum {
        ATOMIC_TYPE_FLOAT_COMPLEX,
        ATOMIC_TYPE_DOUBLE_COMPLEX,
        ATOMIC_TYPE_LONG_DOUBLE_COMPLEX,
-#endif
-#ifdef PROVIDE_IMAGINARY
        ATOMIC_TYPE_FLOAT_IMAGINARY,
        ATOMIC_TYPE_DOUBLE_IMAGINARY,
        ATOMIC_TYPE_LONG_DOUBLE_IMAGINARY,
@@ -120,7 +118,7 @@ struct compound_type_t {
 struct enum_type_t {
        type_t         type;
        /** the declaration of the enum type. You can find the enum entries by
-        * walking the declaration->context_next list until you don't find
+        * walking the declaration->next list until you don't find
         * STORAGE_CLASS_ENUM_ENTRY declarations anymore */
        declaration_t *declaration;
 };