// File: /workspace/github_c_makefile_star2_O3/sisshiki1969[P]monocc/src/parse.c
// Function: parse_type_specifier
Type *parse_type_specifier(bool allow_undefined_tag) {
  Token *t = consume();
  Type *ty;
  switch (t->kind) {
    case TK_BOOL:
      return new_type_bool();
    case TK_VOID:
      return new_type_void();
    case TK_STRUCT:
      return parse_struct_specifier(allow_undefined_tag);
    case TK_ENUM:
      return parse_enum_specifier();
    case TK_IDENT:
      // typedef-name
      ty = find_typedef(t);
      if (ty)
        return ty;
      else
        error_at_token(t, "Internal error: Must be typedef name.");
  }
  int flag = 0;
  enum {
    CHAR = 1,
    SHORT = 4,
    INT = 16,
    LONG = 64,
    SIGNED = 256,
    UNSIGNED = 1024
  } size;
  while (is_type_specifier(t)) {
    switch (t->kind) {
      case TK_CHAR:
        flag += CHAR;
        break;
      case TK_SHORT:
        flag += SHORT;
        break;
      case TK_INT:
        flag += INT;
        break;
      case TK_LONG:
        flag += LONG;
        break;
      case TK_SIGNED:
        flag += SIGNED;
        break;
      case TK_UNSIGNED:
        flag += UNSIGNED;
        break;
      default:
        error_at_token(t, "Illegal type specifier.");
    }
    switch (flag) {
      case CHAR:
        ty = new_type_char();
        break;
      case SHORT:
      case SHORT + INT:
      case SIGNED + SHORT:
      case SIGNED + SHORT + INT:
        ty = new_type_short();
        break;
      case UNSIGNED + SHORT:
      case UNSIGNED + SHORT + INT:
        ty = new_type_ushort();
        break;
      case INT:
      case SIGNED + INT:
        ty = new_type_int();
        break;
      case UNSIGNED + INT:
        ty = new_type_uint();
        break;
      case LONG:
      case LONG + INT:
      case SIGNED + LONG:
      case SIGNED + LONG + INT:
        ty = new_type_long();
        break;
      case UNSIGNED + LONG:
      case UNSIGNED + LONG + INT:
        ty = new_type_ulong();
        break;
      case SIGNED:
      case UNSIGNED:
        ty = NULL;
        break;
      default:
        error_at_token(t, "Illegal type specifier.");
    }
    if (!is_type_specifier(token)) {
      break;
    }
    t = consume();
  }
  if (!ty) error_at_token(t, "Illegal type specifier.");
  return ty;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0xaac6(%rip), %rdx      # 0x13228
movq (%rdx), %rbx
movq 0x8(%rbx), %rax
movq %rax, (%rdx)
movl (%rbx), %r13d
leal -0x36(%r13), %eax
cmpl $0x5, %eax
ja 0x879d
leaq 0x4af9(%rip), %rcx      # 0xd278
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xac80
testl %r13d, %r13d
jne 0x87d1
movq %rbx, %rdi
callq 0x6217
movq %rax, %r15
testq %rax, %rax
jne 0x8a76
leaq 0x4f40(%rip), %rsi      # 0xd6fd
movq %rbx, %rdi
xorl %eax, %eax
callq 0x52cd
movl (%rbx), %r13d
leaq 0xaa57(%rip), %rdx      # 0x13228
leaq 0x4ab8(%rip), %rbp      # 0xd290
xorl %r15d, %r15d
xorl %r14d, %r14d
addl $-0x34, %r13d
cmpl $0xa, %r13d
ja 0x881e
movslq (%rbp,%r13,4), %rax
addq %rbp, %rax
jmpq *%rax
movq %rbx, %rdi
leaq 0x4f27(%rip), %rsi      # 0xd723
xorl %eax, %eax
callq 0x52cd
leaq 0xaa1e(%rip), %rdx      # 0x13228
jmp 0x8861
addl $0x400, %r14d           # imm = 0x400
jmp 0x8861
addl $0x100, %r14d           # imm = 0x100
jmp 0x8861
movq %rbx, %rdi
callq 0x6217
testq %rax, %rax
je 0x8a5d
cmpl $0x5, %r13d
leaq 0xa9ee(%rip), %rdx      # 0x13228
ja 0x87f2
leaq 0x4a79(%rip), %rcx      # 0xd2bc
movslq (%rcx,%r13,4), %rax
addq %rcx, %rax
jmpq *%rax
addl $0x10, %r14d
jmp 0x8861
addl $0x40, %r14d
jmp 0x8861
addl $0x4, %r14d
jmp 0x8861
incl %r14d
cmpl $0x113, %r14d           # imm = 0x113
jg 0x88b3
cmpl $0x3f, %r14d
jle 0x88f8
cmpl $0xff, %r14d
jle 0x8969
movl $0x0, %r12d
cmpl $0x100, %r14d           # imm = 0x100
je 0x89c0
cmpl $0x104, %r14d           # imm = 0x104
je 0x8943
cmpl $0x110, %r14d           # imm = 0x110
je 0x899d
jmp 0x89fe
cmpl $0x403, %r14d           # imm = 0x403
jle 0x8913
cmpl $0x413, %r14d           # imm = 0x413
jle 0x8982
cmpl $0x414, %r14d           # imm = 0x414
je 0x89a6
cmpl $0x440, %r14d           # imm = 0x440
je 0x88ec
cmpl $0x450, %r14d           # imm = 0x450
jne 0x89fe
xorl %eax, %eax
callq 0xac70
jmp 0x89b6
cmpl $0xf, %r14d
jg 0x8933
cmpl $0x1, %r14d
je 0x89af
cmpl $0x4, %r14d
je 0x8943
jmp 0x89fe
cmpl $0x14f, %r14d           # imm = 0x14F
jg 0x894c
cmpl $0x114, %r14d           # imm = 0x114
je 0x8943
cmpl $0x140, %r14d           # imm = 0x140
je 0x8979
jmp 0x89fe
cmpl $0x10, %r14d
je 0x899d
cmpl $0x14, %r14d
jne 0x89fe
xorl %eax, %eax
callq 0xac58
jmp 0x89b6
cmpl $0x150, %r14d           # imm = 0x150
je 0x8979
movl $0x0, %r12d
cmpl $0x400, %r14d           # imm = 0x400
je 0x89c0
jmp 0x89fe
cmpl $0x40, %r14d
je 0x8979
cmpl $0x50, %r14d
jne 0x89fe
xorl %eax, %eax
callq 0xac68
jmp 0x89b6
cmpl $0x404, %r14d           # imm = 0x404
je 0x89a6
cmpl $0x410, %r14d           # imm = 0x410
jne 0x89fe
xorl %eax, %eax
callq 0xac50
jmp 0x89b6
xorl %eax, %eax
callq 0xac48
jmp 0x89b6
xorl %eax, %eax
callq 0xac60
jmp 0x89b6
xorl %eax, %eax
callq 0xac78
leaq 0xa86b(%rip), %rdx      # 0x13228
movq %rax, %r12
movq (%rdx), %r15
movl (%r15), %r13d
leal -0x34(%r13), %eax
cmpl $0x8, %eax
jb 0x89ec
leal -0x3d(%r13), %eax
cmpl $0x2, %eax
jb 0x89ec
movq %r15, %rdi
callq 0x6217
leaq 0xa841(%rip), %rdx      # 0x13228
testq %rax, %rax
je 0x8a5a
movq 0x8(%r15), %rax
movq %rax, (%rdx)
movq %r15, %rbx
movq %r12, %r15
jmp 0x87de
movq %rbx, %rdi
leaq 0x4d1b(%rip), %rsi      # 0xd723
xorl %eax, %eax
callq 0x52cd
leaq 0xa812(%rip), %rdx      # 0x13228
movq %r15, %r12
jmp 0x89c0
movzbl %dil, %edi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x8556
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x83cd
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xac88
movq %r12, %r15
testq %r15, %r15
jne 0x8a76
leaq 0x4cba(%rip), %rsi      # 0xd723
xorl %r15d, %r15d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x52cd
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq