// File: /workspace/github_c_makefile_star2_O1/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 0x4b57(%rip), %rdi      # 0xf23b
callq 0xa184
testq %rax, %rax
je 0xa788
movq %rax, %r14
movq 0x8a5c(%rip), %rax      # 0x13158
cmpl $0x2, 0x8(%rax)
jne 0xa87c
movq 0x10(%rax), %r15
leaq 0x8a5f(%rip), %r12      # 0x13170
xorl %ebx, %ebx
movq (%r12), %r12
testq %r12, %r12
je 0xa736
movq 0x8(%r12), %rax
movq 0x28(%rax), %rsi
movq %r15, %rdi
callq 0xd952
testl %eax, %eax
je 0xa713
movq 0x8(%r12), %rbx
testq %rbx, %rbx
jne 0xa772
movl $0x5, %edi
xorl %esi, %esi
callq 0x9c91
movq %rax, %rbx
movq %r15, 0x28(%rax)
movl $0x10, %edi
movl $0x1, %esi
callq 0x20f0
movq %rbx, 0x8(%rax)
movq 0x8a08(%rip), %rcx      # 0x13170
movq %rcx, (%rax)
movq %rax, 0x89fe(%rip)      # 0x13170
movq 0x89df(%rip), %rax      # 0x13158
movq (%rax), %rax
movq %rax, 0x89d5(%rip)      # 0x13158
jmp 0xa892
leaq 0x4adc(%rip), %rdi      # 0xf26b
callq 0xa184
movq 0x89bd(%rip), %rcx      # 0x13158
movl 0x8(%rcx), %edx
testq %rax, %rax
je 0xa921
cmpl $0x2, %edx
jne 0xa7b6
movq (%rcx), %rax
movq %rax, 0x89a2(%rip)      # 0x13158
leaq 0x4a8e(%rip), %rdi      # 0xf24b
callq 0xa184
testq %rax, %rax
je 0xa869
xorl %ebp, %ebp
leaq 0x4a53(%rip), %rbx      # 0xf227
leaq 0x49ae(%rip), %r14      # 0xf189
leaq 0x386c(%rip), %r15      # 0xe04e
movl $0x2, %edi
movq %rbx, %rsi
callq 0xaaee
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 0x9c68
movq %rax, %r13
movl %ebp, 0x28(%rax)
callq 0x9d54
movq %rax, 0x10(%r13)
movq %r13, 0x10(%r12)
movq 0x894b(%rip), %rax      # 0x13178
movq %rax, (%r12)
movq %r12, 0x8940(%rip)      # 0x13178
movq %r14, %rdi
callq 0xa184
testq %rax, %rax
jne 0xa869
movq %r15, %rdi
callq 0xa184
testq %rax, %rax
je 0xa9a2
movq %r14, %rdi
callq 0xa184
incl %ebp
testq %rax, %rax
je 0xa7e2
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9d54
movl $0x5, %edi
xorl %esi, %esi
callq 0x9c91
movq %rax, %rbx
leaq 0x49b0(%rip), %r15      # 0xf242
leaq 0x49b2(%rip), %rdi      # 0xf24b
callq 0xa184
testq %rax, %rax
je 0xa90f
cmpq $0x0, 0x30(%rbx)
jne 0xa9c9
callq 0xa9df
movq %rax, 0x30(%rbx)
testq %rax, %rax
je 0xa8ff
movq %rax, %r14
xorl %edi, %edi
movq 0x10(%r14), %rax
movl 0x8(%rax), %esi
callq 0xd7e8
movslq %eax, %r15
movq %r15, 0x18(%r14)
movq 0x10(%r14), %rdi
callq 0x9c8c
movq %rax, %rdi
movq 0x10(%r14), %rax
movq 0x8(%rax), %rax
cmpq %rax, 0x8(%rbx)
jae 0xa8f2
movq %rax, 0x8(%rbx)
addq %r15, %rdi
movq (%r14), %r14
testq %r14, %r14
jne 0xa8c1
jmp 0xa901
xorl %edi, %edi
movl 0x8(%rbx), %esi
callq 0xd7e8
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 0xa99b
movq 0x10(%rcx), %r14
leaq 0x8834(%rip), %r15      # 0x13168
xorl %ebx, %ebx
movq (%r15), %r15
testq %r15, %r15
je 0xa90f
movq 0x8(%r15), %rsi
movq %r14, %rdi
callq 0xd952
testl %eax, %eax
je 0xa936
cmpq $0x0, 0x10(%r15)
je 0xa99b
movq 0x87fc(%rip), %rax      # 0x13158
movq 0x10(%rax), %r14
leaq 0x8801(%rip), %r15      # 0x13168
xorl %ebx, %ebx
movq (%r15), %r15
testq %r15, %r15
je 0xa985
movq 0x8(%r15), %rsi
movq %r14, %rdi
callq 0xd952
testl %eax, %eax
je 0xa969
movq 0x10(%r15), %rbx
movq 0x87cc(%rip), %rax      # 0x13158
movq (%rax), %rax
movq %rax, 0x87c2(%rip)      # 0x13158
jmp 0xa90f
xorl %ebx, %ebx
jmp 0xa90f
movq 0x87af(%rip), %rbx      # 0x13158
leaq 0x36a0(%rip), %rdi      # 0xe050
leaq 0x3697(%rip), %rsi      # 0xe04e
xorl %eax, %eax
callq 0xd7f2
movq %rbx, %rdi
movq %rax, %rsi
callq 0xce4d
leaq 0x487d(%rip), %rdi      # 0xf24d
movq %r15, %rsi
xorl %eax, %eax
callq 0xd7f2
movq %r14, %rdi
jmp 0xa9c1