================================================================================
Number literals
================================================================================

double a = {
  0xAC00,
  0.123,
  0b1010001,
  0xabc00ull,
  -0.1f,
  1'000'000.000'001,
  24e-5,
  0.1E,
  58.,
  4e2,
  123.456e-67,
  .1E4f,
  0x10.1p0,
};

--------------------------------------------------------------------------------

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

================================================================================
Identifiers
================================================================================

int main() {
  _abc;
  d_EG123;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (identifier))
      (expression_statement
        (identifier)))))

================================================================================
Unicode Identifiers
================================================================================

int main() {
  µs;
  blah_accenté;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (identifier))
      (expression_statement
        (identifier)))))

================================================================================
Common constants
================================================================================

int main() {
  true;
  false;
  NULL;

  // regression test - identifiers starting w/ these strings should tokenize correctly.
  true_value;
  false_value;
  NULL_value;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (true))
      (expression_statement
        (false))
      (expression_statement
        (null))
      (comment)
      (expression_statement
        (identifier))
      (expression_statement
        (identifier))
      (expression_statement
        (identifier)))))

================================================================================
Function calls
================================================================================

int main() {
  printf("hi! %d\n", x);
  __assert_fail("some_error_message", 115, __extension__ __func__);
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (string_literal
              (string_content)
              (escape_sequence))
            (identifier))))
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (string_literal
              (string_content))
            (number_literal)
            (type_qualifier)
            (identifier)))))))

================================================================================
GNU inline assembly
================================================================================

asm volatile (
    "mov r0, %0\n"
    "mov r1, %[y]\n"
    "add r2, r0, r1\n"
    "mov %1, r2\n"
    :     "r"  (z)
    :     "=r" (x),
      [y] "=r" ((uintptr_t) y)
    : "r2");

--------------------------------------------------------------------------------

(translation_unit
  (expression_statement
    (gnu_asm_expression
      (gnu_asm_qualifier)
      (concatenated_string
        (string_literal
          (string_content)
          (escape_sequence))
        (string_literal
          (string_content)
          (escape_sequence))
        (string_literal
          (string_content)
          (escape_sequence))
        (string_literal
          (string_content)
          (escape_sequence)))
      (gnu_asm_output_operand_list
        (gnu_asm_output_operand
          (string_literal
            (string_content))
          (identifier)))
      (gnu_asm_input_operand_list
        (gnu_asm_input_operand
          (string_literal
            (string_content))
          (identifier))
        (gnu_asm_input_operand
          (identifier)
          (string_literal
            (string_content))
          (cast_expression
            (type_descriptor
              (primitive_type))
            (identifier))))
      (gnu_asm_clobber_list
        (string_literal
          (string_content))))))

================================================================================
Function call with compound statement
================================================================================

#define TAKES_BLOCK(x, block) for (i = 0; i < x; i++) block

int main(void) {
  {
    int x = 0;
  }
  TAKES_BLOCK(10, {
    // Doesn't matter what I put in here
  });
}

--------------------------------------------------------------------------------

(translation_unit
  (preproc_function_def
    (identifier)
    (preproc_params
      (identifier)
      (identifier))
    (preproc_arg))
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration
          (primitive_type))))
    (compound_statement
      (compound_statement
        (declaration
          (primitive_type)
          (init_declarator
            (identifier)
            (number_literal))))
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (number_literal)
            (compound_statement
              (comment))))))))

================================================================================
String literals
================================================================================

int main() {
  "a";
  "b" "c" "d";
  e "f" g;
  "\"hi\"";
  L"bonjour";
  u"guten morgen";
  U"buenos dias";
  u8"buongiorno";
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (string_literal
          (string_content)))
      (expression_statement
        (concatenated_string
          (string_literal
            (string_content))
          (string_literal
            (string_content))
          (string_literal
            (string_content))))
      (expression_statement
        (concatenated_string
          (identifier)
          (string_literal
            (string_content))
          (identifier)))
      (expression_statement
        (string_literal
          (escape_sequence)
          (string_content)
          (escape_sequence)))
      (expression_statement
        (string_literal
          (string_content)))
      (expression_statement
        (string_literal
          (string_content)))
      (expression_statement
        (string_literal
          (string_content)))
      (expression_statement
        (string_literal
          (string_content))))))

