| 3157 | } |
| 3158 | |
| 3159 | void FunctionEnd(const char* pos) |
| 3160 | { |
| 3161 | FunctionInfo &lastFunc = *currDefinedFunc.back(); |
| 3162 | |
| 3163 | if(lastFunc.retType && lastFunc.retType != typeVoid && !lastFunc.explicitlyReturned) |
| 3164 | ThrowError(pos, "ERROR: function must return a value of type '%s'", lastFunc.retType->GetFullTypeName()); |
| 3165 | |
| 3166 | FunctionInfo *implementedPrototype = NULL; |
| 3167 | HashMap<FunctionInfo*>::Node *curr = funcMap.first(lastFunc.nameHash); |
| 3168 | while(curr) |
| 3169 | { |
| 3170 | FunctionInfo *info = curr->value; |
| 3171 | if(info == &lastFunc) |
| 3172 | { |
| 3173 | curr = funcMap.next(curr); |
| 3174 | continue; |
| 3175 | } |
| 3176 | |
| 3177 | if(info->paramCount == lastFunc.paramCount && info->visible && info->retType == lastFunc.retType) |
| 3178 | { |
| 3179 | // Check all parameter types |
| 3180 | bool paramsEqual = true; |
| 3181 | for(VariableInfo *currN = info->firstParam, *currI = lastFunc.firstParam; currN; currN = currN->next, currI = currI->next) |
| 3182 | { |
| 3183 | if(currN->varType != currI->varType) |
| 3184 | paramsEqual = false; |
| 3185 | } |
| 3186 | if(paramsEqual) |
| 3187 | { |
| 3188 | if(info->implemented) |
| 3189 | ThrowError(pos, "ERROR: function '%s' is being defined with the same set of parameters", lastFunc.name); |
| 3190 | else |
| 3191 | info->address = lastFunc.indexInArr | 0x80000000; |
| 3192 | implementedPrototype = info; |
| 3193 | } |
| 3194 | } |
| 3195 | curr = funcMap.next(curr); |
| 3196 | } |
| 3197 | if(implementedPrototype && implementedPrototype->parentFunc != lastFunc.parentFunc) |
| 3198 | ThrowError(pos, "ERROR: function implementation is found in scope different from function prototype"); |
| 3199 | |
| 3200 | assert(cycleDepth.back() == 0); |
| 3201 | cycleDepth.pop_back(); |
| 3202 | // Save info about all local variables |
| 3203 | for(int i = CodeInfo::varInfo.size()-1; i > (int)(varInfoTop.back().activeVarCnt + lastFunc.paramCount); i--) |
| 3204 | { |
| 3205 | VariableInfo *firstNext = lastFunc.firstLocal; |
| 3206 | lastFunc.firstLocal = CodeInfo::varInfo[i]; |
| 3207 | if(!lastFunc.lastLocal) |
| 3208 | lastFunc.lastLocal = lastFunc.firstLocal; |
| 3209 | lastFunc.firstLocal->next = firstNext; |
| 3210 | if(lastFunc.firstLocal->next) |
| 3211 | lastFunc.firstLocal->next->prev = lastFunc.firstLocal; |
| 3212 | lastFunc.localCount++; |
| 3213 | if(lastFunc.firstLocal->varType->hasPointers) |
| 3214 | lastFunc.pure = false; // Pure functions locals must be simple types |
| 3215 | } |
| 3216 | if(lastFunc.firstLocal) |
no test coverage detected