+static void parse_attributes(void)
+{
+ while(true) {
+ switch(token.type) {
+ case T___attribute__:
+ next_token();
+
+ expect_void('(');
+ int depth = 1;
+ while(depth > 0) {
+ switch(token.type) {
+ case T_EOF:
+ parse_error("EOF while parsing attribute");
+ break;
+ case '(':
+ next_token();
+ depth++;
+ break;
+ case ')':
+ next_token();
+ depth--;
+ break;
+ default:
+ next_token();
+ }
+ }
+ break;
+ case T_asm:
+ next_token();
+ expect_void('(');
+ if(token.type != T_STRING_LITERAL) {
+ parse_error_expected("while parsing assembler attribute",
+ T_STRING_LITERAL);
+ eat_brace();
+ break;
+ } else {
+ parse_string_literals();
+ }
+ expect_void(')');
+ break;
+ default:
+ goto attributes_finished;
+ }
+ }
+
+attributes_finished:
+ ;
+}
+
+static designator_t *parse_designation(void)
+{
+ if(token.type != '[' && token.type != '.')
+ return NULL;
+
+ designator_t *result = NULL;
+ designator_t *last = NULL;
+
+ while(1) {
+ designator_t *designator;
+ switch(token.type) {
+ case '[':
+ designator = allocate_ast_zero(sizeof(designator[0]));
+ next_token();
+ designator->array_access = parse_constant_expression();
+ expect(']');
+ break;
+ case '.':
+ designator = allocate_ast_zero(sizeof(designator[0]));
+ next_token();
+ if(token.type != T_IDENTIFIER) {
+ parse_error_expected("problem while parsing designator",
+ T_IDENTIFIER, 0);
+ return NULL;
+ }
+ designator->symbol = token.v.symbol;
+ next_token();
+ break;
+ default:
+ expect('=');
+ return result;
+ }
+
+ assert(designator != NULL);
+ if(last != NULL) {
+ last->next = designator;
+ } else {
+ result = designator;
+ }
+ last = designator;
+ }
+}
+
+static initializer_t *parse_initializer_list(void);
+
+static initializer_t *parse_initializer(void)
+{
+ designator_t *designator = parse_designation();
+
+ initializer_t *result;
+ if(token.type == '{') {
+ result = parse_initializer_list();
+ } else {
+ result = allocate_ast_zero(sizeof(result[0]));
+ result->type = INITIALIZER_VALUE;
+ result->v.value = parse_assignment_expression();
+ }
+ result->designator = designator;
+
+ return result;
+}
+
+static initializer_t *parse_initializer_list(void)
+{
+ eat('{');
+
+ initializer_t *result = allocate_ast_zero(sizeof(result[0]));
+ result->type = INITIALIZER_LIST;
+
+ initializer_t *last = NULL;
+ while(1) {
+ initializer_t *initializer = parse_initializer();
+ if(last != NULL) {
+ last->next = initializer;
+ } else {
+ result->v.list = initializer;
+ }
+ last = initializer;
+
+ if(token.type == '}')
+ break;
+
+ if(token.type != ',') {
+ parse_error_expected("problem while parsing initializer list",
+ ',', '}', 0);
+ eat_block();
+ return result;
+ }
+ eat(',');
+
+ if(token.type == '}')
+ break;
+ }
+
+ expect('}');
+
+ return result;
+}
+
+static declaration_t *parse_compound_type_specifier(bool is_struct)