// File: /workspace/github_c_makefile_star2_O2/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 0x5475(%rip), %rdi      # 0xd23b
callq 0x7967
testq %rax, %rax
je 0x7e5f
movq %rax, %r14
movq 0xa37a(%rip), %rax      # 0x12158
cmpl $0x2, 0x8(%rax)
jne 0x7f2a
movq 0x10(%rax), %r15
leaq 0xa37d(%rip), %rbx      # 0x12170
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x7e18
movq 0x8(%rbx), %rax
movq 0x28(%rax), %rsi
movq %r15, %rdi
callq 0xaa3e
testl %eax, %eax
je 0x7df3
movq 0x8(%rbx), %rbx
testq %rbx, %rbx
jne 0x7e49
pushq $0x5
popq %rdi
xorl %esi, %esi
callq 0x7603
movq %rax, %rbx
movq %r15, 0x28(%rax)
pushq $0x10
popq %rdi
pushq $0x1
popq %rsi
callq 0x20f0
movq %rbx, 0x8(%rax)
movq 0xa331(%rip), %rcx      # 0x12170
movq %rcx, (%rax)
movq %rax, 0xa327(%rip)      # 0x12170
movq 0xa308(%rip), %rax      # 0x12158
movq (%rax), %rax
movq %rax, 0xa2fe(%rip)      # 0x12158
jmp 0x7f3e
leaq 0x5405(%rip), %rdi      # 0xd26b
callq 0x7967
movq 0xa2e6(%rip), %rcx      # 0x12158
movl 0x8(%rcx), %edx
testq %rax, %rax
je 0x7fc6
cmpl $0x2, %edx
jne 0x7e8d
movq (%rcx), %rax
movq %rax, 0xa2cb(%rip)      # 0x12158
leaq 0x53b7(%rip), %rdi      # 0xd24b
callq 0x7967
testq %rax, %rax
je 0x7f17
xorl %ebx, %ebx
pushq $0x18
popq %r15
leaq 0x52de(%rip), %r12      # 0xd189
leaq 0x419c(%rip), %r13      # 0xc04e
callq 0x8032
movq %rax, %rbp
pushq $0x1
popq %rdi
movq %r15, %rsi
callq 0x20f0
movq %rax, %r14
movq %rbp, 0x8(%rax)
xorl %edi, %edi
movl %ebx, %esi
callq 0x8183
movq %rax, 0x10(%r14)
movq 0xa298(%rip), %rax      # 0x12178
movq %rax, (%r14)
movq %r14, 0xa28e(%rip)      # 0x12178
movq %r12, %rdi
callq 0x7967
testq %rax, %rax
jne 0x7f17
movq %r13, %rdi
callq 0x7967
testq %rax, %rax
je 0x8003
movq %r12, %rdi
callq 0x7967
incl %ebx
testq %rax, %rax
je 0x7eb2
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x768c
pushq $0x5
popq %rdi
xorl %esi, %esi
callq 0x7603
movq %rax, %rbx
leaq 0x5304(%rip), %r15      # 0xd242
leaq 0x5306(%rip), %rdi      # 0xd24b
callq 0x7967
testq %rax, %rax
je 0x7fb4
cmpq $0x0, 0x30(%rbx)
jne 0x8016
callq 0x807e
movq %rax, %r14
movq %rax, 0x30(%rbx)
xorl %edi, %edi
testq %r14, %r14
je 0x7fa6
movq 0x10(%r14), %rax
movl 0x8(%rax), %esi
callq 0xa840
movslq %eax, %r15
movq %r15, 0x18(%r14)
movq 0x10(%r14), %rdi
callq 0x75fe
movq %rax, %rdi
movq 0x10(%r14), %rax
movq 0x8(%rax), %rax
cmpq %rax, 0x8(%rbx)
jae 0x7f9e
movq %rax, 0x8(%rbx)
addq %r15, %rdi
movq (%r14), %r14
jmp 0x7f68
movl 0x8(%rbx), %esi
callq 0xa840
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 0x7fff
movq 0x10(%rcx), %rdi
callq 0x8048
testq %rax, %rax
je 0x7fff
movq 0xa175(%rip), %rax      # 0x12158
movq 0x10(%rax), %rdi
callq 0x8048
movq 0xa165(%rip), %rcx      # 0x12158
movq (%rcx), %rcx
movq %rcx, 0xa15b(%rip)      # 0x12158
jmp 0x7fb7
xorl %ebx, %ebx
jmp 0x7fb4
movq 0xa14e(%rip), %rsi      # 0x12158
leaq 0x403d(%rip), %rdi      # 0xc04e
callq 0x7d21
leaq 0x5230(%rip), %rdi      # 0xd24d
movq %r15, %rsi
xorl %eax, %eax
callq 0xa84a
movq %r14, %rdi
movq %rax, %rsi
callq 0xa124