OSDN Git Service

Start using backend interface separate from gofrontend.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Apr 2011 22:44:18 +0000 (22:44 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Apr 2011 22:44:18 +0000 (22:44 +0000)
* go-gcc.cc: New file.
* Make-lang.in (GO_OBJS): Add go/go-gcc.o.
(go/go-gcc.o): New target.
(go/go.o): Depend on go/gofrontend/backend.h.
(go/statements.o): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171917 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/go-gcc.cc [new file with mode: 0644]
gcc/go/gofrontend/backend.h [new file with mode: 0644]
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/statements.cc

index c21dc75..5d50db2 100644 (file)
@@ -1,3 +1,11 @@
+2011-04-03  Ian Lance Taylor  <iant@google.com>
+
+       * go-gcc.cc: New file.
+       * Make-lang.in (GO_OBJS): Add go/go-gcc.o.
+       (go/go-gcc.o): New target.
+       (go/go.o): Depend on go/gofrontend/backend.h.
+       (go/statements.o): Likewise.
+
 2011-02-14  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * gccgo.texi (Top, Import and Export): Fix a typo and a markup nit.
index a8c3aa6..07c884d 100644 (file)
@@ -50,6 +50,7 @@ GO_OBJS = \
        go/expressions.o \
        go/go-backend.o \
        go/go-dump.o \
+       go/go-gcc.o \
        go/go-lang.o \
        go/go.o \
        go/gogo-tree.o \
@@ -235,6 +236,9 @@ go/go-lang.o: go/go-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \
 
 GOINCLUDES = -I $(srcdir)/go -I $(srcdir)/go/gofrontend
 
+go/go-gcc.o: go/go-gcc.cc $(GO_SYSTEM_H) $(TREE_H) go/gofrontend/backend.h
+       $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
+
 go/%.o: go/gofrontend/%.cc
        $(CXX) -c $(GOINCLUDES) $(ALL_CPPFLAGS) $(ALL_CXXFLAGS) $< $(OUTPUT_OPTION)
 
@@ -249,7 +253,7 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
        go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
        $(GO_EXPRESSIONS_H)
 go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
-       $(GO_PARSE_H) $(GO_GOGO_H)
+       $(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
        go/gofrontend/go-dump.h
 go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
@@ -272,7 +276,7 @@ go/parse.o: go/gofrontend/parse.cc $(GO_SYSTEM_H) $(GO_LEX_H) $(GO_GOGO_H) \
 go/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) intl.h $(TREE_H) \
        $(GIMPLE_H) convert.h tree-iterator.h $(TREE_FLOW_H) $(REAL_H) \
        $(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \
-       $(GO_STATEMENTS_H)
+       go/gofrontend/backend.h $(GO_STATEMENTS_H)
 go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \
        $(GIMPLE_H) $(REAL_H) convert.h $(GO_C_H) $(GO_GOGO_H) \
        go/gofrontend/operator.h $(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) \
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
new file mode 100644 (file)
index 0000000..ca2d63b
--- /dev/null
@@ -0,0 +1,199 @@
+// go-gcc.cc -- Go frontend to gcc IR.
+// Copyright (C) 2011 Free Software Foundation, Inc.
+// Contributed by Ian Lance Taylor, Google.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "go-system.h"
+
+// This has to be included outside of extern "C", so we have to
+// include it here before tree.h includes it later.
+#include <gmp.h>
+
+#ifndef ENABLE_BUILD_WITH_CXX
+extern "C"
+{
+#endif
+
+#include "tree.h"
+
+#ifndef ENABLE_BUILD_WITH_CXX
+}
+#endif
+
+#include "backend.h"
+
+// A class wrapping a tree.
+
+class Gcc_tree
+{
+ public:
+  Gcc_tree(tree t)
+    : t_(t)
+  { }
+
+  tree
+  get_tree()
+  { return this->t_; }
+
+ private:
+  tree t_;
+};
+
+// In gcc, types, expressions, and statements are all trees.
+class Btype : public Gcc_tree
+{
+ public:
+  Btype(tree t)
+    : Gcc_tree(t)
+  { }
+};
+
+class Bexpression : public Gcc_tree
+{
+ public:
+  Bexpression(tree t)
+    : Gcc_tree(t)
+  { }
+};
+
+class Bstatement : public Gcc_tree
+{
+ public:
+  Bstatement(tree t)
+    : Gcc_tree(t)
+  { }
+};
+
+// This file implements the interface between the Go frontend proper
+// and the gcc IR.  This implements specific instantiations of
+// abstract classes defined by the Go frontend proper.  The Go
+// frontend proper class methods of these classes to generate the
+// backend representation.
+
+class Gcc_backend : public Backend
+{
+ public:
+  // Types.
+
+  Btype*
+  error_type()
+  { gcc_unreachable(); }
+
+  Btype*
+  void_type()
+  { gcc_unreachable(); }
+
+  Btype*
+  bool_type()
+  { gcc_unreachable(); }
+
+  Btype*
+  integer_type(bool /* is_unsigned */, int /* bits */)
+  { gcc_unreachable(); }
+
+  Btype*
+  float_type(int /* bits */)
+  { gcc_unreachable(); }
+
+  Btype*
+  string_type()
+  { gcc_unreachable(); }
+
+  Btype*
+  function_type(const Function_type*, Btype* /* receiver */,
+               const Btypes* /* parameters */,
+               const Btypes* /* results */)
+  { gcc_unreachable(); }
+
+  Btype*
+  struct_type(const Struct_type*, const Btypes* /* field_types */)
+  { gcc_unreachable(); }
+
+  Btype*
+  array_type(const Btype* /* element_type */, const Bexpression* /* length */)
+  { gcc_unreachable(); }
+
+  Btype*
+  slice_type(const Btype* /* element_type */)
+  { gcc_unreachable(); }
+
+  Btype*
+  map_type(const Btype* /* key_type */, const Btype* /* value_type */,
+          source_location)
+  { gcc_unreachable(); }
+
+  Btype*
+  channel_type(const Btype* /* element_type */)
+  { gcc_unreachable(); }
+
+  Btype*
+  interface_type(const Interface_type*, const Btypes* /* method_types */)
+  { gcc_unreachable(); }
+
+  // Statements.
+
+  // Create an assignment statement.
+  Bstatement*
+  assignment(Bexpression* lhs, Bexpression* rhs,
+            source_location location);
+
+ private:
+  // Make a Bstatement from a tree.
+  Bstatement*
+  make_statement(tree t)
+  { return new Bstatement(t); }
+};
+
+// Assignment.
+
+Bstatement*
+Gcc_backend::assignment(Bexpression* lhs, Bexpression* rhs,
+                       source_location location)
+{
+  return this->make_statement(fold_build2_loc(location, MODIFY_EXPR,
+                                             void_type_node,
+                                             lhs->get_tree(),
+                                             rhs->get_tree()));
+}
+
+// The single backend.
+
+static Gcc_backend gcc_backend;
+
+// Return the backend generator.
+
+Backend*
+go_get_backend()
+{
+  return &gcc_backend;
+}
+
+// FIXME: Temporary functions while converting to the new backend
+// interface.
+
+Bexpression*
+tree_to_expr(tree t)
+{
+  return new Bexpression(t);
+}
+
+tree
+statement_to_tree(Bstatement* bs)
+{
+  return bs->get_tree();
+}
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
new file mode 100644 (file)
index 0000000..babef83
--- /dev/null
@@ -0,0 +1,119 @@
+// backend.h -- Go frontend interface to backend  -*- C++ -*-
+
+// Copyright 2011 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.
+
+#ifndef GO_BACKEND_H
+#define GO_BACKEND_H
+
+class Function_type;
+class Struct_type;
+class Interface_type;
+
+// Pointers to these types are created by the backend, passed to the
+// frontend, and passed back to the backend.  The types must be
+// defined by the backend using these names.
+
+// The backend representation of a type.
+class Btype;
+
+// The backend represention of an expression.
+class Bexpression;
+
+// The backend representation of a statement.
+class Bstatement;
+
+// A list of backend types.
+typedef std::vector<Btype*> Btypes;
+
+// The backend interface.  This is a pure abstract class that a
+// specific backend will implement.
+
+class Backend
+{
+ public:
+  virtual ~Backend() { }
+
+  // Types.
+
+  // Produce an error type.  Actually the backend could probably just
+  // crash if this is called.
+  virtual Btype*
+  error_type() = 0;
+
+  // Get a void type.  This is used in (at least) two ways: 1) as the
+  // return type of a function with no result parameters; 2)
+  // unsafe.Pointer is represented as *void.
+  virtual Btype*
+  void_type() = 0;
+
+  // Get the unnamed boolean type.
+  virtual Btype*
+  bool_type() = 0;
+
+  // Get an unnamed integer type with the given signedness and number
+  // of bits.
+  virtual Btype*
+  integer_type(bool is_unsigned, int bits) = 0;
+
+  // Get an unnamed floating point type with the given number of bits.
+  virtual Btype*
+  float_type(int bits) = 0;
+
+  // Get the unnamed string type.
+  virtual Btype*
+  string_type() = 0;
+
+  // Get a function type.  The receiver, parameter, and results are
+  // generated from the types in the Function_type.  The Function_type
+  // is provided so that the names are available.
+  virtual Btype*
+  function_type(const Function_type*, Btype* receiver,
+               const Btypes* parameters,
+               const Btypes* results) = 0;
+
+  // Get a struct type.  The Struct_type is provided to get the field
+  // names.
+  virtual Btype*
+  struct_type(const Struct_type*, const Btypes* field_types) = 0;
+
+  // Get an array type.
+  virtual Btype*
+  array_type(const Btype* element_type, const Bexpression* length) = 0;
+
+  // Get a slice type.
+  virtual Btype*
+  slice_type(const Btype* element_type) = 0;
+
+  // Get a map type.
+  virtual Btype*
+  map_type(const Btype* key_type, const Btype* value_type, source_location) = 0;
+
+  // Get a channel type.
+  virtual Btype*
+  channel_type(const Btype* element_type) = 0;
+
+  // Get an interface type.  The Interface_type is provided to get the
+  // method names.
+  virtual Btype*
+  interface_type(const Interface_type*, const Btypes* method_types) = 0;
+
+  // Statements.
+
+  // Create an assignment statement.
+  virtual Bstatement*
+  assignment(Bexpression* lhs, Bexpression* rhs, source_location location) = 0;
+};
+
+// The backend interface has to define this function.
+
+extern Backend* go_get_backend();
+
+// FIXME: Temporary helper functions while converting to new backend
+// interface.
+
+extern Bexpression* tree_to_expr(tree);
+extern tree statement_to_tree(Bstatement*);
+
+#endif // !defined(GO_BACKEND_H)
index 7b1fd7e..e872973 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "lex.h"
 #include "parse.h"
+#include "backend.h"
 #include "gogo.h"
 
 // The unique prefix to use for exported symbols.  This is set during
@@ -27,7 +28,7 @@ void
 go_create_gogo(int int_type_size, int pointer_size)
 {
   gcc_assert(::gogo == NULL);
-  ::gogo = new Gogo(int_type_size, pointer_size);
+  ::gogo = new Gogo(go_get_backend(), int_type_size, pointer_size);
   if (!unique_prefix.empty())
     ::gogo->set_unique_prefix(unique_prefix);
 }
index 9001d2b..6450141 100644 (file)
@@ -19,8 +19,9 @@
 
 // Class Gogo.
 
-Gogo::Gogo(int int_type_size, int pointer_size)
-  : package_(NULL),
+Gogo::Gogo(Backend* backend, int int_type_size, int pointer_size)
+  : backend_(backend),
+    package_(NULL),
     functions_(),
     globals_(new Bindings(NULL)),
     imports_(),
index 365860d..b6b1f4d 100644 (file)
@@ -37,6 +37,7 @@ class Methods;
 class Named_object;
 class Label;
 class Translate_context;
+class Backend;
 class Export;
 class Import;
 
@@ -102,7 +103,12 @@ class Gogo
  public:
   // Create the IR, passing in the sizes of the types "int" and
   // "uintptr" in bits.
-  Gogo(int int_type_size, int pointer_size);
+  Gogo(Backend* backend, int int_type_size, int pointer_size);
+
+  // Get the backend generator.
+  Backend*
+  backend()
+  { return this->backend_; }
 
   // Get the package name.
   const std::string&
@@ -647,6 +653,8 @@ class Gogo
   typedef Unordered_map_hash(const Type*, tree, Type_hash_identical,
                             Type_identical) Type_descriptor_decls;
 
+  // The backend generator.
+  Backend* backend_;
   // The package we are compiling.
   Package* package_;
   // The list of currently open functions during parsing.
@@ -2451,16 +2459,16 @@ class Traverse
   Expressions_seen* expressions_seen_;
 };
 
-// When translating the gogo IR into trees, this is the context we
-// pass down the blocks and statements.
+// When translating the gogo IR into the backend data structure, this
+// is the context we pass down the blocks and statements.
 
 class Translate_context
 {
  public:
   Translate_context(Gogo* gogo, Named_object* function, Block* block,
                    tree block_tree)
-    : gogo_(gogo), function_(function), block_(block), block_tree_(block_tree),
-      is_const_(false)
+    : gogo_(gogo), backend_(gogo->backend()), function_(function),
+      block_(block), block_tree_(block_tree), is_const_(false)
   { }
 
   // Accessors.
@@ -2469,6 +2477,10 @@ class Translate_context
   gogo()
   { return this->gogo_; }
 
+  Backend*
+  backend()
+  { return this->backend_; }
+
   Named_object*
   function()
   { return this->function_; }
@@ -2493,6 +2505,8 @@ class Translate_context
  private:
   // The IR for the entire compilation unit.
   Gogo* gogo_;
+  // The generator for the backend data structures.
+  Backend* backend_;
   // The function we are currently translating.
   Named_object* function_;
   // The block we are currently translating.
index f57ada8..b1e7613 100644 (file)
@@ -29,6 +29,7 @@ extern "C"
 #include "types.h"
 #include "expressions.h"
 #include "gogo.h"
+#include "backend.h"
 #include "statements.h"
 
 // Class Statement.
@@ -560,8 +561,10 @@ Assignment_statement::do_get_tree(Translate_context* context)
   if (rhs_tree == error_mark_node)
     return error_mark_node;
 
-  return fold_build2_loc(this->location(), MODIFY_EXPR, void_type_node,
-                        lhs_tree, rhs_tree);
+  Bstatement* ret = context->backend()->assignment(tree_to_expr(lhs_tree),
+                                                  tree_to_expr(rhs_tree),
+                                                  this->location());
+  return statement_to_tree(ret);
 }
 
 // Make an assignment statement.