// File: /workspace/github_c_makefile_star2_O3/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, %rbx
movq %rsi, %rdi
callq 0x6460
movl %eax, 0x134a1(%rip)     # 0x19358
movl %eax, %eax
imulq $0x38, %rax, %rsi
movl $0x1, %edi
callq 0x20b0
movq %rax, 0x13492(%rip)     # 0x19360
testq %rbx, %rbx
je 0x60f1
xorl %r13d, %r13d
movq 0x18(%rbx), %rdx
movq 0x1347b(%rip), %rax     # 0x19360
movl %r13d, %r13d
imulq $0x38, %r13, %r14
movq $0x0, 0x18(%rax,%r14)
movq 0x10(%rbx), %rax
movq 0x13460(%rip), %rcx     # 0x19360
movq %rax, 0x10(%rcx,%r14)
movq 0x13454(%rip), %rax     # 0x19360
movq (%rbx), %rcx
movq %rcx, 0x8(%rax,%r14)
movq 0x13445(%rip), %r15     # 0x19360
testq %rdx, %rdx
je 0x5f57
movq %rdx, %rcx
movq %r13, -0x38(%rbp)
movl 0x4(%rdx), %eax
cmpl $0xf, %eax
movq %rdx, -0x30(%rbp)
je 0x5f76
cmpl $0x10, %eax
jne 0x5fd8
movq -0x30(%rbp), %rcx
movq 0x28(%rcx), %rcx
movq 0x8(%rcx), %r13
cmpl $0x13, 0x4(%r13)
movq %r13, %rcx
je 0x5f79
jmp 0x5fd8
movl $0x0, 0x28(%r15,%r14)
leaq 0x133d9(%rip), %rax     # 0x19340
movl (%rax), %esi
testl %esi, %esi
jle 0x60e1
jmp 0x6100
xorl %r13d, %r13d
movq 0x28(%rcx), %rcx
movq (%rcx), %r12
testq %r12, %r12
je 0x5fd8
addq %r14, %r15
testq %r13, %r13
je 0x5fa8
movq 0x28(%r13), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r12
movl $0x0, %r13d
cmovneq %rcx, %r13
jmp 0x5fab
xorl %r13d, %r13d
movq %r12, %rdi
movq %r15, %rsi
callq 0x6aa9
testl %eax, %eax
jne 0x5fbf
testq %r13, %r13
jne 0x5f88
movq 0x1339a(%rip), %r15     # 0x19360
movl $0x0, 0x28(%r15,%r14)
movq -0x30(%rbp), %rcx
movl 0x4(%rcx), %eax
jmp 0x5fe5
movl $0x0, 0x28(%r15,%r14)
movq -0x30(%rbp), %rcx
cmpl $0xf, %eax
je 0x6007
cmpl $0x10, %eax
jne 0x6053
movq -0x30(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %r13
cmpl $0x13, 0x4(%r13)
movq %r13, %rax
je 0x600d
jmp 0x6053
xorl %r13d, %r13d
movq %rcx, %rax
movq 0x28(%rax), %rax
movq (%rax), %r12
testq %r12, %r12
je 0x6053
addq %r14, %r15
testq %r13, %r13
je 0x603c
movq 0x28(%r13), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r12
movl $0x0, %r13d
cmovneq %rcx, %r13
jmp 0x603f
xorl %r13d, %r13d
movq %r12, %rdi
movq %r15, %rsi
callq 0x6c2c
testl %eax, %eax
jne 0x6053
testq %r13, %r13
jne 0x601c
leaq 0x132e6(%rip), %rax     # 0x19340
movl (%rax), %esi
testl %esi, %esi
movq -0x38(%rbp), %r13
movq -0x30(%rbp), %rcx
jg 0x6100
testq %rcx, %rcx
je 0x60e1
addq 0x132e8(%rip), %r14     # 0x19360
movl 0x4(%rcx), %eax
cmpl $0xf, %eax
je 0x609a
cmpl $0x10, %eax
jne 0x60e1
movq 0x28(%rcx), %rax
movq 0x8(%rax), %r12
cmpl $0x13, 0x4(%r12)
movq %r12, %rcx
je 0x609d
jmp 0x60e1
xorl %r12d, %r12d
movq 0x28(%rcx), %rax
movq (%rax), %r15
testq %r15, %r15
je 0x60e1
testq %r12, %r12
je 0x60ca
movq 0x28(%r12), %rax
movq 0x8(%rax), %rcx
cmpl $0x14, 0x4(%rcx)
movq (%rax), %r15
movl $0x0, %r12d
cmovneq %rcx, %r12
jmp 0x60cd
xorl %r12d, %r12d
movq %r15, %rdi
movq %r14, %rsi
callq 0x3b35
testl %eax, %eax
jne 0x60e1
testq %r12, %r12
jne 0x60a9
movq 0x28(%rbx), %rbx
incl %r13d
testq %rbx, %rbx
jne 0x5eda
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2723(%rip), %rdi      # 0x882a
xorl %eax, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2090