// File: /workspace/github_c_makefile_star2_O0/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
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rdi
callq 0x9220
movl %eax, 0x138a5(%rip)     # 0x1c348
movl 0x1389f(%rip), %eax     # 0x1c348
imulq $0x38, %rax, %rdi
callq 0x20e0
movq %rax, 0x13897(%rip)     # 0x1c350
movq 0x13890(%rip), %rdi     # 0x1c350
movl 0x13882(%rip), %eax     # 0x1c348
imulq $0x38, %rax, %rdx
xorl %esi, %esi
callq 0x2090
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x8c03
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq 0x13852(%rip), %rax     # 0x1c350
movl -0x24(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x18(%rax)
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rcx
movq 0x13831(%rip), %rax     # 0x1c350
movl -0x24(%rbp), %edx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq 0x1381c(%rip), %rax     # 0x1c350
movl -0x24(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x8(%rax)
movq -0x30(%rbp), %rdi
movq 0x137fc(%rip), %rdx     # 0x1c350
movl -0x24(%rbp), %eax
imulq $0x38, %rax, %rax
addq %rax, %rdx
leaq 0xfbb(%rip), %rsi       # 0x9b20
callq 0x8c10
movq 0x137df(%rip), %rax     # 0x1c350
movl -0x24(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x28(%rax)
movq -0x30(%rbp), %rdi
movq 0x137c3(%rip), %rdx     # 0x1c350
movl -0x24(%rbp), %eax
imulq $0x38, %rax, %rax
addq %rax, %rdx
leaq 0x11f2(%rip), %rsi      # 0x9d90
callq 0x8c10
leaq 0x13786(%rip), %rax     # 0x1c330
cmpl $0x0, (%rax)
jle 0x8bc8
leaq 0x1377a(%rip), %rax     # 0x1c330
movl (%rax), %esi
leaq 0x2c6b(%rip), %rdi      # 0xb82a
movb $0x0, %al
callq 0x2070
jmp 0x8c03
movq -0x30(%rbp), %rdi
movq 0x1377d(%rip), %rdx     # 0x1c350
movl -0x24(%rbp), %eax
imulq $0x38, %rax, %rax
addq %rax, %rdx
leaq -0x35c4(%rip), %rsi     # 0x5620
callq 0x8c10
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x8ae0
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)