| 3614 | } |
| 3615 | |
| 3616 | unsigned int GetFunctionRating(FunctionType *currFunc, unsigned int callArgCount) |
| 3617 | { |
| 3618 | if(currFunc->paramCount != callArgCount) |
| 3619 | return ~0u; // Definitely, this isn't the function we are trying to call. Parameter count does not match. |
| 3620 | |
| 3621 | unsigned int fRating = 0; |
| 3622 | for(unsigned int i = 0; i < callArgCount; i++) |
| 3623 | { |
| 3624 | NodeZeroOP* activeNode = CodeInfo::nodeList[CodeInfo::nodeList.size() - callArgCount + i]; |
| 3625 | TypeInfo *paramType = activeNode->typeInfo; |
| 3626 | unsigned int nodeType = activeNode->nodeType; |
| 3627 | TypeInfo *expectedType = currFunc->paramType[i]; |
| 3628 | if(expectedType != paramType) |
| 3629 | { |
| 3630 | if(expectedType == typeGeneric) // generic function argument |
| 3631 | continue; |
| 3632 | else if(expectedType->dependsOnGeneric) // generic function argument that is derivative from generic |
| 3633 | continue; |
| 3634 | else if(expectedType->arrSize == TypeInfo::UNSIZED_ARRAY && paramType->arrSize != 0 && paramType->subType == expectedType->subType) |
| 3635 | fRating += 2; // array -> class (unsized array) |
| 3636 | else if(expectedType == typeAutoArray && paramType->arrLevel) |
| 3637 | fRating += 10; // array -> auto[] |
| 3638 | else if(expectedType->refLevel == 1 && expectedType->refLevel == paramType->refLevel && expectedType->subType->arrSize == TypeInfo::UNSIZED_ARRAY && paramType->subType->subType == expectedType->subType->subType) |
| 3639 | fRating += 5; // array[N] ref -> array[] -> array[] ref |
| 3640 | else if(expectedType->funcType != NULL){ |
| 3641 | if(nodeType == typeNodeFuncDef && ((NodeFuncDef*)activeNode)->GetFuncInfo()->funcType == expectedType) |
| 3642 | continue; // Inline function definition doesn't cost anything |
| 3643 | else if(nodeType == typeNodeFunctionProxy && ((NodeFunctionProxy*)activeNode)->HasType(expectedType)) |
| 3644 | continue; // If a set of function overloads has an expected overload, this doesn't cont anything |
| 3645 | else if(nodeType == typeNodeExpressionList && ((NodeExpressionList*)activeNode)->GetFirstNode()->nodeType == typeNodeFunctionProxy) |
| 3646 | continue; // Generic function is expected to have an appropriate instance, but there will be a check after instancing |
| 3647 | else |
| 3648 | return ~0u; // Otherwise this function is not a match |
| 3649 | |
| 3650 | }else if(expectedType->refLevel == paramType->refLevel + 1 && expectedType->subType == paramType) |
| 3651 | fRating += 5; // type -> type ref |
| 3652 | else if(expectedType == typeObject && paramType->refLevel) |
| 3653 | fRating += 5; // type ref -> auto ref |
| 3654 | else if(expectedType == typeObject) |
| 3655 | fRating += 10; // type -> type ref -> auto ref |
| 3656 | else if(expectedType->type == TypeInfo::TYPE_COMPLEX || paramType->type == TypeInfo::TYPE_COMPLEX || paramType->type == TypeInfo::TYPE_VOID || expectedType->firstVariable || paramType->firstVariable) |
| 3657 | return ~0u; // If one of types is complex, and they aren't equal, function cannot match |
| 3658 | else if(paramType->subType != expectedType->subType) |
| 3659 | return ~0u; // Pointer or array with a different type inside. Doesn't matter if simple or complex. |
| 3660 | else // Build-in types can convert to each other, but the fact of conversion tells us, that there could be a better suited function |
| 3661 | fRating += 1; // type -> type |
| 3662 | } |
| 3663 | } |
| 3664 | return fRating; |
| 3665 | } |
| 3666 | |
| 3667 | bool PrepareMemberCall(const char* pos, const char* funcName) |
| 3668 | { |
no test coverage detected