diff mbox

Go patch committed: Use backend interface for field references

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

Commit Message

Ian Lance Taylor Dec. 16, 2013, 7:58 p.m. UTC
This patch from Chris Manghane uses the backend interface for references
to struct fields.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2013-12-16  Chris Manghane  <cmang@google.com>

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

Patch

Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 205955)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -11539,28 +11539,12 @@  Field_reference_expression::do_check_typ
 tree
 Field_reference_expression::do_get_tree(Translate_context* context)
 {
-  tree struct_tree = this->expr_->get_tree(context);
-  if (struct_tree == error_mark_node
-      || TREE_TYPE(struct_tree) == error_mark_node)
-    return error_mark_node;
-  go_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
-  tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
-  if (field == NULL_TREE)
-    {
-      // This can happen for a type which refers to itself indirectly
-      // and then turns out to be erroneous.
-      go_assert(saw_errors());
-      return error_mark_node;
-    }
-  for (unsigned int i = this->field_index_; i > 0; --i)
-    {
-      field = DECL_CHAIN(field);
-      go_assert(field != NULL_TREE);
-    }
-  if (TREE_TYPE(field) == error_mark_node)
-    return error_mark_node;
-  return build3(COMPONENT_REF, TREE_TYPE(field), struct_tree, field,
-		NULL_TREE);
+  Bexpression* bstruct = tree_to_expr(this->expr_->get_tree(context));
+  Bexpression* ret =
+      context->gogo()->backend()->struct_field_expression(bstruct,
+                                                          this->field_index_,
+                                                          this->location());
+  return expr_to_tree(ret);
 }
 
 // Dump ast representation for a field reference expression.
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h	(revision 205955)
+++ gcc/go/gofrontend/backend.h	(working copy)
@@ -280,6 +280,10 @@  class Backend
   virtual Bexpression*
   address_expression(Bexpression*, Location) = 0;
 
+  // Return an expression for the field at INDEX in BSTRUCT.
+  virtual Bexpression*
+  struct_field_expression(Bexpression* bstruct, size_t index, Location) = 0;
+
   // Statements.
 
   // Create an error statement.  This is used for cases which should
Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 205955)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -243,6 +243,9 @@  class Gcc_backend : public Backend
   Bexpression*
   address_expression(Bexpression*, Location);
 
+  Bexpression*
+  struct_field_expression(Bexpression*, size_t, Location);
+
   // Statements.
 
   Bstatement*
@@ -998,6 +1001,39 @@  Gcc_backend::address_expression(Bexpress
   return this->make_expression(ret);
 }
 
+// Return an expression for the field at INDEX in BSTRUCT.
+
+Bexpression*
+Gcc_backend::struct_field_expression(Bexpression* bstruct, size_t index,
+                                     Location location)
+{
+  tree struct_tree = bstruct->get_tree();
+  if (struct_tree == error_mark_node
+      || TREE_TYPE(struct_tree) == error_mark_node)
+    return this->error_expression();
+  gcc_assert(TREE_CODE(TREE_TYPE(struct_tree)) == RECORD_TYPE);
+  tree field = TYPE_FIELDS(TREE_TYPE(struct_tree));
+  if (field == NULL_TREE)
+  {
+    // This can happen for a type which refers to itself indirectly
+    // and then turns out to be erroneous.
+    return this->error_expression();
+  }
+  for (unsigned int i = index; i > 0; --i)
+  {
+    field = DECL_CHAIN(field);
+    gcc_assert(field != NULL_TREE);
+  }
+  if (TREE_TYPE(field) == error_mark_node)
+    return this->error_expression();
+  tree ret = fold_build3_loc(location.gcc_location(), COMPONENT_REF,
+                             TREE_TYPE(field), struct_tree, field,
+                             NULL_TREE);
+  if (TREE_CONSTANT(struct_tree))
+    TREE_CONSTANT(ret) = 1;
+  return tree_to_expr(ret);
+}
+
 // An expression as a statement.
 
 Bstatement*
Index: gcc/go/ChangeLog
===================================================================
--- gcc/go/ChangeLog	(revision 205955)
+++ gcc/go/ChangeLog	(working copy)
@@ -1,3 +1,7 @@ 
+2013-12-16  Chris Manghane  <cmang@google.com>
+
+	* go-gcc.cc (Gcc_backend::struct_field_expression): New function.
+
 2013-12-11  Ian Lance Taylor  <iant@google.com>
 
 	* go-lang.c (go_langhook_post_options): Disable sibling calls by