=========================================
Namespace definitions
=========================================

namespace std {

int x;

}  // namespace std

---

(translation_unit
  (namespace_definition
    (identifier)
    (declaration_list
      (declaration (primitive_type) (identifier))))
  (comment))

=========================================
Using declarations
=========================================

using a;
using ::b;
using c::d;
using ::e::f::g;
using h = i::j;
using namespace std;

---

(translation_unit
  (using_declaration (identifier))
  (using_declaration (scoped_identifier (identifier)))
  (using_declaration (scoped_identifier (namespace_identifier) (identifier)))
  (using_declaration
    (scoped_identifier
      (scoped_namespace_identifier
        (scoped_namespace_identifier (namespace_identifier))
        (namespace_identifier))
      (identifier)))
  (alias_declaration
    (type_identifier)
    (type_descriptor (scoped_type_identifier (namespace_identifier) (type_identifier))))
  (using_declaration (identifier)))

=========================================
Reference declarations
=========================================

int main() {
  T &x = y<T &>();
}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (declaration
        (type_identifier)
        (init_declarator
          (reference_declarator (identifier))
          (call_expression
            (template_function
              (identifier)
              (template_argument_list
                (type_descriptor (type_identifier) (abstract_reference_declarator))))
            (argument_list)))))))

=========================================
R-value reference declarations
=========================================

int main(T &&);

int main(T &&t) {
  const U &&u = v;
}

---

(translation_unit
  (declaration
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator)))))
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list (parameter_declaration (type_identifier) (reference_declarator (identifier)))))
    (compound_statement
      (declaration
        (type_qualifier)
        (type_identifier)
        (init_declarator (reference_declarator (identifier)) (identifier))))))

=========================================
Inline method definitions
=========================================

struct S {
  int f;

  S() : f(0) {}

 private:
  int getF() const { return f; }
};

---

(translation_unit
  (struct_specifier (type_identifier) (field_declaration_list
    (field_declaration (primitive_type) (field_identifier))
    (function_definition
      (function_declarator (identifier) (parameter_list))
      (field_initializer_list (field_initializer (field_identifier) (argument_list (number_literal))))
      (compound_statement))
    (access_specifier)
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (type_qualifier))
      (compound_statement (return_statement (identifier)))))))

=========================================
Inline method definitions with overrides
=========================================

struct B : A {
  int foo() override { return 2; }
  int pho() final { return 3; }
  int bar() const override { return 4; }
  int baz() const final { return 5; }
  int bag() const final override { return 6; }
  int bah() const override final { return 7; }
};

---

(translation_unit
  (struct_specifier (type_identifier) (base_class_clause (type_identifier)) (field_declaration_list
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (virtual_specifier))
      (compound_statement (return_statement (number_literal))))
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (virtual_specifier))
      (compound_statement (return_statement (number_literal))))
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier))
      (compound_statement (return_statement (number_literal))))
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier))
      (compound_statement (return_statement (number_literal))))
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier) (virtual_specifier))
      (compound_statement (return_statement (number_literal))))
    (function_definition
      (primitive_type)
      (function_declarator (field_identifier) (parameter_list) (type_qualifier) (virtual_specifier) (virtual_specifier))
      (compound_statement (return_statement (number_literal)))))))

=========================================
Constructor and destructor declarations
=========================================

class C {
  void *data_;

 public:
  C();
  C(int, float);
  ~C();
};

---

(translation_unit
  (class_specifier (type_identifier) (field_declaration_list
    (field_declaration (primitive_type) (pointer_declarator (field_identifier)))
    (access_specifier)
    (declaration (function_declarator (identifier) (parameter_list)))
    (declaration (function_declarator (identifier) (parameter_list
      (parameter_declaration (primitive_type))
      (parameter_declaration (primitive_type)))))
    (declaration (function_declarator (destructor_name (identifier)) (parameter_list))))))

=========================================
Classes with inheritance
=========================================

class A : public B {
};

class C : C::D, public E {
};

---

(translation_unit
  (class_specifier
    (type_identifier)
    (base_class_clause (type_identifier))
    (field_declaration_list))
  (class_specifier
    (type_identifier)
    (base_class_clause
      (scoped_type_identifier (namespace_identifier) (type_identifier))
      (type_identifier))
    (field_declaration_list)))

=========================================
Classes with final virt specifier
=========================================

class A final : public B {
};

class C final {};

struct D final {};

---

(translation_unit
  (class_specifier
    (type_identifier)
    (virtual_specifier)
    (base_class_clause (type_identifier))
    (field_declaration_list))
  (class_specifier
    (type_identifier)
    (virtual_specifier)
    (field_declaration_list))
  (struct_specifier
    (type_identifier)
    (virtual_specifier)
    (field_declaration_list)))

=========================================
Friend declarations
=========================================

struct C {
  friend class D;
  friend int f(C &);
};

---

(translation_unit
  (struct_specifier (type_identifier) (field_declaration_list
    (friend_declaration (class_specifier (type_identifier)))
    (friend_declaration (declaration (primitive_type) (function_declarator
      (identifier)
      (parameter_list (parameter_declaration (type_identifier) (abstract_reference_declarator)))))))))

=========================================
Function parameters with default values
=========================================

int foo(bool x = 5) {}

---

(translation_unit
  (function_definition
    (primitive_type)
    (function_declarator
      (identifier)
      (parameter_list
        (parameter_declaration (primitive_type) (init_declarator (identifier) (number_literal)))))
    (compound_statement)))

