// File: hzeller[P]jcxxgen/schema-compiler.cc
// Function: ValidateTypes(std::vector<ObjectType*, std::allocator<ObjectType*>>*)
static bool ValidateTypes(ObjectTypeVector *object_types) {
  std::unordered_map<std::string, ObjectType *> typeByName;

  for (auto &o : *object_types) {
    // We only insert types as they come, so that we can make sure they are
    // used after being defined.
    auto inserted = typeByName.insert({o->name, o});
    if (!inserted.second) {
      std::cerr << o->location << "Duplicate name; previous defined in "
                << inserted.first->second->location << "\n";
      return false;
    }

    // Resolve superclasses
    for (const auto &e : o->extends) {
      const auto& found = typeByName.find(e);
      if (found == typeByName.end()) {
        std::cerr << o->location << "Unknown superclass " << e << "\n";
        return false;
      }
      o->superclasses.push_back(found->second);
    }

    for (auto &p : o->properties) {
      const std::string &t = p.type;
      if (t == "object" || t == "string" ||
          t == "integer" || t == "boolean") {
        continue;
      }

      const auto& found = typeByName.find(t);
      if (found == typeByName.end()) {
        std::cerr << p.location << "Unknown object type '" << t << "'\n";
        return false;
      }
      p.object_type = found->second;
    }

    // Validate that we don't have properties with the same name twice in
    // one class (including superclasses)
    std::unordered_map<std::string, const Property*> my_property_names;
    for (const auto &p : o->properties) {
      auto inserted = my_property_names.insert({p.name, &p});
      if (inserted.second) continue;
      std::cerr << p.location << "In class '" << o->name
                << "' same name property '"
                << p.name << "' defined here\n"
                << inserted.first->second->location << "  ... and here\n";
      return false;
    }
    for (const auto &s : o->superclasses) {
      for (const auto &sp : s->properties) {
        auto inserted = my_property_names.insert({sp.name, &sp});
        if (inserted.second) continue;
        const bool is_owner_superclass = (inserted.first->second->owner != o);
        std::cerr << o->location << o->name
                  << " has duplicate property '" << sp.name << "'\n"
                  << inserted.first->second->location
                  << "  ... found in "
                  << (is_owner_superclass ? "super" : "")
                  << "class '" << inserted.first->second->owner->name << "'\n"
                  << sp.location
                  << "  ... and in superclass '" << s->name << "'\n";
        return false;
      }
    }
  }

  return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3d0, %rsp            # imm = 0x3D0
movq %rdi, -0x10(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x330f0
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x31bd0
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x31a60
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x33110
testb $0x1, %al
jne 0x6270
jmp 0x6dd1
leaq -0x58(%rbp), %rdi
callq 0x33150
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdx
movq (%rdx), %rsi
addq $0x10, %rsi
leaq -0xa0(%rbp), %rdi
callq 0x331b0
jmp 0x6296
leaq -0x48(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x33170
movb %dl, -0x289(%rbp)
movq %rax, -0x288(%rbp)
jmp 0x62b5
movb -0x289(%rbp), %al
movq -0x288(%rbp), %rcx
movq %rcx, -0xc0(%rbp)
movb %al, -0xb8(%rbp)
movq -0xc0(%rbp), %rax
movq %rax, -0x78(%rbp)
movb -0xb8(%rbp), %al
movb %al, -0x70(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x331f0
testb $0x1, -0x70(%rbp)
jne 0x63b5
movq -0x68(%rbp), %rax
movq (%rax), %rsi
movq 0x4dce9(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x298(%rbp)
jmp 0x6315
movq -0x298(%rbp), %rdi
leaq 0x32c31(%rip), %rsi     # 0x38f54
callq 0x53c0
movq %rax, -0x2a0(%rbp)
jmp 0x6331
leaq -0x78(%rbp), %rdi
callq 0x33210
movq -0x2a0(%rbp), %rdi
movq 0x20(%rax), %rsi
callq 0x8130
movq %rax, -0x2a8(%rbp)
jmp 0x6353
movq -0x2a8(%rbp), %rdi
leaq 0x31e79(%rip), %rsi     # 0x381da
callq 0x53c0
jmp 0x6368
movb $0x0, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x6ddf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x6df6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0xa0(%rbp), %rdi
callq 0x331f0
jmp 0x6df6
movq -0x68(%rbp), %rax
movq (%rax), %rax
addq $0x30, %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x7f60
movq %rax, -0xd8(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x7f90
movq %rax, -0xe0(%rbp)
leaq -0xd8(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x7fc0
testb $0x1, %al
jne 0x6409
jmp 0x654a
leaq -0xd8(%rbp), %rdi
callq 0x8000
movq %rax, -0xe8(%rbp)
movq -0xe8(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x33240
movq %rax, -0x2b0(%rbp)
jmp 0x6435
movq -0x2b0(%rbp), %rax
movq %rax, -0xf8(%rbp)
leaq -0xf8(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movq %rax, -0x2b8(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x332a0
movq -0x2b8(%rbp), %rdi
movq %rax, -0x100(%rbp)
leaq -0x100(%rbp), %rsi
callq 0x33270
testb $0x1, %al
jne 0x6488
jmp 0x6504
movq -0x68(%rbp), %rax
movq (%rax), %rsi
movq 0x4db5a(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x2c0(%rbp)
jmp 0x64a4
movq -0x2c0(%rbp), %rdi
leaq 0x32ac7(%rip), %rsi     # 0x38f79
callq 0x53c0
movq %rax, -0x2c8(%rbp)
jmp 0x64c0
movq -0x2c8(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0x5390
movq %rax, -0x2d0(%rbp)
jmp 0x64dc
movq -0x2d0(%rbp), %rdi
leaq 0x31cf0(%rip), %rsi     # 0x381da
callq 0x53c0
jmp 0x64f1
movb $0x0, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x6ddf
movq -0x68(%rbp), %rax
movq (%rax), %rax
addq $0x60, %rax
movq %rax, -0x2d8(%rbp)
movq -0xf0(%rbp), %rdi
callq 0x33210
movq -0x2d8(%rbp), %rdi
movq %rax, %rsi
addq $0x20, %rsi
callq 0x332d0
jmp 0x6537
jmp 0x6539
leaq -0xd8(%rbp), %rdi
callq 0x8020
jmp 0x63ed
movq -0x68(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0x8040
movq %rax, -0x110(%rbp)
movq -0x108(%rbp), %rdi
callq 0x8070
movq %rax, -0x118(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x80a0
testb $0x1, %al
jne 0x659e
jmp 0x677b
leaq -0x110(%rbp), %rdi
callq 0x80e0
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rax
addq $0x60, %rax
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rdi
leaq 0x31c39(%rip), %rsi     # 0x3820a
callq 0x8100
movb %al, -0x2d9(%rbp)
jmp 0x65de
movb -0x2d9(%rbp), %al
testb $0x1, %al
jne 0x665f
jmp 0x65ea
movq -0x128(%rbp), %rdi
leaq 0x31c03(%rip), %rsi     # 0x381fb
callq 0x8100
movb %al, -0x2da(%rbp)
jmp 0x6605
movb -0x2da(%rbp), %al
testb $0x1, %al
jne 0x665f
jmp 0x6611
movq -0x128(%rbp), %rdi
leaq 0x31be3(%rip), %rsi     # 0x38202
callq 0x8100
movb %al, -0x2db(%rbp)
jmp 0x662c
movb -0x2db(%rbp), %al
testb $0x1, %al
jne 0x665f
jmp 0x6638
movq -0x128(%rbp), %rdi
leaq 0x31bda(%rip), %rsi     # 0x38220
callq 0x8100
movb %al, -0x2dc(%rbp)
jmp 0x6653
movb -0x2dc(%rbp), %al
testb $0x1, %al
jne 0x665f
jmp 0x6664
jmp 0x676a
movq -0x128(%rbp), %rsi
leaq -0x48(%rbp), %rdi
callq 0x33240
movq %rax, -0x2e8(%rbp)
jmp 0x667d
movq -0x2e8(%rbp), %rax
movq %rax, -0x138(%rbp)
leaq -0x138(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x130(%rbp), %rax
movq %rax, -0x2f0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x332a0
movq -0x2f0(%rbp), %rdi
movq %rax, -0x140(%rbp)
leaq -0x140(%rbp), %rsi
callq 0x33270
testb $0x1, %al
jne 0x66d0
jmp 0x674c
movq -0x120(%rbp), %rsi
movq 0x4d912(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x2f8(%rbp)
jmp 0x66ec
movq -0x2f8(%rbp), %rdi
leaq 0x32893(%rip), %rsi     # 0x38f8d
callq 0x53c0
movq %rax, -0x300(%rbp)
jmp 0x6708
movq -0x300(%rbp), %rdi
movq -0x128(%rbp), %rsi
callq 0x5390
movq %rax, -0x308(%rbp)
jmp 0x6724
movq -0x308(%rbp), %rdi
leaq 0x31e55(%rip), %rsi     # 0x38587
callq 0x53c0
jmp 0x6739
movb $0x0, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x6ddf
movq -0x130(%rbp), %rdi
callq 0x33210
movq 0x20(%rax), %rcx
movq -0x120(%rbp), %rax
movq %rcx, 0x80(%rax)
leaq -0x110(%rbp), %rdi
callq 0x8190
jmp 0x6582
leaq -0x178(%rbp), %rdi
callq 0x33340
movq -0x68(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rdi
callq 0x8040
movq %rax, -0x188(%rbp)
movq -0x180(%rbp), %rdi
callq 0x8070
movq %rax, -0x190(%rbp)
leaq -0x188(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x80a0
testb $0x1, %al
jne 0x67db
jmp 0x69d0
leaq -0x188(%rbp), %rdi
callq 0x80e0
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rax
movq %rax, %rsi
addq $0x18, %rsi
movq %rax, -0x1d8(%rbp)
leaq -0x1d0(%rbp), %rdi
leaq -0x1d8(%rbp), %rdx
callq 0x333a0
jmp 0x6818
leaq -0x178(%rbp), %rdi
leaq -0x1d0(%rbp), %rsi
callq 0x33360
movb %dl, -0x311(%rbp)
movq %rax, -0x310(%rbp)
jmp 0x683a
movb -0x311(%rbp), %al
movq -0x310(%rbp), %rcx
movq %rcx, -0x1e8(%rbp)
movb %al, -0x1e0(%rbp)
movq -0x1e8(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movb -0x1e0(%rbp), %al
movb %al, -0x1a0(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x333e0
testb $0x1, -0x1a0(%rbp)
je 0x68c2
jmp 0x69bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
jmp 0x6dc3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x333e0
jmp 0x6dc3
movq -0x198(%rbp), %rsi
movq 0x4d720(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x320(%rbp)
jmp 0x68de
movq -0x320(%rbp), %rdi
leaq 0x326b7(%rip), %rsi     # 0x38fa3
callq 0x53c0
movq %rax, -0x328(%rbp)
jmp 0x68fa
movq -0x328(%rbp), %rdi
movq -0x68(%rbp), %rax
movq (%rax), %rsi
addq $0x10, %rsi
callq 0x5390
movq %rax, -0x330(%rbp)
jmp 0x691a
movq -0x330(%rbp), %rdi
leaq 0x32686(%rip), %rsi     # 0x38fae
callq 0x53c0
movq %rax, -0x338(%rbp)
jmp 0x6936
movq -0x338(%rbp), %rdi
movq -0x198(%rbp), %rsi
addq $0x18, %rsi
callq 0x5390
movq %rax, -0x340(%rbp)
jmp 0x6956
movq -0x340(%rbp), %rdi
leaq 0x32661(%rip), %rsi     # 0x38fc5
callq 0x53c0
movq %rax, -0x348(%rbp)
jmp 0x6972
leaq -0x1a8(%rbp), %rdi
callq 0x33400
movq -0x348(%rbp), %rdi
movq 0x20(%rax), %rsi
callq 0x8130
movq %rax, -0x350(%rbp)
jmp 0x6997
movq -0x350(%rbp), %rdi
leaq 0x32630(%rip), %rsi     # 0x38fd5
callq 0x53c0
jmp 0x69ac
movb $0x0, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x6d9b
leaq -0x188(%rbp), %rdi
callq 0x8190
jmp 0x67bf
movq -0x68(%rbp), %rax
movq (%rax), %rax
addq $0x60, %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x33430
movq %rax, -0x1f8(%rbp)
movq -0x1f0(%rbp), %rdi
callq 0x33460
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x33490
testb $0x1, %al
jne 0x6a24
jmp 0x6d91
leaq -0x1f8(%rbp), %rdi
callq 0x334d0
movq %rax, -0x208(%rbp)
movq -0x208(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0x210(%rbp)
movq -0x210(%rbp), %rdi
callq 0x334f0
movq %rax, -0x218(%rbp)
movq -0x210(%rbp), %rdi
callq 0x33520
movq %rax, -0x220(%rbp)
leaq -0x218(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x33550
testb $0x1, %al
jne 0x6a8e
jmp 0x6d7e
leaq -0x218(%rbp), %rdi
callq 0x33590
movq %rax, -0x228(%rbp)
movq -0x228(%rbp), %rax
movq %rax, %rsi
addq $0x18, %rsi
movq %rax, -0x268(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rdx
callq 0x333a0
jmp 0x6acb
leaq -0x178(%rbp), %rdi
leaq -0x260(%rbp), %rsi
callq 0x33360
movb %dl, -0x359(%rbp)
movq %rax, -0x358(%rbp)
jmp 0x6aed
movb -0x359(%rbp), %al
movq -0x358(%rbp), %rcx
movq %rcx, -0x278(%rbp)
movb %al, -0x270(%rbp)
movq -0x278(%rbp), %rax
movq %rax, -0x238(%rbp)
movb -0x270(%rbp), %al
movb %al, -0x230(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x333e0
testb $0x1, -0x230(%rbp)
je 0x6b5e
jmp 0x6d6d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xa8(%rbp)
movl %eax, -0xac(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x333e0
jmp 0x6dc3
leaq -0x238(%rbp), %rdi
callq 0x33400
movq 0x20(%rax), %rax
movq 0x10(%rax), %rax
movq -0x68(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
setne -0x279(%rbp)
movq -0x68(%rbp), %rax
movq (%rax), %rsi
movq 0x4d45f(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x368(%rbp)
jmp 0x6b9f
movq -0x368(%rbp), %rdi
movq -0x68(%rbp), %rax
movq (%rax), %rsi
addq $0x10, %rsi
callq 0x5390
movq %rax, -0x370(%rbp)
jmp 0x6bbf
movq -0x370(%rbp), %rdi
leaq 0x32418(%rip), %rsi     # 0x38fe5
callq 0x53c0
movq %rax, -0x378(%rbp)
jmp 0x6bdb
movq -0x378(%rbp), %rdi
movq -0x228(%rbp), %rsi
addq $0x18, %rsi
callq 0x5390
movq %rax, -0x380(%rbp)
jmp 0x6bfb
movq -0x380(%rbp), %rdi
leaq 0x3197e(%rip), %rsi     # 0x38587
callq 0x53c0
movq %rax, -0x388(%rbp)
jmp 0x6c17
leaq -0x238(%rbp), %rdi
callq 0x33400
movq -0x388(%rbp), %rdi
movq 0x20(%rax), %rsi
callq 0x8130
movq %rax, -0x390(%rbp)
jmp 0x6c3c
movq -0x390(%rbp), %rdi
leaq 0x323b5(%rip), %rsi     # 0x38fff
callq 0x53c0
movq %rax, -0x398(%rbp)
jmp 0x6c58
movq -0x398(%rbp), %rdi
movb -0x279(%rbp), %cl
leaq 0x323a3(%rip), %rax     # 0x3900f
leaq 0x31568(%rip), %rsi     # 0x381db
testb $0x1, %cl
cmovneq %rax, %rsi
callq 0x53c0
movq %rax, -0x3a0(%rbp)
jmp 0x6c88
movq -0x3a0(%rbp), %rdi
leaq 0x32310(%rip), %rsi     # 0x38fa6
callq 0x53c0
movq %rax, -0x3a8(%rbp)
jmp 0x6ca4
leaq -0x238(%rbp), %rdi
callq 0x33400
movq -0x3a8(%rbp), %rdi
movq 0x20(%rax), %rax
movq 0x10(%rax), %rsi
addq $0x10, %rsi
callq 0x5390
movq %rax, -0x3b0(%rbp)
jmp 0x6cd1
movq -0x3b0(%rbp), %rdi
leaq 0x318a8(%rip), %rsi     # 0x38587
callq 0x53c0
movq %rax, -0x3b8(%rbp)
jmp 0x6ced
movq -0x3b8(%rbp), %rdi
movq -0x228(%rbp), %rsi
callq 0x8130
movq %rax, -0x3c0(%rbp)
jmp 0x6d09
movq -0x3c0(%rbp), %rdi
leaq 0x322fe(%rip), %rsi     # 0x39015
callq 0x53c0
movq %rax, -0x3c8(%rbp)
jmp 0x6d25
movq -0x3c8(%rbp), %rdi
movq -0x208(%rbp), %rax
movq (%rax), %rsi
addq $0x10, %rsi
callq 0x5390
movq %rax, -0x3d0(%rbp)
jmp 0x6d48
movq -0x3d0(%rbp), %rdi
leaq 0x31831(%rip), %rsi     # 0x38587
callq 0x53c0
jmp 0x6d5d
movb $0x0, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
jmp 0x6d9b
leaq -0x218(%rbp), %rdi
callq 0x335b0
jmp 0x6a72
jmp 0x6d80
leaq -0x1f8(%rbp), %rdi
callq 0x335d0
jmp 0x6a08
movl $0x0, -0xc4(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x335f0
movl -0xc4(%rbp), %eax
testl %eax, %eax
jne 0x6ddf
jmp 0x6db3
jmp 0x6db5
leaq -0x58(%rbp), %rdi
callq 0x33610
jmp 0x625a
leaq -0x178(%rbp), %rdi
callq 0x335f0
jmp 0x6df6
movb $0x1, -0x1(%rbp)
movl $0x1, -0xc4(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x33630
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x3d0, %rsp            # imm = 0x3D0
popq %rbp
retq
leaq -0x48(%rbp), %rdi
callq 0x33630
movq -0xa8(%rbp), %rdi
callq 0x5680
nopl (%rax,%rax)