(target, value)
| 2035 | return storeAsVal |
| 2036 | |
| 2037 | def process_assignment(target, value): |
| 2038 | |
| 2039 | if isinstance(target, ast.Tuple): |
| 2040 | |
| 2041 | if (isinstance(value, ast.Tuple) or |
| 2042 | isinstance(value, ast.List)): |
| 2043 | return target, value |
| 2044 | |
| 2045 | if isinstance(value, ast.AST): |
| 2046 | # Measurements need to push their values to the stack, so we |
| 2047 | # set a so we set a non-None variable name here. |
| 2048 | self.currentAssignVariableName = '' |
| 2049 | # NOTE: The way the assignment logic is processed, including |
| 2050 | # that we load this value for the purpose of deconstruction, |
| 2051 | # does not preserve any inner references. There are a bunch |
| 2052 | # of issues that prevent us from properly dealing with any |
| 2053 | # reference types stored as items in lists and |
| 2054 | # `dataclasses`. We hence currently prevent the creation of |
| 2055 | # such lists and `dataclasses`, and would need to change the |
| 2056 | # representation for `dataclasses` to allow that. |
| 2057 | self.visit(value) |
| 2058 | value = self.popValue() |
| 2059 | self.currentAssignVariableName = None |
| 2060 | return target, value |
| 2061 | |
| 2062 | return target, value |
| 2063 | |
| 2064 | # Make sure we process arbitrary combinations |
| 2065 | # of subscript and attributes |
| 2066 | target_root = target |
| 2067 | while (isinstance(target_root, ast.Subscript) or |
| 2068 | isinstance(target_root, ast.Attribute)): |
| 2069 | target_root = target_root.value |
| 2070 | if not isinstance(target_root, ast.Name): |
| 2071 | self.emitFatalError("invalid target for assignment", node) |
| 2072 | |
| 2073 | def update_in_parent_block(destination, value): |
| 2074 | assert not cc.PointerType.isinstance(value.type) |
| 2075 | assert self.symbolTable.isFromParentBlock(target_root.id) |
| 2076 | if cc.StructType.isinstance( |
| 2077 | value.type) and cc.StructType.getName( |
| 2078 | value.type) != 'tuple': |
| 2079 | |
| 2080 | # We can't properly deal with this case if the value we are |
| 2081 | # assigning is not an `rvalue`. Consider the case were we |
| 2082 | # have `v1` defined in the parent scope, `v2` in a child |
| 2083 | # scope, and we are assigning v2 to v1 in the child |
| 2084 | # scope. To do this assignment properly, we would need to |
| 2085 | # make sure that the pointers for both v1 and v2 points to |
| 2086 | # the same memory location such that any changes to v1 after |
| 2087 | # the assignment are reflected in v2 and vice versa (v2 |
| 2088 | # could be changed in the child while v1 is still |
| 2089 | # alive). Since we merely store the raw pointer in the |
| 2090 | # symbol table for `dataclasses`, we have no way of updating |
| 2091 | # that pointer conditionally on the child scope being |
| 2092 | # executed. To determine whether the value we assign is an |
| 2093 | # `rvalue`, it is sufficient to check whether its root is a |
| 2094 | # value in the symbol table (values returned from calls are |
nothing calls this directly
no test coverage detected