// File: /workspace/github_c_makefile_star2_O1/gregtour[P]minimal-compiler/preprocess.c
// Function: SecondPassStaticAnalysis
void SecondPassStaticAnalysis(SOURCE* sources, FUNCTION* functions, VARLIST* variables)
{
    FUNCTION* iterator;
    unsigned int funcIndex;

    // allocate data table
    gPrgrmFunctionCount = FunctionCount(functions);
    gPrgrmFunctionTable = (FUNC_SEGMENT*)malloc(gPrgrmFunctionCount * sizeof(FUNC_SEGMENT));

    AssertS(gPrgrmFunctionCount > 0, "Program contains no functions.");

    memset((void*)gPrgrmFunctionTable, 0, sizeof(FUNC_SEGMENT) * gPrgrmFunctionCount);

    // process each function
    iterator = functions;
    funcIndex = 0;
    while (iterator)
    {
        SYNTAX_BLOCK* block = iterator->block;

        Assert(funcIndex == iterator->index);

        // set function header properly
        gPrgrmFunctionTable[funcIndex].locals = NULL;
        gPrgrmFunctionTable[funcIndex].params = iterator->parameters;
        gPrgrmFunctionTable[funcIndex].returnType = iterator->type;

        // step zero, create local variable list
        ProcessCodeBlock(block, CreateLocalVariables, (void*)&gPrgrmFunctionTable[funcIndex]);

        // step one, perform type-checking on all statements
        gPrgrmFunctionTable[funcIndex].isInLoop = 0;
        ProcessCodeBlock(block, StaticTypeChecking, (void*)&gPrgrmFunctionTable[funcIndex]);

        // should halt on compiler _errors_ here
        if (compiler_error_count > 0)
        {
            printf("Too many errors. (%i)\n", compiler_error_count);
            return;
        }

        // our one built in function
        /*if (strcmp("printf", iterator->identifier) == 0)
        {
            Assert(iterator->type.basic == TYPE_INTEGER);
            Assert(iterator->parameters);
            Assert(iterator->parameters->type.basic == TYPE_STRING);
            // ...
            ProcessPrintf(block, &gPrgrmFunctionTable[funcIndex]);
            iterator = iterator->next;
            funcIndex++;
            continue;
        }*/

        // step two, generate intermediate code
        ProcessCodeBlock(block, GenerateIntermediateCode, (void*)&gPrgrmFunctionTable[funcIndex]);

        // ...

        // iterate on all functions
        iterator = iterator->next;
        funcIndex++;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r13
movq %rsi, %rdi
callq 0x6355
movl %eax, 0x135c7(%rip)     # 0x19358
movl %eax, %eax
imulq $0x38, %rax, %r14
movq %r14, %rdi
callq 0x2100
movq %rax, 0x135ba(%rip)     # 0x19360
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x20b0
movl $0x0, -0x2c(%rbp)
testq %r13, %r13
je 0x5fec
movq 0x18(%r13), %rbx
movq 0x13592(%rip), %rax     # 0x19360
movl -0x2c(%rbp), %ecx
imulq $0x38, %rcx, %r15
movq $0x0, 0x18(%rax,%r15)
movq 0x10(%r13), %rax
movq 0x13577(%rip), %rcx     # 0x19360
movq %rax, 0x10(%rcx,%r15)
movq 0x1356b(%rip), %rax     # 0x19360
movq %r13, -0x38(%rbp)
movq (%r13), %rcx
movq %rcx, 0x8(%rax,%r15)
testq %rbx, %rbx
je 0x5e92
movl 0x4(%rbx), %eax
cmpl $0xf, %eax
je 0x5e38
movl $0x0, %r14d
movl $0x0, %r12d
cmpl $0x10, %eax
jne 0x5e4c
movq 0x28(%rbx), %rax
movq 0x8(%rax), %r14
cmpl $0x13, 0x4(%r14)
jne 0x5e49
movq %r14, %rax
jmp 0x5e3d
movq %rbx, %r14
xorl %eax, %eax
movq 0x28(%r14), %rcx
movq (%rcx), %r12
movq %rax, %r14
jmp 0x5e4c
xorl %r12d, %r12d
testq %r12, %r12
je 0x5e92
movq 0x13508(%rip), %r13     # 0x19360
addq %r15, %r13
testq %r14, %r14
je 0x5e7b
movq 0x28(%r14), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r12
movl $0x0, %r14d
cmovneq %rcx, %r14
jmp 0x5e7e
xorl %r14d, %r14d
movq %r12, %rdi
movq %r13, %rsi
callq 0x6995
testl %eax, %eax
jne 0x5e92
testq %r14, %r14
jne 0x5e5b
movq 0x134c7(%rip), %r12     # 0x19360
movl $0x0, 0x28(%r12,%r15)
testq %rbx, %rbx
je 0x5f2b
movl 0x4(%rbx), %eax
cmpl $0xf, %eax
je 0x5ed8
movl $0x0, %r14d
movl $0x0, %r13d
cmpl $0x10, %eax
jne 0x5eec
movq 0x28(%rbx), %rax
movq 0x8(%rax), %r14
cmpl $0x13, 0x4(%r14)
jne 0x5ee9
movq %r14, %rax
jmp 0x5edd
movq %rbx, %r14
xorl %eax, %eax
movq 0x28(%r14), %rcx
movq (%rcx), %r13
movq %rax, %r14
jmp 0x5eec
xorl %r13d, %r13d
testq %r13, %r13
je 0x5f2b
addq %r15, %r12
testq %r14, %r14
je 0x5f14
movq 0x28(%r14), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r13
movl $0x0, %r14d
cmovneq %rcx, %r14
jmp 0x5f17
xorl %r14d, %r14d
movq %r13, %rdi
movq %r12, %rsi
callq 0x6b07
testl %eax, %eax
jne 0x5f2b
testq %r14, %r14
jne 0x5ef4
leaq 0x1340e(%rip), %rax     # 0x19340
movl (%rax), %r12d
testl %r12d, %r12d
jle 0x5f54
leaq 0x28e9(%rip), %rdi      # 0x882a
movl %r12d, %esi
xorl %eax, %eax
callq 0x2090
movq -0x38(%rbp), %r13
jmp 0x5fe3
testq %rbx, %rbx
je 0x5fd8
movl 0x4(%rbx), %eax
cmpl $0xf, %eax
je 0x5f86
movl $0x0, %r14d
movl $0x0, %r13d
cmpl $0x10, %eax
jne 0x5f95
movq 0x28(%rbx), %rax
movq 0x8(%rax), %r14
cmpl $0x13, 0x4(%r14)
jne 0x5f92
movq %r14, %rbx
jmp 0x5f89
xorl %r14d, %r14d
movq 0x28(%rbx), %rax
movq (%rax), %r13
jmp 0x5f95
xorl %r13d, %r13d
testq %r13, %r13
je 0x5fd8
addq 0x133bf(%rip), %r15     # 0x19360
testq %r14, %r14
je 0x5fc1
movq 0x28(%r14), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r13
movl $0x0, %r14d
cmovneq %rcx, %r14
jmp 0x5fc4
xorl %r14d, %r14d
movq %r13, %rdi
movq %r15, %rsi
callq 0x3ae9
testl %eax, %eax
jne 0x5fd8
testq %r14, %r14
jne 0x5fa1
movq -0x38(%rbp), %r13
movq 0x28(%r13), %r13
incl -0x2c(%rbp)
testl %r12d, %r12d
jle 0x5dba
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq