summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-17 20:42:31 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2014-04-17 20:42:31 +0000
commitf2de45326e2514f5489651019fa09138cb9c5361 (patch)
tree0f0a7fc9a1aefaaab07c083ef183efc2a474f3d5
parent80d1e1a8d9645d1e57efa882725d16e6de6f1ad4 (diff)
downloadgcc-f2de45326e2514f5489651019fa09138cb9c5361.tar.gz
compiler: Use backend interface for constant expressions.
* go-gcc.cc (Gcc_backend::named_constant_expression): New function. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209495 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/ChangeLog5
-rw-r--r--gcc/go/go-gcc.cc27
-rw-r--r--gcc/go/gofrontend/backend.h6
-rw-r--r--gcc/go/gofrontend/expressions.cc12
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc48
5 files changed, 54 insertions, 44 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 0d153fa02e6..c8beaec2c94 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -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".
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 3abefaee9e6..1af639ef1ac 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -227,6 +227,10 @@ class Gcc_backend : public Backend
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*
@@ -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*
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
index fd657ecc989..dd76204e70c 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -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;
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 25718944b71..74ae9ddcd7d 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -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.
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index e92acae7af4..32a7f38093f 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -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;