// File: /workspace/github_c_makefile_star2_O3/takoeight0821[P]hoc_nyan/src/parse.c
// Function: type_specifier
static Type *type_specifier() {
  /* Type* ty; */

  Token *tok;
  if ((tok = match("struct"))) {
    Type *ty;
    char *tag = "(noname)";

    if (peek_tag(0) == TIDENT) {
      tag = peek(0)->ident;
      ty = find_tag(tag);
      if (!ty) {
        ty = new_type(TY_STRUCT, 0);
        ty->tag = tag;
        Tag *new_tag = calloc(sizeof(Tag), 1);
        new_tag->type = ty;
        new_tag->next = tag_env;
        tag_env = new_tag;
      }
      consume();
    } else {
      ty = new_type(TY_STRUCT, 0);
    }

    // struct definition
    if (match("{")) {
      if (ty->fields != NULL) {
        bad_token(tok, format("struct %s is already defined\n", tag));
      }

      ty->fields = read_field();

      set_field_offset(ty);
    }

    return ty;
  } else if (match("enum")) {
    if (peek_tag(0) == TIDENT) {
      consume(); // タグは読み飛ばす
    }

    if (match("{")) {
      int val = 0;
      while (true) {
        char *name = read_ident();
        add_enum(name, val);
        val++;

        // 要素末尾の","を許す
        if (match("}")) {
          break;
        }
        if (!match(",")) {
          parse_error(",", peek(0));
        }
        if (match("}")) {
          break;
        }
      }
    }

    return int_type();
  } else if ((peek_tag(0) == TIDENT || peek_tag(0) == TRESERVED) &&
             find_type(peek(0)->ident)) {
    Type *ty = find_type(peek(0)->ident);
    consume();
    return ty;
  } else {
    return NULL;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0x4c49(%rip), %rdi      # 0xf213
callq 0xa09f
testq %rax, %rax
je 0xa669
movq %rax, %r14
movq 0x8b76(%rip), %rax      # 0x13158
cmpl $0x2, 0x8(%rax)
jne 0xa75d
movq 0x10(%rax), %r15
leaq 0x8b79(%rip), %rbx      # 0x13170
movq (%rbx), %rbx
testq %rbx, %rbx
je 0xa61c
movq 0x8(%rbx), %rax
movq 0x28(%rax), %rsi
movq %r15, %rdi
callq 0xd9ca
testl %eax, %eax
je 0xa5f7
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
jne 0xa653
movl $0x5, %edi
xorl %esi, %esi
callq 0x9bf9
movq %rax, %rbx
movq %r15, 0x28(%rax)
movl $0x10, %edi
movl $0x1, %esi
callq 0x20f0
movq %rbx, 0x8(%rax)
movq 0x8b27(%rip), %rcx      # 0x13170
movq %rcx, (%rax)
movq %rax, 0x8b1d(%rip)      # 0x13170
movq 0x8afe(%rip), %rax      # 0x13158
movq (%rax), %rax
movq %rax, 0x8af4(%rip)      # 0x13158
jmp 0xa773
leaq 0x4bd3(%rip), %rdi      # 0xf243
callq 0xa09f
movq 0x8adc(%rip), %rcx      # 0x13158
movl 0x8(%rcx), %edx
testq %rax, %rax
je 0xa809
cmpl $0x2, %edx
jne 0xa697
movq (%rcx), %rax
movq %rax, 0x8ac1(%rip)      # 0x13158
leaq 0x4b85(%rip), %rdi      # 0xf223
callq 0xa09f
testq %rax, %rax
je 0xa74a
xorl %ebp, %ebp
leaq 0x4b4a(%rip), %rbx      # 0xf1ff
leaq 0x4aa5(%rip), %r14      # 0xf161
leaq 0x398b(%rip), %r15      # 0xe04e
movl $0x2, %edi
movq %rbx, %rsi
callq 0xa9d6
movq 0x10(%rax), %r13
movl $0x1, %edi
movl $0x18, %esi
callq 0x20f0
movq %rax, %r12
movq %r13, 0x8(%rax)
xorl %edi, %edi
xorl %esi, %esi
callq 0x9bd0
movq %rax, %r13
movl %ebp, 0x28(%rax)
callq 0x9cac
movq %rax, 0x10(%r13)
movq %r13, 0x10(%r12)
movq 0x8a6a(%rip), %rax      # 0x13178
movq %rax, (%r12)
movq %r12, 0x8a5f(%rip)      # 0x13178
movq %r14, %rdi
callq 0xa09f
testq %rax, %rax
jne 0xa74a
movq %r15, %rdi
callq 0xa09f
testq %rax, %rax
je 0xa88a
movq %r14, %rdi
callq 0xa09f
incl %ebp
testq %rax, %rax
je 0xa6c3
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9cac
movl $0x5, %edi
xorl %esi, %esi
callq 0x9bf9
movq %rax, %rbx
leaq 0x4aa7(%rip), %r15      # 0xf21a
leaq 0x4aa9(%rip), %rdi      # 0xf223
callq 0xa09f
testq %rax, %rax
je 0xa7f7
cmpq $0x0, 0x30(%rbx)
jne 0xa8b1
callq 0xa8c7
movq %rax, 0x30(%rbx)
testq %rax, %rax
je 0xa7e6
movq %rax, %r14
xorl %edi, %edi
movq 0x10(%r14), %rax
movl 0x8(%rax), %esi
callq 0xd860
movslq %eax, %r15
movq %r15, 0x18(%r14)
movq 0x10(%r14), %rdi
callq 0x9bf4
movq %rax, %rdi
movq 0x8(%rbx), %rsi
movq 0x10(%r14), %rax
movq 0x8(%rax), %rax
cmpq %rax, %rsi
jae 0xa7d9
movq %rax, 0x8(%rbx)
movq %rax, %rsi
addq %r15, %rdi
movq (%r14), %r14
testq %r14, %r14
jne 0xa7a2
jmp 0xa7ec
movq 0x8(%rbx), %rsi
xorl %edi, %edi
callq 0xd860
cltq
movq %rax, 0x10(%rbx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
andl $-0x2, %edx
cmpl $0x2, %edx
jne 0xa883
movq 0x10(%rcx), %r14
leaq 0x894c(%rip), %r15      # 0x13168
xorl %ebx, %ebx
movq (%r15), %r15
testq %r15, %r15
je 0xa7f7
movq 0x8(%r15), %rsi
movq %r14, %rdi
callq 0xd9ca
testl %eax, %eax
je 0xa81e
cmpq $0x0, 0x10(%r15)
je 0xa883
movq 0x8914(%rip), %rax      # 0x13158
movq 0x10(%rax), %r14
leaq 0x8919(%rip), %r15      # 0x13168
xorl %ebx, %ebx
movq (%r15), %r15
testq %r15, %r15
je 0xa86d
movq 0x8(%r15), %rsi
movq %r14, %rdi
callq 0xd9ca
testl %eax, %eax
je 0xa851
movq 0x10(%r15), %rbx
movq 0x88e4(%rip), %rax      # 0x13158
movq (%rax), %rax
movq %rax, 0x88da(%rip)      # 0x13158
jmp 0xa7f7
xorl %ebx, %ebx
jmp 0xa7f7
movq 0x88c7(%rip), %rbx      # 0x13158
leaq 0x37b8(%rip), %rdi      # 0xe050
leaq 0x37af(%rip), %rsi      # 0xe04e
xorl %eax, %eax
callq 0xd86a
movq %rbx, %rdi
movq %rax, %rsi
callq 0xcd01
leaq 0x496d(%rip), %rdi      # 0xf225
movq %r15, %rsi
xorl %eax, %eax
callq 0xd86a
movq %r14, %rdi
jmp 0xa8a9