=========================================
Operator overload declarations
=========================================

ostream &operator<<(ostream &, const A &a);

bool A::operator!=(const A &other) const;

---

(translation_unit
  (declaration
    (type_identifier)
    (reference_declarator
      (function_declarator
        (operator_name)
        (parameter_list
          (parameter_declaration (type_identifier) (abstract_reference_declarator))
          (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier)))))))
  (declaration
    (primitive_type)
    (function_declarator
      (scoped_identifier (namespace_identifier) (operator_name))
      (parameter_list
        (parameter_declaration (type_qualifier) (type_identifier) (reference_declarator (identifier))))
      (type_qualifier))))

=========================================
Template declarations
=========================================

template <typename T>
void foo(T &t);

template <typename T, int u>
int bar(T &t) { return u; }

template <typename T>
class Foo {};

---

(translation_unit
  (template_declaration
    (template_parameter_list
      (type_parameter_declaration (type_identifier)))
    (declaration
      (primitive_type)
      (function_declarator
        (identifier)
        (parameter_list
          (parameter_declaration (type_identifier) (reference_declarator (identifier)))))))
  (template_declaration
    (template_parameter_list
      (type_parameter_declaration (type_identifier))
      (parameter_declaration (primitive_type) (identifier)))
    (function_definition
      (primitive_type)
      (function_declarator
        (identifier)
        (parameter_list (parameter_declaration (type_identifier) (reference_declarator (identifier)))))
      (compound_statement (return_statement (identifier)))))
  (template_declaration
    (template_parameter_list
      (type_parameter_declaration (type_identifier)))
    (class_specifier (type_identifier) (field_declaration_list))))

=========================================
Template specializations
=========================================

template <>
void foo<T>(T &t);

template <>
struct foo::bar<T> {};

---

(translation_unit
  (template_declaration
    (template_parameter_list)
    (declaration
      (primitive_type)
      (function_declarator
        (template_function
          (identifier)
          (template_argument_list (type_descriptor (type_identifier))))
        (parameter_list
          (parameter_declaration (type_identifier) (reference_declarator (identifier)))))))
  (template_declaration
    (template_parameter_list)
    (struct_specifier
      (template_type
        (scoped_type_identifier (namespace_identifier) (type_identifier))
        (template_argument_list (type_descriptor (type_identifier))))
      (field_declaration_list))))

====================================================
Template methods
====================================================

class Person {
  Person() {
    this->speak<int>();
  }

  template <typename T>
  void speak() {}

  template <>
  void speak<bool>() {}
};

---

(translation_unit
  (class_specifier (type_identifier) (field_declaration_list
    (function_definition
      (function_declarator (identifier) (parameter_list))
      (compound_statement
        (expression_statement (call_expression
          (field_expression
            (identifier)
            (template_method
              (field_identifier)
              (template_argument_list (type_descriptor (primitive_type)))))
          (argument_list)))))
    (template_declaration
      (template_parameter_list (type_parameter_declaration (type_identifier)))
      (function_definition
        (primitive_type)
        (function_declarator
          (identifier)
          (parameter_list))
        (compound_statement)))
    (template_declaration
      (template_parameter_list)
      (function_definition
        (primitive_type)
        (function_declarator
          (template_function (identifier) (template_argument_list (type_descriptor (primitive_type))))
          (parameter_list))
        (compound_statement))))))

==========================================
Templates with default type parameters
==========================================

template <typename T = U::V<void>>
class X
{
};

---

(translation_unit
  (template_declaration
    (template_parameter_list
      (optional_type_parameter_declaration
        (type_identifier)
        (template_type
          (scoped_type_identifier
            (namespace_identifier)
            (type_identifier))
          (template_argument_list
            (type_descriptor (primitive_type))))))
    (class_specifier (type_identifier) (field_declaration_list))))

==========================================
Declarations with braced initializer lists
==========================================

A foo{1, 2};

---

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

===========================================
Empty function bodies
===========================================

int main() {}

---

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

==========================================
Explicit template instantiations
==========================================

template A<int, bool>::A(char *, size_t);

---

(translation_unit
  (template_instantiation
    (function_declarator
      (scoped_identifier
        (template_type
          (type_identifier)
          (template_argument_list
            (type_descriptor (primitive_type))
            (type_descriptor (primitive_type))))
        (identifier))
      (parameter_list
        (parameter_declaration (primitive_type) (abstract_pointer_declarator))
        (parameter_declaration (primitive_type))))))

=====================================
Structured binding declarations
=====================================

auto [a] = B{};

int main() {
  auto &&[b, c] = std::make_tuple(c);
  const auto [x, y] {1, 2};
}

---

(translation_unit
  (structured_binding_declaration (auto) (structured_binding_declarator (identifier)) (compound_literal_expression (type_identifier) (initializer_list)))
  (function_definition
    (primitive_type)
    (function_declarator (identifier) (parameter_list))
    (compound_statement
      (structured_binding_declaration
        (auto)
        (reference_declarator (structured_binding_declarator (identifier) (identifier)))
        (call_expression
          (scoped_identifier (namespace_identifier) (identifier))
          (argument_list (identifier))))
      (structured_binding_declaration
        (type_qualifier)
        (auto)
        (structured_binding_declarator (identifier) (identifier))
        (initializer_list (number_literal) (number_literal))))))

==========================
Constexpr declarations
==========================

constexpr double pi = 3.14159;

---

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