// File: /workspace/github_c_makefile_star2_O3/hikalium[P]compilium/type.c
// Function: TestType
_Noreturn void TestType() {
  fprintf(stderr, "Testing Type...\n");

  struct Node *int_type = CreateTypeBase(CreateToken("int"));
  struct Node *another_int_type = CreateTypeBase(CreateToken("int"));
  struct Node *lvalue_int_type = CreateTypeLValue(int_type);
  struct Node *pointer_of_int_type = CreateTypePointer(int_type);
  struct Node *another_pointer_of_int_type =
      CreateTypePointer(another_int_type);

  assert(IsSameTypeExceptAttr(int_type, int_type));
  assert(IsSameTypeExceptAttr(int_type, another_int_type));
  assert(IsSameTypeExceptAttr(int_type, lvalue_int_type));
  assert(IsSameTypeExceptAttr(lvalue_int_type, lvalue_int_type));
  assert(!IsSameTypeExceptAttr(int_type, pointer_of_int_type));
  assert(
      IsSameTypeExceptAttr(pointer_of_int_type, another_pointer_of_int_type));
  assert(GetSizeOfType(int_type) == 4);
  assert(GetSizeOfType(pointer_of_int_type) == 8);

  struct Node *char_type = CreateTypeBase(CreateToken("char"));
  assert(GetSizeOfType(char_type) == 1);

  struct Node *long_type = CreateTypeBase(CreateToken("long"));
  assert(GetSizeOfType(long_type) == 4);

  struct Node *ppi_type = CreateTypePointer(pointer_of_int_type);

  struct Node *args_i = AllocList();
  PushToList(args_i, int_type);
  struct Node *if_i_type = CreateTypeFunction(int_type, args_i);
  struct Node *ppif_i_type = CreateTypeFunction(ppi_type, args_i);

  struct Node *args_pi = AllocList();
  PushToList(args_pi, pointer_of_int_type);
  struct Node *if_pi_type = CreateTypeFunction(int_type, args_pi);
  struct Node *ppif_pi_type = CreateTypeFunction(ppi_type, args_pi);

  struct Node *type;

  type = CreateTypeFromInput("void* (*f)(int size);");
  PrintASTNode(type);
  type = GetTypeWithoutAttr(type);
  assert(type->type == kTypePointer);
  type = type->right;
  assert(type->type == kTypeFunction);
  type = GetReturnTypeOfFunction(type);
  assert(type->type == kTypePointer);
  assert(GetSizeOfType(type) == 8);

  type = CreateTypeFromInput("int v;");
  PrintASTNode(type);
  assert(IsSameTypeExceptAttr(type, int_type));

  type = CreateTypeFromInput("int *p;");
  PrintASTNode(type);
  assert(IsSameTypeExceptAttr(type, pointer_of_int_type));

  type = CreateTypeFromInput("int **p;");
  PrintASTNode(type);
  assert(IsSameTypeExceptAttr(type, ppi_type));

  type = CreateTypeFromInput("int f(int a);");
  PrintASTNode(type);
  assert(IsSameTypeExceptAttr(type, if_i_type));
  assert(!IsSameTypeExceptAttr(type, if_pi_type));

  type = CreateTypeFromInput("int f(int *a);");
  PrintASTNode(type);
  assert(!IsSameTypeExceptAttr(type, if_i_type));
  assert(IsSameTypeExceptAttr(type, if_pi_type));

  type = CreateTypeFromInput("int **f(int a);");
  PrintASTNode(type);
  assert(IsSameTypeExceptAttr(type, ppif_i_type));
  assert(!IsSameTypeExceptAttr(type, ppif_pi_type));
  PrintASTNode(if_i_type);
  assert(!IsSameTypeExceptAttr(type, if_i_type));
  assert(!IsSameTypeExceptAttr(type, if_pi_type));

  type =
      CreateTypeFromInput("void (*signal(int sig, void (*func)(int)))(int);");
  assert(type && GetTypeWithoutAttr(type) &&
         GetTypeWithoutAttr(type)->type == kTypeFunction);
  PrintASTNode(type);

  type = CreateTypeFromInput("struct IncompleteStruct;");
  assert(type);
  PrintASTNode(type);

  fprintf(stderr, "PASS\n");
  exit(EXIT_SUCCESS);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq 0x66e9(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x2108(%rip), %rdi      # 0xca21
movl $0x10, %esi
movl $0x1, %edx
callq 0x21b0
leaq 0x739(%rip), %r14       # 0xb068
movq %r14, %rdi
callq 0x9898
movq %rax, %rdi
callq 0x41c7
movq %rax, %rbx
movq %r14, %rdi
callq 0x9898
movq %rax, %rdi
callq 0x41c7
movq %rax, %r13
movq %rbx, %rdi
callq 0x41e6
movq %rax, %r12
movq %rbx, %rdi
callq 0x4205
movq %rax, %r14
movq %r13, %rdi
callq 0x4205
movq %rax, %r15
movq %rbx, %rdi
movq %rbx, %rsi
callq 0x9f40
testl %eax, %eax
je 0xad64
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9f40
testl %eax, %eax
je 0xad7c
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f40
testl %eax, %eax
je 0xad94
movq %r12, %rdi
movq %r12, %rsi
callq 0x9f40
testl %eax, %eax
je 0xadac
movq %rbx, %rdi
movq %r14, %rsi
callq 0x9f40
testl %eax, %eax
jne 0xadc4
movq %r14, %rdi
movq %r15, %rsi
callq 0x9f40
testl %eax, %eax
je 0xaddc
movq %rbx, %rdi
callq 0xa1c5
cmpl $0x4, %eax
jne 0xadf4
movq %r14, %rdi
callq 0xa1c5
cmpl $0x8, %eax
jne 0xae0c
leaq 0x65b(%rip), %rdi       # 0xb06c
callq 0x9898
movq %rax, %rdi
callq 0x41c7
movq %rax, %rdi
callq 0xa1c5
cmpl $0x1, %eax
jne 0xae24
leaq 0x1dc7(%rip), %rdi      # 0xc7fd
callq 0x9898
movq %rax, %rdi
callq 0x41c7
movq %rax, %rdi
callq 0xa1c5
cmpl $0x4, %eax
jne 0xae3c
movq %r14, %rdi
callq 0x4205
movq %rax, %r13
xorl %eax, %eax
callq 0x47d2
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x485a
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4224
movq %rax, %r15
movq %r13, %rdi
movq %r12, %rsi
callq 0x4224
movq %rax, 0x10(%rsp)
xorl %eax, %eax
callq 0x47d2
movq %rax, %rbp
movq %rax, %rdi
movq %r14, %rsi
callq 0x485a
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x4224
movq %rax, %r12
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4224
movq %rax, 0x8(%rsp)
leaq 0x2124(%rip), %rdi      # 0xcbf0
callq 0x2eaa
movq %rax, %rbp
movq %rax, %rdi
callq 0x441a
movl (%rbp), %eax
cmpl $0x15, %eax
je 0xaae9
cmpl $0x18, %eax
jne 0xaaef
movq 0x20(%rbp), %rbp
jmp 0xaadc
cmpl $0x16, %eax
jne 0xad4c
movq 0x20(%rbp), %rdi
cmpl $0x17, (%rdi)
jne 0xae54
callq 0x4275
cmpl $0x16, (%rax)
jne 0xae6c
movq %rax, %rdi
callq 0xa1c5
cmpl $0x8, %eax
jne 0xae84
leaq 0x20f4(%rip), %rdi      # 0xcc1f
callq 0x2eaa
movq %rax, %rbp
movq %rax, %rdi
callq 0x441a
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x9f40
testl %eax, %eax
je 0xae9c
leaq 0x20f6(%rip), %rdi      # 0xcc4b
callq 0x2eaa
movq %rax, %rbx
movq %rax, %rdi
callq 0x441a
movq %rbx, %rdi
movq %r14, %rsi
callq 0x9f40
testl %eax, %eax
je 0xaeb4
leaq 0x2104(%rip), %rdi      # 0xcc83
callq 0x2eaa
movq %rax, %rbx
movq %rax, %rdi
callq 0x441a
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9f40
testl %eax, %eax
je 0xaecc
leaq 0x2108(%rip), %rdi      # 0xccb1
callq 0x2eaa
movq %rax, %rbx
movq %rax, %rdi
callq 0x441a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f40
testl %eax, %eax
je 0xaee4
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f40
testl %eax, %eax
jne 0xaefc
leaq 0x2101(%rip), %rdi      # 0xcce7
callq 0x2eaa
movq %rax, %rbx
movq %rax, %rdi
callq 0x441a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f40
testl %eax, %eax
jne 0xaf14
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f40
testl %eax, %eax
je 0xaf2c
leaq 0x20fa(%rip), %rdi      # 0xcd1d
callq 0x2eaa
movq %rax, %rbx
movq %rax, %rdi
callq 0x441a
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x9f40
testl %eax, %eax
je 0xaf44
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x9f40
testl %eax, %eax
jne 0xaf5c
movq %r15, %rdi
callq 0x441a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f40
testl %eax, %eax
jne 0xaf74
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f40
testl %eax, %eax
jne 0xaf8c
leaq 0x20ed(%rip), %rdi      # 0xcd7f
callq 0x2eaa
testq %rax, %rax
je 0xad34
movq %rax, %rcx
movl (%rcx), %edx
cmpl $0x15, %edx
je 0xacaf
cmpl $0x18, %edx
jne 0xacba
movq 0x20(%rcx), %rcx
testq %rcx, %rcx
jne 0xaca3
jmp 0xad34
movq %rax, %rcx
movl (%rcx), %edx
cmpl $0x15, %edx
je 0xacc9
cmpl $0x18, %edx
jne 0xaccf
movq 0x20(%rcx), %rcx
jmp 0xacbd
cmpl $0x17, %edx
jne 0xad34
movq %rax, %rdi
callq 0x441a
leaq 0x2121(%rip), %rdi      # 0xce04
callq 0x2eaa
testq %rax, %rax
jne 0xad05
leaq 0x362(%rip), %rdi       # 0xb056
leaq 0x1bb8(%rip), %rsi      # 0xc8b3
movl $0x150, %edx            # imm = 0x150
callq 0x46d0
movq %rax, %rdi
callq 0x441a
movq 0x62e4(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0xac2(%rip), %rdi       # 0xb7e0
movl $0x5, %esi
movl $0x1, %edx
callq 0x21b0
xorl %edi, %edi
callq 0x21a0
leaq 0x2075(%rip), %rdi      # 0xcdb0
leaq 0x1b71(%rip), %rsi      # 0xc8b3
movl $0x14c, %edx            # imm = 0x14C
callq 0x46d0
leaq 0x38e(%rip), %rdi       # 0xb0e1
leaq 0x1b59(%rip), %rsi      # 0xc8b3
movl $0x124, %edx            # imm = 0x124
callq 0x46d0
leaq 0x1cc7(%rip), %rdi      # 0xca32
leaq 0x1b41(%rip), %rsi      # 0xc8b3
movl $0x103, %edx            # imm = 0x103
callq 0x46d0
leaq 0x1cd8(%rip), %rdi      # 0xca5b
leaq 0x1b29(%rip), %rsi      # 0xc8b3
movl $0x104, %edx            # imm = 0x104
callq 0x46d0
leaq 0x1cf1(%rip), %rdi      # 0xca8c
leaq 0x1b11(%rip), %rsi      # 0xc8b3
movl $0x105, %edx            # imm = 0x105
callq 0x46d0
leaq 0x1d09(%rip), %rdi      # 0xcabc
leaq 0x1af9(%rip), %rsi      # 0xc8b3
movl $0x106, %edx            # imm = 0x106
callq 0x46d0
leaq 0x1d28(%rip), %rdi      # 0xcaf3
leaq 0x1ae1(%rip), %rsi      # 0xc8b3
movl $0x107, %edx            # imm = 0x107
callq 0x46d0
leaq 0x1d45(%rip), %rdi      # 0xcb28
leaq 0x1ac9(%rip), %rsi      # 0xc8b3
movl $0x109, %edx            # imm = 0x109
callq 0x46d0
leaq 0x1d74(%rip), %rdi      # 0xcb6f
leaq 0x1ab1(%rip), %rsi      # 0xc8b3
movl $0x10a, %edx            # imm = 0x10A
callq 0x46d0
leaq 0x1d79(%rip), %rdi      # 0xcb8c
leaq 0x1a99(%rip), %rsi      # 0xc8b3
movl $0x10b, %edx            # imm = 0x10B
callq 0x46d0
leaq 0x1d89(%rip), %rdi      # 0xcbb4
leaq 0x1a81(%rip), %rsi      # 0xc8b3
movl $0x10e, %edx            # imm = 0x10E
callq 0x46d0
leaq 0x1d8f(%rip), %rdi      # 0xcbd2
leaq 0x1a69(%rip), %rsi      # 0xc8b3
movl $0x111, %edx            # imm = 0x111
callq 0x46d0
leaq 0x646(%rip), %rdi       # 0xb4a1
leaq 0x1a51(%rip), %rsi      # 0xc8b3
movl $0x126, %edx            # imm = 0x126
callq 0x46d0
leaq 0x26e(%rip), %rdi       # 0xb0e1
leaq 0x1a39(%rip), %rsi      # 0xc8b3
movl $0x128, %edx            # imm = 0x128
callq 0x46d0
leaq 0x1d7b(%rip), %rdi      # 0xcc06
leaq 0x1a21(%rip), %rsi      # 0xc8b3
movl $0x129, %edx            # imm = 0x129
callq 0x46d0
leaq 0x1d83(%rip), %rdi      # 0xcc26
leaq 0x1a09(%rip), %rsi      # 0xc8b3
movl $0x12d, %edx            # imm = 0x12D
callq 0x46d0
leaq 0x1d98(%rip), %rdi      # 0xcc53
leaq 0x19f1(%rip), %rsi      # 0xc8b3
movl $0x131, %edx            # imm = 0x131
callq 0x46d0
leaq 0x1db9(%rip), %rdi      # 0xcc8c
leaq 0x19d9(%rip), %rsi      # 0xc8b3
movl $0x135, %edx            # imm = 0x135
callq 0x46d0
leaq 0x1e0c(%rip), %rdi      # 0xccf7
leaq 0x19c1(%rip), %rsi      # 0xc8b3
movl $0x139, %edx            # imm = 0x139
callq 0x46d0
leaq 0x1dbc(%rip), %rdi      # 0xccbf
leaq 0x19a9(%rip), %rsi      # 0xc8b3
movl $0x13a, %edx            # imm = 0x13A
callq 0x46d0
leaq 0x1ddb(%rip), %rdi      # 0xccf6
leaq 0x1991(%rip), %rsi      # 0xc8b3
movl $0x13e, %edx            # imm = 0x13E
callq 0x46d0
leaq 0x1d8d(%rip), %rdi      # 0xccc0
leaq 0x1979(%rip), %rsi      # 0xc8b3
movl $0x13f, %edx            # imm = 0x13F
callq 0x46d0
leaq 0x1de2(%rip), %rdi      # 0xcd2d
leaq 0x1961(%rip), %rsi      # 0xc8b3
movl $0x143, %edx            # imm = 0x143
callq 0x46d0
leaq 0x1df2(%rip), %rdi      # 0xcd55
leaq 0x1949(%rip), %rsi      # 0xc8b3
movl $0x144, %edx            # imm = 0x144
callq 0x46d0
leaq 0x1d7b(%rip), %rdi      # 0xccf6
leaq 0x1931(%rip), %rsi      # 0xc8b3
movl $0x146, %edx            # imm = 0x146
callq 0x46d0
leaq 0x1d2c(%rip), %rdi      # 0xccbf
leaq 0x1919(%rip), %rsi      # 0xc8b3
movl $0x147, %edx            # imm = 0x147
callq 0x46d0