| 12739 | } |
| 12740 | |
| 12741 | int asCCompiler::CompileFunctionCall(asCScriptNode *node, asCExprContext *ctx, asCObjectType *objectType, bool objIsConst, const asCString &scope) |
| 12742 | { |
| 12743 | asCExprValue tempObj; |
| 12744 | asCArray<int> funcs; |
| 12745 | int localVar = -1; |
| 12746 | bool initializeMembers = false; |
| 12747 | asCExprContext funcExpr(engine); |
| 12748 | |
| 12749 | // Skip over the optional scope to get the name of the function |
| 12750 | asCScriptNode* nm = node->firstChild; |
| 12751 | if (nm->nodeType == snScope) nm = nm->next; |
| 12752 | asASSERT(nm->tokenType == ttIdentifier); |
| 12753 | asCString name(&script->code[nm->tokenPos], nm->tokenLength); |
| 12754 | |
| 12755 | // Find the matching entities |
| 12756 | // If objectType is set then this is a post op expression and we shouldn't look for local variables |
| 12757 | asCExprContext lookupResult(engine); |
| 12758 | SYMBOLTYPE symbolType = SymbolLookup(name, scope, objectType, &lookupResult, node); |
| 12759 | if (symbolType < 0) |
| 12760 | return -1; |
| 12761 | if (symbolType == SL_NOMATCH) |
| 12762 | { |
| 12763 | // No matching symbol |
| 12764 | asCString msg; |
| 12765 | asCString smbl; |
| 12766 | if (scope == "::") |
| 12767 | smbl = scope; |
| 12768 | else if (scope != "") |
| 12769 | smbl = scope + "::"; |
| 12770 | smbl += name; |
| 12771 | msg.Format(TXT_NO_MATCHING_SYMBOL_s, smbl.AddressOf()); |
| 12772 | Error(msg, node); |
| 12773 | return -1; |
| 12774 | } |
| 12775 | |
| 12776 | // Is the symbol matching a variable/property? |
| 12777 | if (symbolType == SL_LOCALCONST || symbolType == SL_LOCALVAR || |
| 12778 | symbolType == SL_THISPTR || symbolType == SL_CLASSPROPACCESS || symbolType == SL_CLASSPROP || |
| 12779 | symbolType == SL_GLOBALPROPACCESS || symbolType == SL_GLOBALCONST || symbolType == SL_GLOBALVAR || symbolType == SL_ENUMVAL) |
| 12780 | { |
| 12781 | // Variables/properties can be used as functions if they have the opCall |
| 12782 | |
| 12783 | // Compile the variable |
| 12784 | // TODO: Take advantage of the known symbol, so it doesn't have to be looked up again |
| 12785 | localVar = CompileVariableAccess(name, scope, &funcExpr, node, false, objectType); |
| 12786 | if( localVar < 0 ) |
| 12787 | return -1; |
| 12788 | |
| 12789 | if (funcExpr.type.dataType.IsFuncdef()) |
| 12790 | { |
| 12791 | funcs.PushLast(CastToFuncdefType(funcExpr.type.dataType.GetTypeInfo())->funcdef->id); |
| 12792 | } |
| 12793 | else if (funcExpr.type.dataType.IsObject()) |
| 12794 | { |
| 12795 | // Keep information about temporary variables as deferred expression so it can be properly cleaned up after the call |
| 12796 | if (ctx->type.isTemporary) |
| 12797 | { |
| 12798 | asASSERT(objectType); |
nothing calls this directly
no test coverage detected