Function for variable assignment in place of definition
| 1761 | |
| 1762 | // Function for variable assignment in place of definition |
| 1763 | void AddDefineVariableNode(const char* pos, VariableInfo* varInfo, bool noOverload) |
| 1764 | { |
| 1765 | CodeInfo::lastKnownStartPos = pos; |
| 1766 | VariableInfo *variableInfo = (VariableInfo*)varInfo; |
| 1767 | |
| 1768 | // If a function is being assigned to variable, then take it's address |
| 1769 | ConvertFunctionToPointer(pos, variableInfo->varType); |
| 1770 | |
| 1771 | // If current type is set to NULL, it means that current type is auto |
| 1772 | // Is such case, type is retrieved from last AST node |
| 1773 | TypeInfo *realCurrType = variableInfo->varType ? variableInfo->varType : CodeInfo::nodeList.back()->typeInfo; |
| 1774 | |
| 1775 | // If variable type is array without explicit size, and it is being defined with value of different type |
| 1776 | ConvertArrayToUnsized(pos, realCurrType); |
| 1777 | HandlePointerToObject(pos, realCurrType); |
| 1778 | |
| 1779 | // If type wasn't known until assignment, it means that variable alignment wasn't performed in AddVariable function |
| 1780 | if(!variableInfo->varType) |
| 1781 | { |
| 1782 | if(realCurrType == typeVoid) |
| 1783 | ThrowError(pos, "ERROR: r-value type is 'void'"); |
| 1784 | |
| 1785 | variableInfo->pos = varTop; |
| 1786 | // If type has default alignment or if user specified it |
| 1787 | if(realCurrType->alignBytes != 0 || currAlign != TypeInfo::UNSPECIFIED_ALIGNMENT) |
| 1788 | { |
| 1789 | // Find address offset. Alignment selected by user has higher priority than default alignment |
| 1790 | unsigned int offset = GetAlignmentOffset(pos, currAlign != TypeInfo::UNSPECIFIED_ALIGNMENT ? currAlign : realCurrType->alignBytes); |
| 1791 | variableInfo->pos += offset; |
| 1792 | varTop += offset; |
| 1793 | } |
| 1794 | variableInfo->varType = realCurrType; |
| 1795 | varTop += realCurrType->size; |
| 1796 | |
| 1797 | if(variableInfo->varType->hasFinalizer) |
| 1798 | ThrowError(pos, "ERROR: cannot create '%s' that implements 'finalize' on stack", variableInfo->varType->GetFullTypeName()); |
| 1799 | if(!variableInfo->varType->hasFinished && variableInfo->varType != newType) |
| 1800 | ThrowError(pos, "ERROR: type '%s' is not fully defined", variableInfo->varType->GetFullTypeName()); |
| 1801 | } |
| 1802 | |
| 1803 | if(currDefinedFunc.size() && currDefinedFunc.back()->type == FunctionInfo::COROUTINE && variableInfo->blockDepth > currDefinedFunc[0]->vTopSize && variableInfo->pos > currDefinedFunc.back()->allParamSize) |
| 1804 | { |
| 1805 | // If that variable is not in current scope, we have to get it through current closure |
| 1806 | FunctionInfo *currFunc = currDefinedFunc.back(); |
| 1807 | // Add variable to the list of function external variables |
| 1808 | FunctionInfo::ExternalInfo *external = AddFunctionExternal(currFunc, variableInfo); |
| 1809 | |
| 1810 | assert(currFunc->allParamSize % 4 == 0); |
| 1811 | CodeInfo::nodeList.push_back(new NodeGetUpvalue(currFunc, currFunc->allParamSize, external->closurePos, CodeInfo::GetReferenceType(variableInfo->varType))); |
| 1812 | }else{ |
| 1813 | CodeInfo::nodeList.push_back(new NodeGetAddress(variableInfo, variableInfo->pos, variableInfo->varType)); |
| 1814 | } |
| 1815 | |
| 1816 | varDefined = false; |
| 1817 | |
| 1818 | // Call overloaded operator with error suppression |
| 1819 | if(!noOverload) |
| 1820 | { |
no test coverage detected