// File: /workspace/github_c_makefile_star2_O2/sisshiki1969[P]monocc/src/parse.c
// Function: parse_struct_specifier
Type *parse_struct_specifier(bool allow_undefined_tag) {
  Type *struct_ty = new_type_struct();
  // struct-or-union-specifier
  TagName *tag = NULL;
  // tag_name: Token of tag-name
  Token *tag_name = NULL;
  if (peek(TK_IDENT)) tag_name = consume();
  if (consume_if(TK_OP_BRACE)) {
    // struct-declaration-list
    if (find_tag(tag_name))
      error_at_token(tag_name, "Duplicate definition of a tag name.");
    tag = new_tag(tag_name, struct_ty);
    // struct-specifier
    MemberInfo head;
    head.next = NULL;
    MemberInfo *cursor = &head;
    int offset = 0;
    while (!consume_if(TK_CL_BRACE)) {
      // struct-declaration
      MemberInfo *ty_ident = parse_decl(false);
      Token *ident = ty_ident->ident;
      Type *type = ty_ident->type;
      if (!ident) error_at_token(token, "Missing Identifier.");
      // check duplicate member definition
      MemberInfo *ty = head.next;
      while (ty) {
        if (cmp_token(ty->ident, ident))
          error_at_token(ident, "Duplicate member.");
        ty = ty->next;
      }

      int align = alignof_type(type);
      offset = align_to(offset, align);
      ty_ident->offset = offset;
      offset += sizeof_type(type);
      cursor->next = ty_ident;
      cursor = ty_ident;
      expect(TK_SEMI);
    }
    struct_ty->member = head.next;
    if (tag) tag->type = struct_ty;
    return struct_ty;
  } else {
    if (!tag_name)
      error_at_token(token, "Expected either of a tag name  or a definition.");
    tag = find_tag(tag_name);
    if (!tag) {
      if (allow_undefined_tag) {
        struct_ty->tag_name = tag_name;
      } else
        error_at_token(tag_name, "Tag name is not defined.");
    } else {
      struct_ty = tag->type;
    }
    return struct_ty;
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edi, %ebx
xorl %r15d, %r15d
xorl %eax, %eax
callq 0x912b
movq %rax, %r12
leaq 0x9dae(%rip), %rbp      # 0x11228
movq (%rbp), %r14
movl (%r14), %eax
cmpl $0x1f, %eax
je 0x74a3
testl %eax, %eax
jne 0x75af
movq 0x8(%r14), %rax
movq %rax, (%rbp)
cmpl $0x1f, (%rax)
movq %r14, %r15
je 0x74a6
jmp 0x75c3
movq %r14, %rax
movq 0x8(%rax), %rax
movq %rax, (%rbp)
movq %r15, %rdi
callq 0x5cca
testq %rax, %rax
je 0x74cc
leaq 0x4190(%rip), %rsi      # 0xb652
movq %r15, %rdi
xorl %eax, %eax
callq 0x48b3
movq %r15, %rdi
movq %r12, 0x8(%rsp)
movq %r12, %rsi
callq 0x5c8a
movq %rsp, %r13
andq $0x0, (%r13)
leaq 0x419f(%rip), %r15      # 0xb68a
xorl %r12d, %r12d
movq (%rbp), %rax
cmpl $0x20, (%rax)
je 0x7597
movq %r13, 0x10(%rsp)
xorl %edi, %edi
callq 0x651c
movq %rax, %r13
movq 0x8(%rax), %r14
movq 0x10(%rax), %rbx
testq %r14, %r14
jne 0x7529
movq (%rbp), %rdi
leaq 0x4154(%rip), %rsi      # 0xb676
xorl %eax, %eax
callq 0x48b3
movq %rsp, %rbp
movq (%rbp), %rbp
testq %rbp, %rbp
je 0x7554
movq 0x8(%rbp), %rdi
movq %r14, %rsi
callq 0x5a72
testb %al, %al
je 0x752c
movq %r14, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x48b3
jmp 0x752c
movq %rbx, %rdi
callq 0x9356
movl %r12d, %edi
movl %eax, %esi
callq 0x92f0
movl %eax, %r14d
movl %eax, 0x18(%r13)
movq %rbx, %rdi
callq 0x929b
movl %eax, %r12d
addl %r14d, %r12d
movq 0x10(%rsp), %rax
movq %r13, (%rax)
pushq $0x1c
popq %rdi
callq 0x5a46
leaq 0x9c96(%rip), %rbp      # 0x11228
jmp 0x74ee
movq 0x8(%rax), %rax
movq %rax, (%rbp)
movq (%rsp), %rax
movq 0x8(%rsp), %r12
movq %rax, 0x20(%r12)
jmp 0x75f2
leaq 0x40e6(%rip), %rsi      # 0xb69c
movq %r14, %rdi
xorl %eax, %eax
callq 0x48b3
xorl %r14d, %r14d
movq %r14, %rdi
callq 0x5cca
testq %rax, %rax
je 0x75d6
movq 0x10(%rax), %r12
jmp 0x75f2
testb %bl, %bl
je 0x75e1
movq %r14, 0x30(%r12)
jmp 0x75f2
leaq 0x40e4(%rip), %rsi      # 0xb6cc
movq %r14, %rdi
xorl %eax, %eax
callq 0x48b3
movq %r12, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq