This patch to the Go frontend and to libgo adds more uses of the backend
interface for types.  There were some changes to libgo because the code
now uses produces a Go type for maps.  Previously the map types were
using size_t, but there is no equivalent to size_t in Go.  Go instead
has uintptr_t, so I changed the libgo code accordingly.  This should not
make any actual difference, of course.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian

diff -r 0a1edd881eca go/types.cc
--- a/go/types.cc	Fri May 06 11:28:30 2011 -0700
+++ b/go/types.cc	Fri May 06 12:58:15 2011 -0700
@@ -845,7 +845,7 @@
 
   if (this->forward_declaration_type() != NULL
       || this->named_type() != NULL)
-    return this->get_tree_without_hash(gogo);
+    return type_to_tree(this->get_btype_without_hash(gogo));
 
   if (this->is_error_type())
     return error_mark_node;
@@ -865,7 +865,7 @@
       return ins.first->second;
     }
 
-  tree t = this->get_tree_without_hash(gogo);
+  tree t = type_to_tree(this->get_btype_without_hash(gogo));
 
   if (ins.first->second == NULL_TREE)
     ins.first->second = t;
@@ -884,43 +884,33 @@
   return t;
 }
 
-// Return a tree for a type without looking in the hash table for
-// identical types.  This is used for named types, since there is no
-// point to looking in the hash table for them.
-
-tree
-Type::get_tree_without_hash(Gogo* gogo)
+// Return the backend representation for a type without looking in the
+// hash table for identical types.  This is used for named types,
+// since a named type is never identical to any other type.
+
+Btype*
+Type::get_btype_without_hash(Gogo* gogo)
 {
   if (this->tree_ == NULL_TREE)
     {
-      tree t = this->do_get_tree(gogo);
+      Btype* bt = tree_to_type(this->do_get_tree(gogo));
 
       // For a recursive function or pointer type, we will temporarily
       // return a circular pointer type during the recursion.  We
       // don't want to record that for a forwarding type, as it may
       // confuse us later.
       if (this->forward_declaration_type() != NULL
-	  && gogo->backend()->is_circular_pointer_type(tree_to_type(t)))
-	return t;
+	  && gogo->backend()->is_circular_pointer_type(bt))
+	return bt;
 
       if (gogo == NULL || !gogo->named_types_are_converted())
-	return t;
-
+	return bt;
+
+      tree t = type_to_tree(bt);
       this->tree_ = t;
-      go_preserve_from_gc(t);
-    }
-
-  return this->tree_;
-}
-
-// Return the backend representation for a type without looking in the
-// hash table for identical types.  This is used for named types,
-// since a named type is never identical to any other type.
-
-Btype*
-Type::get_btype_without_hash(Gogo* gogo)
-{
-  return tree_to_type(this->get_tree_without_hash(gogo));
+    }
+
+  return tree_to_type(this->tree_);
 }
 
 // Return a tree representing a zero initialization for this type.
@@ -1596,8 +1586,8 @@
 
  protected:
   tree
-  do_get_tree(Gogo*)
-  { return error_mark_node; }
+  do_get_tree(Gogo* gogo)
+  { return type_to_tree(gogo->backend()->error_type()); }
 
   tree
   do_get_init_tree(Gogo*, tree, bool)
@@ -3228,8 +3218,11 @@
 
  protected:
   tree
-  do_get_tree(Gogo*)
-  { return ptr_type_node; }
+  do_get_tree(Gogo* gogo)
+  {
+    Btype* bt = gogo->backend()->pointer_type(gogo->backend()->void_type());
+    return type_to_tree(bt);
+  }
 
   tree
   do_get_init_tree(Gogo*, tree type_tree, bool is_clear)
@@ -5064,61 +5057,44 @@
   return true;
 }
 
