From: Ian Lance Taylor Date: Sun, 3 Apr 2011 22:44:18 +0000 (+0000) Subject: Start using backend interface separate from gofrontend. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a9ac13f7bf9f86977984590b32359f7f4742216f;p=gcc.git 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 --- diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index c21dc756954..5d50db2d560 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,11 @@ +2011-04-03 Ian Lance Taylor + + * 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 * gccgo.texi (Top, Import and Export): Fix a typo and a markup nit. diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in index a8c3aa63fcf..07c884d6cb8 100644 --- a/gcc/go/Make-lang.in +++ b/gcc/go/Make-lang.in @@ -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 index 00000000000..ca2d63b1b66 --- /dev/null +++ b/gcc/go/go-gcc.cc @@ -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 +// . + +#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 + +#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 index 00000000000..babef832742 --- /dev/null +++ b/gcc/go/gofrontend/backend.h @@ -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 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) diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index 7b1fd7eccbb..e8729739e12 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -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); } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 9001d2b9ea7..645014154d5 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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_(), diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 365860d36ce..b6b1f4d7c14 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index f57ada8278c..b1e7613eb50 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -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.