// File: /workspace/github_c_makefile_star2_O0/takoeight0821[P]hoc_nyan/src/parse.c
// Function: funcdef
static Function *funcdef(bool is_static) {
  Token *back = peek(0);
  Type *ret_type = type_specifier();

  while (match("*")) {
    ret_type = ptr_to(ret_type);
  }

  char *name = peek(0)->ident;

  if (peek_tag(0) != TIDENT) {
    if (match(";")) {
      // type definition
      return NULL;
    }
    parse_error("function name or ;", peek(0));
  } else {
    consume(); // TIDENT
  }

  if (!match("(")) {
    tokens = back;
    global_var();
    return NULL;
  }

  Vector *params = new_vec();
  LVar *tmp = local_env; // start scope
  bool has_va_arg = false;
  local_size = 0;

  if (eq_reserved(peek(0), "void") && eq_reserved(peek(1), ")")) {
    consume();
    consume();
  } else {
    for (;;) {
      if (is_typename(peek(0))) {
        Node *param_decl = declarator(type_specifier()); // NDEFVAR
        add_lvar(param_decl->token, param_decl->name, param_decl->type);
        Node *param = find_var(param_decl->token, param_decl->name);

        vec_push(params, param);
        if (match(")"))
          break;
        if (!match(",")) {
          parse_error(", or )", peek(0));
        }
      } else if (match("...") && match(")")) {
        has_va_arg = true;
        break;
      } else if (match(")")) {
        break;
      } else {
        parse_error(")", peek(0));
      }
    }
  }

  if (match(";")) {
    local_env = tmp; // end scope

    Function *func = calloc(1, sizeof(Function));
    func->name = name;
    func->ret_type = ret_type;
    func->body = NULL;
    func->params = params;
    func->local_size = local_size;
    func->is_static = is_static;
    func->has_va_arg = has_va_arg;
    return func;
  }

  Node *body = statement();

  local_env = tmp; // end scope

  Function *func = calloc(1, sizeof(Function));
  func->name = name;
  func->ret_type = ret_type;
  func->body = body;
  func->params = params;
  func->local_size = local_size;
  func->is_static = is_static;
  func->has_va_arg = has_va_arg;

  return func;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movb %dil, %al
andb $0x1, %al
movb %al, -0x9(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, -0x18(%rbp)
callq 0xaad0
movq %rax, -0x20(%rbp)
leaq 0x903c(%rip), %rdi      # 0x13649
callq 0xa330
cmpq $0x0, %rax
je 0xa627
movq -0x20(%rbp), %rdi
callq 0x9ed0
movq %rax, -0x20(%rbp)
jmp 0xa606
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0xa970
cmpl $0x2, %eax
je 0xa67f
leaq 0x8d0c(%rip), %rdi      # 0x13359
callq 0xa330
cmpq $0x0, %rax
je 0xa665
movq $0x0, -0x8(%rbp)
jmp 0xa958
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rsi
leaq 0x8c72(%rip), %rdi      # 0x132ea
callq 0xaa00
jmp 0xa684
callq 0xa9e0
leaq 0x9343(%rip), %rdi      # 0x139ce
callq 0xa330
cmpq $0x0, %rax
jne 0xa6b3
movq -0x18(%rbp), %rax
movq %rax, 0xcfdf(%rip)      # 0x17680
callq 0xa440
movq $0x0, -0x8(%rbp)
jmp 0xa958
movb $0x0, %al
callq 0x2280
movq %rax, -0x30(%rbp)
movq 0xcfe3(%rip), %rax      # 0x176a8
movq %rax, -0x38(%rbp)
movb $0x0, -0x39(%rbp)
movq $0x0, 0xcfe0(%rip) # 0x176b8
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rdi
leaq 0x8b23(%rip), %rsi      # 0x1320e
callq 0xfe80
testb $0x1, %al
jne 0xa6f6
jmp 0xa724
movl $0x1, %edi
callq 0xa990
movq %rax, %rdi
leaq 0x8bf8(%rip), %rsi      # 0x13302
callq 0xfe80
testb $0x1, %al
jne 0xa715
jmp 0xa724
callq 0xa9e0
callq 0xa9e0
jmp 0xa838
jmp 0xa726
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rdi
callq 0xbb60
cmpl $0x0, %eax
je 0xa7d7
callq 0xaad0
movq %rax, %rdi
callq 0xb030
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x48(%rbp), %rax
movq 0x40(%rax), %rsi
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rdx
callq 0xc830
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x48(%rbp), %rax
movq 0x40(%rax), %rsi
callq 0xc410
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x22e0
leaq 0x8b67(%rip), %rdi      # 0x13302
callq 0xa330
cmpq $0x0, %rax
je 0xa7ab
jmp 0xa836
leaq 0x789c(%rip), %rdi      # 0x1204e
callq 0xa330
cmpq $0x0, %rax
jne 0xa7d5
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rsi
leaq 0x8b2d(%rip), %rdi      # 0x132fd
callq 0xaa00
jmp 0xa831
leaq 0x8b26(%rip), %rdi      # 0x13304
callq 0xa330
cmpq $0x0, %rax
je 0xa801
leaq 0x8b12(%rip), %rdi      # 0x13302
callq 0xa330
cmpq $0x0, %rax
je 0xa801
movb $0x1, -0x39(%rbp)
jmp 0xa836
leaq 0x8afa(%rip), %rdi      # 0x13302
callq 0xa330
cmpq $0x0, %rax
je 0xa815
jmp 0xa836
xorl %eax, %eax
movl %eax, %edi
callq 0xa990
movq %rax, %rsi
leaq 0x8ada(%rip), %rdi      # 0x13302
callq 0xaa00
jmp 0xa82f
jmp 0xa831
jmp 0xa726
jmp 0xa838
leaq 0x8b1a(%rip), %rdi      # 0x13359
callq 0xa330
cmpq $0x0, %rax
je 0xa8d1
movq -0x38(%rbp), %rax
movq %rax, 0xce4f(%rip)      # 0x176a8
movl $0x1, %edi
movl $0x30, %esi
callq 0x20d0
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x58(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x30(%rbp), %rcx
movq -0x58(%rbp), %rax
movq %rcx, 0x18(%rax)
movq 0xce16(%rip), %rcx      # 0x176b8
movq -0x58(%rbp), %rax
movq %rcx, 0x20(%rax)
movb -0x9(%rbp), %cl
movq -0x58(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x28(%rax)
movb -0x39(%rbp), %cl
movq -0x58(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x29(%rax)
movq -0x58(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xa958
callq 0xc8c0
movq %rax, -0x60(%rbp)
movq -0x38(%rbp), %rax
movq %rax, 0xcdc3(%rip)      # 0x176a8
movl $0x1, %edi
movl $0x30, %esi
callq 0x20d0
movq %rax, -0x68(%rbp)
movq -0x28(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x60(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x18(%rax)
movq 0xcd8a(%rip), %rcx      # 0x176b8
movq -0x68(%rbp), %rax
movq %rcx, 0x20(%rax)
movb -0x9(%rbp), %cl
movq -0x68(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x28(%rax)
movb -0x39(%rbp), %cl
movq -0x68(%rbp), %rax
andb $0x1, %cl
movb %cl, 0x29(%rax)
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)