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:
parent
3edf1dd5bd
commit
a9ac13f7bf
|
@ -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.
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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)
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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_(),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue