import symbol:* import tree:* import map:* import util:* import str:* import io:* import ast_nodes:* import ast_transformation:* import pass_common:* fun address_of_ensure_variable_lower(name_ast_map: *map,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree>) { var visited = hash_set<*ast_node>() name_ast_map->for_each(fun(name: str, syntax_ast_pair: pair<*tree,*ast_node>) { var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { match(*node) { ast_node::function_call(backing) { if (is_function(backing.func) && backing.func->function.name == "&") { var addresse = backing.parameters[0] // Identifier is always fine. The other options are // function call, value, or cast. The only fine one here // is a function call of * if ( (is_function_call(addresse) && !(is_function(addresse->function_call.func) && (addresse->function_call.func->function.name == "*" || addresse->function_call.func->function.name == "." || addresse->function_call.func->function.name == "->" || addresse->function_call.func->function.name == "[]"))) || is_value(addresse) || is_cast(addresse) ) { // so we're a function call that's not * or a cast or value // so make a temp variable for us // Note that we don't have to worry about destruction because // all object stuff has already ran, so this isn't an object var enclosing_block_idx = parent_chain->index_from_top_satisfying(is_code_block) var enclosing_block = parent_chain->from_top(enclosing_block_idx) var before_block_parent = parent_chain->from_top(enclosing_block_idx-1) var ident = _ident("for_address_of_temp", backing.func->function.type->parameter_types[0], enclosing_block) var decl = _declaration(ident, addresse) add_before_in(decl, before_block_parent, enclosing_block) replace_with_in(addresse, ident, node) } } } } } run_on_tree(helper_before, empty_pass_second_half(), syntax_ast_pair.second, &visited) }) }