// File: /workspace/github_c_makefile_star2_O2/michaelforney[P]cproc/decl.c
// Function: decl
bool
decl(struct scope *s, struct func *f)
{
	struct qualtype base, qt;
	struct type *t;
	enum typequal tq;
	enum storageclass sc;
	enum funcspec fs;
	struct init *init;
	bool hasinit;
	char *name, *asmname;
	int allowfunc = !f;
	struct decl *d, *prior;
	enum declkind kind;
	struct scope *funcscope;
	int align;

	if (staticassert(s))
		return true;
	if (attr(NULL, 0) && consume(TSEMICOLON))
		return true;
	base = declspecs(s, &sc, &fs, &align);
	if (!base.type)
		return false;
	if (f) {
		if (sc == SCTHREADLOCAL)
			error(&tok.loc, "block scope declaration containing 'thread_local' must contain 'static' or 'extern'");
	} else {
		/* 6.9p2 */
		if (sc & SCAUTO)
			error(&tok.loc, "external declaration must not contain 'auto'");
		if (sc & SCREGISTER)
			error(&tok.loc, "external declaration must not contain 'register'");
	}
	if (consume(TSEMICOLON)) {
		/* XXX 6.7p2 error unless in function parameter/struct/union, or tag/enum members are declared */
		return true;
	}
	for (;;) {
		qt = declarator(s, base, &name, &funcscope, false);
		t = qt.type;
		tq = qt.qual;
		if (consume(T__ASM__)) {
			expect(TLPAREN, "after __asm__");
			asmname = expect(TSTRINGLIT, "for assembler name");
			expect(TRPAREN, "after assembler name");
			allowfunc = 0;
		} else {
			asmname = NULL;
		}
		kind = sc & SCTYPEDEF ? DECLTYPE : t->kind == TYPEFUNC ? DECLFUNC : DECLOBJECT;
		prior = scopegetdecl(s, name, false);
		if (prior && prior->kind != kind)
			error(&tok.loc, "'%s' redeclared with different kind", name);
		switch (kind) {
		case DECLTYPE:
			if (align)
				error(&tok.loc, "typedef '%s' declared with alignment specifier", name);
			if (asmname)
				error(&tok.loc, "typedef '%s' declared with assembler label", name);
			if (!prior)
				scopeputdecl(s, mkdecl(name, DECLTYPE, t, tq, LINKNONE));
			else if (!typesame(prior->type, t) || prior->qual != tq)
				error(&tok.loc, "typedef '%s' redefined with different type", name);
			break;
		case DECLOBJECT:
			if (align && align < t->align)
				error(&tok.loc, "object '%s' requires alignment %d, which is stricter than specified alignment %d", name, t->align, align);
			d = declcommon(s, kind, name, asmname, t, tq, sc, prior);
			if (d->u.obj.align < align)
				d->u.obj.align = align;
			if (d->linkage == LINKNONE && !(sc & SCSTATIC)) {
				d->u.obj.storage = SDAUTO;
			} else {
				d->u.obj.storage = sc & SCTHREADLOCAL ? SDTHREAD : SDSTATIC;
				if (t->prop & PROPVM)
					error(&tok.loc, "object '%s' with %s storage duration cannot have variably modified type", name, d->u.obj.storage == SDSTATIC ? "static" : "thread");
				d->value = mkglobal(d);
			}

			if (base.expr)
				funcexpr(f, base.expr);
			init = NULL;
			hasinit = false;
			if (consume(TASSIGN)) {
				if (f && d->linkage != LINKNONE)
					error(&tok.loc, "object '%s' with block scope and %s linkage cannot have initializer", name, d->linkage == LINKEXTERN ? "external" : "internal");
				if (d->defined)
					error(&tok.loc, "object '%s' redefined", name);
				init = parseinit(s, d->type);
				hasinit = true;
			} else if (sc & SCEXTERN) {
				break;
			} else if (d->linkage != LINKNONE && d->u.obj.storage == SDSTATIC) {
				if (!d->defined && !d->tentative) {
					d->tentative = true;
					*tentativedefnsend = d;
					tentativedefnsend = &d->next;
				}
				break;
			}
			defineobj(d, init, hasinit, f);
			break;
		case DECLFUNC:
			if (align)
				error(&tok.loc, "function '%s' declared with alignment specifier", name);
			if (f && sc && sc != SCEXTERN)  /* 6.7.1p7 */
				error(&tok.loc, "function '%s' with block scope may only have storage class 'extern'", name);
			d = declcommon(s, kind, name, asmname, t, tq, sc, prior);
			d->value = mkglobal(d);
			d->u.func.inlinedefn = d->linkage == LINKEXTERN && fs & FUNCINLINE && !(sc & SCEXTERN) && (!prior || prior->u.func.inlinedefn);
			d->u.func.isnoreturn = fs & FUNCNORETURN;
			if (tok.kind == TLBRACE) {
				if (!allowfunc)
					error(&tok.loc, "function definition not allowed");
				if (d->defined)
					error(&tok.loc, "function '%s' redefined", name);
				/* re-open scope from function declarator */
				assert(funcscope);
				s = funcscope;
				f = mkfunc(d, name, t, s);
				stmt(f, s);
				if (d->u.func.isnoreturn)
					funchlt(f);
				/* XXX: need to keep track of function in case a later declaration specifies extern */
				if (!d->u.func.inlinedefn)
					emitfunc(f, d->linkage == LINKEXTERN);
				s = delscope(s);
				delfunc(f);
				d->defined = true;
				return true;
			} else if (funcscope) {
				delscope(funcscope);
			}
			break;
		}
		if (consume(TSEMICOLON))
			return true;
		expect(TCOMMA, "or ';' after declarator");
		allowfunc = 0;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %r15
movq %rsi, 0x20(%rsp)
testq %rsi, %rsi
setne %r14b
callq 0x4ee5
movb $0x1, %bpl
testb %al, %al
jne 0x4eb5
xorl %edi, %edi
xorl %esi, %esi
callq 0x334c
testb %al, %al
je 0x4933
pushq $0x61
popq %rdi
callq 0xa28d
testb %al, %al
jne 0x4eb5
leaq 0x38(%rsp), %rbx
leaq 0xc(%rsp), %rdx
leaq 0x2c(%rsp), %rcx
leaq 0x28(%rsp), %r8
movq %rbx, %rdi
movq %r15, %rsi
callq 0x381f
cmpq $0x0, (%rbx)
je 0x4972
movl 0xc(%rsp), %eax
cmpq $0x0, 0x20(%rsp)
je 0x4979
cmpl $0x40, %eax
jne 0x49b7
leaq 0xc868(%rip), %rsi      # 0x111d8
jmp 0x49a5
xorl %ebp, %ebp
jmp 0x4eb5
testb $0x10, %al
je 0x499a
leaq 0x17784(%rip), %rdi     # 0x1c108
addq $0x8, %rdi
leaq 0xc89d(%rip), %rsi      # 0x1122c
xorl %eax, %eax
callq 0xc536
movl 0xc(%rsp), %eax
testb $0x20, %al
je 0x49b7
leaq 0xc8b4(%rip), %rsi      # 0x11259
leaq 0x1775c(%rip), %rdi     # 0x1c108
addq $0x8, %rdi
xorl %eax, %eax
callq 0xc536
pushq $0x61
popq %rdi
callq 0xa28d
testb %al, %al
jne 0x4eb5
leaq 0x1773a(%rip), %rax     # 0x1c108
addq $0x8, %rax
movq %rax, 0x18(%rsp)
subq $0x20, %rsp
movq 0x68(%rsp), %rax
movq %rax, 0x10(%rsp)
movups 0x58(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0x70(%rsp), %rdi
movq %r15, %rsi
leaq 0x30(%rsp), %rdx
leaq 0x50(%rsp), %rcx
xorl %r8d, %r8d
callq 0x46fd
addq $0x20, %rsp
movq 0x50(%rsp), %rbp
movl 0x58(%rsp), %r13d
pushq $0x3e
popq %rdi
callq 0xa28d
testb %al, %al
je 0x4a59
pushq $0x42
popq %rdi
leaq 0xc85e(%rip), %rsi      # 0x1128a
callq 0xa26e
pushq $0x7
popq %rdi
leaq 0xc85d(%rip), %rsi      # 0x11298
callq 0xa26e
movq %rax, %r14
pushq $0x43
popq %rdi
leaq 0xc85e(%rip), %rsi      # 0x112ab
callq 0xa26e
movb $0x1, 0xb(%rsp)
jmp 0x4a61
movb %r14b, 0xb(%rsp)
xorl %r14d, %r14d
xorl %r12d, %r12d
testb $0x2, 0xc(%rsp)
jne 0x4a79
xorl %r12d, %r12d
cmpl $0xe, (%rbp)
sete %r12b
incl %r12d
movq 0x10(%rsp), %rsi
movq %r15, %rdi
xorl %edx, %edx
callq 0xb758
movq %rax, %rbx
testq %rax, %rax
je 0x4aae
cmpl %r12d, 0x8(%rbx)
je 0x4aae
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc819(%rip), %rsi      # 0x112c0
xorl %eax, %eax
callq 0xc536
movl 0x28(%rsp), %r8d
cmpl $0x2, %r12d
je 0x4b36
cmpl $0x1, %r12d
jne 0x4bd7
testl %r8d, %r8d
je 0x4ae8
movl 0x8(%rbp), %ecx
cmpl %ecx, %r8d
jge 0x4ae8
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc888(%rip), %rsi      # 0x11369
xorl %eax, %eax
callq 0xc536
movq 0x10(%rsp), %rdx
movl 0xc(%rsp), %eax
movq %r15, %rdi
pushq $0x1
popq %rsi
movq %r14, %rcx
movq %rbp, %r8
movl %r13d, %r9d
pushq %rbx
pushq %rax
callq 0x4fbd
popq %rcx
popq %rdx
movq %rax, %rbx
movl 0x28(%rsp), %eax
cmpl %eax, 0x40(%rbx)
jge 0x4b18
movl %eax, 0x40(%rbx)
movl 0xc(%rsp), %eax
movl %eax, %ecx
andl $0x8, %ecx
orl 0xc(%rbx), %ecx
jne 0x4c51
movl $0x2, 0x44(%rbx)
jmp 0x4c98
testl %r8d, %r8d
je 0x4b53
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc929(%rip), %rsi      # 0x11475
xorl %eax, %eax
callq 0xc536
cmpq $0x0, 0x20(%rsp)
setne %cl
movl 0xc(%rsp), %eax
testl $0xfffffffb, %eax       # imm = 0xFFFFFFFB
setne %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x4b8b
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc925(%rip), %rsi      # 0x114a5
xorl %eax, %eax
callq 0xc536
movl 0xc(%rsp), %eax
movq 0x10(%rsp), %rdx
movq %r15, %rdi
pushq $0x2
popq %rsi
movq %r14, %rcx
movq %rbp, %r8
movl %r13d, %r9d
pushq %rbx
pushq %rax
callq 0x4fbd
popq %rcx
popq %rdx
movq %rax, %r14
movq %rax, %rdi
callq 0xd2c0
movq %rax, 0x20(%r14)
cmpl $0x2, 0xc(%r14)
setne %cl
movl 0x2c(%rsp), %eax
testb $0x2, %al
sete %dl
orb %cl, %dl
je 0x4d55
xorl %ecx, %ecx
jmp 0x4d70
testl %r8d, %r8d
je 0x4bf4
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc6f7(%rip), %rsi      # 0x112e4
xorl %eax, %eax
callq 0xc536
testq %r14, %r14
je 0x4c11
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc709(%rip), %rsi      # 0x11313
xorl %eax, %eax
callq 0xc536
testq %rbx, %rbx
je 0x4d9e
movq 0x10(%rbx), %rdi
movq %rbp, %rsi
callq 0xc959
testb %al, %al
je 0x4c34
cmpl %r13d, 0x18(%rbx)
je 0x4dbe
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc6f9(%rip), %rsi      # 0x1133e
xorl %eax, %eax
callq 0xc536
jmp 0x4dbe
shrl $0x6, %eax
andl $0x1, %eax
movl %eax, 0x44(%rbx)
testb $0x40, 0x4(%rbp)
je 0x4c8c
movq 0x10(%rsp), %rdx
testl %eax, %eax
leaq 0xeefe(%rip), %rcx      # 0x13b6c
leaq 0xc78d(%rip), %rax      # 0x11402
cmoveq %rax, %rcx
movq 0x18(%rsp), %rdi
leaq 0xc735(%rip), %rsi      # 0x113ba
xorl %eax, %eax
callq 0xc536
movq %rbx, %rdi
callq 0xd2c0
movq %rax, 0x20(%rbx)
movq 0x48(%rsp), %rsi
testq %rsi, %rsi
je 0x4cac
movq 0x20(%rsp), %rdi
callq 0xdfc5
pushq $0x63
popq %rdi
callq 0xa28d
movl %eax, %ebp
testb %al, %al
je 0x4d25
cmpq $0x0, 0x20(%rsp)
je 0x4cf6
movl 0xc(%rbx), %eax
testl %eax, %eax
je 0x4cf6
movq 0x10(%rsp), %rdx
cmpl $0x2, %eax
leaq 0xc77e(%rip), %rcx      # 0x11456
leaq 0xc76e(%rip), %rax      # 0x1144d
cmoveq %rax, %rcx
movq 0x18(%rsp), %rdi
leaq 0xc71a(%rip), %rsi      # 0x11409
xorl %eax, %eax
callq 0xc536
cmpb $0x1, 0x30(%rbx)
jne 0x4d14
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rdi
leaq 0xc752(%rip), %rsi      # 0x1145f
xorl %eax, %eax
callq 0xc536
movq 0x10(%rbx), %rsi
movq %r15, %rdi
callq 0x8f44
movq %rax, %rsi
jmp 0x4d42
testb $0x4, 0xc(%rsp)
jne 0x4dbe
cmpl $0x0, 0xc(%rbx)
je 0x4d40
cmpl $0x0, 0x44(%rbx)
je 0x4de1
xorl %esi, %esi
movzbl %bpl, %edx
movq %rbx, %rdi
movq 0x20(%rsp), %rcx
callq 0x52d7
jmp 0x4dbe
testq %rbx, %rbx
sete %dl
movl 0xc(%rsp), %esi
andl $0x4, %esi
sete %cl
shrl $0x2, %esi
orb %dl, %sil
jne 0x4d70
movb 0x40(%rbx), %cl
movb %cl, 0x40(%r14)
shrb $0x2, %al
andb $0x1, %al
movb %al, 0x41(%r14)
leaq 0x17384(%rip), %rax     # 0x1c108
cmpl $0x44, (%rax)
je 0x4e10
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x4dbe
callq 0xb718
jmp 0x4dbe
movq 0x10(%rsp), %rdi
xorl %esi, %esi
movq %rbp, %rdx
movl %r13d, %ecx
xorl %r8d, %r8d
callq 0x3724
movq %r15, %rdi
movq %rax, %rsi
callq 0xb693
pushq $0x61
popq %rdi
callq 0xa28d
testb %al, %al
jne 0x4e08
pushq $0x6e
popq %rdi
leaq 0xc788(%rip), %rsi      # 0x1155c
callq 0xa26e
movb $0x1, %r14b
jmp 0x49d7
cmpb $0x0, 0x30(%rbx)
jne 0x4dbe
cmpb $0x0, 0x31(%rbx)
jne 0x4dbe
movb $0x1, 0x31(%rbx)
movq 0x16348(%rip), %rax     # 0x1b140
movq %rbx, (%rax)
addq $0x38, %rbx
movq %rbx, 0x1633a(%rip)     # 0x1b140
jmp 0x4dbe
movb $0x1, %bpl
jmp 0x4eb5
testb $0x1, 0xb(%rsp)
je 0x4e2a
leaq 0xc6cb(%rip), %rsi      # 0x114e9
movq 0x18(%rsp), %rdi
xorl %eax, %eax
callq 0xc536
cmpb $0x1, 0x30(%r14)
jne 0x4e49
movq 0x10(%rsp), %rdx
leaq 0xc6cc(%rip), %rsi      # 0x11509
movq 0x18(%rsp), %rdi
xorl %eax, %eax
callq 0xc536
movq 0x30(%rsp), %rbx
testq %rbx, %rbx
je 0x4ec6
movq 0x10(%rsp), %rsi
movq %r14, %rdi
movq %rbp, %rdx
movq %rbx, %rcx
callq 0xd32f
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0xb870
cmpb $0x1, 0x41(%r14)
jne 0x4e83
movq %r15, %rdi
callq 0xdf48
cmpb $0x0, 0x40(%r14)
movb $0x1, %bpl
jne 0x4ea0
xorl %esi, %esi
cmpl $0x2, 0xc(%r14)
sete %sil
movq %r15, %rdi
callq 0xf389
movq %rbx, %rdi
callq 0xb718
movq %r15, %rdi
callq 0xdb72
movb $0x1, 0x30(%r14)
movl %ebp, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xc654(%rip), %rdi      # 0x11521
leaq 0xc657(%rip), %rsi      # 0x1152b
leaq 0xc657(%rip), %rcx      # 0x11532
movl $0x449, %edx            # imm = 0x449
callq 0x30e0