compiler: Use backend interface for variable expressions.
* go-gcc.cc (Backend::error_expression): New function. (Backend::var_expression): New function. (Backend::indirect_expression): New function. From-SVN: r203038
This commit is contained in:
parent
a10bad862f
commit
d4fe7beb78
4 changed files with 61 additions and 8 deletions
|
@ -1,3 +1,9 @@
|
|||
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.
|
||||
|
|
|
@ -208,6 +208,16 @@ class Gcc_backend : public Backend
|
|||
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*
|
||||
|
@ -848,6 +858,30 @@ Gcc_backend::zero_expression(Btype* btype)
|
|||
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*
|
||||
|
|
|
@ -231,6 +231,22 @@ class Backend
|
|||
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
|
||||
|
|
|
@ -978,22 +978,19 @@ Var_expression::do_get_tree(Translate_context* context)
|
|||
{
|
||||
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.
|
||||
|
|
Loading…
Add table
Reference in a new issue