| 2249 | } |
| 2250 | |
| 2251 | void ConvertFunctionToPointer(const char* pos, TypeInfo *dstPreferred) |
| 2252 | { |
| 2253 | // If node is a function definition or a pair of { function definition, function closure setup } |
| 2254 | if(CodeInfo::nodeList.back()->nodeType == typeNodeFuncDef) |
| 2255 | { |
| 2256 | // Take its address and hide its name |
| 2257 | FunctionInfo *fInfo = ((NodeFuncDef*)CodeInfo::nodeList.back())->GetFuncInfo(); |
| 2258 | assert(!fInfo->generic); |
| 2259 | GetFunctionContext(pos, fInfo, true); |
| 2260 | fInfo->pure = false; |
| 2261 | CodeInfo::nodeList.push_back(new NodeFunctionAddress(fInfo)); |
| 2262 | AddExtraNode(); |
| 2263 | fInfo->visible = false; |
| 2264 | }else if(CodeInfo::nodeList.back()->nodeType == typeNodeExpressionList && ((NodeExpressionList*)CodeInfo::nodeList.back())->GetFirstNode()->nodeType == typeNodeFunctionProxy){ // generic function |
| 2265 | if(!dstPreferred) |
| 2266 | ThrowError(pos, "ERROR: cannot instance generic function, because target type is not known"); |
| 2267 | |
| 2268 | NodeFunctionProxy *fProxy = (NodeFunctionProxy*)((NodeExpressionList*)CodeInfo::nodeList.back())->GetFirstNode(); |
| 2269 | assert(fProxy->noError); |
| 2270 | assert(fProxy->funcInfo); |
| 2271 | if(!dstPreferred->funcType) |
| 2272 | ThrowError(pos, "ERROR: cannot instance generic function to a type '%s'", dstPreferred->GetFullTypeName()); |
| 2273 | |
| 2274 | FunctionInfo *fInfo = fProxy->funcInfo, *fTarget = NULL; |
| 2275 | |
| 2276 | for(unsigned i = 0; i < dstPreferred->funcType->paramCount; i++) // push function argument placeholders |
| 2277 | CodeInfo::nodeList.push_back(new NodeZeroOP(dstPreferred->funcType->paramType[i])); |
| 2278 | NodeZeroOP *funcDefAtEnd = CreateGenericFunctionInstance(pos, fInfo, fTarget, ~0u); |
| 2279 | for(unsigned i = 0; i < dstPreferred->funcType->paramCount; i++) // remove function argument placeholders |
| 2280 | CodeInfo::nodeList.pop_back(); |
| 2281 | |
| 2282 | // generated generic function instance can be different from the type we wanted to get |
| 2283 | if(dstPreferred != fTarget->funcType) |
| 2284 | ThrowError(pos, "ERROR: cannot convert from '%s' to '%s'", fTarget->funcType->GetFullTypeName(), dstPreferred->GetFullTypeName()); |
| 2285 | |
| 2286 | assert(funcDefAtEnd); // This node will be missing if we had a generic function prototype which doesn't happen |
| 2287 | |
| 2288 | CodeInfo::nodeList.push_back(funcDefAtEnd); |
| 2289 | AddExtraNode(); |
| 2290 | |
| 2291 | // Take an address of a generic function instance |
| 2292 | GetFunctionContext(pos, fTarget, true); |
| 2293 | CodeInfo::nodeList.push_back(new NodeFunctionAddress(fTarget)); |
| 2294 | AddExtraNode(); |
| 2295 | }else if(CodeInfo::nodeList.back()->nodeType == typeNodeFunctionProxy){ // If it is an unresolved function overload selection |
| 2296 | FunctionInfo *info = ((NodeFunctionProxy*)CodeInfo::nodeList.back())->funcInfo; |
| 2297 | NodeZeroOP *thisNode = ((NodeFunctionProxy*)CodeInfo::nodeList.back())->GetFirstNode(); |
| 2298 | CodeInfo::nodeList.pop_back(); |
| 2299 | if(!dstPreferred) |
| 2300 | { |
| 2301 | HashMap<FunctionInfo*>::Node *func = funcMap.first(info->nameHash), *funcS = func; |
| 2302 | bestFuncList.clear(); |
| 2303 | bestFuncRating.clear(); |
| 2304 | do |
| 2305 | { |
| 2306 | bestFuncList.push_back(func->value); |
| 2307 | bestFuncRating.push_back(0); |
| 2308 | func = funcMap.next(func); |
no test coverage detected