// File: /workspace/github_c_makefile_star2_O2/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
pushq %rax
movq %rsi, %rbx
movq %rsi, %rdi
callq 0x5d7f
movl %eax, 0x129bd(%rip)     # 0x18358
movl %eax, %eax
imulq $0x38, %rax, %rsi
pushq $0x1
popq %rdi
callq 0x20b0
movq %rax, 0x129b0(%rip)     # 0x18360
xorl %r12d, %r12d
leaq 0x12986(%rip), %r15     # 0x18340
testq %rbx, %rbx
je 0x5a5e
movq 0x18(%rbx), %r13
movq 0x12992(%rip), %rax     # 0x18360
movl %r12d, %ecx
imulq $0x38, %rcx, %r14
andq $0x0, 0x18(%rax,%r14)
movq 0x10(%rbx), %rax
movq 0x1297a(%rip), %rcx     # 0x18360
movq %rax, 0x10(%rcx,%r14)
movq 0x1296e(%rip), %rax     # 0x18360
movq (%rbx), %rcx
movq %rcx, 0x8(%rax,%r14)
movq 0x1295f(%rip), %rdx     # 0x18360
addq %r14, %rdx
movq %r13, %rdi
leaq 0x890(%rip), %rsi       # 0x629e
callq 0x5a89
movq 0x12946(%rip), %rdx     # 0x18360
andl $0x0, 0x28(%rdx,%r14)
addq %r14, %rdx
movq %r13, %rdi
leaq 0x9e4(%rip), %rsi       # 0x6411
callq 0x5a89
movl (%r15), %esi
testl %esi, %esi
jg 0x5a6d
addq 0x12920(%rip), %r14     # 0x18360
movq %r13, %rdi
leaq -0x2059(%rip), %rsi     # 0x39f1
movq %r14, %rdx
callq 0x5a89
movq 0x28(%rbx), %rbx
incl %r12d
jmp 0x59ba
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1db6(%rip), %rdi      # 0x782a
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2090