================================================
Scoped function calls
================================================

int main() {
  abc::def("hello", "world");
}

---

(translation_unit (function_definition
  (primitive_type)
  (function_declarator (identifier) (parameter_list))
  (compound_statement
    (expression_statement (call_expression
      (scoped_identifier (namespace_identifier) (identifier))
      (argument_list
        (string_literal)
        (string_literal)))))))

=================================================
Compound literals without parentheses
=================================================

T x = T{0};
U<V> y = U<V>{0};

---

(translation_unit
  (declaration
    (type_identifier)
    (init_declarator
      (identifier)
      (compound_literal_expression
        (type_identifier)
        (initializer_list (number_literal)))))
  (declaration
    (template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
    (init_declarator
      (identifier)
      (compound_literal_expression
        (template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier))))
        (initializer_list (number_literal))))))

=================================================
Explicit destructor calls
=================================================

int main() {
  foo.~Foo();
  bar->~Bar();
}

---

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

=================================================
New and Delete expressions
=================================================

int main() {
  auto a = new T();
  auto b = new U::V{};
  auto c = new (&d) T();
  auto c = new T[5][3]();
  delete a;
  ::delete[] c;
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (declaration
        (auto)
        (init_declarator
          (identifier)
          (new_expression (type_identifier) (argument_list))))
      (declaration
        (auto)
        (init_declarator
          (identifier)
          (new_expression
            (scoped_type_identifier (namespace_identifier) (type_identifier))
            (initializer_list))))
      (declaration
        (auto)
        (init_declarator
          (identifier)
          (new_expression
            (parenthesized_expression (pointer_expression (identifier)))
            (type_identifier)
            (argument_list))))
      (declaration
        (auto)
        (init_declarator
          (identifier)
          (new_expression
            (type_identifier)
            (new_declarator (number_literal) (new_declarator (number_literal)))
            (argument_list))))
      (expression_statement (delete_expression (identifier)))
      (expression_statement (delete_expression (identifier))))))

====================================================
Initializer lists as arguments
====================================================

int main() {
  pairs.push_back({true, false});
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (expression_statement (call_expression
        (field_expression (identifier) (field_identifier))
        (argument_list (initializer_list (true) (false))))))))

====================================================
Lambda expressions
====================================================

auto f = [&](int x) -> bool {
  return true;
};

---

(translation_unit
  (declaration
    (auto)
    (init_declarator
      (identifier)
      (lambda_expression
        (lambda_capture_specifier (lambda_default_capture))
        (abstract_function_declarator
          (parameter_list (parameter_declaration (primitive_type) (identifier)))
          (trailing_return_type (primitive_type)))
        (compound_statement (return_statement (true)))))))

====================================================
Nested template calls
====================================================

class A {
  B<C::D<E, F>>::G field;

  H<I<J>> method() {
    K::L<M<N>> variable1 = K::L<M<N>>{};
  }
};

---

(translation_unit
  (class_specifier (type_identifier) (field_declaration_list
    (field_declaration
      (scoped_type_identifier
        (template_type
          (type_identifier)
          (template_argument_list
            (type_descriptor (template_type
              (scoped_type_identifier (namespace_identifier) (type_identifier))
              (template_argument_list
                (type_descriptor (type_identifier)) (type_descriptor (type_identifier)))))))
        (type_identifier))
      (field_identifier))
    (function_definition
      (template_type
        (type_identifier)
        (template_argument_list (type_descriptor
          (template_type
            (type_identifier)
            (template_argument_list (type_descriptor (type_identifier)))))))
      (function_declarator (field_identifier) (parameter_list))
      (compound_statement
        (declaration
          (template_type
            (scoped_type_identifier (namespace_identifier) (type_identifier))
            (template_argument_list (type_descriptor
              (template_type (type_identifier) (template_argument_list (type_descriptor (type_identifier)))))))
          (init_declarator
            (identifier)
            (compound_literal_expression
              (template_type
                (scoped_type_identifier (namespace_identifier) (type_identifier))
                (template_argument_list (type_descriptor
                  (template_type
                    (type_identifier)
                    (template_argument_list (type_descriptor (type_identifier)))))))
              (initializer_list)))))))))

====================================================
Comma expressions at the start of blocks
====================================================

int main() { a(), b(); }

---

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

====================================================
Nullptr
====================================================

void *x = nullptr;

---

(translation_unit
  (declaration (primitive_type) (init_declarator (pointer_declarator (identifier)) (nullptr)))) 
