* 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.
From-SVN: r171917
+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.
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 \
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)
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) \
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) \
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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)
#include "lex.h"
#include "parse.h"
+#include "backend.h"
#include "gogo.h"
// The unique prefix to use for exported symbols. This is set during
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);
}
// 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_(),
class Named_object;
class Label;
class Translate_context;
+class Backend;
class Export;
class Import;
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&
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.
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.
gogo()
{ return this->gogo_; }
+ Backend*
+ backend()
+ { return this->backend_; }
+
Named_object*
function()
{ return this->function_; }
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.
#include "types.h"
#include "expressions.h"
#include "gogo.h"
+#include "backend.h"
#include "statements.h"
// Class Statement.
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.