-// Get a tree for a map type.  A map type is represented as a pointer
-// to a struct.  The struct is __go_map in libgo/map.h.
+// Get the backend representation for a map type.  A map type is
+// represented as a pointer to a struct.  The struct is __go_map in
+// libgo/map.h.
 
 tree
 Map_type::do_get_tree(Gogo* gogo)
 {
-  static tree type_tree;
-  if (type_tree == NULL_TREE)
-    {
-      tree struct_type = make_node(RECORD_TYPE);
-
-      tree map_descriptor_type = gogo->map_descriptor_type();
-      tree const_map_descriptor_type =
-	build_qualified_type(map_descriptor_type, TYPE_QUAL_CONST);
-      tree name = get_identifier("__descriptor");
-      tree field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name,
-			      build_pointer_type(const_map_descriptor_type));
-      DECL_CONTEXT(field) = struct_type;
-      TYPE_FIELDS(struct_type) = field;
-      tree last_field = field;
-
-      name = get_identifier("__element_count");
-      field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
-      DECL_CONTEXT(field) = struct_type;
-      DECL_CHAIN(last_field) = field;
-      last_field = field;
-
-      name = get_identifier("__bucket_count");
-      field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name, sizetype);
-      DECL_CONTEXT(field) = struct_type;
-      DECL_CHAIN(last_field) = field;
-      last_field = field;
-
-      name = get_identifier("__buckets");
-      field = build_decl(BUILTINS_LOCATION, FIELD_DECL, name,
-			 build_pointer_type(ptr_type_node));
-      DECL_CONTEXT(field) = struct_type;
-      DECL_CHAIN(last_field) = field;
-
-      layout_type(struct_type);
-
-      // Give the struct a name for better debugging info.
-      name = get_identifier("__go_map");
-      tree type_decl = build_decl(BUILTINS_LOCATION, TYPE_DECL, name,
-				  struct_type);
-      DECL_ARTIFICIAL(type_decl) = 1;
-      TYPE_NAME(struct_type) = type_decl;
-      go_preserve_from_gc(type_decl);
-      rest_of_decl_compilation(type_decl, 1, 0);
-
-      type_tree = build_pointer_type(struct_type);
-      go_preserve_from_gc(type_tree);
-    }
-
-  return type_tree;
+  static Btype* backend_map_type;
+  if (backend_map_type == NULL)
+    {
+      std::vector<Backend::Btyped_identifier> bfields(4);
+
+      Type* pdt = Type::make_type_descriptor_ptr_type();
+      bfields[0].name = "__descriptor";
+      bfields[0].btype = tree_to_type(pdt->get_tree(gogo));
+      bfields[0].location = BUILTINS_LOCATION;
+
+      Type* uintptr_type = Type::lookup_integer_type("uintptr");
+      bfields[1].name = "__element_count";
+      bfields[1].btype = tree_to_type(uintptr_type->get_tree(gogo));
+      bfields[1].location = BUILTINS_LOCATION;
+
+      bfields[2].name = "__bucket_count";
+      bfields[2].btype = bfields[1].btype;
+      bfields[2].location = BUILTINS_LOCATION;
+
+      Btype* bvt = gogo->backend()->void_type();
+      Btype* bpvt = gogo->backend()->pointer_type(bvt);
+      Btype* bppvt = gogo->backend()->pointer_type(bpvt);
+      bfields[3].name = "__buckets";
+      bfields[3].btype = bppvt;
+      bfields[3].location = BUILTINS_LOCATION;
+
+      Btype *bt = gogo->backend()->struct_type(bfields);
+      bt = gogo->backend()->named_type("__go_map", bt, BUILTINS_LOCATION);
+      backend_map_type = gogo->backend()->pointer_type(bt);
+    }
+  return type_to_tree(backend_map_type);
 }
 
 // Initialize a map.
@@ -5354,19 +5330,17 @@
 // libgo/runtime/channel.h.
 
 tree
-Channel_type::do_get_tree(Gogo*)
-{
-  static tree type_tree;
-  if (type_tree == NULL_TREE)
-    {
-      tree ret = make_node(RECORD_TYPE);
-      TYPE_NAME(ret) = get_identifier("__go_channel");
-      TYPE_STUB_DECL(ret) = build_decl(BUILTINS_LOCATION, TYPE_DECL, NULL_TREE,
-				       ret);
-      type_tree = build_pointer_type(ret);
-      go_preserve_from_gc(type_tree);
-    }
-  return type_tree;
+Channel_type::do_get_tree(Gogo* gogo)
+{
+  static Btype* backend_channel_type;
+  if (backend_channel_type == NULL)
+    {
+      std::vector<Backend::Btyped_identifier> bfields;
+      Btype* bt = gogo->backend()->struct_type(bfields);
+      bt = gogo->backend()->named_type("__go_channel", bt, BUILTINS_LOCATION);
+      backend_channel_type = gogo->backend()->pointer_type(bt);
+    }
+  return type_to_tree(backend_channel_type);
 }
 
 // Initialize a channel variable.
@@ -8433,7 +8407,7 @@
   return TRAVERSE_CONTINUE;
 }
 
-// Get a tree for the type.
+// Get the backend representation for the type.
 
 tree
 Forward_declaration_type::do_get_tree(Gogo* gogo)
@@ -8445,15 +8419,13 @@
     return error_mark_node;
 
   // We represent an undefined type as a struct with no fields.  That
-  // should work fine for the middle-end, since the same case can
-  // arise in C.
-  Named_object* no = this->named_object();
-  tree type_tree = make_node(RECORD_TYPE);
-  tree id = no->get_id(gogo);
-  tree decl = build_decl(no->location(), TYPE_DECL, id, type_tree);
-  TYPE_NAME(type_tree) = decl;
-  layout_type(type_tree);
-  return type_tree;
+  // should work fine for the backend, since the same case can arise
+  // in C.
+  std::vector<Backend::Btyped_identifier> fields;
+  Btype* bt = gogo->backend()->struct_type(fields);
+  bt = gogo->backend()->named_type(this->name(), bt,
+				   this->named_object()->location());
+  return type_to_tree(bt);
 }
 
 // Build a type descriptor for a forwarded type.
