| 817 | // Node to change variable value with following operations: += -= *= /= **= %= <<= >>= &= |= ^= |
| 818 | |
| 819 | NodeVariableModify::NodeVariableModify(TypeInfo* targetType, CmdID cmd) |
| 820 | { |
| 821 | assert(targetType); |
| 822 | typeInfo = targetType->subType; |
| 823 | |
| 824 | cmdID = cmd; |
| 825 | |
| 826 | second = TakeLastNode(); |
| 827 | |
| 828 | // Address of the target variable |
| 829 | first = TakeLastNode(); |
| 830 | assert(first->typeInfo->refLevel != 0); |
| 831 | |
| 832 | if(second->typeInfo == typeVoid) |
| 833 | ThrowError(CodeInfo::lastKnownStartPos, "ERROR: cannot convert from void to %s", typeInfo->GetFullTypeName()); |
| 834 | if(typeInfo == typeVoid) |
| 835 | ThrowError(CodeInfo::lastKnownStartPos, "ERROR: cannot convert from %s to void", second->typeInfo->GetFullTypeName()); |
| 836 | if(first->typeInfo->subType->refLevel != 0 || second->typeInfo->refLevel != 0 || typeInfo->type == TypeInfo::TYPE_COMPLEX || second->typeInfo->type == TypeInfo::TYPE_COMPLEX) |
| 837 | ThrowError(CodeInfo::lastKnownStartPos, "ERROR: there is no built-in operator for types '%s' and '%s'", typeInfo->GetFullTypeName(), second->typeInfo->GetFullTypeName()); |
| 838 | |
| 839 | // If types don't match |
| 840 | if(second->typeInfo != typeInfo) |
| 841 | { |
| 842 | // If it is not built-in basic types or if pointers point to different types |
| 843 | if(typeInfo->type == TypeInfo::TYPE_COMPLEX || second->typeInfo->type == TypeInfo::TYPE_COMPLEX || typeInfo->subType != second->typeInfo->subType) |
| 844 | ThrowError(CodeInfo::lastKnownStartPos, "ERROR: cannot convert '%s' to '%s'", second->typeInfo->GetFullTypeName(), typeInfo->GetFullTypeName()); |
| 845 | } |
| 846 | |
| 847 | if((first->typeInfo->subType == typeDouble || first->typeInfo->subType == typeFloat || second->typeInfo == typeDouble || second->typeInfo == typeFloat) && (cmd >= cmdShl && cmd <= cmdLogXor)) |
| 848 | ThrowError(CodeInfo::lastKnownStartPos, "ERROR: binary operations are not available on floating-point numbers"); |
| 849 | |
| 850 | absAddress = true; |
| 851 | knownAddress = false; |
| 852 | addrShift = 0; |
| 853 | |
| 854 | #ifndef NULLC_ENABLE_C_TRANSLATION |
| 855 | if(first->nodeType == typeNodeGetAddress) |
| 856 | { |
| 857 | absAddress = static_cast<NodeGetAddress*>(first)->IsAbsoluteAddress(); |
| 858 | addrShift = static_cast<NodeGetAddress*>(first)->varAddress; |
| 859 | knownAddress = true; |
| 860 | } |
| 861 | if(first->nodeType == typeNodeShiftAddress) |
| 862 | { |
| 863 | addrShift = static_cast<NodeShiftAddress*>(first)->memberShift; |
| 864 | first = static_cast<NodeShiftAddress*>(first)->first; |
| 865 | } |
| 866 | if(first->nodeType == typeNodeArrayIndex && static_cast<NodeArrayIndex*>(first)->knownShift) |
| 867 | { |
| 868 | addrShift = static_cast<NodeArrayIndex*>(first)->shiftValue; |
| 869 | first = static_cast<NodeArrayIndex*>(first)->first; |
| 870 | } |
| 871 | #endif |
| 872 | |
| 873 | nodeType = typeNodeVariableModify; |
| 874 | } |
| 875 | |
| 876 | NodeVariableModify::~NodeVariableModify() |
nothing calls this directly
no test coverage detected