diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 20:42:31 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-04-17 20:42:31 +0000 |
commit | f2de45326e2514f5489651019fa09138cb9c5361 (patch) | |
tree | 0f0a7fc9a1aefaaab07c083ef183efc2a474f3d5 | |
parent | 80d1e1a8d9645d1e57efa882725d16e6de6f1ad4 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 27 | ||||
-rw-r--r-- | gcc/go/gofrontend/backend.h | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 12 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo-tree.cc | 48 |
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; |