// File: /workspace/github_c_makefile_star2_O3/Mithreindeir[P]ewcc/src/frontend/cdecl.c
// Function: parse_dir_declarator
int parse_dir_declarator(struct parser *p, struct declaration *decl)
{
	/*Identifier */
	struct token *t;
	if ((t = match(p, t_ident))) {
		if (decl->ident)
			syntax_error(p,
				     "Too many identifiers in declaration");
		int len = strlen(t->tok);
		decl->ident = malloc(len + 1);
		memcpy(decl->ident, t->tok, len);
		decl->ident[len] = 0;
	} else if (match(p, t_lparen) && parse_declarator(p, decl)) {
		if (!match(p, t_rparen))
			syntax_error(p,
				     "Missing right parentheses in declarator");
	} else {
		return 0;
	}
	while ((t = match(p, t_lbrack)) || (t = match(p, t_lparen))) {
		if (t->type == t_lbrack) {
			struct expr *cexpr;
			if (!(cexpr=parse_expr(p)))
				syntax_error(p, "Missing constant expression in array decl");
			if (cexpr->type != node_cnum)
				syntax_error(p, "Only constant value cexprs implemented right now");
			if (!match(p, t_rbrack))
				syntax_error(p,
					     "Missing right bracket in array declaration");
			struct type *arr;
			decl->type =
			    types_merge(decl->type, (arr=type_init(type_array)));
			arr->info.elem = CNUM(cexpr);
			node_free(cexpr);
		} else if (t->type == t_lparen) {
			/*Declaration list */
			int paramc = 0;
			char **paramv = NULL;
			struct type **paramt = NULL;
			struct declaration *d;
			while ((d = parse_param(p))) {
				paramc++;
				if (paramc == 1) {
					paramv = malloc(sizeof(char *));
					paramt =
					    malloc(sizeof(struct type *));
				} else {
					paramv =
					    realloc(paramv,
						    sizeof(char *) *
						    paramc);
					paramt =
					    realloc(paramt,
						    sizeof(struct type *) *
						    paramc);
				}
				paramv[paramc - 1] = d->ident;
				paramt[paramc - 1] = d->type;
				free(d);
				if (!match(p, t_comma))
					break;
			}
			if (!match(p, t_rparen))
				syntax_error(p,
					     "Missing right parentheses in function ptr declaration");
			struct type *fcn;
			decl->type =
			    types_merge(decl->type,
					(fcn = type_init(type_fcn)));
			fcn->info.fcn.paramc = paramc;
			fcn->info.fcn.paramv = paramv;
			fcn->info.fcn.paramt = paramt;
		}
	}
	return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl $0xc, %esi
callq 0x7c4e
testq %rax, %rax
je 0x6088
movq %rax, %r15
cmpq $0x0, (%rbx)
je 0x5e8b
leaq 0x368d(%rip), %rsi      # 0x9510
movq %r14, %rdi
callq 0x7ca4
movq (%r15), %r15
movq %r15, %rdi
callq 0x2070
movq %rax, %r12
incl %eax
movslq %eax, %rdi
callq 0x2100
movq %rax, %r13
movq %rax, (%rbx)
movslq %r12d, %r12
movq %rax, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x20f0
movb $0x0, (%r13,%r12)
movq %rbx, 0x8(%rsp)
movq %r14, %rdi
movl $0x16, %esi
callq 0x7c4e
testq %rax, %rax
jne 0x5eed
movq %r14, %rdi
movl $0x14, %esi
callq 0x7c4e
testq %rax, %rax
je 0x6072
movl 0x14(%rax), %eax
cmpl $0x16, %eax
je 0x5fe6
cmpl $0x14, %eax
jne 0x5ec5
movl $0x8, %ebp
xorl %ebx, %ebx
xorl %r15d, %r15d
xorl %r12d, %r12d
movq %r14, %rdi
callq 0x6153
testq %rax, %rax
je 0x5f86
movq %rax, %r13
testq %rbx, %rbx
je 0x5f3b
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2110
movq %rax, %r15
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2110
jmp 0x5f52
movl $0x8, %edi
callq 0x2100
movq %rax, %r15
movl $0x8, %edi
callq 0x2100
movq %rax, %r12
movq (%r13), %rax
movq %rax, (%r15,%rbx,8)
movq 0x8(%r13), %rax
movq %rax, (%r12,%rbx,8)
movq %r13, %rdi
callq 0x2030
movq %r14, %rdi
movl $0x29, %esi
callq 0x7c4e
addq $0x8, %rbp
incq %rbx
testq %rax, %rax
jne 0x5f0b
movq %r14, %rdi
movl $0x15, %esi
callq 0x7c4e
testq %rax, %rax
jne 0x5fa7
movq %r14, %rdi
leaq 0x3640(%rip), %rsi      # 0x95e2
callq 0x7ca4
movq 0x8(%rsp), %r13
movq 0x8(%r13), %rax
movq %rax, 0x10(%rsp)
movl $0x3, %edi
callq 0x7f14
movq %rax, %rbp
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x7f2e
movq %rax, 0x8(%r13)
movl %ebx, (%rbp)
movq %r13, %rbx
movq %r15, 0x8(%rbp)
movq %r12, 0x10(%rbp)
jmp 0x5ec5
movq %r14, %rdi
callq 0x6fc9
movq %rax, %r15
testq %rax, %rax
jne 0x6005
movq %r14, %rdi
leaq 0x355c(%rip), %rsi      # 0x955c
callq 0x7ca4
cmpl $0x4, (%r15)
je 0x601a
movq %r14, %rdi
leaq 0x3571(%rip), %rsi      # 0x9586
callq 0x7ca4
movq %r14, %rdi
movl $0x17, %esi
callq 0x7c4e
testq %rax, %rax
jne 0x603b
movq %r14, %rdi
leaq 0x3581(%rip), %rsi      # 0x95b7
callq 0x7ca4
movq 0x8(%rbx), %r12
movl $0x2, %edi
callq 0x7f14
movq %rax, %r13
movq %r12, %rdi
movq %rax, %rsi
callq 0x7f2e
movq %rax, 0x8(%rbx)
movq 0x8(%r15), %rax
movl (%rax), %eax
movl %eax, (%r13)
movq %r15, %rdi
callq 0x57a0
jmp 0x5ec5
movl $0x1, %ebp
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
movl $0x14, %esi
callq 0x7c4e
xorl %ebp, %ebp
testq %rax, %rax
je 0x6077
movq %r14, %rdi
movq %rbx, %rsi
callq 0x60d5
testl %eax, %eax
je 0x6077
movq %r14, %rdi
movl $0x15, %esi
callq 0x7c4e
testq %rax, %rax
jne 0x5ec0
leaq 0x346c(%rip), %rsi      # 0x9534
movq %r14, %rdi
callq 0x7ca4
jmp 0x5ec0