Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
f54d331e
Commit
f54d331e
authored
Apr 15, 2011
by
Ian Lance Taylor
Committed by
Ian Lance Taylor
Apr 15, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use the backend interface for select statements.
From-SVN: r172468
parent
7427a368
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
205 additions
and
135 deletions
+205
-135
gcc/go/ChangeLog
+4
-0
gcc/go/go-gcc.cc
+4
-0
gcc/go/gofrontend/backend.h
+6
-0
gcc/go/gofrontend/expressions.cc
+4
-3
gcc/go/gofrontend/runtime.cc
+9
-0
gcc/go/gofrontend/runtime.h
+9
-0
gcc/go/gofrontend/statements.cc
+160
-125
gcc/go/gofrontend/statements.h
+9
-7
No files found.
gcc/go/ChangeLog
View file @
f54d331e
2011-04-14 Ian Lance Taylor <iant@google.com>
* go-gcc.cc (Backend::error_statement): New function.
2011-04-13 Ian Lance Taylor <iant@google.com>
2011-04-13 Ian Lance Taylor <iant@google.com>
* Make-lang.in (go/gogo-tree.o): depend on $(GO_RUNTIME_H).
* Make-lang.in (go/gogo-tree.o): depend on $(GO_RUNTIME_H).
...
...
gcc/go/go-gcc.cc
View file @
f54d331e
...
@@ -167,6 +167,10 @@ class Gcc_backend : public Backend
...
@@ -167,6 +167,10 @@ class Gcc_backend : public Backend
// Statements.
// Statements.
Bstatement
*
Bstatement
*
error_statement
()
{
return
this
->
make_statement
(
error_mark_node
);
}
Bstatement
*
expression_statement
(
Bexpression
*
);
expression_statement
(
Bexpression
*
);
Bstatement
*
Bstatement
*
...
...
gcc/go/gofrontend/backend.h
View file @
f54d331e
...
@@ -107,6 +107,12 @@ class Backend
...
@@ -107,6 +107,12 @@ class Backend
// Statements.
// Statements.
// Create an error statement. This is used for cases which should
// not occur in a correct program, in order to keep the compilation
// going without crashing.
virtual
Bstatement
*
error_statement
()
=
0
;
// Create an expression statement.
// Create an expression statement.
virtual
Bstatement
*
virtual
Bstatement
*
expression_statement
(
Bexpression
*
)
=
0
;
expression_statement
(
Bexpression
*
)
=
0
;
...
...
gcc/go/gofrontend/expressions.cc
View file @
f54d331e
...
@@ -3603,10 +3603,11 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
...
@@ -3603,10 +3603,11 @@ Unsafe_type_conversion_expression::do_get_tree(Translate_context* context)
else
if
(
t
->
channel_type
()
!=
NULL
)
else
if
(
t
->
channel_type
()
!=
NULL
)
gcc_assert
(
et
->
channel_type
()
!=
NULL
);
gcc_assert
(
et
->
channel_type
()
!=
NULL
);
else
if
(
t
->
points_to
()
!=
NULL
&&
t
->
points_to
()
->
channel_type
()
!=
NULL
)
else
if
(
t
->
points_to
()
!=
NULL
&&
t
->
points_to
()
->
channel_type
()
!=
NULL
)
gcc_assert
(
et
->
points_to
()
!=
NULL
gcc_assert
((
et
->
points_to
()
!=
NULL
&&
et
->
points_to
()
->
channel_type
()
!=
NULL
);
&&
et
->
points_to
()
->
channel_type
()
!=
NULL
)
||
et
->
is_nil_type
());
else
if
(
t
->
is_unsafe_pointer_type
())
else
if
(
t
->
is_unsafe_pointer_type
())
gcc_assert
(
et
->
points_to
()
!=
NULL
);
gcc_assert
(
et
->
points_to
()
!=
NULL
||
et
->
is_nil_type
()
);
else
if
(
et
->
is_unsafe_pointer_type
())
else
if
(
et
->
is_unsafe_pointer_type
())
gcc_assert
(
t
->
points_to
()
!=
NULL
);
gcc_assert
(
t
->
points_to
()
!=
NULL
);
else
if
(
t
->
interface_type
()
!=
NULL
&&
!
t
->
interface_type
()
->
is_empty
())
else
if
(
t
->
interface_type
()
!=
NULL
&&
!
t
->
interface_type
()
->
is_empty
())
...
...
gcc/go/gofrontend/runtime.cc
View file @
f54d331e
...
@@ -381,3 +381,12 @@ Runtime::map_iteration_type()
...
@@ -381,3 +381,12 @@ Runtime::map_iteration_type()
return
Type
::
make_array_type
(
runtime_function_type
(
RFT_POINTER
),
iexpr
);
return
Type
::
make_array_type
(
runtime_function_type
(
RFT_POINTER
),
iexpr
);
}
}
// Return the type used to pass a list of general channels to the
// select runtime function.
Type
*
Runtime
::
chanptr_type
()
{
return
runtime_function_type
(
RFT_CHANPTR
);
}
gcc/go/gofrontend/runtime.h
View file @
f54d331e
...
@@ -30,15 +30,24 @@ class Runtime
...
@@ -30,15 +30,24 @@ class Runtime
NUMBER_OF_FUNCTIONS
NUMBER_OF_FUNCTIONS
};
};
// Make a call to a runtime function.
static
Call_expression
*
static
Call_expression
*
make_call
(
Function
,
source_location
,
int
,
...);
make_call
(
Function
,
source_location
,
int
,
...);
// Convert all the types used by runtime functions to the backend
// representation.
static
void
static
void
convert_types
(
Gogo
*
);
convert_types
(
Gogo
*
);
// Return the type used for iterations over maps.
static
Type
*
static
Type
*
map_iteration_type
();
map_iteration_type
();
// Return the type used to pass a list of general channels to the
// select runtime function.
static
Type
*
chanptr_type
();
private
:
private
:
static
Named_object
*
static
Named_object
*
runtime_declaration
(
Function
);
runtime_declaration
(
Function
);
...
...
gcc/go/gofrontend/statements.cc
View file @
f54d331e
...
@@ -3974,12 +3974,13 @@ Select_clauses::Select_clause::may_fall_through() const
...
@@ -3974,12 +3974,13 @@ Select_clauses::Select_clause::may_fall_through() const
// Return a tree for the statements to execute.
// Return a tree for the statements to execute.
tree
Bstatement
*
Select_clauses
::
Select_clause
::
get_statements_tree
(
Translate_context
*
context
)
Select_clauses
::
Select_clause
::
get_statements_backend
(
Translate_context
*
context
)
{
{
if
(
this
->
statements_
==
NULL
)
if
(
this
->
statements_
==
NULL
)
return
NULL
_TREE
;
return
NULL
;
return
t
his
->
statements_
->
get_tree
(
context
);
return
t
ree_to_stat
(
this
->
statements_
->
get_tree
(
context
)
);
}
}
// Class Select_clauses.
// Class Select_clauses.
...
@@ -4037,7 +4038,7 @@ Select_clauses::may_fall_through() const
...
@@ -4037,7 +4038,7 @@ Select_clauses::may_fall_through() const
return
false
;
return
false
;
}
}
//
Return a tree
. We build a call to
//
Convert to the backend representation
. We build a call to
// size_t __go_select(size_t count, _Bool has_default,
// size_t __go_select(size_t count, _Bool has_default,
// channel* channels, _Bool* is_send)
// channel* channels, _Bool* is_send)
//
//
...
@@ -4051,20 +4052,24 @@ Select_clauses::may_fall_through() const
...
@@ -4051,20 +4052,24 @@ Select_clauses::may_fall_through() const
// FIXME: This doesn't handle channels which send interface types
// FIXME: This doesn't handle channels which send interface types
// where the receiver has a static type which matches that interface.
// where the receiver has a static type which matches that interface.
tree
Bstatement
*
Select_clauses
::
get_
tree
(
Translate_context
*
context
,
Select_clauses
::
get_
backend
(
Translate_context
*
context
,
Unnamed_label
*
break_label
,
Unnamed_label
*
break_label
,
source_location
location
)
source_location
location
)
{
{
size_t
count
=
this
->
clauses_
.
size
();
size_t
count
=
this
->
clauses_
.
size
();
VEC
(
constructor_elt
,
gc
)
*
chan_init
=
VEC_alloc
(
constructor_elt
,
gc
,
count
);
VEC
(
constructor_elt
,
gc
)
*
is_send_init
=
VEC_alloc
(
constructor_elt
,
gc
,
count
);
Select_clause
*
default_clause
=
NULL
;
tree
final_stmt_list
=
NULL_TREE
;
tree
channel_type_tree
=
NULL_TREE
;
size_t
i
=
0
;
Expression_list
*
chan_init
=
new
Expression_list
();
chan_init
->
reserve
(
count
);
Expression_list
*
is_send_init
=
new
Expression_list
();
is_send_init
->
reserve
(
count
);
Select_clause
*
default_clause
=
NULL
;
Type
*
runtime_chanptr_type
=
Runtime
::
chanptr_type
();
Type
*
runtime_chan_type
=
runtime_chanptr_type
->
points_to
();
for
(
Clauses
::
iterator
p
=
this
->
clauses_
.
begin
();
for
(
Clauses
::
iterator
p
=
this
->
clauses_
.
begin
();
p
!=
this
->
clauses_
.
end
();
p
!=
this
->
clauses_
.
end
();
++
p
)
++
p
)
...
@@ -4081,153 +4086,182 @@ Select_clauses::get_tree(Translate_context* context,
...
@@ -4081,153 +4086,182 @@ Select_clauses::get_tree(Translate_context* context,
// We should have given an error in the send or receive
// We should have given an error in the send or receive
// statement we created via lowering.
// statement we created via lowering.
gcc_assert
(
saw_errors
());
gcc_assert
(
saw_errors
());
return
error_mark_node
;
return
context
->
backend
()
->
error_statement
()
;
}
}
tree
channel_tree
=
p
->
channel
()
->
get_tree
(
context
);
Expression
*
c
=
p
->
channel
();
if
(
channel_tree
==
error_mark_node
)
c
=
Expression
::
make_unsafe_cast
(
runtime_chan_type
,
c
,
p
->
location
());
return
error_mark_node
;
chan_init
->
push_back
(
c
);
channel_type_tree
=
TREE_TYPE
(
channel_tree
);
constructor_elt
*
elt
=
VEC_quick_push
(
constructor_elt
,
chan_init
,
NULL
);
elt
->
index
=
build_int_cstu
(
sizetype
,
i
);
elt
->
value
=
channel_tree
;
elt
=
VEC_quick_push
(
constructor_elt
,
is_send_init
,
NULL
);
is_send_init
->
push_back
(
Expression
::
make_boolean
(
p
->
is_send
(),
elt
->
index
=
build_int_cstu
(
sizetype
,
i
);
p
->
location
()));
elt
->
value
=
p
->
is_send
()
?
boolean_true_node
:
boolean_false_node
;
++
i
;
}
}
gcc_assert
(
i
==
count
);
if
(
i
==
0
&&
default_clause
!=
NULL
)
if
(
chan_init
->
empty
()
)
{
{
// There is only a default clause.
gcc_assert
(
count
==
0
);
gcc_assert
(
final_stmt_list
==
NULL_TREE
);
Bstatement
*
s
;
tree
stmt_list
=
NULL_TREE
;
append_to_statement_list
(
default_clause
->
get_statements_tree
(
context
),
&
stmt_list
);
Bstatement
*
ldef
=
break_label
->
get_definition
(
context
);
Bstatement
*
ldef
=
break_label
->
get_definition
(
context
);
append_to_statement_list
(
stat_to_tree
(
ldef
),
&
stmt_list
);
if
(
default_clause
!=
NULL
)
return
stmt_list
;
}
tree
pointer_chan_type_tree
=
(
channel_type_tree
==
NULL_TREE
?
ptr_type_node
:
build_pointer_type
(
channel_type_tree
));
tree
chans_arg
;
tree
pointer_boolean_type_tree
=
build_pointer_type
(
boolean_type_node
);
tree
is_sends_arg
;
if
(
i
==
0
)
{
{
chans_arg
=
fold_convert_loc
(
location
,
pointer_chan_type_tree
,
// There is a default clause and no cases. Just execute the
null_pointer_node
);
// default clause.
is_sends_arg
=
fold_convert_loc
(
location
,
pointer_boolean_type_tree
,
s
=
default_clause
->
get_statements_backend
(
context
);
null_pointer_node
);
}
}
else
else
{
{
tree
index_type_tree
=
build_index_type
(
size_int
(
count
-
1
));
// There isn't even a default clause. In this case select
tree
chan_array_type_tree
=
build_array_type
(
channel_type_tree
,
// pauses forever. Call the runtime function with nils.
index_type_tree
);
mpz_t
zval
;
tree
chan_constructor
=
build_constructor
(
chan_array_type_tree
,
mpz_init_set_ui
(
zval
,
0
);
chan_init
);
Expression
*
zero
=
Expression
::
make_integer
(
&
zval
,
NULL
,
location
);
tree
chan_var
=
create_tmp_var
(
chan_array_type_tree
,
"CHAN"
);
mpz_clear
(
zval
);
DECL_IGNORED_P
(
chan_var
)
=
0
;
Expression
*
default_arg
=
Expression
::
make_boolean
(
false
,
location
);
DECL_INITIAL
(
chan_var
)
=
chan_constructor
;
Expression
*
nil1
=
Expression
::
make_nil
(
location
);
DECL_SOURCE_LOCATION
(
chan_var
)
=
location
;
Expression
*
nil2
=
nil1
->
copy
();
TREE_ADDRESSABLE
(
chan_var
)
=
1
;
Expression
*
call
=
Runtime
::
make_call
(
Runtime
::
SELECT
,
location
,
4
,
tree
decl_expr
=
build1
(
DECL_EXPR
,
void_type_node
,
chan_var
);
zero
,
default_arg
,
nil1
,
nil2
);
SET_EXPR_LOCATION
(
decl_expr
,
location
);
context
->
gogo
()
->
lower_expression
(
context
->
function
(),
&
call
);
append_to_statement_list
(
decl_expr
,
&
final_stmt_list
);
Bexpression
*
bcall
=
tree_to_expr
(
call
->
get_tree
(
context
));
s
=
context
->
backend
()
->
expression_statement
(
bcall
);
tree
is_send_array_type_tree
=
build_array_type
(
boolean_type_node
,
}
index_type_tree
);
if
(
s
==
NULL
)
tree
is_send_constructor
=
build_constructor
(
is_send_array_type_tree
,
return
ldef
;
is_send_init
);
std
::
vector
<
Bstatement
*>
stats
(
2
);
tree
is_send_var
=
create_tmp_var
(
is_send_array_type_tree
,
"ISSEND"
);
stats
[
0
]
=
s
;
DECL_IGNORED_P
(
is_send_var
)
=
0
;
stats
[
1
]
=
ldef
;
DECL_INITIAL
(
is_send_var
)
=
is_send_constructor
;
return
context
->
backend
()
->
statement_list
(
stats
);
DECL_SOURCE_LOCATION
(
is_send_var
)
=
location
;
}
TREE_ADDRESSABLE
(
is_send_var
)
=
1
;
gcc_assert
(
count
>
0
);
decl_expr
=
build1
(
DECL_EXPR
,
void_type_node
,
is_send_var
);
SET_EXPR_LOCATION
(
decl_expr
,
location
);
append_to_statement_list
(
decl_expr
,
&
final_stmt_list
);
chans_arg
=
fold_convert_loc
(
location
,
pointer_chan_type_tree
,
build_fold_addr_expr_loc
(
location
,
chan_var
));
is_sends_arg
=
fold_convert_loc
(
location
,
pointer_boolean_type_tree
,
build_fold_addr_expr_loc
(
location
,
is_send_var
));
}
static
tree
select_fndecl
;
tree
call
=
Gogo
::
call_builtin
(
&
select_fndecl
,
location
,
"__go_select"
,
4
,
sizetype
,
sizetype
,
size_int
(
count
),
boolean_type_node
,
(
default_clause
==
NULL
?
boolean_false_node
:
boolean_true_node
),
pointer_chan_type_tree
,
chans_arg
,
pointer_boolean_type_tree
,
is_sends_arg
);
if
(
call
==
error_mark_node
)
return
error_mark_node
;
tree
stmt_list
=
NULL_TREE
;
std
::
vector
<
Bstatement
*>
statements
;
mpz_t
ival
;
mpz_init_set_ui
(
ival
,
count
);
Expression
*
ecount
=
Expression
::
make_integer
(
&
ival
,
NULL
,
location
);
mpz_clear
(
ival
);
Type
*
chan_array_type
=
Type
::
make_array_type
(
runtime_chan_type
,
ecount
);
Expression
*
chans
=
Expression
::
make_composite_literal
(
chan_array_type
,
0
,
false
,
chan_init
,
location
);
context
->
gogo
()
->
lower_expression
(
context
->
function
(),
&
chans
);
Temporary_statement
*
chan_temp
=
Statement
::
make_temporary
(
chan_array_type
,
chans
,
location
);
statements
.
push_back
(
tree_to_stat
(
chan_temp
->
get_tree
(
context
)));
Type
*
is_send_array_type
=
Type
::
make_array_type
(
Type
::
lookup_bool_type
(),
ecount
->
copy
());
Expression
*
is_sends
=
Expression
::
make_composite_literal
(
is_send_array_type
,
0
,
false
,
is_send_init
,
location
);
context
->
gogo
()
->
lower_expression
(
context
->
function
(),
&
is_sends
);
Temporary_statement
*
is_send_temp
=
Statement
::
make_temporary
(
is_send_array_type
,
is_sends
,
location
);
statements
.
push_back
(
tree_to_stat
(
is_send_temp
->
get_tree
(
context
)));
mpz_init_set_ui
(
ival
,
0
);
Expression
*
zero
=
Expression
::
make_integer
(
&
ival
,
NULL
,
location
);
mpz_clear
(
ival
);
Expression
*
ref
=
Expression
::
make_temporary_reference
(
chan_temp
,
location
);
Expression
*
chan_arg
=
Expression
::
make_array_index
(
ref
,
zero
,
NULL
,
location
);
chan_arg
=
Expression
::
make_unary
(
OPERATOR_AND
,
chan_arg
,
location
);
chan_arg
=
Expression
::
make_unsafe_cast
(
runtime_chanptr_type
,
chan_arg
,
location
);
ref
=
Expression
::
make_temporary_reference
(
is_send_temp
,
location
);
Expression
*
is_send_arg
=
Expression
::
make_array_index
(
ref
,
zero
->
copy
(),
NULL
,
location
);
is_send_arg
=
Expression
::
make_unary
(
OPERATOR_AND
,
is_send_arg
,
location
);
Expression
*
default_arg
=
Expression
::
make_boolean
(
default_clause
!=
NULL
,
location
);
Expression
*
call
=
Runtime
::
make_call
(
Runtime
::
SELECT
,
location
,
4
,
ecount
->
copy
(),
default_arg
,
chan_arg
,
is_send_arg
);
context
->
gogo
()
->
lower_expression
(
context
->
function
(),
&
call
);
Bexpression
*
bcall
=
tree_to_expr
(
call
->
get_tree
(
context
));
std
::
vector
<
std
::
vector
<
Bexpression
*>
>
cases
;
std
::
vector
<
Bstatement
*>
clauses
;
cases
.
resize
(
count
+
(
default_clause
!=
NULL
?
1
:
0
));
clauses
.
resize
(
count
+
(
default_clause
!=
NULL
?
1
:
0
));
int
index
=
0
;
if
(
default_clause
!=
NULL
)
if
(
default_clause
!=
NULL
)
this
->
add_clause_tree
(
context
,
0
,
default_clause
,
break_label
,
&
stmt_list
);
{
this
->
add_clause_backend
(
context
,
location
,
index
,
0
,
default_clause
,
break_label
,
&
cases
,
&
clauses
);
++
index
;
}
i
=
1
;
i
nt
i
=
1
;
for
(
Clauses
::
iterator
p
=
this
->
clauses_
.
begin
();
for
(
Clauses
::
iterator
p
=
this
->
clauses_
.
begin
();
p
!=
this
->
clauses_
.
end
();
p
!=
this
->
clauses_
.
end
();
++
p
)
++
p
)
{
{
if
(
!
p
->
is_default
())
if
(
!
p
->
is_default
())
{
{
this
->
add_clause_tree
(
context
,
i
,
&*
p
,
break_label
,
&
stmt_list
);
this
->
add_clause_backend
(
context
,
location
,
index
,
i
,
&*
p
,
break_label
,
&
cases
,
&
clauses
);
++
i
;
++
i
;
++
index
;
}
}
}
}
Bstatement
*
ldef
=
break_label
->
get_definition
(
context
);
Bstatement
*
switch_stmt
=
context
->
backend
()
->
switch_statement
(
bcall
,
append_to_statement_list
(
stat_to_tree
(
ldef
),
&
stmt_list
);
cases
,
clauses
,
location
);
statements
.
push_back
(
switch_stmt
);
tree
switch_stmt
=
build3
(
SWITCH_EXPR
,
sizetype
,
call
,
stmt_list
,
NULL_TREE
);
Bstatement
*
ldef
=
break_label
->
get_definition
(
context
);
SET_EXPR_LOCATION
(
switch_stmt
,
location
);
statements
.
push_back
(
ldef
);
append_to_statement_list
(
switch_stmt
,
&
final_stmt_list
);
return
final_stmt_list
;
return
context
->
backend
()
->
statement_list
(
statements
)
;
}
}
// Add the tree for CLAUSE to STMT_LIST.
// Add the tree for CLAUSE to STMT_LIST.
void
void
Select_clauses
::
add_clause_tree
(
Translate_context
*
context
,
int
case_index
,
Select_clauses
::
add_clause_backend
(
Translate_context
*
context
,
source_location
location
,
int
index
,
int
case_value
,
Select_clause
*
clause
,
Select_clause
*
clause
,
Unnamed_label
*
bottom_label
,
tree
*
stmt_list
)
Unnamed_label
*
bottom_label
,
{
std
::
vector
<
std
::
vector
<
Bexpression
*>
>
*
cases
,
tree
label
=
create_artificial_label
(
clause
->
location
());
std
::
vector
<
Bstatement
*>*
clauses
)
append_to_statement_list
(
build3
(
CASE_LABEL_EXPR
,
void_type_node
,
{
build_int_cst
(
sizetype
,
case_index
),
mpz_t
ival
;
NULL_TREE
,
label
),
mpz_init_set_ui
(
ival
,
case_value
);
stmt_list
);
Expression
*
e
=
Expression
::
make_integer
(
&
ival
,
NULL
,
location
);
append_to_statement_list
(
clause
->
get_statements_tree
(
context
),
stmt_list
);
mpz_clear
(
ival
);
(
*
cases
)[
index
].
push_back
(
tree_to_expr
(
e
->
get_tree
(
context
)));
Bstatement
*
s
=
clause
->
get_statements_backend
(
context
);
source_location
gloc
=
(
clause
->
statements
()
==
NULL
source_location
gloc
=
(
clause
->
statements
()
==
NULL
?
clause
->
location
()
?
clause
->
location
()
:
clause
->
statements
()
->
end_location
());
:
clause
->
statements
()
->
end_location
());
Bstatement
*
g
=
bottom_label
->
get_goto
(
context
,
gloc
);
Bstatement
*
g
=
bottom_label
->
get_goto
(
context
,
gloc
);
append_to_statement_list
(
stat_to_tree
(
g
),
stmt_list
);
if
(
s
==
NULL
)
(
*
clauses
)[
index
]
=
g
;
else
{
std
::
vector
<
Bstatement
*>
stats
(
2
);
stats
[
0
]
=
s
;
stats
[
1
]
=
g
;
(
*
clauses
)[
index
]
=
context
->
backend
()
->
statement_list
(
stats
);
}
}
}
// Class Select_statement.
// Class Select_statement.
...
@@ -4266,8 +4300,9 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
...
@@ -4266,8 +4300,9 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
tree
tree
Select_statement
::
do_get_tree
(
Translate_context
*
context
)
Select_statement
::
do_get_tree
(
Translate_context
*
context
)
{
{
return
this
->
clauses_
->
get_tree
(
context
,
this
->
break_label
(),
Bstatement
*
ret
=
this
->
clauses_
->
get_backend
(
context
,
this
->
break_label
(),
this
->
location
());
this
->
location
());
return
stat_to_tree
(
ret
);
}
}
// Make a select statement.
// Make a select statement.
...
...
gcc/go/gofrontend/statements.h
View file @
f54d331e
...
@@ -678,9 +678,9 @@ class Select_clauses
...
@@ -678,9 +678,9 @@ class Select_clauses
bool
bool
may_fall_through
()
const
;
may_fall_through
()
const
;
//
Return a tree implementing the select statement
.
//
Convert to the backend representation
.
tree
Bstatement
*
get_
tree
(
Translate_context
*
,
Unnamed_label
*
break_label
,
source_location
);
get_
backend
(
Translate_context
*
,
Unnamed_label
*
break_label
,
source_location
);
private
:
private
:
// A single clause.
// A single clause.
...
@@ -749,8 +749,8 @@ class Select_clauses
...
@@ -749,8 +749,8 @@ class Select_clauses
may_fall_through
()
const
;
may_fall_through
()
const
;
// Return a tree for the statements to execute.
// Return a tree for the statements to execute.
tree
Bstatement
*
get_statements_
tree
(
Translate_context
*
);
get_statements_
backend
(
Translate_context
*
);
private
:
private
:
// The channel.
// The channel.
...
@@ -778,8 +778,10 @@ class Select_clauses
...
@@ -778,8 +778,10 @@ class Select_clauses
};
};
void
void
add_clause_tree
(
Translate_context
*
,
int
,
Select_clause
*
,
Unnamed_label
*
,
add_clause_backend
(
Translate_context
*
,
source_location
,
int
index
,
tree
*
);
int
case_value
,
Select_clause
*
,
Unnamed_label
*
,
std
::
vector
<
std
::
vector
<
Bexpression
*>
>*
cases
,
std
::
vector
<
Bstatement
*>*
clauses
);
typedef
std
::
vector
<
Select_clause
>
Clauses
;
typedef
std
::
vector
<
Select_clause
>
Clauses
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment