compiler: Use backend interface for constant expressions.

* go-gcc.cc (Gcc_backend::named_constant_expression): New
	function.

From-SVN: r209495
This commit is contained in:
Chris Manghane 2014-04-17 20:42:31 +00:00 committed by Ian Lance Taylor
parent be7341a882
commit e85baec793
5 changed files with 54 additions and 44 deletions

View File

@ -1,3 +1,8 @@
2014-04-17 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::named_constant_expression): New
function.
2014-04-14 Chris Manghane <cmang@google.com>
* go-gcc.cc: Include "convert.h".

View File

@ -226,6 +226,10 @@ class Gcc_backend : public Backend
Bexpression*
indirect_expression(Bexpression* expr, bool known_valid, Location);
Bexpression*
named_constant_expression(Btype* btype, const std::string& name,
Bexpression* val, Location);
Bexpression*
integer_constant_expression(Btype* btype, mpz_t val);
@ -962,6 +966,29 @@ Gcc_backend::indirect_expression(Bexpression* expr, bool known_valid,
return tree_to_expr(ret);
}
// Return an expression that declares a constant named NAME with the
// constant value VAL in BTYPE.
Bexpression*
Gcc_backend::named_constant_expression(Btype* btype, const std::string& name,
Bexpression* val, Location location)
{
tree type_tree = btype->get_tree();
tree const_val = val->get_tree();
if (type_tree == error_mark_node || const_val == error_mark_node)
return this->error_expression();
tree name_tree = get_identifier_from_string(name);
tree decl = build_decl(location.gcc_location(), CONST_DECL, name_tree,
type_tree);
DECL_INITIAL(decl) = const_val;
TREE_CONSTANT(decl) = 1;
TREE_READONLY(decl) = 1;
go_preserve_from_gc(decl);
return this->make_expression(decl);
}
// Return a typed value as a constant integer.
Bexpression*

View File

@ -257,6 +257,12 @@ class Backend
virtual Bexpression*
indirect_expression(Bexpression* expr, bool known_valid, Location) = 0;
// Return an expression that declares a constant named NAME with the
// constant value VAL in BTYPE.
virtual Bexpression*
named_constant_expression(Btype* btype, const std::string& name,
Bexpression* val, Location) = 0;
// Return an expression for the multi-precision integer VAL in BTYPE.
virtual Bexpression*
integer_constant_expression(Btype* btype, mpz_t val) = 0;

View File

@ -2792,12 +2792,12 @@ Const_expression::do_get_tree(Translate_context* context)
// If the type has been set for this expression, but the underlying
// object is an abstract int or float, we try to get the abstract
// value. Otherwise we may lose something in the conversion.
Expression* expr = this->constant_->const_value()->expr();
if (this->type_ != NULL
&& this->type_->is_numeric_type()
&& (this->constant_->const_value()->type() == NULL
|| this->constant_->const_value()->type()->is_abstract()))
{
Expression* expr = this->constant_->const_value()->expr();
Numeric_constant nc;
if (expr->numeric_constant_value(&nc)
&& nc.set_type(this->type_, false, this->location()))
@ -2807,15 +2807,9 @@ Const_expression::do_get_tree(Translate_context* context)
}
}
Gogo* gogo = context->gogo();
Bexpression* ret =
tree_to_expr(this->constant_->get_tree(gogo, context->function()));
if (this->type_ != NULL)
{
Btype* btype = this->type_->get_backend(gogo);
ret = gogo->backend()->convert_expression(btype, ret, this->location());
}
return expr_to_tree(ret);
expr = Expression::make_cast(this->type_, expr, this->location());
return expr->get_tree(context);
}
// Dump ast representation for constant expression.

View File

@ -1015,44 +1015,22 @@ Named_object::get_tree(Gogo* gogo, Named_object* function)
{
case NAMED_OBJECT_CONST:
{
Named_constant* named_constant = this->u_.const_value;
Translate_context subcontext(gogo, function, NULL, NULL);
tree expr_tree = named_constant->expr()->get_tree(&subcontext);
if (expr_tree == error_mark_node)
decl = error_mark_node;
else
Type* type = this->u_.const_value->type();
Location loc = this->location();
Expression* const_ref = Expression::make_const_reference(this, loc);
Bexpression* const_decl =
tree_to_expr(const_ref->get_tree(&subcontext));
if (type != NULL && type->is_numeric_type())
{
Type* type = named_constant->type();
if (type != NULL && !type->is_abstract())
{
if (type->is_error())
expr_tree = error_mark_node;
else
{
Btype* btype = type->get_backend(gogo);
expr_tree = fold_convert(type_to_tree(btype), expr_tree);
}
}
if (expr_tree == error_mark_node)
decl = error_mark_node;
else if (INTEGRAL_TYPE_P(TREE_TYPE(expr_tree)))
{
tree name = get_identifier_from_string(this->get_id(gogo));
decl = build_decl(named_constant->location().gcc_location(),
CONST_DECL, name, TREE_TYPE(expr_tree));
DECL_INITIAL(decl) = expr_tree;
TREE_CONSTANT(decl) = 1;
TREE_READONLY(decl) = 1;
}
else
{
// A CONST_DECL is only for an enum constant, so we
// shouldn't use for non-integral types. Instead we
// just return the constant itself, rather than a
// decl.
decl = expr_tree;
}
Btype* btype = type->get_backend(gogo);
std::string name = this->get_id(gogo);
const_decl =
gogo->backend()->named_constant_expression(btype, name,
const_decl, loc);
}
decl = expr_to_tree(const_decl);
}
break;