// File: baziotis[P]minijava-cpp/typecheck.cpp
// Function: typecheck(Goal*)
bool typecheck(Goal *goal) {
    typecheck_init();
    constexpr int approximated_num_of_classes_per_inheritance_tree = 8;
    // +1 for the main class
    int type_decls_len = goal->type_decls.len + 1;
    inher_roots.reserve(type_decls_len /
                        approximated_num_of_classes_per_inheritance_tree);
    // Pass 1
    TypeTable type_table = install_type_declarations(goal);
    if (config.log) {
        printf("\n");
    }

    // TODO: How able we are to continue?
    // Print types that could not be inserted. This can
    // happen if the types used are more than the type
    // declarations. See TypeTable.
    // TODO: The types in `could_not_be_inserted` might actually have a
    // declaration. Consider that if say we have space in the table for 2
    // type declarations. The declarations that _exist_ are for A and D.
    // In A, let's say we use A, B, C and D in that order. D will be inserted
    // last and it won't be in the type table. It will be in the
    // `could_not_be_inserted` because of lack of space. But D
    // actually has a declaration.
    for (IdType *type : type_table.could_not_be_inserted) {
        typecheck_error(type->loc, "Type `", type->id, "` has not been ",
                        "defined");
    }

    // Offset computation
    type_table.offset_computation();

    // Print calloc declarations etc.
    cgen_init();

    // Pass 2
    full_typecheck(goal, type_table);
    
    if (num_global_typecheck_errors == 0) {
        return true;
    }
    return false;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1c0, %rsp            # imm = 0x1C0
movq %rdi, -0x10(%rbp)
callq 0xbdd0
movl $0x8, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
addq $0x1, %rax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
movl $0x8, %ecx
cltd
idivl %ecx
movslq %eax, %rsi
leaq 0x19f81(%rip), %rdi     # 0x26a80
callq 0x15bb0
movq -0x10(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0xbde0
leaq 0x17f2d(%rip), %rax     # 0x24a48
testb $0x1, (%rax)
je 0xcb2e
leaq 0xdc1d(%rip), %rdi      # 0x1a744
movb $0x0, %al
callq 0x2030
leaq -0x90(%rbp), %rax
addq $0x60, %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rdi
callq 0x15b00
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rdi
callq 0x15b20
movq %rax, -0xa8(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0xa8(%rbp), %rax
je 0xcbd5
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xb4(%rbp)
movq -0xb0(%rbp), %rax
movq 0x8(%rax), %rdx
movl -0xb4(%rbp), %edi
leaq 0xed36(%rip), %rsi      # 0x1b8e4
leaq 0xed36(%rip), %rcx      # 0x1b8eb
leaq 0xf9d8(%rip), %r8       # 0x1c594
callq 0xcca0
movq -0xa0(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xa0(%rbp)
jmp 0xcb66
leaq -0x90(%rbp), %rdi
callq 0xc9c0
callq 0x5c20
movq -0x10(%rbp), %rax
movq %rax, -0x140(%rbp)
leaq -0x130(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movl $0x78, %edx
callq 0x2100
movq -0x140(%rbp), %rdi
movq -0xc0(%rbp), %rcx
movq %rsp, %rax
movq %rax, -0x138(%rbp)
movq %rcx, 0x70(%rax)
movups -0xd0(%rbp), %xmm0
movups %xmm0, 0x60(%rax)
movups -0xe0(%rbp), %xmm0
movups %xmm0, 0x50(%rax)
movups -0xf0(%rbp), %xmm0
movups %xmm0, 0x40(%rax)
movups -0x130(%rbp), %xmm0
movups -0x120(%rbp), %xmm1
movups -0x110(%rbp), %xmm2
movups -0x100(%rbp), %xmm3
movups %xmm3, 0x30(%rax)
movups %xmm2, 0x20(%rax)
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
callq 0xbe50
cmpl $0x0, 0x19e1b(%rip)     # 0x26a98
jne 0xcc85
movb $0x1, -0x1(%rbp)
jmp 0xcc89
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x1c0, %rsp            # imm = 0x1C0
popq %rbp
retq
nopw (%rax,%rax)