+2013-09-30 Chris Manghane <cmang@google.com>
+
+ * go-gcc.cc (Backend::error_expression): New function.
+ (Backend::var_expression): New function.
+ (Backend::indirect_expression): New function.
+
2013-09-25 Tom Tromey <tromey@redhat.com>
* Make-lang.in (gospec.o): Remove.
Bexpression*
zero_expression(Btype*);
+ Bexpression*
+ error_expression()
+ { return this->make_expression(error_mark_node); }
+
+ Bexpression*
+ var_expression(Bvariable* var, Location);
+
+ Bexpression*
+ indirect_expression(Bexpression* expr, bool known_valid, Location);
+
// Statements.
Bstatement*
return tree_to_expr(ret);
}
+// An expression that references a variable.
+
+Bexpression*
+Gcc_backend::var_expression(Bvariable* var, Location)
+{
+ tree ret = var->get_tree();
+ if (ret == error_mark_node)
+ return this->error_expression();
+ return tree_to_expr(ret);
+}
+
+// An expression that indirectly references an expression.
+
+Bexpression*
+Gcc_backend::indirect_expression(Bexpression* expr, bool known_valid,
+ Location location)
+{
+ tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
+ expr->get_tree());
+ if (known_valid)
+ TREE_THIS_NOTRAP(ret) = 1;
+ return tree_to_expr(ret);
+}
+
// An expression as a statement.
Bstatement*
virtual Bexpression*
zero_expression(Btype*) = 0;
+ // Create an error expression. This is used for cases which should
+ // not occur in a correct program, in order to keep the compilation
+ // going without crashing.
+ virtual Bexpression*
+ error_expression() = 0;
+
+ // Create a reference to a variable.
+ virtual Bexpression*
+ var_expression(Bvariable* var, Location) = 0;
+
+ // Create an expression that indirects through the pointer expression EXPR
+ // (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer
+ // is known to point to a valid memory location.
+ virtual Bexpression*
+ indirect_expression(Bexpression* expr, bool known_valid, Location) = 0;
+
// Statements.
// Create an error statement. This is used for cases which should
{
Bvariable* bvar = this->variable_->get_backend_variable(context->gogo(),
context->function());
- tree ret = var_to_tree(bvar);
- if (ret == error_mark_node)
- return error_mark_node;
bool is_in_heap;
+ Location loc = this->location();
if (this->variable_->is_variable())
is_in_heap = this->variable_->var_value()->is_in_heap();
else if (this->variable_->is_result_variable())
is_in_heap = this->variable_->result_var_value()->is_in_heap();
else
go_unreachable();
+
+ Bexpression* ret = context->backend()->var_expression(bvar, loc);
if (is_in_heap)
- {
- ret = build_fold_indirect_ref_loc(this->location().gcc_location(), ret);
- TREE_THIS_NOTRAP(ret) = 1;
- }
- return ret;
+ ret = context->backend()->indirect_expression(ret, true, loc);
+ return expr_to_tree(ret);
}
// Ast dump for variable expression.