// File: /workspace/github_c_makefile_star2_O2/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 0x7275(%rip), %rbp      # 0x10ff8
movq (%rbp), %rcx
leaq 0x2c7b(%rip), %rdi      # 0xca09
pushq $0x10
popq %rsi
pushq $0x1
popq %rdx
callq 0x21b0
leaq 0x12c8(%rip), %r14      # 0xb068
movq %r14, %rdi
callq 0x8e44
movq %rax, %rdi
callq 0x33c2
movq %rax, %rbx
movq %r14, %rdi
callq 0x8e44
movq %rax, %rdi
callq 0x33c2
movq %rax, %r13
movq %rbx, %rdi
callq 0x33d4
movq %rax, %r12
movq %rbx, %rdi
callq 0x33e6
movq %rax, %r14
movq %r13, %rdi
callq 0x33e6
movq %rax, %r15
movq %rbx, %rdi
movq %rbx, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9e0e
leaq 0x2c1d(%rip), %rdi      # 0xca1a
leaq 0x2a97(%rip), %rsi      # 0xc89b
movl $0x103, %edx            # imm = 0x103
callq 0x3cc4
movq %rbx, %rdi
movq %r13, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9e35
leaq 0x2c1f(%rip), %rdi      # 0xca43
leaq 0x2a70(%rip), %rsi      # 0xc89b
movl $0x104, %edx            # imm = 0x104
callq 0x3cc4
movq %rbx, %rdi
movq %r12, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9e5c
leaq 0x2c29(%rip), %rdi      # 0xca74
leaq 0x2a49(%rip), %rsi      # 0xc89b
movl $0x105, %edx            # imm = 0x105
callq 0x3cc4
movq %r12, %rdi
movq %r12, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9e83
leaq 0x2c32(%rip), %rdi      # 0xcaa4
leaq 0x2a22(%rip), %rsi      # 0xc89b
movl $0x106, %edx            # imm = 0x106
callq 0x3cc4
movq %rbx, %rdi
movq %r14, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9eb9
movq %r14, %rdi
movq %r15, %rsi
callq 0x942c
testl %eax, %eax
jne 0x9ed1
leaq 0x2c68(%rip), %rdi      # 0xcb10
leaq 0x29ec(%rip), %rsi      # 0xc89b
movl $0x109, %edx            # imm = 0x109
callq 0x3cc4
leaq 0x2c1b(%rip), %rdi      # 0xcadb
leaq 0x29d4(%rip), %rsi      # 0xc89b
movl $0x107, %edx            # imm = 0x107
callq 0x3cc4
movq %rbx, %rdi
callq 0x9672
cmpl $0x4, %eax
jne 0xa045
movq %r14, %rdi
callq 0x9672
cmpl $0x8, %eax
jne 0xa05d
leaq 0x1172(%rip), %rdi      # 0xb06c
callq 0x8e44
movq %rax, %rdi
callq 0x33c2
movq %rax, %rdi
callq 0x9672
cmpl $0x1, %eax
jne 0xa075
leaq 0x28de(%rip), %rdi      # 0xc7fd
callq 0x8e44
movq %rax, %rdi
callq 0x33c2
movq %rax, %rdi
callq 0x9672
cmpl $0x4, %eax
jne 0xa08d
movq %r14, %rdi
callq 0x33e6
movq %rax, %r15
xorl %eax, %eax
callq 0x3ea7
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3f25
movq %rbx, %rdi
movq %r12, %rsi
callq 0x33f8
movq %rax, 0x8(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x33f8
movq %rax, 0x10(%rsp)
xorl %eax, %eax
callq 0x3ea7
movq %rax, %r12
movq %rax, %rdi
movq %r14, %rsi
callq 0x3f25
movq %rbx, %rdi
movq %r12, %rsi
callq 0x33f8
movq %rax, (%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x33f8
movq %rax, %r13
leaq 0x2c22(%rip), %rdi      # 0xcbd8
callq 0xa3b8
movq %rax, %r12
movq %rax, %rdi
callq 0x3598
movq %r12, %rdi
callq 0x9554
cmpl $0x16, (%rax)
jne 0xa0a5
movq 0x20(%rax), %rdi
cmpl $0x17, (%rdi)
jne 0xa0bd
callq 0x343a
cmpl $0x16, (%rax)
jne 0xa0d5
movq %rax, %rdi
callq 0x9672
cmpl $0x8, %eax
jne 0xa0ed
leaq 0x2bfd(%rip), %rdi      # 0xcc07
callq 0xa3b8
movq %rax, %r12
movq %rax, %rdi
callq 0x3598
movq %r12, %rdi
movq %rbx, %rsi
callq 0x942c
testl %eax, %eax
jne 0xa105
leaq 0x2bda(%rip), %rdi      # 0xcc0e
leaq 0x2860(%rip), %rsi      # 0xc89b
movl $0x12d, %edx            # imm = 0x12D
callq 0x3cc4
leaq 0x2b0b(%rip), %rdi      # 0xcb57
leaq 0x2848(%rip), %rsi      # 0xc89b
movl $0x10a, %edx            # imm = 0x10A
callq 0x3cc4
leaq 0x2b10(%rip), %rdi      # 0xcb74
leaq 0x2830(%rip), %rsi      # 0xc89b
movl $0x10b, %edx            # imm = 0x10B
callq 0x3cc4
leaq 0x2b20(%rip), %rdi      # 0xcb9c
leaq 0x2818(%rip), %rsi      # 0xc89b
movl $0x10e, %edx            # imm = 0x10E
callq 0x3cc4
leaq 0x2b26(%rip), %rdi      # 0xcbba
leaq 0x2800(%rip), %rsi      # 0xc89b
movl $0x111, %edx            # imm = 0x111
callq 0x3cc4
leaq 0x1035(%rip), %rdi      # 0xb0e1
leaq 0x27e8(%rip), %rsi      # 0xc89b
movl $0x124, %edx            # imm = 0x124
callq 0x3cc4
leaq 0x13dd(%rip), %rdi      # 0xb4a1
leaq 0x27d0(%rip), %rsi      # 0xc89b
movl $0x126, %edx            # imm = 0x126
callq 0x3cc4
leaq 0x1005(%rip), %rdi      # 0xb0e1
leaq 0x27b8(%rip), %rsi      # 0xc89b
movl $0x128, %edx            # imm = 0x128
callq 0x3cc4
leaq 0x2afa(%rip), %rdi      # 0xcbee
leaq 0x27a0(%rip), %rsi      # 0xc89b
movl $0x129, %edx            # imm = 0x129
callq 0x3cc4
leaq 0x2b27(%rip), %rdi      # 0xcc33
callq 0xa3b8
movq %rax, %rbx
movq %rax, %rdi
callq 0x3598
movq %rbx, %rdi
movq %r14, %rsi
callq 0x942c
testl %eax, %eax
jne 0xa143
leaq 0x2b09(%rip), %rdi      # 0xcc3b
leaq 0x2762(%rip), %rsi      # 0xc89b
movl $0x131, %edx            # imm = 0x131
callq 0x3cc4
leaq 0x2b21(%rip), %rdi      # 0xcc6b
callq 0xa3b8
movq %rax, %rbx
movq %rax, %rdi
callq 0x3598
movq %rbx, %rdi
movq %r15, %rsi
callq 0x942c
testl %eax, %eax
jne 0xa181
leaq 0x2b04(%rip), %rdi      # 0xcc74
leaq 0x2724(%rip), %rsi      # 0xc89b
movl $0x135, %edx            # imm = 0x135
callq 0x3cc4
leaq 0x2b11(%rip), %rdi      # 0xcc99
callq 0xa3b8
movq %rax, %rbx
movq %rax, %rdi
callq 0x3598
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa1c1
leaq 0x2b2f(%rip), %rdi      # 0xccdf
leaq 0x26e4(%rip), %rsi      # 0xc89b
movl $0x139, %edx            # imm = 0x139
callq 0x3cc4
movq %rbx, %rdi
movq (%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa221
leaq 0x2af7(%rip), %rdi      # 0xcccf
callq 0xa3b8
movq %rax, %rbx
movq %rax, %rdi
callq 0x3598
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa239
movq %rbx, %rdi
movq (%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa251
leaq 0x2a98(%rip), %rdi      # 0xcca8
leaq 0x2684(%rip), %rsi      # 0xc89b
movl $0x13f, %edx            # imm = 0x13F
callq 0x3cc4
leaq 0x2a7f(%rip), %rdi      # 0xcca7
leaq 0x266c(%rip), %rsi      # 0xc89b
movl $0x13a, %edx            # imm = 0x13A
callq 0x3cc4
leaq 0x2a9e(%rip), %rdi      # 0xccde
leaq 0x2654(%rip), %rsi      # 0xc89b
movl $0x13e, %edx            # imm = 0x13E
callq 0x3cc4
leaq 0x2aad(%rip), %rdi      # 0xcd05
callq 0xa3b8
movq %rax, %rbx
movq %rax, %rdi
callq 0x3598
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa291
leaq 0x2a95(%rip), %rdi      # 0xcd15
leaq 0x2614(%rip), %rsi      # 0xc89b
movl $0x143, %edx            # imm = 0x143
callq 0x3cc4
movq %rbx, %rdi
movq %r13, %rsi
callq 0x942c
testl %eax, %eax
jne 0xa333
movq 0x8(%rsp), %r14
movq %r14, %rdi
callq 0x3598
movq %rbx, %rdi
movq %r14, %rsi
callq 0x942c
testl %eax, %eax
jne 0xa34b
movq %rbx, %rdi
movq (%rsp), %rsi
callq 0x942c
testl %eax, %eax
jne 0xa363
leaq 0x2a88(%rip), %rdi      # 0xcd67
callq 0xa3b8
testq %rax, %rax
je 0xa37b
movq %rax, %rbx
movq %rax, %rdi
callq 0x9554
testq %rax, %rax
je 0xa37b
cmpl $0x17, (%rax)
jne 0xa37b
movq %rbx, %rdi
callq 0x3598
leaq 0x2adb(%rip), %rdi      # 0xcdec
callq 0xa3b8
testq %rax, %rax
jne 0xa393
leaq 0xd34(%rip), %rdi       # 0xb056
leaq 0x2572(%rip), %rsi      # 0xc89b
movl $0x150, %edx            # imm = 0x150
callq 0x3cc4
leaq 0x2a03(%rip), %rdi      # 0xcd3d
leaq 0x255a(%rip), %rsi      # 0xc89b
movl $0x144, %edx            # imm = 0x144
callq 0x3cc4
leaq 0x298c(%rip), %rdi      # 0xccde
leaq 0x2542(%rip), %rsi      # 0xc89b
movl $0x146, %edx            # imm = 0x146
callq 0x3cc4
leaq 0x293d(%rip), %rdi      # 0xcca7
leaq 0x252a(%rip), %rsi      # 0xc89b
movl $0x147, %edx            # imm = 0x147
callq 0x3cc4
leaq 0x2a16(%rip), %rdi      # 0xcd98
leaq 0x2512(%rip), %rsi      # 0xc89b
movl $0x14c, %edx            # imm = 0x14C
callq 0x3cc4
movq %rax, %rdi
callq 0x3598
movq (%rbp), %rcx
leaq 0x143a(%rip), %rdi      # 0xb7e0
pushq $0x5
popq %rsi
pushq $0x1
popq %rdx
callq 0x21b0
xorl %edi, %edi
callq 0x21a0