compiler: Use backend interface for constant expressions.
authorChris Manghane <cmang@google.com>
Thu, 17 Apr 2014 20:42:31 +0000 (20:42 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 17 Apr 2014 20:42:31 +0000 (20:42 +0000)
* go-gcc.cc (Gcc_backend::named_constant_expression): New
function.

From-SVN: r209495

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo-tree.cc

index 0d153fa..c8beaec 100644 (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".
index 3abefae..1af639e 100644 (file)
@@ -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*
index fd657ec..dd76204 100644 (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;
index 2571894..74ae9dd 100644 (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.
index e92acae..32a7f38 100644 (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;