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
8dc421e0
Commit
8dc421e0
authored
Apr 13, 2011
by
Ian Lance Taylor
Committed by
Ian Lance Taylor
Apr 13, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use backend interface for go and defer statements.
Change defer stack from tree to Expression. From-SVN: r172402
parent
123c516a
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
133 additions
and
130 deletions
+133
-130
gcc/go/ChangeLog
+4
-0
gcc/go/Make-lang.in
+1
-1
gcc/go/gofrontend/gogo-tree.cc
+31
-54
gcc/go/gofrontend/gogo.cc
+23
-0
gcc/go/gofrontend/gogo.h
+6
-4
gcc/go/gofrontend/statements.cc
+65
-68
gcc/go/gofrontend/statements.h
+3
-3
No files found.
gcc/go/ChangeLog
View file @
8dc421e0
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).
2011-04-13 Ian Lance Taylor <iant@google.com>
* Make-lang.in (GO_OBJS): Add go/runtime.o.
* Make-lang.in (GO_OBJS): Add go/runtime.o.
(GO_RUNTIME_H): New variable.
(GO_RUNTIME_H): New variable.
(go/runtime.o): New target.
(go/runtime.o): New target.
...
...
gcc/go/Make-lang.in
View file @
8dc421e0
...
@@ -262,7 +262,7 @@ go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
...
@@ -262,7 +262,7 @@ go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
go/gogo-tree.o
:
go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H)
\
go/gogo-tree.o
:
go/gofrontend/gogo-tree.cc $(GO_SYSTEM_H) $(TOPLEV_H)
\
$(TREE_H) $(GIMPLE_H) tree-iterator.h $(CGRAPH_H) langhooks.h
\
$(TREE_H) $(GIMPLE_H) tree-iterator.h $(CGRAPH_H) langhooks.h
\
convert.h output.h $(DIAGNOSTIC_H) $(GO_TYPES_H)
\
convert.h output.h $(DIAGNOSTIC_H) $(GO_TYPES_H)
\
$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_GOGO_H)
$(GO_EXPRESSIONS_H) $(GO_STATEMENTS_H) $(GO_
RUNTIME_H) $(GO_
GOGO_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_RUNTIME_H)
\
$(GO_EXPRESSIONS_H) go/gofrontend/dataflow.h $(GO_RUNTIME_H)
\
...
...
gcc/go/gofrontend/gogo-tree.cc
View file @
8dc421e0
...
@@ -31,6 +31,7 @@ extern "C"
...
@@ -31,6 +31,7 @@ extern "C"
#include "types.h"
#include "types.h"
#include "expressions.h"
#include "expressions.h"
#include "statements.h"
#include "statements.h"
#include "runtime.h"
#include "gogo.h"
#include "gogo.h"
// Whether we have seen any errors.
// Whether we have seen any errors.
...
@@ -1585,13 +1586,22 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
...
@@ -1585,13 +1586,22 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
// Declare variables if necessary.
// Declare variables if necessary.
tree
bind
=
NULL_TREE
;
tree
bind
=
NULL_TREE
;
if
(
declare_vars
!=
NULL_TREE
)
tree
defer_init
=
NULL_TREE
;
if
(
declare_vars
!=
NULL_TREE
||
this
->
defer_stack_
!=
NULL
)
{
{
tree
block
=
make_node
(
BLOCK
);
tree
block
=
make_node
(
BLOCK
);
BLOCK_SUPERCONTEXT
(
block
)
=
fndecl
;
BLOCK_SUPERCONTEXT
(
block
)
=
fndecl
;
DECL_INITIAL
(
fndecl
)
=
block
;
DECL_INITIAL
(
fndecl
)
=
block
;
BLOCK_VARS
(
block
)
=
declare_vars
;
BLOCK_VARS
(
block
)
=
declare_vars
;
TREE_USED
(
block
)
=
1
;
TREE_USED
(
block
)
=
1
;
if
(
this
->
defer_stack_
!=
NULL
)
{
Translate_context
dcontext
(
gogo
,
named_function
,
this
->
block_
,
block
);
defer_init
=
this
->
defer_stack_
->
get_tree
(
&
dcontext
);
}
bind
=
build3
(
BIND_EXPR
,
void_type_node
,
BLOCK_VARS
(
block
),
bind
=
build3
(
BIND_EXPR
,
void_type_node
,
BLOCK_VARS
(
block
),
NULL_TREE
,
block
);
NULL_TREE
,
block
);
TREE_SIDE_EFFECTS
(
bind
)
=
1
;
TREE_SIDE_EFFECTS
(
bind
)
=
1
;
...
@@ -1615,10 +1625,8 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
...
@@ -1615,10 +1625,8 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
// If we have a defer stack, initialize it at the start of a
// If we have a defer stack, initialize it at the start of a
// function.
// function.
if
(
this
->
defer_stack_
!=
NULL_TREE
)
if
(
defer_init
!=
NULL_TREE
&&
defer_init
!=
error_mark_node
)
{
{
tree
defer_init
=
build1
(
DECL_EXPR
,
void_type_node
,
this
->
defer_stack_
);
SET_EXPR_LOCATION
(
defer_init
,
this
->
block_
->
start_location
());
SET_EXPR_LOCATION
(
defer_init
,
this
->
block_
->
start_location
());
append_to_statement_list
(
defer_init
,
&
init
);
append_to_statement_list
(
defer_init
,
&
init
);
...
@@ -1663,17 +1671,15 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
...
@@ -1663,17 +1671,15 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
// purpose is to stop the stack unwinding if a deferred function
// purpose is to stop the stack unwinding if a deferred function
// calls recover. There are more details in
// calls recover. There are more details in
// libgo/runtime/go-unwind.c.
// libgo/runtime/go-unwind.c.
tree
stmt_list
=
NULL_TREE
;
tree
stmt_list
=
NULL_TREE
;
static
tree
check_fndecl
;
tree
call
=
Gogo
::
call_builtin
(
&
check_fndecl
,
Expression
*
call
=
Runtime
::
make_call
(
Runtime
::
CHECK_DEFER
,
end_loc
,
1
,
end_loc
,
this
->
defer_stack
(
end_loc
));
"__go_check_defer"
,
Translate_context
context
(
gogo
,
named_function
,
NULL
,
NULL
);
1
,
tree
call_tree
=
call
->
get_tree
(
&
context
);
void_type_node
,
if
(
call_tree
!=
error_mark_node
)
ptr_type_node
,
append_to_statement_list
(
call_tree
,
&
stmt_list
);
this
->
defer_stack
(
end_loc
));
if
(
call
!=
error_mark_node
)
append_to_statement_list
(
call
,
&
stmt_list
);
tree
retval
=
this
->
return_value
(
gogo
,
named_function
,
end_loc
,
&
stmt_list
);
tree
retval
=
this
->
return_value
(
gogo
,
named_function
,
end_loc
,
&
stmt_list
);
tree
set
;
tree
set
;
...
@@ -1704,24 +1710,17 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
...
@@ -1704,24 +1710,17 @@ Function::build_defer_wrapper(Gogo* gogo, Named_object* named_function,
label
);
label
);
append_to_statement_list
(
define_label
,
&
stmt_list
);
append_to_statement_list
(
define_label
,
&
stmt_list
);
static
tree
undefer_fndecl
;
call
=
Runtime
::
make_call
(
Runtime
::
UNDEFER
,
end_loc
,
1
,
tree
undefer
=
Gogo
::
call_builtin
(
&
undefer_fndecl
,
this
->
defer_stack
(
end_loc
));
end_loc
,
tree
undefer
=
call
->
get_tree
(
&
context
);
"__go_undefer"
,
1
,
call
=
Runtime
::
make_call
(
Runtime
::
CHECK_DEFER
,
end_loc
,
1
,
void_type_node
,
this
->
defer_stack
(
end_loc
));
ptr_type_node
,
tree
defer
=
call
->
get_tree
(
&
context
);
this
->
defer_stack
(
end_loc
));
if
(
undefer_fndecl
!=
NULL_TREE
)
if
(
undefer
==
error_mark_node
||
defer
==
error_mark_node
)
TREE_NOTHROW
(
undefer_fndecl
)
=
0
;
return
;
tree
defer
=
Gogo
::
call_builtin
(
&
check_fndecl
,
end_loc
,
"__go_check_defer"
,
1
,
void_type_node
,
ptr_type_node
,
this
->
defer_stack
(
end_loc
));
tree
jump
=
fold_build1_loc
(
end_loc
,
GOTO_EXPR
,
void_type_node
,
label
);
tree
jump
=
fold_build1_loc
(
end_loc
,
GOTO_EXPR
,
void_type_node
,
label
);
tree
catch_body
=
build2
(
COMPOUND_EXPR
,
void_type_node
,
defer
,
jump
);
tree
catch_body
=
build2
(
COMPOUND_EXPR
,
void_type_node
,
defer
,
jump
);
catch_body
=
build2
(
CATCH_EXPR
,
void_type_node
,
NULL
,
catch_body
);
catch_body
=
build2
(
CATCH_EXPR
,
void_type_node
,
NULL
,
catch_body
);
...
@@ -1794,28 +1793,6 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
...
@@ -1794,28 +1793,6 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
}
}
}
}
// Get the tree for the variable holding the defer stack for this
// function. At least at present, the value of this variable is not
// used. However, a pointer to this variable is used as a marker for
// the functions on the defer stack associated with this function.
// Doing things this way permits inlining a function which uses defer.
tree
Function
::
defer_stack
(
source_location
location
)
{
if
(
this
->
defer_stack_
==
NULL_TREE
)
{
tree
var
=
create_tmp_var
(
ptr_type_node
,
"DEFER"
);
DECL_INITIAL
(
var
)
=
null_pointer_node
;
DECL_SOURCE_LOCATION
(
var
)
=
location
;
TREE_ADDRESSABLE
(
var
)
=
1
;
this
->
defer_stack_
=
var
;
}
return
fold_convert_loc
(
location
,
ptr_type_node
,
build_fold_addr_expr_loc
(
location
,
this
->
defer_stack_
));
}
// Get a tree for the statements in a block.
// Get a tree for the statements in a block.
tree
tree
...
...
gcc/go/gofrontend/gogo.cc
View file @
8dc421e0
...
@@ -2884,6 +2884,29 @@ Function::determine_types()
...
@@ -2884,6 +2884,29 @@ Function::determine_types()
this
->
block_
->
determine_types
();
this
->
block_
->
determine_types
();
}
}
// Get a pointer to the variable holding the defer stack for this
// function, making it if necessary. At least at present, the value
// of this variable is not used. However, a pointer to this variable
// is used as a marker for the functions on the defer stack associated
// with this function. Doing things this way permits inlining a
// function which uses defer.
Expression
*
Function
::
defer_stack
(
source_location
location
)
{
Type
*
t
=
Type
::
make_pointer_type
(
Type
::
make_void_type
());
if
(
this
->
defer_stack_
==
NULL
)
{
Expression
*
n
=
Expression
::
make_nil
(
location
);
this
->
defer_stack_
=
Statement
::
make_temporary
(
t
,
n
,
location
);
this
->
defer_stack_
->
set_is_address_taken
();
}
Expression
*
ref
=
Expression
::
make_temporary_reference
(
this
->
defer_stack_
,
location
);
Expression
*
addr
=
Expression
::
make_unary
(
OPERATOR_AND
,
ref
,
location
);
return
Expression
::
make_unsafe_cast
(
t
,
addr
,
location
);
}
// Export the function.
// Export the function.
void
void
...
...
gcc/go/gofrontend/gogo.h
View file @
8dc421e0
...
@@ -17,6 +17,7 @@ class Typed_identifier_list;
...
@@ -17,6 +17,7 @@ class Typed_identifier_list;
class
Function_type
;
class
Function_type
;
class
Expression
;
class
Expression
;
class
Statement
;
class
Statement
;
class
Temporary_statement
;
class
Block
;
class
Block
;
class
Function
;
class
Function
;
class
Bindings
;
class
Bindings
;
...
@@ -977,7 +978,7 @@ class Function
...
@@ -977,7 +978,7 @@ class Function
return_value
(
Gogo
*
,
Named_object
*
,
source_location
,
tree
*
stmt_list
)
const
;
return_value
(
Gogo
*
,
Named_object
*
,
source_location
,
tree
*
stmt_list
)
const
;
// Get a tree for the variable holding the defer stack.
// Get a tree for the variable holding the defer stack.
tree
Expression
*
defer_stack
(
source_location
);
defer_stack
(
source_location
);
// Export the function.
// Export the function.
...
@@ -1033,9 +1034,10 @@ class Function
...
@@ -1033,9 +1034,10 @@ class Function
Labels
labels_
;
Labels
labels_
;
// The function decl.
// The function decl.
tree
fndecl_
;
tree
fndecl_
;
// A variable holding the defer stack variable. This is NULL unless
// The defer stack variable. A pointer to this variable is used to
// we actually need a defer stack.
// distinguish the defer stack for one function from another. This
tree
defer_stack_
;
// is NULL unless we actually need a defer stack.
Temporary_statement
*
defer_stack_
;
// True if the result variables are named.
// True if the result variables are named.
bool
results_are_named_
;
bool
results_are_named_
;
// True if this function calls the predeclared recover function.
// True if this function calls the predeclared recover function.
...
...
gcc/go/gofrontend/statements.cc
View file @
8dc421e0
...
@@ -1718,17 +1718,39 @@ class Simplify_thunk_traverse : public Traverse
...
@@ -1718,17 +1718,39 @@ class Simplify_thunk_traverse : public Traverse
{
{
public
:
public
:
Simplify_thunk_traverse
(
Gogo
*
gogo
)
Simplify_thunk_traverse
(
Gogo
*
gogo
)
:
Traverse
(
traverse_blocks
),
:
Traverse
(
traverse_
functions
|
traverse_
blocks
),
gogo_
(
gogo
)
gogo_
(
gogo
)
,
function_
(
NULL
)
{
}
{
}
int
int
function
(
Named_object
*
);
int
block
(
Block
*
);
block
(
Block
*
);
private
:
private
:
// General IR.
Gogo
*
gogo_
;
Gogo
*
gogo_
;
// The function we are traversing.
Named_object
*
function_
;
};
};
// Keep track of the current function while looking for thunks.
int
Simplify_thunk_traverse
::
function
(
Named_object
*
no
)
{
gcc_assert
(
this
->
function_
==
NULL
);
this
->
function_
=
no
;
int
t
=
no
->
func_value
()
->
traverse
(
this
);
this
->
function_
=
NULL
;
if
(
t
==
TRAVERSE_EXIT
)
return
t
;
return
TRAVERSE_SKIP_COMPONENTS
;
}
// Look for thunks in a block.
int
int
Simplify_thunk_traverse
::
block
(
Block
*
b
)
Simplify_thunk_traverse
::
block
(
Block
*
b
)
{
{
...
@@ -1739,7 +1761,7 @@ Simplify_thunk_traverse::block(Block* b)
...
@@ -1739,7 +1761,7 @@ Simplify_thunk_traverse::block(Block* b)
Thunk_statement
*
stat
=
b
->
statements
()
->
back
()
->
thunk_statement
();
Thunk_statement
*
stat
=
b
->
statements
()
->
back
()
->
thunk_statement
();
if
(
stat
==
NULL
)
if
(
stat
==
NULL
)
return
TRAVERSE_CONTINUE
;
return
TRAVERSE_CONTINUE
;
if
(
stat
->
simplify_statement
(
this
->
gogo_
,
b
))
if
(
stat
->
simplify_statement
(
this
->
gogo_
,
this
->
function_
,
b
))
return
TRAVERSE_SKIP_COMPONENTS
;
return
TRAVERSE_SKIP_COMPONENTS
;
return
TRAVERSE_CONTINUE
;
return
TRAVERSE_CONTINUE
;
}
}
...
@@ -1761,13 +1783,23 @@ Gogo::simplify_thunk_statements()
...
@@ -1761,13 +1783,23 @@ Gogo::simplify_thunk_statements()
// struct to a thunk. The thunk does the real call.
// struct to a thunk. The thunk does the real call.
bool
bool
Thunk_statement
::
simplify_statement
(
Gogo
*
gogo
,
Block
*
block
)
Thunk_statement
::
simplify_statement
(
Gogo
*
gogo
,
Named_object
*
function
,
Block
*
block
)
{
{
if
(
this
->
classification
()
==
STATEMENT_ERROR
)
if
(
this
->
classification
()
==
STATEMENT_ERROR
)
return
false
;
return
false
;
if
(
this
->
call_
->
is_error_expression
())
if
(
this
->
call_
->
is_error_expression
())
return
false
;
return
false
;
if
(
this
->
classification
()
==
STATEMENT_DEFER
)
{
// Make sure that the defer stack exists for the function. We
// will use when converting this statement to the backend
// representation, but we want it to exist when we start
// converting the function.
function
->
func_value
()
->
defer_stack
(
this
->
location
());
}
Call_expression
*
ce
=
this
->
call_
->
call_expression
();
Call_expression
*
ce
=
this
->
call_
->
call_expression
();
Function_type
*
fntype
=
ce
->
get_function_type
();
Function_type
*
fntype
=
ce
->
get_function_type
();
if
(
fntype
==
NULL
)
if
(
fntype
==
NULL
)
...
@@ -2160,30 +2192,26 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
...
@@ -2160,30 +2192,26 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name,
// Get the function and argument trees.
// Get the function and argument trees.
void
bool
Thunk_statement
::
get_fn_and_arg
(
Translate_context
*
context
,
tree
*
pfn
,
Thunk_statement
::
get_fn_and_arg
(
Expression
**
pfn
,
Expression
**
parg
)
tree
*
parg
)
{
{
if
(
this
->
call_
->
is_error_expression
())
if
(
this
->
call_
->
is_error_expression
())
{
return
false
;
*
pfn
=
error_mark_node
;
*
parg
=
error_mark_node
;
return
;
}
Call_expression
*
ce
=
this
->
call_
->
call_expression
();
Call_expression
*
ce
=
this
->
call_
->
call_expression
();
Expression
*
fn
=
ce
->
fn
();
*
pfn
=
ce
->
fn
();
*
pfn
=
fn
->
get_tree
(
context
);
const
Expression_list
*
args
=
ce
->
args
();
const
Expression_list
*
args
=
ce
->
args
();
if
(
args
==
NULL
||
args
->
empty
())
if
(
args
==
NULL
||
args
->
empty
())
*
parg
=
null_pointer_node
;
*
parg
=
Expression
::
make_nil
(
this
->
location
())
;
else
else
{
{
gcc_assert
(
args
->
size
()
==
1
);
gcc_assert
(
args
->
size
()
==
1
);
*
parg
=
args
->
front
()
->
get_tree
(
context
)
;
*
parg
=
args
->
front
();
}
}
return
true
;
}
}
// Class Go_statement.
// Class Go_statement.
...
@@ -2191,30 +2219,17 @@ Thunk_statement::get_fn_and_arg(Translate_context* context, tree* pfn,
...
@@ -2191,30 +2219,17 @@ Thunk_statement::get_fn_and_arg(Translate_context* context, tree* pfn,
tree
tree
Go_statement
::
do_get_tree
(
Translate_context
*
context
)
Go_statement
::
do_get_tree
(
Translate_context
*
context
)
{
{
tree
fn_tree
;
Expression
*
fn
;
tree
arg_tree
;
Expression
*
arg
;
this
->
get_fn_and_arg
(
context
,
&
fn_tree
,
&
arg_tree
);
if
(
!
this
->
get_fn_and_arg
(
&
fn
,
&
arg
))
return
error_mark_node
;
static
tree
go_fndecl
;
tree
fn_arg_type
=
NULL_TREE
;
if
(
go_fndecl
==
NULL_TREE
)
{
// Only build FN_ARG_TYPE if we need it.
tree
subargtypes
=
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
);
tree
subfntype
=
build_function_type
(
ptr_type_node
,
subargtypes
);
fn_arg_type
=
build_pointer_type
(
subfntype
);
}
return
Gogo
::
call_builtin
(
&
go_fndecl
,
Expression
*
call
=
Runtime
::
make_call
(
Runtime
::
GO
,
this
->
location
(),
2
,
this
->
location
(),
fn
,
arg
);
"__go_go"
,
tree
call_tree
=
call
->
get_tree
(
context
);
2
,
Bexpression
*
call_bexpr
=
tree_to_expr
(
call_tree
);
void_type_node
,
Bstatement
*
ret
=
context
->
backend
()
->
expression_statement
(
call_bexpr
);
fn_arg_type
,
return
stat_to_tree
(
ret
);
fn_tree
,
ptr_type_node
,
arg_tree
);
}
}
// Make a go statement.
// Make a go statement.
...
@@ -2230,38 +2245,20 @@ Statement::make_go_statement(Call_expression* call, source_location location)
...
@@ -2230,38 +2245,20 @@ Statement::make_go_statement(Call_expression* call, source_location location)
tree
tree
Defer_statement
::
do_get_tree
(
Translate_context
*
context
)
Defer_statement
::
do_get_tree
(
Translate_context
*
context
)
{
{
source_location
loc
=
this
->
location
();
Expression
*
fn
;
Expression
*
arg
;
tree
fn_tree
;
if
(
!
this
->
get_fn_and_arg
(
&
fn
,
&
arg
))
tree
arg_tree
;
this
->
get_fn_and_arg
(
context
,
&
fn_tree
,
&
arg_tree
);
if
(
fn_tree
==
error_mark_node
||
arg_tree
==
error_mark_node
)
return
error_mark_node
;
return
error_mark_node
;
static
tree
defer_fndecl
;
source_location
loc
=
this
->
location
();
Expression
*
ds
=
context
->
function
()
->
func_value
()
->
defer_stack
(
loc
);
tree
fn_arg_type
=
NULL_TREE
;
if
(
defer_fndecl
==
NULL_TREE
)
{
// Only build FN_ARG_TYPE if we need it.
tree
subargtypes
=
tree_cons
(
NULL_TREE
,
ptr_type_node
,
void_list_node
);
tree
subfntype
=
build_function_type
(
ptr_type_node
,
subargtypes
);
fn_arg_type
=
build_pointer_type
(
subfntype
);
}
tree
defer_stack
=
context
->
function
()
->
func_value
()
->
defer_stack
(
loc
);
Expression
*
call
=
Runtime
::
make_call
(
Runtime
::
DEFER
,
loc
,
3
,
ds
,
fn
,
arg
);
return
Gogo
::
call_builtin
(
&
defer_fndecl
,
tree
call_tree
=
call
->
get_tree
(
context
);
loc
,
Bexpression
*
call_bexpr
=
tree_to_expr
(
call_tree
);
"__go_defer"
,
Bstatement
*
ret
=
context
->
backend
()
->
expression_statement
(
call_bexpr
);
3
,
return
stat_to_tree
(
ret
);
void_type_node
,
ptr_type_node
,
defer_stack
,
fn_arg_type
,
fn_tree
,
ptr_type_node
,
arg_tree
);
}
}
// Make a defer statement.
// Make a defer statement.
...
...
gcc/go/gofrontend/statements.h
View file @
8dc421e0
...
@@ -852,7 +852,7 @@ class Thunk_statement : public Statement
...
@@ -852,7 +852,7 @@ class Thunk_statement : public Statement
// Simplify a go or defer statement so that it only uses a single
// Simplify a go or defer statement so that it only uses a single
// parameter.
// parameter.
bool
bool
simplify_statement
(
Gogo
*
,
Block
*
);
simplify_statement
(
Gogo
*
,
Named_object
*
,
Block
*
);
protected
:
protected
:
int
int
...
@@ -868,8 +868,8 @@ class Thunk_statement : public Statement
...
@@ -868,8 +868,8 @@ class Thunk_statement : public Statement
do_check_types
(
Gogo
*
);
do_check_types
(
Gogo
*
);
// Return the function and argument trees for the call.
// Return the function and argument trees for the call.
void
bool
get_fn_and_arg
(
Translate_context
*
,
tree
*
pfn
,
tree
*
parg
);
get_fn_and_arg
(
Expression
**
pfn
,
Expression
*
*
parg
);
private
:
private
:
// Return whether this is a simple go statement.
// Return whether this is a simple go statement.
...
...
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