// File: /workspace/github_c_makefile_star2_O0/michaelforney[P]cproc/decl.c
// Function: declaratortypes
static void
declaratortypes(struct scope *s, struct list *result, char **name, struct scope **funcscope, bool allowabstract)
{
	struct list *ptr, *prev;
	struct type *t;
	struct decl *d, **paramend;
	struct expr *e;
	enum typequal tq;
	bool allowattr;

	while (consume(TMUL)) {
		attr(NULL, 0);
		tq = QUALNONE;
		while (typequal(&tq))
			;
		t = mkpointertype(NULL, tq);
		listinsert(result, &t->link);
	}
	if (name)
		*name = NULL;
	ptr = result->next;
	prev = ptr->prev;
	switch (tok.kind) {
	case TLPAREN:
		next();
		if (allowabstract) {
			switch (tok.kind) {
			case TMUL:
			case TLPAREN:
				break;
			case TIDENT:
				if (!istypename(s, tok.lit))
					break;
				/* fallthrough */
			default:
				allowattr = true;
				goto func;
			}
		}
		declaratortypes(s, result, name, funcscope, allowabstract);
		expect(TRPAREN, "after parenthesized declarator");
		allowattr = false;
		break;
	case TIDENT:
		if (!name)
			error(&tok.loc, "identifier not allowed in abstract declarator");
		*name = tok.lit;
		next();
		allowattr = true;
		break;
	default:
		if (!allowabstract)
			error(&tok.loc, "expected '(' or identifier");
		allowattr = true;
	}
	for (;;) {
		switch (tok.kind) {
		case TLPAREN:  /* function declarator */
			next();
		func:
			t = mktype(TYPEFUNC, 0);
			t->qual = QUALNONE;
			t->u.func.isvararg = false;
			t->u.func.params = NULL;
			t->u.func.nparam = 0;
			paramend = &t->u.func.params;
			s = mkscope(s);
			d = NULL;
			do {
				if (consume(TELLIPSIS)) {
					t->u.func.isvararg = true;
					break;
				}
				if (tok.kind == TRPAREN)
					break;
				d = parameter(s);
				if (d->name)
					scopeputdecl(s, d);
				*paramend = d;
				paramend = &d->next;
				++t->u.func.nparam;
			} while (consume(TCOMMA));
			expect(TRPAREN, "to close function declarator");
			if (funcscope && ptr->prev == prev) {
				/* we may need to re-open the scope later if this is a function definition */
				*funcscope = s;
				s = s->parent;
			} else {
				s = delscope(s);
			}
			if (t->u.func.nparam == 1 && !t->u.func.isvararg && d->type->kind == TYPEVOID && !d->name) {
				t->u.func.params = NULL;
				t->u.func.nparam = 0;
			}
			listinsert(ptr->prev, &t->link);
			allowattr = true;
			break;
		case TLBRACK:  /* array declarator */
			if (allowattr && attr(NULL, 0))
				goto attr;
			next();
			t = mkarraytype(NULL, QUALNONE, 0);
			while (consume(TSTATIC) || typequal(&t->u.array.ptrqual))
				;
			if (tok.kind == TMUL && peek(TRBRACK)) {
				t->prop |= PROPVM;
				t->incomplete = false;
			} else if (!consume(TRBRACK)) {
				e = assignexpr(s);
				if (!(e->type->prop & PROPINT))
					error(&tok.loc, "array length expression must have integer type");
				t->u.array.length = e;
				t->incomplete = false;
				expect(TRBRACK, "after array length");
			}
			listinsert(ptr->prev, &t->link);
			allowattr = true;
			break;
		case T__ATTRIBUTE__:
			if (!allowattr)
				error(&tok.loc, "attribute not allowed after parenthesized declarator");
			/* attribute applies to identifier if ptr->prev == result, otherwise type ptr->prev */
			gnuattr(NULL, 0);
		attr:
			break;
		default:
			return;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movl $0x4b, %edi
callq 0xd910
testb $0x1, %al
jne 0x6950
jmp 0x6995
xorl %eax, %eax
movl %eax, %edi
xorl %esi, %esi
callq 0x3360
movl $0x0, -0x5c(%rbp)
leaq -0x5c(%rbp), %rdi
callq 0x55b0
cmpl $0x0, %eax
je 0x6972
jmp 0x6962
movl -0x5c(%rbp), %esi
xorl %eax, %eax
movl %eax, %edi
callq 0x11760
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
addq $0x28, %rsi
callq 0x12a50
jmp 0x6940
cmpq $0x0, -0x18(%rbp)
je 0x69a7
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
leaq 0x1b7e3(%rip), %rax     # 0x221a8
movl (%rax), %eax
movl %eax, -0x64(%rbp)
subl $0x4, %eax
je 0x6a73
jmp 0x69d5
movl -0x64(%rbp), %eax
subl $0x42, %eax
jne 0x6ab0
jmp 0x69e3
callq 0xd540
testb $0x1, -0x21(%rbp)
je 0x6a3e
leaq 0x1b7b3(%rip), %rax     # 0x221a8
movl (%rax), %eax
movl %eax, -0x68(%rbp)
subl $0x4, %eax
je 0x6a17
jmp 0x6a01
movl -0x68(%rbp), %eax
subl $0x42, %eax
je 0x6a15
jmp 0x6a0b
movl -0x68(%rbp), %eax
subl $0x4b, %eax
jne 0x6a33
jmp 0x6a15
jmp 0x6a3c
movq -0x8(%rbp), %rdi
leaq 0x1b786(%rip), %rax     # 0x221a8
movq 0x20(%rax), %rsi
callq 0x6e00
testb $0x1, %al
jne 0x6a31
jmp 0x6a3c
jmp 0x6a33
movb $0x1, -0x5d(%rbp)
jmp 0x6b0d
jmp 0x6a3e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movb -0x21(%rbp), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x6920
movl $0x43, %edi
leaq 0x124ee(%rip), %rsi     # 0x18f56
callq 0xd8d0
movb $0x0, -0x5d(%rbp)
jmp 0x6ad3
cmpq $0x0, -0x18(%rbp)
jne 0x6a93
leaq 0x1b727(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x1240c(%rip), %rsi     # 0x18e98
movb $0x0, %al
callq 0x11190
leaq 0x1b70e(%rip), %rax     # 0x221a8
movq 0x20(%rax), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
callq 0xd540
movb $0x1, -0x5d(%rbp)
jmp 0x6ad3
testb $0x1, -0x21(%rbp)
jne 0x6acf
leaq 0x1b6eb(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x123fe(%rip), %rsi     # 0x18ec6
movb $0x0, %al
callq 0x11190
movb $0x1, -0x5d(%rbp)
jmp 0x6ad5
leaq 0x1b6cc(%rip), %rax     # 0x221a8
movl (%rax), %eax
movl %eax, -0x6c(%rbp)
subl $0x3f, %eax
je 0x6dc7
jmp 0x6aec
movl -0x6c(%rbp), %eax
subl $0x40, %eax
je 0x6c9e
jmp 0x6afa
movl -0x6c(%rbp), %eax
subl $0x42, %eax
jne 0x6df3
jmp 0x6b08
callq 0xd540
movl $0xe, %edi
xorl %esi, %esi
callq 0x11700
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x0, 0x38(%rax)
movq -0x40(%rbp), %rax
movb $0x0, 0x40(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x48(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x50(%rax)
movq -0x40(%rbp), %rax
addq $0x40, %rax
addq $0x8, %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
callq 0xfe10
movq %rax, -0x8(%rbp)
movq $0x0, -0x48(%rbp)
movl $0x62, %edi
callq 0xd910
testb $0x1, %al
jne 0x6b7d
jmp 0x6b87
movq -0x40(%rbp), %rax
movb $0x1, 0x40(%rax)
jmp 0x6bf2
leaq 0x1b61a(%rip), %rax     # 0x221a8
cmpl $0x43, (%rax)
jne 0x6b95
jmp 0x6bf2
movq -0x8(%rbp), %rdi
callq 0x6e50
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq $0x0, (%rax)
je 0x6bb9
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0xfd90
movq -0x48(%rbp), %rcx
movq -0x50(%rbp), %rax
movq %rcx, (%rax)
movq -0x48(%rbp), %rax
addq $0x38, %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x50(%rax)
movl $0x6e, %edi
callq 0xd910
testb $0x1, %al
jne 0x6b6d
movl $0x43, %edi
leaq 0x122e3(%rip), %rsi     # 0x18ee1
callq 0xd8d0
cmpq $0x0, -0x20(%rbp)
je 0x6c30
movq -0x30(%rbp), %rax
movq (%rax), %rax
cmpq -0x38(%rbp), %rax
jne 0x6c30
movq -0x8(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x8(%rbp)
jmp 0x6c3d
movq -0x8(%rbp), %rdi
callq 0xfe90
movq %rax, -0x8(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x1, 0x50(%rax)
jne 0x6c81
movq -0x40(%rbp), %rax
testb $0x1, 0x40(%rax)
jne 0x6c81
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
cmpl $0x1, (%rax)
jne 0x6c81
movq -0x48(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x6c81
movq -0x40(%rbp), %rax
movq $0x0, 0x48(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x50(%rax)
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq -0x40(%rbp), %rsi
addq $0x28, %rsi
callq 0x12a50
movb $0x1, -0x5d(%rbp)
jmp 0x6df9
testb $0x1, -0x5d(%rbp)
je 0x6cba
xorl %eax, %eax
movl %eax, %edi
xorl %esi, %esi
callq 0x3360
testb $0x1, %al
jne 0x6cb5
jmp 0x6cba
jmp 0x6df1
callq 0xd540
xorl %eax, %eax
movl %eax, %edx
xorl %esi, %esi
movq %rdx, %rdi
callq 0x117e0
movq %rax, -0x40(%rbp)
movl $0x27, %edi
callq 0xd910
movb %al, %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x6d(%rbp)
jne 0x6d01
movq -0x40(%rbp), %rdi
addq $0x40, %rdi
addq $0x8, %rdi
callq 0x55b0
cmpl $0x0, %eax
setne %al
movb %al, -0x6d(%rbp)
movb -0x6d(%rbp), %al
testb $0x1, %al
jne 0x6d0a
jmp 0x6d0c
jmp 0x6cd1
leaq 0x1b495(%rip), %rax     # 0x221a8
cmpl $0x4b, (%rax)
jne 0x6d3f
movl $0x41, %edi
callq 0xd7b0
testb $0x1, %al
jne 0x6d28
jmp 0x6d3f
movq -0x40(%rbp), %rax
movl 0x4(%rax), %ecx
orl $0x40, %ecx
movl %ecx, 0x4(%rax)
movq -0x40(%rbp), %rax
movb $0x0, 0x3c(%rax)
jmp 0x6dad
movl $0x41, %edi
callq 0xd910
testb $0x1, %al
jne 0x6dab
movq -0x8(%rbp), %rdi
callq 0x9170
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x6d86
leaq 0x1b434(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x1217f(%rip), %rsi     # 0x18efe
movb $0x0, %al
callq 0x11190
movq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x40(%rbp), %rax
movb $0x0, 0x3c(%rax)
movl $0x41, %edi
leaq 0x12187(%rip), %rsi     # 0x18f2d
callq 0xd8d0
jmp 0x6dad
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq -0x40(%rbp), %rsi
addq $0x28, %rsi
callq 0x12a50
movb $0x1, -0x5d(%rbp)
jmp 0x6df9
testb $0x1, -0x5d(%rbp)
jne 0x6de6
leaq 0x1b3d4(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x12161(%rip), %rsi     # 0x18f40
movb $0x0, %al
callq 0x11190
xorl %eax, %eax
movl %eax, %edi
xorl %esi, %esi
callq 0x3450
jmp 0x6df9
addq $0x70, %rsp
popq %rbp
retq
jmp 0x6ad5
nop