Commit e29cdea8 authored by Sergio Costas's avatar Sergio Costas

Added support for designated initializers in structs (both C99 standard and GNU GCC extension)

parent 46738be9
......@@ -58,18 +58,14 @@ class crust(object):
def copy(self):
retval = crust.AST_node()
for element in dir(self):
if element.startswith("_"):
continue
for element in self.__dict__:
setattr(retval, element, getattr(self, element))
return retval
def __str__(self):
first = True
salida = ""
for element in dir(self):
if element.startswith("_"):
continue
for element in self.__dict__:
if not first:
salida += ", "
first = False
......
......@@ -686,25 +686,39 @@ initializer
initializer_list
: initializer { $$ = $1; }
| designation initializer { $$ = $1; show_error(__LINE__, $$); }
| IDENTIFIER ':' initializer { $$ = $1;
$$->child1 = $3;
free_tree($2); }
| designation initializer { $$ = $1;
// initializer for designated initializer in struct
$$->child2 = $2; }
| initializer_list ',' initializer { $$ = $1;
append_right($$,$3);
free_tree($2); }
| initializer_list ',' designation initializer { $$ = $1; show_error(__LINE__, $$); }
| initializer_list ',' IDENTIFIER ':' initializer { $$ = $1;
append_right($$,$3);
$3->child1 = $5;
free_tree($2);
free_tree($4); }
| initializer_list ',' designation initializer { $$ = $1;
append_right($$, $3);
$3->child2 = $4;
free_tree($2); }
;
designation
: designator_list '=' { $$ = $1; show_error(__LINE__, $$); }
: designator_list '=' { $$ = $2; /* assignment of designated initializer in struct */
$$->child1 = $1; }
;
designator_list
: designator { $$ = $1; show_error(__LINE__, $$); }
: designator { $$ = $1; }
| designator_list designator { $$ = $1; show_error(__LINE__, $$); }
;
designator
: '[' constant_expression ']' { $$ = $1; show_error(__LINE__, $$); }
| '.' IDENTIFIER { $$ = $1; show_error(__LINE__, $$); }
| '.' IDENTIFIER { $$ = $1; /* For designated initializers in structs */ }
;
statement
......
......@@ -704,6 +704,9 @@ class Test(unittest.TestCase):
def test144CheckSignatures(self):
self._generic_test("unitest/test144.c", [ (crust.crust.MSG_CRITICAL, "Function definition for '{:s}' at line {:d}, file '{:s}' differs from definition at line {:d}, file '{:s}'", "main", 7, "unitest/test144.c", 5, "unitest/test144.c") ])
def test145TestStructInitializationWithFieldNames(self):
self._all_fine_test("unitest/test145.c")
if __name__ == '__main__':
try:
os.remove("error_list.txt")
......
int a; // just to ensure that variables with the same name than a field doesn't interfere
struct {int a; char b;} name1 = { a:5, b:8}; // must support this definition format
struct {int a; char b;} name2 = { .a = 5, .b = 8}; // must support this definition format too
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment