// File: /workspace/github_cpp_makefile_star2_O1/rofl0r[P]ascc/cs_parser.cpp
// Function: check_type_mismatch(int, int, int)
int check_type_mismatch(int typeIs, int typeWantsToBe, int orderMatters) {
  int isTypeMismatch = 0;
  int numstrings = 0;

  int typeIsOriginally = typeIs;
  int typeWantsToBeOriginally = typeWantsToBe;

  if (is_string(typeIs))
    numstrings++;
  if (is_string(typeWantsToBe))
    numstrings++;

  // we allow to turn char* or char[] addresses into ints and vice versa
  // if -fpointerhack=1 is passed, to enable some low-level routines
  // to be written.
  if (ccGetOption(SCOPT_POINTERHACK)!=0) {
    if (numstrings == 1 && (is_int(typeIs) || is_int(typeWantsToBe)))
      return 0;
    if (is_int(typeIs) && (typeWantsToBe & STYPE_POINTER) &&
        is_integral_type(typeWantsToBe & ~STYPE_POINTER))
      return 0;
    if (is_int(typeWantsToBe) && (typeIs & STYPE_POINTER) &&
        is_integral_type(typeIs & ~STYPE_POINTER))
      return 0;
  }

  if (numstrings == 1) {
    isTypeMismatch = 1;
  }

  // can convert String* to const string
  if ((typeIs == (STYPE_POINTER | sym.stringStructSym)) &&
      (typeWantsToBe == (STYPE_CONST | sym.normalStringSym)))
    return 0;

  // cannot convert 'void' to anything
  if (typeIs == sym.normalVoidSym)
    isTypeMismatch = 1;

  // cannot convert const to non-const
  if (((typeIs & STYPE_CONST) != 0) && ((typeWantsToBe & STYPE_CONST) == 0))
    isTypeMismatch = 1;

  // cannot convert from/to dynamic array
  if ((typeIs == (STYPE_POINTER | sym.nullSym)) &&
      ((typeWantsToBe & STYPE_DYNARRAY) != 0))
  {
    // null is always allowed
    return 0;
  }
  else if ((typeIs & STYPE_DYNARRAY) != (typeWantsToBe & STYPE_DYNARRAY))
    isTypeMismatch = 1;

  // allow safe comparisons from here on
  typeIs &= ~(STYPE_CONST | STYPE_DYNARRAY);
  typeWantsToBe &= ~(STYPE_CONST | STYPE_DYNARRAY);

  // floats cannot mingle with other types
  if ((typeIs == sym.normalFloatSym) && (typeWantsToBe != sym.normalFloatSym))
    isTypeMismatch = 1;
  if ((typeWantsToBe == sym.normalFloatSym) && (typeIs != sym.normalFloatSym))
    isTypeMismatch = 1;

  // a pointer can only be compared with another pointer (except for
  // the   string/char*  exception)
  if (numstrings == 2) { }
  else if ((typeIs & STYPE_POINTER) || (typeWantsToBe & STYPE_POINTER)) {
    // pointers must point to same type
    int pointerIsOk = 0;
    if (typeIs == (STYPE_POINTER | sym.nullSym)) {
      // null can be cast to any pointer type
      if (typeWantsToBe & STYPE_POINTER)
        pointerIsOk = 1;
    }
    // check against inherited classes
    int tryTypeIs = typeIs & ~STYPE_POINTER;
    while (sym.entries[tryTypeIs].extends > 0) {
      tryTypeIs = sym.entries[tryTypeIs].extends;
      if ((tryTypeIs | STYPE_POINTER) == typeWantsToBe) {
        pointerIsOk = 1;
        break;
      }
    }
    // both sides must be pointers
    if ((typeIs & STYPE_POINTER) != (typeWantsToBe & STYPE_POINTER))
      isTypeMismatch = 1;

    if ((pointerIsOk == 0) && (typeIs != typeWantsToBe)) {
      isTypeMismatch = 1;
    }
  }
  else if ((sym.entries[typeIs].flags & SFLG_STRUCTTYPE) ||
           (sym.entries[typeWantsToBe].flags & SFLG_STRUCTTYPE)) {
    if (typeIs != typeWantsToBe) {
      isTypeMismatch = 1;
    }
  }

  if (isTypeMismatch) {
    if (!orderMatters) {
      // if not an assignment so left and right are interchangable,
      // try the other way round
      if (check_type_mismatch(typeWantsToBeOriginally, typeIsOriginally, 1))
        return -1;
    }
    else {
      cc_error("Type mismatch: cannot convert '%s' to '%s'", sym.get_friendly_name(typeIsOriginally).c_str(), sym.get_friendly_name(typeWantsToBeOriginally).c_str());
      return -1;
    }
  }
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %edx, %r14d
movl %esi, %ebx
movl %edi, %ebp
callq 0x74d6
movl %eax, %r12d
movl %ebx, %edi
callq 0x74d6
movl %eax, %r15d
addl %r12d, %r15d
movl $0x800, %edi            # imm = 0x800
callq 0x140a4
testl %eax, %eax
je 0x7799
cmpl $0x1, %r15d
jne 0x7712
leaq 0x1dfe2(%rip), %rax     # 0x256e0
movl (%rax), %eax
cmpl %ebp, %eax
sete %cl
cmpl %ebx, %eax
sete %al
orb %cl, %al
jne 0x79b1
leaq 0x1dfc7(%rip), %rcx     # 0x256e0
movl (%rcx), %edx
cmpl %ebp, %edx
setne %al
btl $0x1e, %ebx
setae %sil
orb %al, %sil
jne 0x775a
movl %ebx, %esi
andl $0xbfffffff, %esi       # imm = 0xBFFFFFFF
xorl %eax, %eax
cmpl %esi, %edx
je 0x79b3
cmpl %esi, 0x8(%rcx)
je 0x79b3
cmpl %esi, 0x4(%rcx)
je 0x79b3
cmpl %esi, 0xc(%rcx)
je 0x79b3
cmpl %ebx, %edx
setne %al
btl $0x1e, %ebp
setae %sil
orb %al, %sil
jne 0x7799
movl %ebp, %esi
andl $0xbfffffff, %esi       # imm = 0xBFFFFFFF
xorl %eax, %eax
cmpl %esi, %edx
je 0x79b3
cmpl %esi, 0x8(%rcx)
je 0x79b3
cmpl %esi, 0x4(%rcx)
je 0x79b3
cmpl %esi, 0xc(%rcx)
je 0x79b3
leaq 0x1df40(%rip), %rcx     # 0x256e0
movl $0x40000000, %esi       # imm = 0x40000000
movl 0x20(%rcx), %eax
orl %esi, %eax
cmpl %ebp, %eax
jne 0x77be
movl $0x20000000, %eax       # imm = 0x20000000
orl 0x10(%rcx), %eax
cmpl %ebx, %eax
je 0x79b1
orl 0x1c(%rcx), %esi
cmpl %ebp, %esi
sete %dl
movl %ebx, %edi
shrl $0x1c, %edi
xorl %eax, %eax
testb %dl, %dil
jne 0x79b3
cmpl $0x1, %r15d
sete %al
movl %ebp, %edx
shrl $0x1d, %edx
btl $0x1d, %ebx
setae %dil
andb %dl, %dil
movl 0x14(%rcx), %r8d
cmpl %ebp, 0x18(%rcx)
sete %r9b
movl %ebx, %r10d
xorl %ebp, %r10d
shrl $0x1c, %r10d
andl $0x1, %r10d
orb %dil, %r10b
movl $0xcfffffff, %edx       # imm = 0xCFFFFFFF
movl %ebp, %edi
andl %edx, %edi
andl %ebx, %edx
cmpl %r8d, %edi
sete %r11b
setne %r12b
cmpl %r8d, %edx
setne %r8b
sete %r13b
andb %r11b, %r8b
orb %r10b, %r8b
andb %r12b, %r13b
orb %r9b, %r13b
orb %r8b, %r13b
orb %al, %r13b
movzbl %r13b, %eax
andl $0x1, %eax
cmpl $0x2, %r15d
je 0x790d
movl %ebx, %r8d
orl %ebp, %r8d
btl $0x1e, %r8d
jb 0x7894
movslq %edi, %rsi
movq 0x28(%rcx), %rcx
imulq $0xb0, %rsi, %rsi
testb $0x4, 0x29(%rcx,%rsi)
jne 0x7904
cmpl %edx, %edi
je 0x790d
movslq %edx, %rdx
imulq $0xb0, %rdx, %rdx
movq 0x28(%rcx,%rdx), %rcx
andl $0x400, %ecx            # imm = 0x400
jne 0x7908
jmp 0x790d
movl $0x40000000, %r8d       # imm = 0x40000000
movl %ebp, %r9d
andl %r8d, %r9d
andl %ebx, %r8d
setne %r10b
cmpl %esi, %edi
sete %sil
andb %r10b, %sil
movl %ebp, %r10d
andl $0x8fffffff, %r10d      # imm = 0x8FFFFFFF
movq 0x28(%rcx), %rcx
movslq %r10d, %r10
imulq $0xb0, %r10, %r10
movswl 0x50(%rcx,%r10), %r10d
testl %r10d, %r10d
jle 0x78e5
movl %r10d, %r11d
orl $0x40000000, %r11d      # imm = 0x40000000
cmpl %edx, %r11d
jne 0x78be
movb $0x1, %sil
testb %sil, %sil
movl $0x1, %ecx
cmovnel %eax, %ecx
movl $0x1, %esi
cmpl %edx, %edi
cmovel %eax, %ecx
cmpl %r8d, %r9d
cmovnel %esi, %ecx
movl %ecx, %eax
jmp 0x790d
cmpl %edx, %edi
je 0x790d
movl $0x1, %eax
testl %eax, %eax
je 0x79b1
testl %r14d, %r14d
je 0x7998
leaq 0x1ddbf(%rip), %r15     # 0x256e0
leaq 0x28(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
movl %ebp, %edx
callq 0x11fa0
movq (%r14), %r14
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
movl %ebx, %edx
callq 0x11fa0
movq 0x8(%rsp), %rdx
leaq 0x136ed(%rip), %rdi     # 0x1b03e
movq %r14, %rsi
xorl %eax, %eax
callq 0x10418
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7976
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3320
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7991
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x79b3
movl %ebx, %edi
movl %ebp, %esi
movl $0x1, %edx
callq 0x76b5
movl %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testl %ecx, %ecx
jne 0x79b3
xorl %eax, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x79e5
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x3320
jmp 0x79e5
movq %rax, %rbx
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x7a00
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x3320
movq %rbx, %rdi
callq 0x3560