aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2011-04-05 05:57:39 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-04-05 05:57:39 +0000
commitd56e667993d46456e38c70d7e36c9be3c4dbf37f (patch)
tree577d44ef128d82982e60ea0b47f375eebb0187b5 /gcc/go/gofrontend
parent566475c80091b451af0513f2144d853b702eb73b (diff)
downloadgcc-d56e667993d46456e38c70d7e36c9be3c4dbf37f.zip
gcc-d56e667993d46456e38c70d7e36c9be3c4dbf37f.tar.gz
gcc-d56e667993d46456e38c70d7e36c9be3c4dbf37f.tar.bz2
Use backend interface for labels and goto statements.
* go-gcc.c (class Blabel): Define. (Gcc_backend::make_expression): New function. (get_identifier_from_string): New function. (Gcc_backend::label): New function. (Gcc_backend::label_definition_statement): New function. (Gcc_backend::goto_statement): New function. (Gcc_backend::label_address): New function. (expression_to_tree): New function. * Make-lang.in (go/expressions.o): Depend on go/gofrontend/backend.h. (go/gogo.o): Likewise. From-SVN: r171968
Diffstat (limited to 'gcc/go/gofrontend')
-rw-r--r--gcc/go/gofrontend/backend.h28
-rw-r--r--gcc/go/gofrontend/expressions.cc8
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc56
-rw-r--r--gcc/go/gofrontend/gogo.cc64
-rw-r--r--gcc/go/gofrontend/gogo.h43
-rw-r--r--gcc/go/gofrontend/statements.cc55
6 files changed, 159 insertions, 95 deletions
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
index 959fc78..814263e 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -27,6 +27,9 @@ class Bstatement;
// The backend representation of a function definition.
class Bfunction;
+// The backend representation of a label.
+class Blabel;
+
// A list of backend types.
typedef std::vector<Btype*> Btypes;
@@ -114,6 +117,30 @@ class Backend
virtual Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location) = 0;
+
+ // Labels.
+
+ // Create a new label. NAME will be empty if this is a label
+ // created by the frontend for a loop construct. The location is
+ // where the the label is defined.
+ virtual Blabel*
+ label(Bfunction*, const std::string& name, source_location) = 0;
+
+ // Create a statement which defines a label. This statement will be
+ // put into the codestream at the point where the label should be
+ // defined.
+ virtual Bstatement*
+ label_definition_statement(Blabel*) = 0;
+
+ // Create a goto statement to a label.
+ virtual Bstatement*
+ goto_statement(Blabel*, source_location) = 0;
+
+ // Create an expression for the address of a label. This is used to
+ // get the return address of a deferred function which may call
+ // recover.
+ virtual Bexpression*
+ label_address(Blabel*, source_location) = 0;
};
// The backend interface has to define this function.
@@ -125,6 +152,7 @@ extern Backend* go_get_backend();
extern Bexpression* tree_to_expr(tree);
extern Bfunction* tree_to_function(tree);
+extern tree expression_to_tree(Bexpression*);
extern tree statement_to_tree(Bstatement*);
#endif // !defined(GO_BACKEND_H)
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index a0cfcfc..afd2191 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -33,6 +33,7 @@ extern "C"
#include "import.h"
#include "statements.h"
#include "lex.h"
+#include "backend.h"
#include "expressions.h"
// Class Expression.
@@ -12595,8 +12596,11 @@ class Label_addr_expression : public Expression
{ return new Label_addr_expression(this->label_, this->location()); }
tree
- do_get_tree(Translate_context*)
- { return this->label_->get_addr(this->location()); }
+ do_get_tree(Translate_context* context)
+ {
+ return expression_to_tree(this->label_->get_addr(context,
+ this->location()));
+ }
private:
// The label whose address we are taking.
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index bd5945b..53e43c7 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -1915,62 +1915,6 @@ Block::get_tree(Translate_context* context)
return bind;
}
-// Get the LABEL_DECL for a label.
-
-tree
-Label::get_decl()
-{
- if (this->decl_ == NULL)
- {
- tree id = get_identifier_from_string(this->name_);
- this->decl_ = build_decl(this->location_, LABEL_DECL, id, void_type_node);
- DECL_CONTEXT(this->decl_) = current_function_decl;
- }
- return this->decl_;
-}
-
-// Return an expression for the address of this label.
-
-tree
-Label::get_addr(source_location location)
-{
- tree decl = this->get_decl();
- TREE_USED(decl) = 1;
- TREE_ADDRESSABLE(decl) = 1;
- return fold_convert_loc(location, ptr_type_node,
- build_fold_addr_expr_loc(location, decl));
-}
-
-// Get the LABEL_DECL for an unnamed label.
-
-tree
-Unnamed_label::get_decl()
-{
- if (this->decl_ == NULL)
- this->decl_ = create_artificial_label(this->location_);
- return this->decl_;
-}
-
-// Get the LABEL_EXPR for an unnamed label.
-
-tree
-Unnamed_label::get_definition()
-{
- tree t = build1(LABEL_EXPR, void_type_node, this->get_decl());
- SET_EXPR_LOCATION(t, this->location_);
- return t;
-}
-
-// Return a goto to this label.
-
-tree
-Unnamed_label::get_goto(source_location location)
-{
- tree t = build1(GOTO_EXPR, void_type_node, this->get_decl());
- SET_EXPR_LOCATION(t, location);
- return t;
-}
-
// Return the integer type to use for a size.
GO_EXTERN_C
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 5b3ac8c..31549ac 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -15,6 +15,7 @@
#include "dataflow.h"
#include "import.h"
#include "export.h"
+#include "backend.h"
#include "gogo.h"
// Class Gogo.
@@ -4430,6 +4431,69 @@ Bindings::traverse(Traverse* traverse, bool is_global)
return TRAVERSE_CONTINUE;
}
+// Class Label.
+
+// Get the backend representation for a label.
+
+Blabel*
+Label::get_backend_label(Translate_context* context)
+{
+ if (this->blabel_ == NULL)
+ {
+ Function* function = context->function()->func_value();
+ tree fndecl = function->get_decl();
+ Bfunction* bfunction = tree_to_function(fndecl);
+ this->blabel_ = context->backend()->label(bfunction, this->name_,
+ this->location_);
+ }
+ return this->blabel_;
+}
+
+// Return an expression for the address of this label.
+
+Bexpression*
+Label::get_addr(Translate_context* context, source_location location)
+{
+ Blabel* label = this->get_backend_label(context);
+ return context->backend()->label_address(label, location);
+}
+
+// Class Unnamed_label.
+
+// Get the backend representation for an unnamed label.
+
+Blabel*
+Unnamed_label::get_blabel(Translate_context* context)
+{
+ if (this->blabel_ == NULL)
+ {
+ Function* function = context->function()->func_value();
+ tree fndecl = function->get_decl();
+ Bfunction* bfunction = tree_to_function(fndecl);
+ this->blabel_ = context->backend()->label(bfunction, "",
+ this->location_);
+ }
+ return this->blabel_;
+}
+
+// Return a statement which defines this unnamed label.
+
+Bstatement*
+Unnamed_label::get_definition(Translate_context* context)
+{
+ Blabel* blabel = this->get_blabel(context);
+ return context->backend()->label_definition_statement(blabel);
+}
+
+// Return a goto statement to this unnamed label.
+
+Bstatement*
+Unnamed_label::get_goto(Translate_context* context, source_location location)
+{
+ Blabel* blabel = this->get_blabel(context);
+ return context->backend()->goto_statement(blabel, location);
+}
+
// Class Package.
Package::Package(const std::string& name, const std::string& unique_prefix,
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 87e2da6..cf126cd 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -40,6 +40,9 @@ class Translate_context;
class Backend;
class Export;
class Import;
+class Bexpression;
+class Bstatement;
+class Blabel;
// This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser.
@@ -2115,7 +2118,7 @@ class Label
{
public:
Label(const std::string& name)
- : name_(name), location_(0), is_used_(false), decl_(NULL)
+ : name_(name), location_(0), is_used_(false), blabel_(NULL)
{ }
// Return the label's name.
@@ -2151,13 +2154,15 @@ class Label
this->location_ = location;
}
- // Return the LABEL_DECL for this decl.
- tree
- get_decl();
+ // Return the backend representation for this label.
+ Blabel*
+ get_backend_label(Translate_context*);
- // Return an expression for the address of this label.
- tree
- get_addr(source_location location);
+ // Return an expression for the address of this label. This is used
+ // to get the return address of a deferred function to see whether
+ // the function may call recover.
+ Bexpression*
+ get_addr(Translate_context*, source_location location);
private:
// The name of the label.
@@ -2167,8 +2172,8 @@ class Label
source_location location_;
// Whether the label has been used.
bool is_used_;
- // The LABEL_DECL.
- tree decl_;
+ // The backend representation.
+ Blabel* blabel_;
};
// An unnamed label. These are used when lowering loops.
@@ -2177,7 +2182,7 @@ class Unnamed_label
{
public:
Unnamed_label(source_location location)
- : location_(location), decl_(NULL)
+ : location_(location), blabel_(NULL)
{ }
// Get the location where the label is defined.
@@ -2191,22 +2196,22 @@ class Unnamed_label
{ this->location_ = location; }
// Return a statement which defines this label.
- tree
- get_definition();
+ Bstatement*
+ get_definition(Translate_context*);
// Return a goto to this label from LOCATION.
- tree
- get_goto(source_location location);
+ Bstatement*
+ get_goto(Translate_context*, source_location location);
private:
- // Return the LABEL_DECL to use with GOTO_EXPR.
- tree
- get_decl();
+ // Return the backend representation.
+ Blabel*
+ get_blabel(Translate_context*);
// The location where the label is defined.
source_location location_;
- // The LABEL_DECL.
- tree decl_;
+ // The backend representation of this label.
+ Blabel* blabel_;
};
// An imported package.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 3783fb8..854b329 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -2619,8 +2619,11 @@ class Bc_statement : public Statement
{ return false; }
tree
- do_get_tree(Translate_context*)
- { return this->label_->get_goto(this->location()); }
+ do_get_tree(Translate_context* context)
+ {
+ return statement_to_tree(this->label_->get_goto(context,
+ this->location()));
+ }
private:
// The label that this branches to.
@@ -2692,9 +2695,12 @@ Goto_statement::do_check_types(Gogo*)
// Return the tree for the goto statement.
tree
-Goto_statement::do_get_tree(Translate_context*)
+Goto_statement::do_get_tree(Translate_context* context)
{
- return this->build_stmt_1(GOTO_EXPR, this->label_->get_decl());
+ Blabel* blabel = this->label_->get_backend_label(context);
+ Bstatement* statement = context->backend()->goto_statement(blabel,
+ this->location());
+ return statement_to_tree(statement);
}
// Make a goto statement.
@@ -2725,8 +2731,11 @@ class Goto_unnamed_statement : public Statement
{ return false; }
tree
- do_get_tree(Translate_context*)
- { return this->label_->get_goto(this->location()); }
+ do_get_tree(Translate_context* context)
+ {
+ return statement_to_tree(this->label_->get_goto(context,
+ this->location()));
+ }
private:
Unnamed_label* label_;
@@ -2754,9 +2763,12 @@ Label_statement::do_traverse(Traverse*)
// Return a tree defining this label.
tree
-Label_statement::do_get_tree(Translate_context*)
+Label_statement::do_get_tree(Translate_context* context)
{
- return this->build_stmt_1(LABEL_EXPR, this->label_->get_decl());
+ Blabel* blabel = this->label_->get_backend_label(context);
+ Bstatement* statement;
+ statement = context->backend()->label_definition_statement(blabel);
+ return statement_to_tree(statement);
}
// Make a label statement.
@@ -2783,8 +2795,8 @@ class Unnamed_label_statement : public Statement
{ return TRAVERSE_CONTINUE; }
tree
- do_get_tree(Translate_context*)
- { return this->label_->get_definition(); }
+ do_get_tree(Translate_context* context)
+ { return statement_to_tree(this->label_->get_definition(context)); }
private:
// The label.
@@ -3134,7 +3146,10 @@ Case_clauses::Case_clause::get_constant_tree(Translate_context* context,
}
if (!this->is_fallthrough_)
- append_to_statement_list(break_label->get_goto(this->location_), stmt_list);
+ {
+ Bstatement* g = break_label->get_goto(context, this->location_);
+ append_to_statement_list(statement_to_tree(g), stmt_list);
+ }
}
// Class Case_clauses.
@@ -3387,7 +3402,8 @@ Constant_switch_statement::do_get_tree(Translate_context* context)
SET_EXPR_LOCATION(s, this->location());
append_to_statement_list(s, &stmt_list);
- append_to_statement_list(break_label->get_definition(), &stmt_list);
+ Bstatement* ldef = break_label->get_definition(context);
+ append_to_statement_list(statement_to_tree(ldef), &stmt_list);
return stmt_list;
}
@@ -4245,7 +4261,8 @@ Select_clauses::get_tree(Translate_context* context,
tree stmt_list = NULL_TREE;
append_to_statement_list(default_clause->get_statements_tree(context),
&stmt_list);
- append_to_statement_list(break_label->get_definition(), &stmt_list);
+ Bstatement* ldef = break_label->get_definition(context);
+ append_to_statement_list(statement_to_tree(ldef), &stmt_list);
return stmt_list;
}
@@ -4336,7 +4353,8 @@ Select_clauses::get_tree(Translate_context* context,
}
}
- append_to_statement_list(break_label->get_definition(), &stmt_list);
+ Bstatement* ldef = break_label->get_definition(context);
+ append_to_statement_list(statement_to_tree(ldef), &stmt_list);
tree switch_stmt = build3(SWITCH_EXPR, sizetype, call, stmt_list, NULL_TREE);
SET_EXPR_LOCATION(switch_stmt, location);
@@ -4358,10 +4376,11 @@ Select_clauses::add_clause_tree(Translate_context* context, int case_index,
NULL_TREE, label),
stmt_list);
append_to_statement_list(clause->get_statements_tree(context), stmt_list);
- tree g = bottom_label->get_goto(clause->statements() == NULL
- ? clause->location()
- : clause->statements()->end_location());
- append_to_statement_list(g, stmt_list);
+ source_location gloc = (clause->statements() == NULL
+ ? clause->location()
+ : clause->statements()->end_location());
+ Bstatement* g = bottom_label->get_goto(context, gloc);
+ append_to_statement_list(statement_to_tree(g), stmt_list);
}
// Class Select_statement.