================================================================================
Character literals
================================================================================

int main() {
  'a';
  '\0';
  '\t';
  '\'';
  L'b';
  u'c';
  U'\xa1';
  u8'\x1A';
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (char_literal
          (character)))
      (expression_statement
        (char_literal
          (escape_sequence)))
      (expression_statement
        (char_literal
          (escape_sequence)))
      (expression_statement
        (char_literal
          (escape_sequence)))
      (expression_statement
        (char_literal
          (character)))
      (expression_statement
        (char_literal
          (character)))
      (expression_statement
        (char_literal
          (escape_sequence)))
      (expression_statement
        (char_literal
          (escape_sequence))))))

================================================================================
Field access
================================================================================

int main() {
  s.data1;
  p->data2;
  q[data3];
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (field_expression
          (identifier)
          (field_identifier)))
      (expression_statement
        (field_expression
          (identifier)
          (field_identifier)))
      (expression_statement
        (subscript_expression
          (identifier)
          (identifier))))))

================================================================================
Boolean operators
================================================================================

int main() {
  !x || !y && !z;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (binary_expression
          (unary_expression
            (identifier))
          (binary_expression
            (unary_expression
              (identifier))
            (unary_expression
              (identifier))))))))

================================================================================
Math operators
================================================================================

int main() {
  -a / b + c * -d;
  a++ - ++b + c-- + --d;
  ++L;
  }

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (binary_expression
          (binary_expression
            (unary_expression
              (identifier))
            (identifier))
          (binary_expression
            (identifier)
            (unary_expression
              (identifier)))))
      (expression_statement
        (binary_expression
          (binary_expression
            (binary_expression
              (update_expression
                (identifier))
              (update_expression
                (identifier)))
            (update_expression
              (identifier)))
          (update_expression
            (identifier))))
      (expression_statement
        (update_expression
          (identifier))))))

================================================================================
The comma operator
================================================================================

int main() {
  i--, j--;
  (i--, j--);
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (comma_expression
          (update_expression
            (identifier))
          (update_expression
            (identifier))))
      (expression_statement
        (parenthesized_expression
          (comma_expression
            (update_expression
              (identifier))
            (update_expression
              (identifier))))))))

================================================================================
Assignments
================================================================================

int main() {
  static int a = 1;
  b = *c = 2;
  d.e = 3;
  f->g = 4;
  h[i] = j;
  k += l;
  m -= o;
  n *= p;
  q /= r;
  *s++ = 1;
  (*t) = 1;
  a *= ((b!=c) ? d : e);
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (declaration
        (storage_class_specifier)
        type: (primitive_type)
        declarator: (init_declarator
          declarator: (identifier)
          value: (number_literal)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (assignment_expression
            left: (pointer_expression
              argument: (identifier))
            right: (number_literal))))
      (expression_statement
        (assignment_expression
          left: (field_expression
            argument: (identifier)
            field: (field_identifier))
          right: (number_literal)))
      (expression_statement
        (assignment_expression
          left: (field_expression
            argument: (identifier)
            field: (field_identifier))
          right: (number_literal)))
      (expression_statement
        (assignment_expression
          left: (subscript_expression
            argument: (identifier)
            index: (identifier))
          right: (identifier)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (identifier)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (identifier)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (identifier)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (identifier)))
      (expression_statement
        (assignment_expression
          left: (pointer_expression
            argument: (update_expression
              argument: (identifier)))
          right: (number_literal)))
      (expression_statement
        (assignment_expression
          left: (parenthesized_expression
            (pointer_expression
              argument: (identifier)))
          right: (number_literal)))
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (parenthesized_expression
            (conditional_expression
              condition: (parenthesized_expression
                (binary_expression
                  left: (identifier)
                  right: (identifier)))
              consequence: (identifier)
              alternative: (identifier))))))))

================================================================================
Pointer operations
================================================================================

int main() {
  doSomething(&x, *x);
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (pointer_expression
              (identifier))
            (pointer_expression
              (identifier))))))))

================================================================================
Type-casts
================================================================================

int main() {
  x = (const SomeType *)thing;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    type: (primitive_type)
    declarator: (function_declarator
      declarator: (identifier)
      parameters: (parameter_list))
    body: (compound_statement
      (expression_statement
        (assignment_expression
          left: (identifier)
          right: (cast_expression
            type: (type_descriptor
              (type_qualifier)
              type: (type_identifier)
              declarator: (abstract_pointer_declarator))
            value: (identifier)))))))

================================================================================
Sizeof expressions
================================================================================

int main() {
  sizeof x.a;
  sizeof(x.a);
  sizeof(const char **);
  sizeof(char * ());
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (sizeof_expression
          (field_expression
            (identifier)
            (field_identifier))))
      (expression_statement
        (sizeof_expression
          (parenthesized_expression
            (field_expression
              (identifier)
              (field_identifier)))))
      (expression_statement
        (sizeof_expression
          (type_descriptor
            (type_qualifier)
            (primitive_type)
            (abstract_pointer_declarator
              (abstract_pointer_declarator)))))
      (expression_statement
        (sizeof_expression
          (type_descriptor
            (primitive_type)
            (abstract_pointer_declarator
              (abstract_function_declarator
                (parameter_list)))))))))

================================================================================
Alignof expressions
================================================================================

typedef struct {
    long long __clang_max_align_nonce1
        __attribute__((__aligned__(__alignof__(long long))));
    long double __clang_max_align_nonce2
        __attribute__((__aligned__(__alignof__(long double))));
} max_align_t;

--------------------------------------------------------------------------------

(translation_unit
  (type_definition
    (struct_specifier
      (field_declaration_list
        (field_declaration
          (sized_type_specifier)
          (field_identifier)
          (attribute_specifier
            (argument_list
              (call_expression
                (identifier)
                (argument_list
                  (alignof_expression
                    (type_descriptor
                      (sized_type_specifier))))))))
        (field_declaration
          (sized_type_specifier
            (primitive_type))
          (field_identifier)
          (attribute_specifier
            (argument_list
              (call_expression
                (identifier)
                (argument_list
                  (alignof_expression
                    (type_descriptor
                      (sized_type_specifier
                        (primitive_type)))))))))))
    (primitive_type)))

================================================================================
Offsetof expressions
================================================================================

int main() {
  offsetof( struct x, a );
  offsetof( x, a );
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (offsetof_expression
          (type_descriptor
            (struct_specifier
              (type_identifier)))
          (field_identifier)))
      (expression_statement
        (offsetof_expression
          (type_descriptor
            (type_identifier))
          (field_identifier))))))

================================================================================
Compound literals
================================================================================

int main() {
  x = (SomeType) {
    .f1.f2[f3] = 5,
    .f4 = {}
  };
  y = (struct SomeStruct) {
    7,
    8
  };
  z = (char const []) {'a', 'b'};
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (assignment_expression
          (identifier)
          (compound_literal_expression
            (type_descriptor
              (type_identifier))
            (initializer_list
              (initializer_pair
                (field_designator
                  (field_identifier))
                (field_designator
                  (field_identifier))
                (subscript_designator
                  (identifier))
                (number_literal))
              (initializer_pair
                (field_designator
                  (field_identifier))
                (initializer_list))))))
      (expression_statement
        (assignment_expression
          (identifier)
          (compound_literal_expression
            (type_descriptor
              (struct_specifier
                (type_identifier)))
            (initializer_list
              (number_literal)
              (number_literal)))))
      (expression_statement
        (assignment_expression
          (identifier)
          (compound_literal_expression
            (type_descriptor
              (primitive_type)
              (type_qualifier)
              (abstract_array_declarator))
            (initializer_list
              (char_literal
                (character))
              (char_literal
                (character)))))))))

================================================================================
Compound literals with trailing commas
================================================================================

int main() {
  y = (struct SomeStruct) { 7, 8, };
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list))
    (compound_statement
      (expression_statement
        (assignment_expression
          (identifier)
          (compound_literal_expression
            (type_descriptor
              (struct_specifier
                (type_identifier)))
            (initializer_list
              (number_literal)
              (number_literal))))))))

================================================================================
Comments with escaped newlines
================================================================================

// one \
   two

--------------------------------------------------------------------------------

(translation_unit
  (comment))

================================================================================
Comments with escaped chars and newlines
================================================================================

// one \a \b \
   two
// one \c \d
--------------------------------------------------------------------------------

(translation_unit
  (comment)
  (comment))

================================================================================
Generic Expressions
================================================================================

