diff mbox

Go patch committed: Use backend interface for constant expressions

Message ID mcrbnvzd6vy.fsf@iant-glaptop.roam.corp.google.com
State New
Headers show

Commit Message

Ian Lance Taylor April 17, 2014, 8:43 p.m. UTC
This patch from Chris Manghane changes the Go frontend to use the
backend interface for global constants.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2014-04-17  Chris Manghane  <cmang@google.com>

	* go-gcc.cc (Gcc_backend::named_constant_expression): New
	function.
diff mbox

Patch

Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 209494)
+++ gcc/go/go-gcc.cc	(revision 209495)
@@ -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(Bexpres
   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: gcc/go/gofrontend/gogo-tree.cc
===================================================================
--- gcc/go/gofrontend/gogo-tree.cc	(revision 209494)
+++ gcc/go/gofrontend/gogo-tree.cc	(revision 209495)
@@ -1015,44 +1015,22 @@  Named_object::get_tree(Gogo* gogo, Named
     {
     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;
 
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h	(revision 209494)
+++ gcc/go/gofrontend/backend.h	(revision 209495)
@@ -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: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 209494)
+++ gcc/go/gofrontend/expressions.cc	(revision 209495)
@@ -2792,12 +2792,12 @@  Const_expression::do_get_tree(Translate_
   // 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_
 	}
     }
 
-  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.