| 1757 | } |
| 1758 | |
| 1759 | bool reshadefx::parser::parse_expression_assignment(expression &lhs_exp) |
| 1760 | { |
| 1761 | // Parse left hand side of the expression |
| 1762 | if (!parse_expression_multary(lhs_exp)) |
| 1763 | return false; |
| 1764 | |
| 1765 | // Check if an operator exists so that this is an assignment |
| 1766 | if (accept_assignment_op()) |
| 1767 | { |
| 1768 | // Remember the operator token before parsing the expression that follows it |
| 1769 | const tokenid op = _token.id; |
| 1770 | |
| 1771 | expression rhs_exp; |
| 1772 | // Propagate precise qualifier to the right hand side |
| 1773 | if (lhs_exp.type.has(type::q_precise)) |
| 1774 | rhs_exp.type.qualifiers |= type::q_precise; |
| 1775 | |
| 1776 | // Parse right hand side of the assignment expression |
| 1777 | // This may be another assignment expression to support chains like "a = b = c = 0;" |
| 1778 | if (!parse_expression_assignment(rhs_exp)) |
| 1779 | return false; |
| 1780 | |
| 1781 | // Check if the assignment is valid |
| 1782 | if (lhs_exp.type.has(type::q_const) || !lhs_exp.is_lvalue) |
| 1783 | { |
| 1784 | error(lhs_exp.location, 3025, "l-value specifies const object"); |
| 1785 | return false; |
| 1786 | } |
| 1787 | if (!type::rank(lhs_exp.type, rhs_exp.type)) |
| 1788 | { |
| 1789 | error(rhs_exp.location, 3020, "cannot convert these types (from " + rhs_exp.type.description() + " to " + lhs_exp.type.description() + ')'); |
| 1790 | return false; |
| 1791 | } |
| 1792 | |
| 1793 | // Cannot perform bitwise operations on non-integral types |
| 1794 | if (!lhs_exp.type.is_integral() && (op == tokenid::ampersand_equal || op == tokenid::pipe_equal || op == tokenid::caret_equal)) |
| 1795 | { |
| 1796 | error(lhs_exp.location, 3082, "int or unsigned int type required"); |
| 1797 | return false; |
| 1798 | } |
| 1799 | |
| 1800 | // Perform implicit type conversion of right hand side value |
| 1801 | if (rhs_exp.type.components() > lhs_exp.type.components()) |
| 1802 | warning(rhs_exp.location, 3206, "implicit truncation of vector type"); |
| 1803 | |
| 1804 | rhs_exp.add_cast_operation(lhs_exp.type); |
| 1805 | |
| 1806 | codegen::id result_value = _codegen->emit_load(rhs_exp); |
| 1807 | |
| 1808 | // Check if this is an assignment with an additional arithmetic instruction |
| 1809 | if (op != tokenid::equal) |
| 1810 | { |
| 1811 | // Load value for modification |
| 1812 | const codegen::id lhs_value = _codegen->emit_load(lhs_exp); |
| 1813 | |
| 1814 | // Handle arithmetic assignment operation |
| 1815 | result_value = _codegen->emit_binary_op(lhs_exp.location, op, lhs_exp.type, lhs_value, result_value); |
| 1816 | } |
nothing calls this directly
no test coverage detected