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:
parent
be7341a882
commit
e85baec793
@ -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".
|
||||
|
@ -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*
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user