Commit d56e6679 by Ian Lance Taylor Committed by Ian Lance Taylor

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
parent 566475c8
2011-04-04 Ian Lance Taylor <iant@google.com> 2011-04-04 Ian Lance Taylor <iant@google.com>
* 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.
2011-04-04 Ian Lance Taylor <iant@google.com>
* go-gcc.cc: #include "tree-iterator.h", "gimple.h", and "gogo.h". * go-gcc.cc: #include "tree-iterator.h", "gimple.h", and "gogo.h".
(class Bfunction): Define. (class Bfunction): Define.
(Gcc_backend::assignment_statement): Rename from assignment. (Gcc_backend::assignment_statement): Rename from assignment.
......
...@@ -252,7 +252,7 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \ ...@@ -252,7 +252,7 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \ intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \ realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \ go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
$(GO_EXPRESSIONS_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H)
go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \ go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
$(GO_PARSE_H) go/gofrontend/backend.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/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
...@@ -264,7 +264,7 @@ go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \ ...@@ -264,7 +264,7 @@ go/gogo-tree.o: go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \ go/gogo.o: go/gofrontend/gogo.cc $(GO_SYSTEM_H) $(GO_C_H) \
go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \ go/gofrontend/go-dump.h $(GO_LEX_H) $(GO_TYPES_H) $(GO_STATEMENTS_H) \
$(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_IMPORT_H) \ $(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_IMPORT_H) \
go/gofrontend/export.h $(GO_GOGO_H) go/gofrontend/export.h go/gofrontend/backend.h $(GO_GOGO_H)
go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \ go/import.o: go/gofrontend/import.cc $(GO_SYSTEM_H) \
$(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \ $(srcdir)/../include/filenames.h $(srcdir)/../include/simple-object.h \
$(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) go/gofrontend/export.h \ $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) go/gofrontend/export.h \
......
...@@ -90,6 +90,14 @@ class Bfunction : public Gcc_tree ...@@ -90,6 +90,14 @@ class Bfunction : public Gcc_tree
{ } { }
}; };
class Blabel : public Gcc_tree
{
public:
Blabel(tree t)
: Gcc_tree(t)
{ }
};
// This file implements the interface between the Go frontend proper // This file implements the interface between the Go frontend proper
// and the gcc IR. This implements specific instantiations of // and the gcc IR. This implements specific instantiations of
// abstract classes defined by the Go frontend proper. The Go // abstract classes defined by the Go frontend proper. The Go
...@@ -158,22 +166,46 @@ class Gcc_backend : public Backend ...@@ -158,22 +166,46 @@ class Gcc_backend : public Backend
// Statements. // Statements.
// Create an assignment statement.
Bstatement* Bstatement*
assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location); assignment_statement(Bexpression* lhs, Bexpression* rhs, source_location);
// Create a return statement.
Bstatement* Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location); source_location);
// Labels.
Blabel*
label(Bfunction*, const std::string& name, source_location);
Bstatement*
label_definition_statement(Blabel*);
Bstatement*
goto_statement(Blabel*, source_location);
Bexpression*
label_address(Blabel*, source_location);
private: private:
// Make a Bexpression from a tree.
Bexpression*
make_expression(tree t)
{ return new Bexpression(t); }
// Make a Bstatement from a tree. // Make a Bstatement from a tree.
Bstatement* Bstatement*
make_statement(tree t) make_statement(tree t)
{ return new Bstatement(t); } { return new Bstatement(t); }
}; };
// A helper function.
static inline tree
get_identifier_from_string(const std::string& str)
{
return get_identifier_with_length(str.data(), str.length());
}
// Assignment. // Assignment.
Bstatement* Bstatement*
...@@ -249,6 +281,58 @@ Gcc_backend::return_statement(Bfunction* bfunction, ...@@ -249,6 +281,58 @@ Gcc_backend::return_statement(Bfunction* bfunction,
return this->make_statement(ret); return this->make_statement(ret);
} }
// Make a label.
Blabel*
Gcc_backend::label(Bfunction* function, const std::string& name,
source_location location)
{
tree decl;
if (name.empty())
decl = create_artificial_label(location);
else
{
tree id = get_identifier_from_string(name);
decl = build_decl(location, LABEL_DECL, id, void_type_node);
DECL_CONTEXT(decl) = function->get_tree();
}
return new Blabel(decl);
}
// Make a statement which defines a label.
Bstatement*
Gcc_backend::label_definition_statement(Blabel* label)
{
tree lab = label->get_tree();
tree ret = fold_build1_loc(DECL_SOURCE_LOCATION(lab), LABEL_EXPR,
void_type_node, lab);
return this->make_statement(ret);
}
// Make a goto statement.
Bstatement*
Gcc_backend::goto_statement(Blabel* label, source_location location)
{
tree lab = label->get_tree();
tree ret = fold_build1_loc(location, GOTO_EXPR, void_type_node, lab);
return this->make_statement(ret);
}
// Get the address of a label.
Bexpression*
Gcc_backend::label_address(Blabel* label, source_location location)
{
tree lab = label->get_tree();
TREE_USED(lab) = 1;
TREE_ADDRESSABLE(lab) = 1;
tree ret = fold_convert_loc(location, ptr_type_node,
build_fold_addr_expr_loc(location, lab));
return this->make_expression(ret);
}
// The single backend. // The single backend.
static Gcc_backend gcc_backend; static Gcc_backend gcc_backend;
...@@ -277,6 +361,12 @@ tree_to_function(tree t) ...@@ -277,6 +361,12 @@ tree_to_function(tree t)
} }
tree tree
expression_to_tree(Bexpression* be)
{
return be->get_tree();
}
tree
statement_to_tree(Bstatement* bs) statement_to_tree(Bstatement* bs)
{ {
return bs->get_tree(); return bs->get_tree();
......
...@@ -27,6 +27,9 @@ class Bstatement; ...@@ -27,6 +27,9 @@ class Bstatement;
// The backend representation of a function definition. // The backend representation of a function definition.
class Bfunction; class Bfunction;
// The backend representation of a label.
class Blabel;
// A list of backend types. // A list of backend types.
typedef std::vector<Btype*> Btypes; typedef std::vector<Btype*> Btypes;
...@@ -114,6 +117,30 @@ class Backend ...@@ -114,6 +117,30 @@ class Backend
virtual Bstatement* virtual Bstatement*
return_statement(Bfunction*, const std::vector<Bexpression*>&, return_statement(Bfunction*, const std::vector<Bexpression*>&,
source_location) = 0; 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. // The backend interface has to define this function.
...@@ -125,6 +152,7 @@ extern Backend* go_get_backend(); ...@@ -125,6 +152,7 @@ extern Backend* go_get_backend();
extern Bexpression* tree_to_expr(tree); extern Bexpression* tree_to_expr(tree);
extern Bfunction* tree_to_function(tree); extern Bfunction* tree_to_function(tree);
extern tree expression_to_tree(Bexpression*);
extern tree statement_to_tree(Bstatement*); extern tree statement_to_tree(Bstatement*);
#endif // !defined(GO_BACKEND_H) #endif // !defined(GO_BACKEND_H)
...@@ -33,6 +33,7 @@ extern "C" ...@@ -33,6 +33,7 @@ extern "C"
#include "import.h" #include "import.h"
#include "statements.h" #include "statements.h"
#include "lex.h" #include "lex.h"
#include "backend.h"
#include "expressions.h" #include "expressions.h"
// Class Expression. // Class Expression.
...@@ -12595,8 +12596,11 @@ class Label_addr_expression : public Expression ...@@ -12595,8 +12596,11 @@ class Label_addr_expression : public Expression
{ return new Label_addr_expression(this->label_, this->location()); } { return new Label_addr_expression(this->label_, this->location()); }
tree tree
do_get_tree(Translate_context*) do_get_tree(Translate_context* context)
{ return this->label_->get_addr(this->location()); } {
return expression_to_tree(this->label_->get_addr(context,
this->location()));
}
private: private:
// The label whose address we are taking. // The label whose address we are taking.
......
...@@ -1915,62 +1915,6 @@ Block::get_tree(Translate_context* context) ...@@ -1915,62 +1915,6 @@ Block::get_tree(Translate_context* context)
return bind; 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. // Return the integer type to use for a size.
GO_EXTERN_C GO_EXTERN_C
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "dataflow.h" #include "dataflow.h"
#include "import.h" #include "import.h"
#include "export.h" #include "export.h"
#include "backend.h"
#include "gogo.h" #include "gogo.h"
// Class Gogo. // Class Gogo.
...@@ -4430,6 +4431,69 @@ Bindings::traverse(Traverse* traverse, bool is_global) ...@@ -4430,6 +4431,69 @@ Bindings::traverse(Traverse* traverse, bool is_global)
return TRAVERSE_CONTINUE; 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. // Class Package.
Package::Package(const std::string& name, const std::string& unique_prefix, Package::Package(const std::string& name, const std::string& unique_prefix,
......
...@@ -40,6 +40,9 @@ class Translate_context; ...@@ -40,6 +40,9 @@ class Translate_context;
class Backend; class Backend;
class Export; class Export;
class Import; class Import;
class Bexpression;
class Bstatement;
class Blabel;
// This file declares the basic classes used to hold the internal // This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser. // representation of Go which is built by the parser.
...@@ -2115,7 +2118,7 @@ class Label ...@@ -2115,7 +2118,7 @@ class Label
{ {
public: public:
Label(const std::string& name) 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. // Return the label's name.
...@@ -2151,13 +2154,15 @@ class Label ...@@ -2151,13 +2154,15 @@ class Label
this->location_ = location; this->location_ = location;
} }
// Return the LABEL_DECL for this decl. // Return the backend representation for this label.
tree Blabel*
get_decl(); get_backend_label(Translate_context*);
// Return an expression for the address of this label. // Return an expression for the address of this label. This is used
tree // to get the return address of a deferred function to see whether
get_addr(source_location location); // the function may call recover.
Bexpression*
get_addr(Translate_context*, source_location location);
private: private:
// The name of the label. // The name of the label.
...@@ -2167,8 +2172,8 @@ class Label ...@@ -2167,8 +2172,8 @@ class Label
source_location location_; source_location location_;
// Whether the label has been used. // Whether the label has been used.
bool is_used_; bool is_used_;
// The LABEL_DECL. // The backend representation.
tree decl_; Blabel* blabel_;
}; };
// An unnamed label. These are used when lowering loops. // An unnamed label. These are used when lowering loops.
...@@ -2177,7 +2182,7 @@ class Unnamed_label ...@@ -2177,7 +2182,7 @@ class Unnamed_label
{ {
public: public:
Unnamed_label(source_location location) Unnamed_label(source_location location)
: location_(location), decl_(NULL) : location_(location), blabel_(NULL)
{ } { }
// Get the location where the label is defined. // Get the location where the label is defined.
...@@ -2191,22 +2196,22 @@ class Unnamed_label ...@@ -2191,22 +2196,22 @@ class Unnamed_label
{ this->location_ = location; } { this->location_ = location; }
// Return a statement which defines this label. // Return a statement which defines this label.
tree Bstatement*
get_definition(); get_definition(Translate_context*);
// Return a goto to this label from LOCATION. // Return a goto to this label from LOCATION.
tree Bstatement*
get_goto(source_location location); get_goto(Translate_context*, source_location location);
private: private:
// Return the LABEL_DECL to use with GOTO_EXPR. // Return the backend representation.
tree Blabel*
get_decl(); get_blabel(Translate_context*);
// The location where the label is defined. // The location where the label is defined.
source_location location_; source_location location_;
// The LABEL_DECL. // The backend representation of this label.
tree decl_; Blabel* blabel_;
}; };
// An imported package. // An imported package.
......
...@@ -2619,8 +2619,11 @@ class Bc_statement : public Statement ...@@ -2619,8 +2619,11 @@ class Bc_statement : public Statement
{ return false; } { return false; }
tree tree
do_get_tree(Translate_context*) do_get_tree(Translate_context* context)
{ return this->label_->get_goto(this->location()); } {
return statement_to_tree(this->label_->get_goto(context,
this->location()));
}
private: private:
// The label that this branches to. // The label that this branches to.
...@@ -2692,9 +2695,12 @@ Goto_statement::do_check_types(Gogo*) ...@@ -2692,9 +2695,12 @@ Goto_statement::do_check_types(Gogo*)
// Return the tree for the goto statement. // Return the tree for the goto statement.
tree 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. // Make a goto statement.
...@@ -2725,8 +2731,11 @@ class Goto_unnamed_statement : public Statement ...@@ -2725,8 +2731,11 @@ class Goto_unnamed_statement : public Statement
{ return false; } { return false; }
tree tree
do_get_tree(Translate_context*) do_get_tree(Translate_context* context)
{ return this->label_->get_goto(this->location()); } {
return statement_to_tree(this->label_->get_goto(context,
this->location()));
}
private: private:
Unnamed_label* label_; Unnamed_label* label_;
...@@ -2754,9 +2763,12 @@ Label_statement::do_traverse(Traverse*) ...@@ -2754,9 +2763,12 @@ Label_statement::do_traverse(Traverse*)
// Return a tree defining this label. // Return a tree defining this label.
tree 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. // Make a label statement.
...@@ -2783,8 +2795,8 @@ class Unnamed_label_statement : public Statement ...@@ -2783,8 +2795,8 @@ class Unnamed_label_statement : public Statement
{ return TRAVERSE_CONTINUE; } { return TRAVERSE_CONTINUE; }
tree tree
do_get_tree(Translate_context*) do_get_tree(Translate_context* context)
{ return this->label_->get_definition(); } { return statement_to_tree(this->label_->get_definition(context)); }
private: private:
// The label. // The label.
...@@ -3134,7 +3146,10 @@ Case_clauses::Case_clause::get_constant_tree(Translate_context* context, ...@@ -3134,7 +3146,10 @@ Case_clauses::Case_clause::get_constant_tree(Translate_context* context,
} }
if (!this->is_fallthrough_) 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. // Class Case_clauses.
...@@ -3387,7 +3402,8 @@ Constant_switch_statement::do_get_tree(Translate_context* context) ...@@ -3387,7 +3402,8 @@ Constant_switch_statement::do_get_tree(Translate_context* context)
SET_EXPR_LOCATION(s, this->location()); SET_EXPR_LOCATION(s, this->location());
append_to_statement_list(s, &stmt_list); 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; return stmt_list;
} }
...@@ -4245,7 +4261,8 @@ Select_clauses::get_tree(Translate_context* context, ...@@ -4245,7 +4261,8 @@ Select_clauses::get_tree(Translate_context* context,
tree stmt_list = NULL_TREE; tree stmt_list = NULL_TREE;
append_to_statement_list(default_clause->get_statements_tree(context), append_to_statement_list(default_clause->get_statements_tree(context),
&stmt_list); &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; return stmt_list;
} }
...@@ -4336,7 +4353,8 @@ Select_clauses::get_tree(Translate_context* context, ...@@ -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); tree switch_stmt = build3(SWITCH_EXPR, sizetype, call, stmt_list, NULL_TREE);
SET_EXPR_LOCATION(switch_stmt, location); SET_EXPR_LOCATION(switch_stmt, location);
...@@ -4358,10 +4376,11 @@ Select_clauses::add_clause_tree(Translate_context* context, int case_index, ...@@ -4358,10 +4376,11 @@ Select_clauses::add_clause_tree(Translate_context* context, int case_index,
NULL_TREE, label), NULL_TREE, label),
stmt_list); stmt_list);
append_to_statement_list(clause->get_statements_tree(context), stmt_list); append_to_statement_list(clause->get_statements_tree(context), stmt_list);
tree g = bottom_label->get_goto(clause->statements() == NULL source_location gloc = (clause->statements() == NULL
? clause->location() ? clause->location()
: clause->statements()->end_location()); : clause->statements()->end_location());
append_to_statement_list(g, stmt_list); Bstatement* g = bottom_label->get_goto(context, gloc);
append_to_statement_list(statement_to_tree(g), stmt_list);
} }
// Class Select_statement. // Class Select_statement.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment