// File: /workspace/github_c_makefile_star2_O2/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, %r13
movq %rdi, %r14
pushq $0xc
popq %rsi
callq 0x7116
testq %rax, %rax
je 0x5717
movq %rax, %rbx
cmpq $0x0, (%r13)
je 0x5526
leaq 0x2ff2(%rip), %rsi      # 0x8510
movq %r14, %rdi
callq 0x7167
movq (%rbx), %rbx
movq %rbx, %rdi
callq 0x2070
movq %rax, %r15
incl %eax
movslq %eax, %rdi
callq 0x20f0
movq %rax, %r12
movq %rax, (%r13)
movslq %r15d, %r15
movq %rax, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x20e0
movb $0x0, (%r12,%r15)
pushq $0x16
popq %rbp
movq %r13, 0x8(%rsp)
movq %r14, %rdi
movl %ebp, %esi
callq 0x7116
testq %rax, %rax
jne 0x5586
movq %r14, %rdi
pushq $0x14
popq %rsi
callq 0x7116
testq %rax, %rax
je 0x5703
movl 0x14(%rax), %eax
cmpl $0x16, %eax
je 0x567b
cmpl $0x14, %eax
jne 0x5563
pushq $0x8
popq %rbp
xorl %r13d, %r13d
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %r14, %rdi
callq 0x57cd
testq %rax, %rax
je 0x561b
movq %rax, %rbx
testq %r13, %r13
je 0x55d3
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2100
movq %rax, %r12
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2100
jmp 0x55ea
pushq $0x8
popq %r15
movq %r15, %rdi
callq 0x20f0
movq %rax, %r12
movq %r15, %rdi
callq 0x20f0
movq %rax, %r15
movq (%rbx), %rax
movq %rax, (%r12,%r13,8)
movq 0x8(%rbx), %rax
movq %rax, (%r15,%r13,8)
movq %rbx, %rdi
callq 0x2030
movq %r14, %rdi
pushq $0x29
popq %rsi
callq 0x7116
addq $0x8, %rbp
incq %r13
testq %rax, %rax
jne 0x55a3
movq %r14, %rdi
pushq $0x15
popq %rsi
callq 0x7116
testq %rax, %rax
jne 0x563a
movq %r14, %rdi
leaq 0x2fad(%rip), %rsi      # 0x85e2
callq 0x7167
movq 0x8(%rsp), %rbx
movq 0x8(%rbx), %rax
movq %rax, 0x10(%rsp)
pushq $0x3
popq %rdi
callq 0x73c8
movq %rax, %rbp
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x73dd
movq %rax, 0x8(%rbx)
movl %r13d, (%rbp)
movq %rbx, %r13
movq %r12, 0x8(%rbp)
movq %r15, 0x10(%rbp)
pushq $0x16
popq %rbp
jmp 0x5563
movq %r14, %rdi
callq 0x6509
movq %rax, %r15
testq %rax, %rax
jne 0x569a
movq %r14, %rdi
leaq 0x2ec7(%rip), %rsi      # 0x855c
callq 0x7167
cmpl $0x4, (%r15)
je 0x56af
movq %r14, %rdi
leaq 0x2edc(%rip), %rsi      # 0x8586
callq 0x7167
movq %r14, %rdi
pushq $0x17
popq %rsi
callq 0x7116
testq %rax, %rax
jne 0x56ce
movq %r14, %rdi
leaq 0x2eee(%rip), %rsi      # 0x85b7
callq 0x7167
movq 0x8(%r13), %rbx
pushq $0x2
popq %rdi
callq 0x73c8
movq %rax, %r12
movq %rbx, %rdi
movq %rax, %rsi
callq 0x73dd
movq %rax, 0x8(%r13)
movq 0x8(%r15), %rax
movl (%rax), %eax
movl %eax, (%r12)
movq %r15, %rdi
callq 0x5058
jmp 0x5563
pushq $0x1
popq %rcx
movl %ecx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x14
popq %rsi
movq %r14, %rdi
callq 0x7116
xorl %ecx, %ecx
testq %rax, %rax
je 0x5706
movq %r14, %rdi
movq %r13, %rsi
callq 0x5762
xorl %ecx, %ecx
testl %eax, %eax
je 0x5706
pushq $0x15
popq %rsi
movq %r14, %rdi
callq 0x7116
testq %rax, %rax
jne 0x555b
leaq 0x2ddf(%rip), %rsi      # 0x8534
movq %r14, %rdi
callq 0x7167
jmp 0x555b