// File: /workspace/github_c_makefile_star2_O1/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 0x668c(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x2097(%rip), %rdi      # 0xca0d
movl $0x10, %esi
movl $0x1, %edx
callq 0x21b0
leaq 0x6dc(%rip), %r14       # 0xb068
movq %r14, %rdi
callq 0x98fc
movq %rax, %rdi
callq 0x41bb
movq %rax, %rbx
movq %r14, %rdi
callq 0x98fc
movq %rax, %rdi
callq 0x41bb
movq %rax, %r13
movq %rbx, %rdi
callq 0x41da
movq %rax, %r12
movq %rbx, %rdi
callq 0x41f9
movq %rax, %r14
movq %r13, %rdi
callq 0x41f9
movq %rax, %r15
movq %rbx, %rdi
movq %rbx, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xad7b
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xad93
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xadab
movq %r12, %rdi
movq %r12, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xadc3
movq %rbx, %rdi
movq %r14, %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xaddb
movq %r14, %rdi
movq %r15, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xadf3
movq %rbx, %rdi
callq 0xa222
cmpl $0x4, %eax
jne 0xae0b
movq %r14, %rdi
callq 0xa222
cmpl $0x8, %eax
jne 0xae23
leaq 0x5fe(%rip), %rdi       # 0xb06c
callq 0x98fc
movq %rax, %rdi
callq 0x41bb
movq %rax, %rdi
callq 0xa222
cmpl $0x1, %eax
jne 0xae3b
leaq 0x1d6e(%rip), %rdi      # 0xc801
callq 0x98fc
movq %rax, %rdi
callq 0x41bb
movq %rax, %rdi
callq 0xa222
cmpl $0x4, %eax
jne 0xae53
movq %r14, %rdi
callq 0x41f9
movq %rax, %r13
xorl %eax, %eax
callq 0x4806
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x488e
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4218
movq %rax, %r15
movq %r13, %rdi
movq %r12, %rsi
callq 0x4218
movq %rax, 0x10(%rsp)
xorl %eax, %eax
callq 0x4806
movq %rax, %rbp
movq %rax, %rdi
movq %r14, %rsi
callq 0x488e
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x4218
movq %rax, %r12
movq %r13, %rdi
movq %rbp, %rsi
callq 0x4218
movq %rax, 0x8(%rsp)
leaq 0x20b3(%rip), %rdi      # 0xcbdc
callq 0x2e5f
movq %rax, %rbp
movq %rax, %rdi
callq 0x440e
movq %rbp, %rdi
callq 0xa104
cmpl $0x16, (%rax)
jne 0xae6b
movq 0x20(%rax), %rdi
cmpl $0x17, (%rdi)
jne 0xae83
callq 0x4269
cmpl $0x16, (%rax)
jne 0xae9b
movq %rax, %rdi
callq 0xa222
cmpl $0x8, %eax
jne 0xaeb3
leaq 0x208e(%rip), %rdi      # 0xcc0b
callq 0x2e5f
movq %rax, %rbp
movq %rax, %rdi
callq 0x440e
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaecb
leaq 0x2090(%rip), %rdi      # 0xcc37
callq 0x2e5f
movq %rax, %rbx
movq %rax, %rdi
callq 0x440e
movq %rbx, %rdi
movq %r14, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaee3
leaq 0x209e(%rip), %rdi      # 0xcc6f
callq 0x2e5f
movq %rax, %rbx
movq %rax, %rdi
callq 0x440e
movq %rbx, %rdi
movq %r13, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaefb
leaq 0x20a2(%rip), %rdi      # 0xcc9d
callq 0x2e5f
movq %rax, %rbx
movq %rax, %rdi
callq 0x440e
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaf13
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xaf2b
leaq 0x209b(%rip), %rdi      # 0xccd3
callq 0x2e5f
movq %rax, %rbx
movq %rax, %rdi
callq 0x440e
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xaf43
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaf5b
leaq 0x2094(%rip), %rdi      # 0xcd09
callq 0x2e5f
movq %rax, %rbx
movq %rax, %rdi
callq 0x440e
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x9f8c
testl %eax, %eax
je 0xaf73
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xaf8b
movq %r15, %rdi
callq 0x440e
movq %rbx, %rdi
movq %r15, %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xafa3
movq %rbx, %rdi
movq %r12, %rsi
callq 0x9f8c
testl %eax, %eax
jne 0xafbb
leaq 0x2087(%rip), %rdi      # 0xcd6b
callq 0x2e5f
testq %rax, %rax
je 0xad63
movq %rax, %rbx
movq %rax, %rdi
callq 0xa104
testq %rax, %rax
je 0xad63
cmpl $0x17, (%rax)
jne 0xad63
movq %rbx, %rdi
callq 0x440e
leaq 0x20de(%rip), %rdi      # 0xcdf0
callq 0x2e5f
testq %rax, %rax
jne 0xad34
leaq 0x333(%rip), %rdi       # 0xb056
leaq 0x1b75(%rip), %rsi      # 0xc89f
movl $0x150, %edx            # imm = 0x150
callq 0x4704
movq %rax, %rdi
callq 0x440e
movq 0x62b5(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0xa93(%rip), %rdi       # 0xb7e0
movl $0x5, %esi
movl $0x1, %edx
callq 0x21b0
xorl %edi, %edi
callq 0x21a0
leaq 0x2032(%rip), %rdi      # 0xcd9c
leaq 0x1b2e(%rip), %rsi      # 0xc89f
movl $0x14c, %edx            # imm = 0x14C
callq 0x4704
leaq 0x1c9c(%rip), %rdi      # 0xca1e
leaq 0x1b16(%rip), %rsi      # 0xc89f
movl $0x103, %edx            # imm = 0x103
callq 0x4704
leaq 0x1cad(%rip), %rdi      # 0xca47
leaq 0x1afe(%rip), %rsi      # 0xc89f
movl $0x104, %edx            # imm = 0x104
callq 0x4704
leaq 0x1cc6(%rip), %rdi      # 0xca78
leaq 0x1ae6(%rip), %rsi      # 0xc89f
movl $0x105, %edx            # imm = 0x105
callq 0x4704
leaq 0x1cde(%rip), %rdi      # 0xcaa8
leaq 0x1ace(%rip), %rsi      # 0xc89f
movl $0x106, %edx            # imm = 0x106
callq 0x4704
leaq 0x1cfd(%rip), %rdi      # 0xcadf
leaq 0x1ab6(%rip), %rsi      # 0xc89f
movl $0x107, %edx            # imm = 0x107
callq 0x4704
leaq 0x1d1a(%rip), %rdi      # 0xcb14
leaq 0x1a9e(%rip), %rsi      # 0xc89f
movl $0x109, %edx            # imm = 0x109
callq 0x4704
leaq 0x1d49(%rip), %rdi      # 0xcb5b
leaq 0x1a86(%rip), %rsi      # 0xc89f
movl $0x10a, %edx            # imm = 0x10A
callq 0x4704
leaq 0x1d4e(%rip), %rdi      # 0xcb78
leaq 0x1a6e(%rip), %rsi      # 0xc89f
movl $0x10b, %edx            # imm = 0x10B
callq 0x4704
leaq 0x1d5e(%rip), %rdi      # 0xcba0
leaq 0x1a56(%rip), %rsi      # 0xc89f
movl $0x10e, %edx            # imm = 0x10E
callq 0x4704
leaq 0x1d64(%rip), %rdi      # 0xcbbe
leaq 0x1a3e(%rip), %rsi      # 0xc89f
movl $0x111, %edx            # imm = 0x111
callq 0x4704
leaq 0x26f(%rip), %rdi       # 0xb0e1
leaq 0x1a26(%rip), %rsi      # 0xc89f
movl $0x124, %edx            # imm = 0x124
callq 0x4704
leaq 0x617(%rip), %rdi       # 0xb4a1
leaq 0x1a0e(%rip), %rsi      # 0xc89f
movl $0x126, %edx            # imm = 0x126
callq 0x4704
leaq 0x23f(%rip), %rdi       # 0xb0e1
leaq 0x19f6(%rip), %rsi      # 0xc89f
movl $0x128, %edx            # imm = 0x128
callq 0x4704
leaq 0x1d38(%rip), %rdi      # 0xcbf2
leaq 0x19de(%rip), %rsi      # 0xc89f
movl $0x129, %edx            # imm = 0x129
callq 0x4704
leaq 0x1d40(%rip), %rdi      # 0xcc12
leaq 0x19c6(%rip), %rsi      # 0xc89f
movl $0x12d, %edx            # imm = 0x12D
callq 0x4704
leaq 0x1d55(%rip), %rdi      # 0xcc3f
leaq 0x19ae(%rip), %rsi      # 0xc89f
movl $0x131, %edx            # imm = 0x131
callq 0x4704
leaq 0x1d76(%rip), %rdi      # 0xcc78
leaq 0x1996(%rip), %rsi      # 0xc89f
movl $0x135, %edx            # imm = 0x135
callq 0x4704
leaq 0x1dc9(%rip), %rdi      # 0xcce3
leaq 0x197e(%rip), %rsi      # 0xc89f
movl $0x139, %edx            # imm = 0x139
callq 0x4704
leaq 0x1d79(%rip), %rdi      # 0xccab
leaq 0x1966(%rip), %rsi      # 0xc89f
movl $0x13a, %edx            # imm = 0x13A
callq 0x4704
leaq 0x1d98(%rip), %rdi      # 0xcce2
leaq 0x194e(%rip), %rsi      # 0xc89f
movl $0x13e, %edx            # imm = 0x13E
callq 0x4704
leaq 0x1d4a(%rip), %rdi      # 0xccac
leaq 0x1936(%rip), %rsi      # 0xc89f
movl $0x13f, %edx            # imm = 0x13F
callq 0x4704
leaq 0x1d9f(%rip), %rdi      # 0xcd19
leaq 0x191e(%rip), %rsi      # 0xc89f
movl $0x143, %edx            # imm = 0x143
callq 0x4704
leaq 0x1daf(%rip), %rdi      # 0xcd41
leaq 0x1906(%rip), %rsi      # 0xc89f
movl $0x144, %edx            # imm = 0x144
callq 0x4704
leaq 0x1d38(%rip), %rdi      # 0xcce2
leaq 0x18ee(%rip), %rsi      # 0xc89f
movl $0x146, %edx            # imm = 0x146
callq 0x4704
leaq 0x1ce9(%rip), %rdi      # 0xccab
leaq 0x18d6(%rip), %rsi      # 0xc89f
movl $0x147, %edx            # imm = 0x147
callq 0x4704