============================================
Struct declarations
============================================

struct s1;

struct s2 {
  int x;
  float y : 5;
};

---

(translation_unit
  (struct_specifier (type_identifier))
  (struct_specifier (type_identifier) (field_declaration_list
    (field_declaration (primitive_type) (field_identifier))
    (field_declaration (primitive_type) (field_identifier) (bitfield_clause (number_literal))))))

============================================
Union declarations
============================================

union u1;

union s2 {
  int x;
  float y;
};

---

(translation_unit
  (union_specifier (type_identifier))
  (union_specifier (type_identifier) (field_declaration_list
    (field_declaration (primitive_type) (field_identifier))
    (field_declaration (primitive_type) (field_identifier)))))

============================================
Enum declarations
============================================

enum e1;

enum e2 {
  val1,
  val2 = 5,
  val3
};

enum e3 {
  val1,
};

---

(translation_unit
  (enum_specifier (type_identifier))
  (enum_specifier (type_identifier) (enumerator_list
    (enumerator (identifier))
    (enumerator (identifier) (number_literal))
    (enumerator (identifier))))
  (enum_specifier (type_identifier) (enumerator_list
    (enumerator (identifier)))))

============================================
Primitive-typed variable declarations
============================================

unsigned short int a;
long int b, c = 5, d;
float d, e;
unsigned f;
short g, h;

---

(translation_unit
  (declaration (sized_type_specifier (primitive_type)) (identifier))
  (declaration
    (sized_type_specifier (primitive_type))
    (identifier)
    (init_declarator (identifier) (number_literal))
    (identifier))
  (declaration (primitive_type) (identifier) (identifier))
  (declaration (sized_type_specifier) (identifier))
  (declaration (sized_type_specifier) (identifier) (identifier)))

============================================
Variable storage classes
============================================

int a;
extern int b, c;
auto int d;
register int e;
static int f;

---

(translation_unit
  (declaration (primitive_type) (identifier))
  (declaration (storage_class_specifier) (primitive_type) (identifier) (identifier))
  (declaration (storage_class_specifier) (primitive_type) (identifier))
  (declaration (storage_class_specifier) (primitive_type) (identifier))
  (declaration (storage_class_specifier) (primitive_type) (identifier)))

============================================
Composite-typed variable declarations
============================================

struct b c;
union { int e; } f;
enum { g, h } i;

---

(translation_unit
  (declaration
    (struct_specifier (type_identifier))
    (identifier))
  (declaration
    (union_specifier (field_declaration_list
      (field_declaration (primitive_type) (field_identifier))))
    (identifier))
  (declaration
    (enum_specifier (enumerator_list
      (enumerator (identifier))
      (enumerator (identifier))))
    (identifier)))

============================================
Pointer variable declarations
============================================

char *the_string;
const char **the_strings;
int const * const restrict x;

---

(translation_unit
  (declaration
    (primitive_type)
    (pointer_declarator (identifier)))
  (declaration
    (type_qualifier)
    (primitive_type)
    (pointer_declarator (pointer_declarator (identifier))))
  (declaration
    (primitive_type)
    (type_qualifier)
    (pointer_declarator (type_qualifier) (type_qualifier) (identifier))))

============================================
Typedefs
============================================

typedef int my_int;

typedef struct {
  int x;
} *a;

typedef void my_callback(void *, size_t);

---

(translation_unit
  (type_definition (primitive_type) (type_identifier))
  (type_definition
    (struct_specifier (field_declaration_list (field_declaration (primitive_type) (field_identifier))))
    (pointer_declarator (type_identifier)))
  (type_definition
    (primitive_type)
    (function_declarator
      (type_identifier)
      (parameter_list
        (parameter_declaration (primitive_type) (abstract_pointer_declarator))
        (parameter_declaration (primitive_type))))))

============================================
Function declarations
============================================

int main(int argc, const char **argv);
static foo bar();
static baz quux(...);

---

(translation_unit
  (declaration
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration
          (primitive_type)
          (identifier))
        (parameter_declaration
          (type_qualifier)
          (primitive_type)
          (pointer_declarator (pointer_declarator (identifier)))))))

  (declaration
    (storage_class_specifier)
    (type_identifier)
    (function_declarator (identifier) (parameter_list)))

  (declaration
    (storage_class_specifier)
    (type_identifier)
    (function_declarator (identifier) (parameter_list))))

============================================
Function definitions
============================================

void * do_stuff(int arg1) {
  return 5;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (pointer_declarator
      (function_declarator (identifier)
        (parameter_list
          (parameter_declaration (primitive_type) (identifier)))))
    (compound_statement (return_statement (number_literal)))))

============================================
Function specifiers after types
============================================

int static inline do_stuff(int arg1) {
  return 5;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (storage_class_specifier)
    (storage_class_specifier)
    (function_declarator
      (identifier)
      (parameter_list (parameter_declaration (primitive_type) (identifier))))
    (compound_statement (return_statement (number_literal)))))

============================================
Linkage specifications
============================================

extern "C" int foo();

extern "C" int foo() { return 0; }

extern "C" {
  int bar();
  int baz();
}

---

(translation_unit
  (linkage_specification
    (string_literal)
    (declaration
      (primitive_type)
      (function_declarator (identifier) (parameter_list))))
  (linkage_specification
    (string_literal)
    (function_definition
      (primitive_type)
      (function_declarator (identifier) (parameter_list))
      (compound_statement (return_statement (number_literal)))))
  (linkage_specification
    (string_literal)
    (declaration_list
      (declaration
        (primitive_type)
        (function_declarator (identifier) (parameter_list)))
      (declaration
        (primitive_type)
        (function_declarator (identifier) (parameter_list))))))

==========================
Type qualifiers
==========================

const _Atomic unsigned long int x = 5;
restrict int y = 6;
volatile int z = 7;

---

(translation_unit
  (declaration
    (type_qualifier)
    (type_qualifier)
    (sized_type_specifier (primitive_type))
    (init_declarator (identifier) (number_literal)))
  (declaration
    (type_qualifier)
    (primitive_type)
    (init_declarator (identifier) (number_literal)))
  (declaration
    (type_qualifier)
    (primitive_type)
    (init_declarator (identifier) (number_literal))))

================================
Local array declarations
================================

int main() {
  char the_buffer[the_size];
  char the_other_buffer[*];
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (declaration (primitive_type) (array_declarator (identifier) (identifier)))
      (declaration (primitive_type) (array_declarator (identifier))))))