int main(int argc, char **argv) {
  int    a = 10;
  float  b = 3.14;
  double c = 2.71828;
  char   d = 'A';

  a = _Generic(d, int: 5, float: 0, char: 100);
  b = _Generic(a, void *: 0, int: 4.0, float: 3.14, double: 2.71828, char: 1.0);
	c = _Generic(b, void *: 0, int: 4.0, float: 3.14, double: 2.71828, char: 1.0);
	d = _Generic(c, void *: '\0', int: '0', float: '3', double: '2', char: '1');

  _Generic(a, int: printf("a is an int\n"), float: printf("a is a float\n"), double: printf("a is a double\n"), char: printf("a is a char\n"));
  _Generic(b, int: printf("b is an int\n"), float: printf("b is a float\n"), double: printf("b is a double\n"), char: printf("b is a char\n"));
  _Generic(c, int: printf("c is an int\n"), float: printf("c is a float\n"), double: printf("c is a double\n"), char: printf("c is a char\n"));
  _Generic(d, int: printf("d is an int\n"), float: printf("d is a float\n"), double: printf("d is a double\n"), char: printf("d is a char\n"));

  return 0;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration
          (primitive_type)
          (identifier))
        (parameter_declaration
          (primitive_type)
          (pointer_declarator
            (pointer_declarator
              (identifier))))))
    (compound_statement
      (declaration
        (primitive_type)
        (init_declarator
          (identifier)
          (number_literal)))
      (declaration
        (primitive_type)
        (init_declarator
          (identifier)
          (number_literal)))
      (declaration
        (primitive_type)
        (init_declarator
          (identifier)
          (number_literal)))
      (declaration
        (primitive_type)
        (init_declarator
          (identifier)
          (char_literal
            (character))))
      (expression_statement
        (assignment_expression
          (identifier)
          (generic_expression
            (identifier)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal))))
      (expression_statement
        (assignment_expression
          (identifier)
          (generic_expression
            (identifier)
            (type_descriptor
              (primitive_type)
              (abstract_pointer_declarator))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal))))
      (expression_statement
        (assignment_expression
          (identifier)
          (generic_expression
            (identifier)
            (type_descriptor
              (primitive_type)
              (abstract_pointer_declarator))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal)
            (type_descriptor
              (primitive_type))
            (number_literal))))
      (expression_statement
        (assignment_expression
          (identifier)
          (generic_expression
            (identifier)
            (type_descriptor
              (primitive_type)
              (abstract_pointer_declarator))
            (char_literal
              (escape_sequence))
            (type_descriptor
              (primitive_type))
            (char_literal
              (character))
            (type_descriptor
              (primitive_type))
            (char_literal
              (character))
            (type_descriptor
              (primitive_type))
            (char_literal
              (character))
            (type_descriptor
              (primitive_type))
            (char_literal
              (character)))))
      (expression_statement
        (generic_expression
          (identifier)
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))))
      (expression_statement
        (generic_expression
          (identifier)
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))))
      (expression_statement
        (generic_expression
          (identifier)
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))))
      (expression_statement
        (generic_expression
          (identifier)
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))
          (type_descriptor
            (primitive_type))
          (call_expression
            (identifier)
            (argument_list
              (string_literal
                (string_content)
                (escape_sequence))))))
      (return_statement
        (number_literal)))))

================================================================================
Noreturn Type Qualifier
================================================================================

_Noreturn void kill(void) {
  printf("Killing the program\n");
  exit(0);
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (type_qualifier)
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration
          (primitive_type))))
    (compound_statement
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (string_literal
              (string_content)
              (escape_sequence)))))
      (expression_statement
        (call_expression
          (identifier)
          (argument_list
            (number_literal)))))))

================================================================================
Restrict Type Qualifier
================================================================================

void fn (int *__restrict__ rptr) {
  int *ptr = rptr;
  *ptr = 0;
}

--------------------------------------------------------------------------------

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration
          (primitive_type)
          (pointer_declarator
            (type_qualifier)
            (identifier)))))
    (compound_statement
      (declaration
        (primitive_type)
        (init_declarator
          (pointer_declarator
            (identifier))
          (identifier)))
      (expression_statement
        (assignment_expression
          (pointer_expression
            (identifier))
          (number_literal))))))
