+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".
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);
Bexpression*
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*
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;
// 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()))
}
}
- 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.
{
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;