compiler: Use backend interface for array length.
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 6 May 2014 01:14:34 +0000 (01:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 6 May 2014 01:14:34 +0000 (01:14 +0000)
From-SVN: r210093

gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h

index 91a535f01c8c50d6fbd5b6b680ff40962fbbd061..0ff9c76d68b1580dc4c13ba7fe9131797e9e5db3 100644 (file)
@@ -245,7 +245,7 @@ Type::points_to() const
   return ptype == NULL ? NULL : ptype->points_to();
 }
 
-// Return whether this is an open array type.
+// Return whether this is a slice type.
 
 bool
 Type::is_slice_type() const
@@ -5839,54 +5839,6 @@ Array_type::write_equal_function(Gogo* gogo, Named_type* name)
   gogo->add_statement(s);
 }
 
-// Get a tree for the length of a fixed array.  The length may be
-// computed using a function call, so we must only evaluate it once.
-
-tree
-Array_type::get_length_tree(Gogo* gogo)
-{
-  go_assert(this->length_ != NULL);
-  if (this->length_tree_ == NULL_TREE)
-    {
-      Numeric_constant nc;
-      mpz_t val;
-      if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val))
-       {
-         if (mpz_sgn(val) < 0)
-           {
-             this->length_tree_ = error_mark_node;
-             return this->length_tree_;
-           }
-         Type* t = nc.type();
-         if (t == NULL)
-           t = Type::lookup_integer_type("int");
-         else if (t->is_abstract())
-           t = t->make_non_abstract_type();
-          Btype* btype = t->get_backend(gogo);
-          Bexpression* iexpr =
-              gogo->backend()->integer_constant_expression(btype, val);
-         this->length_tree_ = expr_to_tree(iexpr);
-         mpz_clear(val);
-       }
-      else
-       {
-         // Make up a translation context for the array length
-         // expression.  FIXME: This won't work in general.
-         Translate_context context(gogo, NULL, NULL, NULL);
-         tree len = this->length_->get_tree(&context);
-         if (len != error_mark_node)
-           {
-             Type* int_type = Type::lookup_integer_type("int");
-             tree int_type_tree = type_to_tree(int_type->get_backend(gogo));
-             len = convert_to_integer(int_type_tree, len);
-             len = save_expr(len);
-           }
-         this->length_tree_ = len;
-       }
-    }
-  return this->length_tree_;
-}
-
 // Get the backend representation of the fields of a slice.  This is
 // not declared in types.h so that types.h doesn't have to #include
 // backend.h.
@@ -5927,7 +5879,7 @@ get_backend_slice_fields(Gogo* gogo, Array_type* type, bool use_placeholder,
 
 // Get a tree for the type of this array.  A fixed array is simply
 // represented as ARRAY_TYPE with the appropriate index--i.e., it is
-// just like an array in C.  An open array is a struct with three
+// just like an array in C.  A slice is a struct with three
 // fields: a data pointer, the length, and the capacity.
 
 Btype*
@@ -5958,12 +5910,48 @@ Array_type::get_backend_element(Gogo* gogo, bool use_placeholder)
     return this->element_type_->get_backend(gogo);
 }
 
-// Return the backend representation of the length.
+// Return the backend representation of the length. The length may be
+// computed using a function call, so we must only evaluate it once.
 
 Bexpression*
 Array_type::get_backend_length(Gogo* gogo)
 {
-  return tree_to_expr(this->get_length_tree(gogo));
+  go_assert(this->length_ != NULL);
+  if (this->blength_ == NULL)
+    {
+      Numeric_constant nc;
+      mpz_t val;
+      if (this->length_->numeric_constant_value(&nc) && nc.to_int(&val))
+       {
+         if (mpz_sgn(val) < 0)
+           {
+             this->blength_ = gogo->backend()->error_expression();
+             return this->blength_;
+           }
+         Type* t = nc.type();
+         if (t == NULL)
+           t = Type::lookup_integer_type("int");
+         else if (t->is_abstract())
+           t = t->make_non_abstract_type();
+          Btype* btype = t->get_backend(gogo);
+          this->blength_ =
+           gogo->backend()->integer_constant_expression(btype, val);
+         mpz_clear(val);
+       }
+      else
+       {
+         // Make up a translation context for the array length
+         // expression.  FIXME: This won't work in general.
+         Translate_context context(gogo, NULL, NULL, NULL);
+         this->blength_ = tree_to_expr(this->length_->get_tree(&context));
+
+         Btype* ibtype = Type::lookup_integer_type("int")->get_backend(gogo);
+         this->blength_ =
+           gogo->backend()->convert_expression(ibtype, this->blength_,
+                                               this->length_->location());
+       }
+    }
+  return this->blength_;
 }
 
 // Finish backend representation of the array.
@@ -5997,7 +5985,7 @@ Array_type::get_value_pointer(Gogo*, Expression* array) const
                                    array->location());
     }
 
-  // Open array.
+  // Slice.
   return Expression::make_slice_info(array,
                                      Expression::SLICE_INFO_VALUE_POINTER,
                                      array->location());
@@ -6012,7 +6000,7 @@ Array_type::get_length(Gogo*, Expression* array) const
   if (this->length_ != NULL)
     return this->length_;
 
-  // This is an open array.  We need to read the length field.
+  // This is a slice.  We need to read the length field.
   return Expression::make_slice_info(array, Expression::SLICE_INFO_LENGTH,
                                      array->location());
 }
@@ -6026,7 +6014,7 @@ Array_type::get_capacity(Gogo*, Expression* array) const
   if (this->length_ != NULL)
     return this->length_;
 
-  // This is an open array.  We need to read the capacity field.
+  // This is a slice.  We need to read the capacity field.
   return Expression::make_slice_info(array, Expression::SLICE_INFO_CAPACITY,
                                      array->location());
 }
index d2ca1bf27fb3ceca658e0939b69d1726fca86ca9..b2a49ac3af11ccebbb54e5ac9f575e56702304c3 100644 (file)
@@ -2305,7 +2305,7 @@ class Array_type : public Type
  public:
   Array_type(Type* element_type, Expression* length)
     : Type(TYPE_ARRAY),
-      element_type_(element_type), length_(length), length_tree_(NULL)
+      element_type_(element_type), length_(length), blength_(NULL)
   { }
 
   // Return the element type.
@@ -2313,7 +2313,7 @@ class Array_type : public Type
   element_type() const
   { return this->element_type_; }
 
-  // Return the length.  This will return NULL for an open array.
+  // Return the length.  This will return NULL for a slice.
   Expression*
   length() const
   { return this->length_; }
@@ -2407,9 +2407,6 @@ class Array_type : public Type
   bool
   verify_length();
 
-  tree
-  get_length_tree(Gogo*);
-
   Expression*
   array_type_descriptor(Gogo*, Named_type*);
 
@@ -2420,8 +2417,9 @@ class Array_type : public Type
   Type* element_type_;
   // The number of elements.  This may be NULL.
   Expression* length_;
-  // The length as a tree.  We only want to compute this once.
-  tree length_tree_;
+  // The backend representation of the length.
+  // We only want to compute this once.
+  Bexpression* blength_;
 };
 
 // The type of a map.