This patch to the Go frontend adjusts statement.cc so that it no longer includes any gcc headers. All operations are now done via the backend interface. There are four remaining files which includes gcc header files: export.cc, expressions.cc, gogo-tree.c, and types.cc. This patch bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian 2011-04-19 Ian Lance Taylor <i...@google.com> * go-system.h: Include "intl.h". * Make-lang.in (GO_SYSTEM_H): Add intl.h. (go/statements.o): Remove dependencies on intl.h $(TREE_H) $(GIMPLE_H) convert.h tree-iterator.h $(TREE_FLOW_H) $(REAL_H).
Index: gcc/go/Make-lang.in =================================================================== --- gcc/go/Make-lang.in (revision 172693) +++ gcc/go/Make-lang.in (working copy) @@ -211,7 +211,7 @@ go.stagefeedback: stagefeedback-start -mv go/*$(objext) stagefeedback/go GO_SYSTEM_H = go/go-system.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(DIAGNOSTIC_CORE_H) $(INPUT_H) + $(DIAGNOSTIC_CORE_H) $(INPUT_H) intl.h GO_C_H = go/go-c.h $(MACHMODE_H) GO_LEX_H = go/gofrontend/lex.h go/gofrontend/operator.h @@ -281,8 +281,7 @@ go/parse.o: go/gofrontend/parse.cc $(GO_ go/runtime.o: go/gofrontend/runtime.cc $(GO_SYSTEM_H) $(GO_GOGO_H) \ $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_RUNTIME_H) \ go/gofrontend/runtime.def -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/statements.o: go/gofrontend/statements.cc $(GO_SYSTEM_H) \ $(GO_C_H) $(GO_TYPES_H) $(GO_EXPRESSIONS_H) $(GO_GOGO_H) \ $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_STATEMENTS_H) go/types.o: go/gofrontend/types.cc $(GO_SYSTEM_H) $(TOPLEV_H) intl.h $(TREE_H) \ Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 172740) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -8,23 +8,6 @@ #include <gmp.h> -#ifndef ENABLE_BUILD_WITH_CXX -extern "C" -{ -#endif - -#include "intl.h" -#include "tree.h" -#include "gimple.h" -#include "convert.h" -#include "tree-iterator.h" -#include "tree-flow.h" -#include "real.h" - -#ifndef ENABLE_BUILD_WITH_CXX -} -#endif - #include "go-c.h" #include "types.h" #include "expressions.h" @@ -148,8 +131,8 @@ Statement::thunk_statement() return ret; } -// Get a tree for a Statement. This is really done by the child -// class. +// Convert a Statement to the backend representation. This is really +// done by the child class. Bstatement* Statement::get_backend(Translate_context* context) @@ -159,17 +142,6 @@ Statement::get_backend(Translate_context return this->do_get_backend(context); } -// Build tree nodes and set locations. - -tree -Statement::build_stmt_1(int tree_code_value, tree node) -{ - tree ret = build1(static_cast<tree_code>(tree_code_value), - void_type_node, node); - SET_EXPR_LOCATION(ret, this->location_); - return ret; -} - // Note that this statement is erroneous. This is called by children // when they discover an error. @@ -245,7 +217,7 @@ Variable_declaration_statement::do_trave return true; } -// Return the tree for a variable declaration. +// Convert a variable declaration to the backend representation. Bstatement* Variable_declaration_statement::do_get_backend(Translate_context* context) @@ -254,40 +226,48 @@ Variable_declaration_statement::do_get_b Bvariable* bvar = this->var_->get_backend_variable(context->gogo(), context->function()); tree init = var->get_init_tree(context->gogo(), context->function()); - Bexpression* binit = init == NULL_TREE ? NULL : tree_to_expr(init); + Bexpression* binit = init == NULL ? NULL : tree_to_expr(init); + if (!var->is_in_heap()) { gcc_assert(binit != NULL); return context->backend()->init_statement(bvar, binit); } - else + + // Something takes the address of this variable, so the value is + // stored in the heap. Initialize it to newly allocated memory + // space, and assign the initial value to the new space. + source_location loc = this->location(); + Named_object* newfn = context->gogo()->lookup_global("new"); + gcc_assert(newfn != NULL && newfn->is_function_declaration()); + Expression* func = Expression::make_func_reference(newfn, NULL, loc); + Expression_list* params = new Expression_list(); + params->push_back(Expression::make_type(var->type(), loc)); + Expression* call = Expression::make_call(func, params, false, loc); + context->gogo()->lower_expression(context->function(), &call); + Temporary_statement* temp = Statement::make_temporary(NULL, call, loc); + Bstatement* btemp = temp->get_backend(context); + + Bstatement* set = NULL; + if (binit != NULL) { - // Something takes the address of this variable, so the value is - // stored in the heap. Initialize it to newly allocated memory - // space, and assign the initial value to the new space. - source_location loc = this->location(); - tree decl = var_to_tree(bvar); - tree decl_type = TREE_TYPE(decl); - gcc_assert(POINTER_TYPE_P(decl_type)); - tree size = TYPE_SIZE_UNIT(TREE_TYPE(decl_type)); - tree space = context->gogo()->allocate_memory(var->type(), size, loc); - if (binit != NULL) - space = save_expr(space); - space = fold_convert_loc(loc, decl_type, space); - Bstatement* s1 = context->backend()->init_statement(bvar, - tree_to_expr(space)); - if (binit == NULL) - return s1; - else - { - tree indir = build_fold_indirect_ref_loc(loc, space); - Bexpression* bindir = tree_to_expr(indir); - Bstatement* s2 = context->backend()->assignment_statement(bindir, - binit, - loc); - return context->backend()->compound_statement(s1, s2); - } - } + Expression* e = Expression::make_temporary_reference(temp, loc); + e = Expression::make_unary(OPERATOR_MULT, e, loc); + Bexpression* be = tree_to_expr(e->get_tree(context)); + set = context->backend()->assignment_statement(be, binit, loc); + } + + Expression* ref = Expression::make_temporary_reference(temp, loc); + Bexpression* bref = tree_to_expr(ref->get_tree(context)); + Bstatement* sinit = context->backend()->init_statement(bvar, bref); + + std::vector<Bstatement*> stats; + stats.reserve(3); + stats.push_back(btemp); + if (set != NULL) + stats.push_back(set); + stats.push_back(sinit); + return context->backend()->statement_list(stats); } // Make a variable declaration. @@ -379,7 +359,7 @@ Temporary_statement::do_check_types(Gogo } } -// Return a tree. +// Convert to backend representation. Bstatement* Temporary_statement::do_get_backend(Translate_context* context) @@ -535,29 +515,18 @@ Assignment_statement::do_check_types(Gog this->set_is_error(); } -// Build a tree for an assignment statement. +// Convert an assignment statement to the backend representation. Bstatement* Assignment_statement::do_get_backend(Translate_context* context) { tree rhs_tree = this->rhs_->get_tree(context); - if (rhs_tree == error_mark_node) - return context->backend()->error_statement(); - if (this->lhs_->is_sink_expression()) return context->backend()->expression_statement(tree_to_expr(rhs_tree)); - tree lhs_tree = this->lhs_->get_tree(context); - - if (lhs_tree == error_mark_node) - return context->backend()->error_statement(); - rhs_tree = Expression::convert_for_assignment(context, this->lhs_->type(), this->rhs_->type(), rhs_tree, this->location()); - if (rhs_tree == error_mark_node) - return context->backend()->error_statement(); - return context->backend()->assignment_statement(tree_to_expr(lhs_tree), tree_to_expr(rhs_tree), this->location()); @@ -2190,7 +2159,7 @@ Thunk_statement::build_thunk(Gogo* gogo, gogo->finish_function(location); } -// Get the function and argument trees. +// Get the function and argument expressions. bool Thunk_statement::get_fn_and_arg(Expression** pfn, Expression** parg) @@ -2545,7 +2514,7 @@ Goto_statement::do_check_types(Gogo*) } } -// Return the tree for the goto statement. +// Convert the goto statement to the backend representation. Bstatement* Goto_statement::do_get_backend(Translate_context* context) @@ -2608,7 +2577,8 @@ Label_statement::do_traverse(Traverse*) return TRAVERSE_CONTINUE; } -// Return a tree defining this label. +// Return the backend representation of the statement defining this +// label. Bstatement* Label_statement::do_get_backend(Translate_context* context) @@ -2738,7 +2708,7 @@ If_statement::do_may_fall_through() cons || this->else_block_->may_fall_through()); } -// Get tree. +// Get the backend representation. Bstatement* If_statement::do_get_backend(Translate_context* context) @@ -3750,7 +3720,7 @@ Send_statement::do_check_types(Gogo*) } } -// Get a tree for a send statement. +// Convert a send statement to the backend representation. Bstatement* Send_statement::do_get_backend(Translate_context* context) @@ -4034,7 +4004,7 @@ Select_clauses::Select_clause::may_fall_ return this->statements_->may_fall_through(); } -// Return a tree for the statements to execute. +// Return the backend representation for the statements to execute. Bstatement* Select_clauses::Select_clause::get_statements_backend( @@ -4287,7 +4257,7 @@ Select_clauses::get_backend(Translate_co return context->backend()->statement_list(statements); } -// Add the tree for CLAUSE to STMT_LIST. +// Add CLAUSE to CASES/CLAUSES at INDEX. void Select_clauses::add_clause_backend( @@ -4350,7 +4320,7 @@ Select_statement::do_lower(Gogo* gogo, N return Statement::make_block_statement(b, this->location()); } -// Return the tree for a select statement. +// Return the backend representation for a select statement. Bstatement* Select_statement::do_get_backend(Translate_context* context) Index: gcc/go/gofrontend/statements.h =================================================================== --- gcc/go/gofrontend/statements.h (revision 172740) +++ gcc/go/gofrontend/statements.h (working copy) @@ -424,12 +424,6 @@ class Statement int traverse_type(Traverse*, Type*); - // Build a tree node with one operand, setting the location. The - // first operand really has type "enum tree_code", but that enum is - // not defined here. - tree - build_stmt_1(int tree_code_value, tree); - // For children to call when they detect that they are in error. void set_is_error(); @@ -744,7 +738,7 @@ class Select_clauses bool may_fall_through() const; - // Return a tree for the statements to execute. + // Convert the statements to the backend representation. Bstatement* get_statements_backend(Translate_context*); @@ -865,7 +859,7 @@ class Thunk_statement : public Statement void do_check_types(Gogo*); - // Return the function and argument trees for the call. + // Return the function and argument for the call. bool get_fn_and_arg(Expression** pfn, Expression** parg); @@ -1168,8 +1162,8 @@ class Case_clauses std::vector<Bstatement*>* all_statements) const; private: - // For a constant tree we need to keep a record of constants we have - // already seen. Note that INTEGER_CST trees are interned. + // For a constant switch we need to keep a record of constants we + // have already seen. class Hash_integer_value; class Eq_integer_value; typedef Unordered_set_hash(Expression*, Hash_integer_value, @@ -1439,10 +1433,6 @@ class Type_switch_statement : public Sta { gcc_unreachable(); } private: - // Get the type descriptor. - tree - get_type_descriptor(Translate_context*, Type*, tree); - // The variable holding the value we are switching on. Named_object* var_; // The expression we are switching on if there is no variable. Index: gcc/go/go-system.h =================================================================== --- gcc/go/go-system.h (revision 172393) +++ gcc/go/go-system.h (working copy) @@ -1,5 +1,5 @@ // go-system.h -- Go frontend inclusion of gcc header files -*- C++ -*- -// Copyright (C) 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. // This file is part of GCC. @@ -145,6 +145,7 @@ extern "C" #include "diagnostic-core.h" /* For error_at and friends. */ #include "input.h" /* For source_location. */ +#include "intl.h" /* For _(). */ #ifndef ENABLE_BUILD_WITH_CXX } // End extern "C"