Start using backend interface separate from gofrontend.

* 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
This commit is contained in:
Ian Lance Taylor 2011-04-03 22:44:18 +00:00 committed by Ian Lance Taylor
parent 3edf1dd5bd
commit a9ac13f7bf
8 changed files with 361 additions and 12 deletions

View 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.

View 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) \

199
gcc/go/go-gcc.cc Normal file
View File

@ -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();
}

119
gcc/go/gofrontend/backend.h Normal file
View File

@ -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)

View 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);
}

View 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_(),

View 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.

View 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.