| 12529 | } |
| 12530 | |
| 12531 | static bool AreCompatibleFnPtrTypes(PPrototype *to, PPrototype *from) |
| 12532 | { |
| 12533 | if(to->ArgumentTypes.Size() != from->ArgumentTypes.Size() |
| 12534 | || to->ReturnTypes.Size() != from->ReturnTypes.Size()) return false; |
| 12535 | int n = to->ArgumentTypes.Size(); |
| 12536 | |
| 12537 | //allow narrowing of arguments |
| 12538 | for(int i = 0; i < n; i++) |
| 12539 | { |
| 12540 | PType * fromType = from->ArgumentTypes[i]; |
| 12541 | PType * toType = to->ArgumentTypes[i]; |
| 12542 | if(fromType->isFunctionPointer() && toType->isFunctionPointer()) |
| 12543 | { |
| 12544 | if(!AreCompatibleFnPtrs(static_cast<PFunctionPointer *>(toType), static_cast<PFunctionPointer *>(fromType))) return false; |
| 12545 | } |
| 12546 | else if(fromType->isClassPointer() && toType->isClassPointer()) |
| 12547 | { |
| 12548 | PClassPointer * fromClass = static_cast<PClassPointer *>(fromType); |
| 12549 | PClassPointer * toClass = static_cast<PClassPointer *>(toType); |
| 12550 | //allow narrowing parameters |
| 12551 | if(!CanNarrowTo(fromClass->ClassRestriction, toClass->ClassRestriction)) return false; |
| 12552 | } |
| 12553 | else if(fromType->isObjectPointer() && toType->isObjectPointer()) |
| 12554 | { |
| 12555 | PObjectPointer * fromObj = static_cast<PObjectPointer *>(fromType); |
| 12556 | PObjectPointer * toObj = static_cast<PObjectPointer *>(toType); |
| 12557 | //allow narrowing parameters |
| 12558 | if(!CanNarrowTo(fromObj->PointedClass(), toObj->PointedClass())) return false; |
| 12559 | } |
| 12560 | else if(fromType != toType) |
| 12561 | { |
| 12562 | return false; |
| 12563 | } |
| 12564 | } |
| 12565 | |
| 12566 | n = to->ReturnTypes.Size(); |
| 12567 | |
| 12568 | for(int i = 0; i < n; i++) |
| 12569 | { |
| 12570 | PType * fromType = from->ReturnTypes[i]; |
| 12571 | PType * toType = to->ReturnTypes[i]; |
| 12572 | if(fromType->isFunctionPointer() && toType->isFunctionPointer()) |
| 12573 | { |
| 12574 | if(!AreCompatibleFnPtrs(static_cast<PFunctionPointer *>(toType), static_cast<PFunctionPointer *>(fromType))) return false; |
| 12575 | } |
| 12576 | else if(fromType->isClassPointer() && toType->isClassPointer()) |
| 12577 | { |
| 12578 | PClassPointer * fromClass = static_cast<PClassPointer *>(fromType); |
| 12579 | PClassPointer * toClass = static_cast<PClassPointer *>(toType); |
| 12580 | //allow widening returns |
| 12581 | if(!CanWidenTo(fromClass->ClassRestriction, toClass->ClassRestriction)) return false; |
| 12582 | } |
| 12583 | else if(fromType->isObjectPointer() && toType->isObjectPointer()) |
| 12584 | { |
| 12585 | PObjectPointer * fromObj = static_cast<PObjectPointer *>(fromType); |
| 12586 | PObjectPointer * toObj = static_cast<PObjectPointer *>(toType); |
| 12587 | //allow widening returns |
| 12588 | if(!CanWidenTo(fromObj->PointedClass(), toObj->PointedClass())) return false; |
no test coverage detected