diff -r 0a1edd881eca go/types.h
--- a/go/types.h	Fri May 06 11:28:30 2011 -0700
+++ b/go/types.h	Fri May 06 12:58:15 2011 -0700
@@ -1098,11 +1098,6 @@
 		       bool* is_method, bool* found_pointer_method,
 		       std::string* ambig1, std::string* ambig2);
 
-  // Get a tree for a type without looking in the hash table for
-  // identical types.
-  tree
-  get_tree_without_hash(Gogo*);
-
   // Get the backend representation for a type without looking in the
   // hash table for identical types.
   Btype*
diff -r 0a1edd881eca libgo/runtime/channel.h
--- a/libgo/runtime/channel.h	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/channel.h	Fri May 06 12:58:15 2011 -0700
@@ -74,6 +74,9 @@
   uint64_t data[];
 };
 
+/* Try to link up with the structure generated by the frontend.  */
+typedef struct __go_channel __go_channel;
+
 /* The mutex used to control access to the value pointed to by the
    __go_channel_select selected field.  No additional mutexes may be
    acquired while this mutex is held.  */
diff -r 0a1edd881eca libgo/runtime/go-map-index.c
--- a/libgo/runtime/go-map-index.c	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/go-map-index.c	Fri May 06 12:58:15 2011 -0700
@@ -21,11 +21,11 @@
   size_t key_offset;
   size_t key_size;
   size_t (*hashfn) (const void *, size_t);
-  size_t old_bucket_count;
+  uintptr_t old_bucket_count;
   void **old_buckets;
-  size_t new_bucket_count;
+  uintptr_t new_bucket_count;
   void **new_buckets;
-  size_t i;
+  uintptr_t i;
 
   descriptor = map->__descriptor;
 
diff -r 0a1edd881eca libgo/runtime/go-map-len.c
--- a/libgo/runtime/go-map-len.c	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/go-map-len.c	Fri May 06 12:58:15 2011 -0700
@@ -18,6 +18,6 @@
 {
   if (map == NULL)
     return 0;
-  __go_assert (map->__element_count == (size_t) (int) map->__element_count);
+  __go_assert (map->__element_count == (uintptr_t) (int) map->__element_count);
   return map->__element_count;
 }
diff -r 0a1edd881eca libgo/runtime/go-map-range.c
--- a/libgo/runtime/go-map-range.c	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/go-map-range.c	Fri May 06 12:58:15 2011 -0700
@@ -34,7 +34,7 @@
   if (entry == NULL)
     {
       const struct __go_map *map;
-      size_t bucket;
+      uintptr_t bucket;
 
       map = it->map;
       bucket = it->bucket;
diff -r 0a1edd881eca libgo/runtime/go-new-map.c
--- a/libgo/runtime/go-new-map.c	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/go-new-map.c	Fri May 06 12:58:15 2011 -0700
@@ -73,8 +73,8 @@
 
 /* Return the next number from PRIME_LIST >= N.  */
 
-unsigned long
-__go_map_next_prime (unsigned long n)
+uintptr_t
+__go_map_next_prime (uintptr_t n)
 {
   size_t low;
   size_t high;
diff -r 0a1edd881eca libgo/runtime/map.h
--- a/libgo/runtime/map.h	Fri May 06 11:28:30 2011 -0700
+++ b/libgo/runtime/map.h	Fri May 06 12:58:15 2011 -0700
@@ -1,10 +1,11 @@
 /* map.h -- the map type for Go.
 
-   Copyright 2009, 2010 The Go Authors. All rights reserved.
+   Copyright 2009 The Go Authors. All rights reserved.
    Use of this source code is governed by a BSD-style
    license that can be found in the LICENSE file.  */
 
 #include <stddef.h>
+#include <stdint.h>
 
 #include "go-type.h"
 
@@ -38,10 +39,10 @@
   const struct __go_map_descriptor *__descriptor;
 
   /* The number of elements in the hash table.  */
-  size_t __element_count;
+  uintptr_t __element_count;
 
   /* The number of entries in the __buckets array.  */
-  size_t __bucket_count;
+  uintptr_t __bucket_count;
 
   /* Each bucket is a pointer to a linked list of map entries.  */
   void **__buckets;
@@ -64,13 +65,13 @@
      all the entries in the current bucket.  */
   const void *next_entry;
   /* The bucket index of the current and next entry.  */
-  size_t bucket;
+  uintptr_t bucket;
 };
 
 extern struct __go_map *__go_new_map (const struct __go_map_descriptor *,
 				      uintptr_t);
 
-extern unsigned long __go_map_next_prime (unsigned long);
+extern uintptr_t __go_map_next_prime (uintptr_t);
 
 extern void *__go_map_index (struct __go_map *, const void *, _Bool);
 

Reply via email to