// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x50, %rsp
leaq 0x876c(%rip), %rdi      # 0x1324b
callq 0xa330
movq %rax, -0x10(%rbp)
cmpq $0x0, %rax
je 0xac0c
leaq 0x8759(%rip), %rax      # 0x13252
movq %rax, -0x20(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0xa970
cmpl $0x2, %eax
jne 0xab91
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0xad40
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xab8a
movl $0x5, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x9d80
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movl $0x10, %edi
movl $0x1, %esi
callq 0x20d0
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0xcb20(%rip), %rcx      # 0x17698
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq %rax, 0xcb0e(%rip)      # 0x17698
callq 0xa9e0
jmp 0xaba3
movl $0x5, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x9d80
movq %rax, -0x18(%rbp)
leaq 0x86b1(%rip), %rdi      # 0x1325b
callq 0xa330
cmpq $0x0, %rax
je 0xabff
movq -0x18(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0xabe6
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rsi
leaq 0x868a(%rip), %rdi      # 0x1325d
movb $0x0, %al
callq 0xfa70
movq -0x48(%rbp), %rdi
movq %rax, %rsi
callq 0xed90
callq 0xaf90
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rdi
callq 0xadb0
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xad2e
leaq 0x8668(%rip), %rdi      # 0x1327b
callq 0xa330
cmpq $0x0, %rax
je 0xaccd
xorl %eax, %eax
movl %eax, %edi
callq 0xa970
cmpl $0x2, %eax
jne 0xac35
callq 0xa9e0
leaq 0x861f(%rip), %rdi      # 0x1325b
callq 0xa330
cmpq $0x0, %rax
je 0xacc2
movl $0x0, -0x2c(%rbp)
callq 0xae80
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xaeb0
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
leaq 0x8526(%rip), %rdi      # 0x13199
callq 0xa330
cmpq $0x0, %rax
je 0xac80
jmp 0xacc0
leaq 0x73c7(%rip), %rdi      # 0x1204e
callq 0xa330
cmpq $0x0, %rax
jne 0xacaa
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rsi
leaq 0x73a9(%rip), %rdi      # 0x1204e
callq 0xaa00
leaq 0x84e8(%rip), %rdi      # 0x13199
callq 0xa330
cmpq $0x0, %rax
je 0xacbe
jmp 0xacc0
jmp 0xac4e
jmp 0xacc2
callq 0x9e90
movq %rax, -0x8(%rbp)
jmp 0xad2e
xorl %eax, %eax
movl %eax, %edi
callq 0xa970
cmpl $0x2, %eax
je 0xace9
xorl %eax, %eax
movl %eax, %edi
callq 0xa970
cmpl $0x3, %eax
jne 0xad26
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq 0x10(%rax), %rdi
callq 0xaf20
cmpq $0x0, %rax
je 0xad26
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq 0x10(%rax), %rdi
callq 0xaf20
movq %rax, -0x40(%rbp)
callq 0xa9e0
movq -0x40(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xad2e
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)