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
a0dabda5
Commit
a0dabda5
authored
Mar 15, 1995
by
Jason Merrill
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle compilation of nested functions from another scope.
From-SVN: r9185
parent
ea9be077
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
34 deletions
+95
-34
gcc/function.c
+12
-10
gcc/function.h
+10
-0
gcc/tree.c
+73
-24
No files found.
gcc/function.c
View file @
a0dabda5
...
@@ -462,8 +462,8 @@ find_function_data (decl)
...
@@ -462,8 +462,8 @@ find_function_data (decl)
since this function knows only about language-independent variables. */
since this function knows only about language-independent variables. */
void
void
push_function_context_to
(
toplevel
)
push_function_context_to
(
context
)
int
toplevel
;
tree
context
;
{
{
struct
function
*
p
=
(
struct
function
*
)
xmalloc
(
sizeof
(
struct
function
));
struct
function
*
p
=
(
struct
function
*
)
xmalloc
(
sizeof
(
struct
function
));
...
@@ -481,6 +481,7 @@ push_function_context_to (toplevel)
...
@@ -481,6 +481,7 @@ push_function_context_to (toplevel)
p
->
calls_alloca
=
current_function_calls_alloca
;
p
->
calls_alloca
=
current_function_calls_alloca
;
p
->
has_nonlocal_label
=
current_function_has_nonlocal_label
;
p
->
has_nonlocal_label
=
current_function_has_nonlocal_label
;
p
->
has_nonlocal_goto
=
current_function_has_nonlocal_goto
;
p
->
has_nonlocal_goto
=
current_function_has_nonlocal_goto
;
p
->
contains_functions
=
current_function_contains_functions
;
p
->
args_size
=
current_function_args_size
;
p
->
args_size
=
current_function_args_size
;
p
->
pretend_args_size
=
current_function_pretend_args_size
;
p
->
pretend_args_size
=
current_function_pretend_args_size
;
p
->
arg_offset_rtx
=
current_function_arg_offset_rtx
;
p
->
arg_offset_rtx
=
current_function_arg_offset_rtx
;
...
@@ -514,7 +515,7 @@ push_function_context_to (toplevel)
...
@@ -514,7 +515,7 @@ push_function_context_to (toplevel)
p
->
fixup_var_refs_queue
=
0
;
p
->
fixup_var_refs_queue
=
0
;
p
->
epilogue_delay_list
=
current_function_epilogue_delay_list
;
p
->
epilogue_delay_list
=
current_function_epilogue_delay_list
;
save_tree_status
(
p
,
toplevel
);
save_tree_status
(
p
,
context
);
save_storage_status
(
p
);
save_storage_status
(
p
);
save_emit_status
(
p
);
save_emit_status
(
p
);
init_emit
();
init_emit
();
...
@@ -529,15 +530,15 @@ push_function_context_to (toplevel)
...
@@ -529,15 +530,15 @@ push_function_context_to (toplevel)
void
void
push_function_context
()
push_function_context
()
{
{
push_function_context_to
(
0
);
push_function_context_to
(
current_function_decl
);
}
}
/* Restore the last saved context, at the end of a nested function.
/* Restore the last saved context, at the end of a nested function.
This function is called from language-specific code. */
This function is called from language-specific code. */
void
void
pop_function_context_from
(
toplevel
)
pop_function_context_from
(
context
)
int
toplevel
;
tree
context
;
{
{
struct
function
*
p
=
outer_function_chain
;
struct
function
*
p
=
outer_function_chain
;
...
@@ -554,8 +555,9 @@ pop_function_context_from (toplevel)
...
@@ -554,8 +555,9 @@ pop_function_context_from (toplevel)
current_function_calls_alloca
=
p
->
calls_alloca
;
current_function_calls_alloca
=
p
->
calls_alloca
;
current_function_has_nonlocal_label
=
p
->
has_nonlocal_label
;
current_function_has_nonlocal_label
=
p
->
has_nonlocal_label
;
current_function_has_nonlocal_goto
=
p
->
has_nonlocal_goto
;
current_function_has_nonlocal_goto
=
p
->
has_nonlocal_goto
;
if
(
!
toplevel
)
current_function_contains_functions
current_function_contains_functions
=
1
;
=
p
->
contains_functions
||
p
->
inline_obstacks
||
context
==
current_function_decl
;
current_function_args_size
=
p
->
args_size
;
current_function_args_size
=
p
->
args_size
;
current_function_pretend_args_size
=
p
->
pretend_args_size
;
current_function_pretend_args_size
=
p
->
pretend_args_size
;
current_function_arg_offset_rtx
=
p
->
arg_offset_rtx
;
current_function_arg_offset_rtx
=
p
->
arg_offset_rtx
;
...
@@ -589,7 +591,7 @@ pop_function_context_from (toplevel)
...
@@ -589,7 +591,7 @@ pop_function_context_from (toplevel)
current_function_epilogue_delay_list
=
p
->
epilogue_delay_list
;
current_function_epilogue_delay_list
=
p
->
epilogue_delay_list
;
reg_renumber
=
0
;
reg_renumber
=
0
;
restore_tree_status
(
p
,
toplevel
);
restore_tree_status
(
p
);
restore_storage_status
(
p
);
restore_storage_status
(
p
);
restore_expr_status
(
p
);
restore_expr_status
(
p
);
restore_emit_status
(
p
);
restore_emit_status
(
p
);
...
@@ -616,7 +618,7 @@ pop_function_context_from (toplevel)
...
@@ -616,7 +618,7 @@ pop_function_context_from (toplevel)
void
pop_function_context
()
void
pop_function_context
()
{
{
pop_function_context_from
(
0
);
pop_function_context_from
(
current_function_decl
);
}
}
/* Allocate fixed slots in the stack frame of the current function. */
/* Allocate fixed slots in the stack frame of the current function. */
...
...
gcc/function.h
View file @
a0dabda5
...
@@ -47,6 +47,14 @@ struct sequence_stack
...
@@ -47,6 +47,14 @@ struct sequence_stack
};
};
extern
struct
sequence_stack
*
sequence_stack
;
extern
struct
sequence_stack
*
sequence_stack
;
/* Stack of single obstacks. */
struct
simple_obstack_stack
{
struct
obstack
*
obstack
;
struct
simple_obstack_stack
*
next
;
};
/* This structure can save all the important global and static variables
/* This structure can save all the important global and static variables
describing the status of the current function. */
describing the status of the current function. */
...
@@ -67,6 +75,7 @@ struct function
...
@@ -67,6 +75,7 @@ struct function
int
calls_alloca
;
int
calls_alloca
;
int
has_nonlocal_label
;
int
has_nonlocal_label
;
int
has_nonlocal_goto
;
int
has_nonlocal_goto
;
int
contains_functions
;
rtx
nonlocal_goto_handler_slot
;
rtx
nonlocal_goto_handler_slot
;
rtx
nonlocal_goto_stack_level
;
rtx
nonlocal_goto_stack_level
;
tree
nonlocal_labels
;
tree
nonlocal_labels
;
...
@@ -158,6 +167,7 @@ struct function
...
@@ -158,6 +167,7 @@ struct function
struct
obstack
*
expression_obstack
;
struct
obstack
*
expression_obstack
;
struct
obstack
*
saveable_obstack
;
struct
obstack
*
saveable_obstack
;
struct
obstack
*
rtl_obstack
;
struct
obstack
*
rtl_obstack
;
struct
simple_obstack_stack
*
inline_obstacks
;
/* For integrate.c. */
/* For integrate.c. */
int
uses_const_pool
;
int
uses_const_pool
;
...
...
gcc/tree.c
View file @
a0dabda5
...
@@ -66,6 +66,17 @@ struct obstack *function_maybepermanent_obstack;
...
@@ -66,6 +66,17 @@ struct obstack *function_maybepermanent_obstack;
struct
obstack
maybepermanent_obstack
;
struct
obstack
maybepermanent_obstack
;
/* This is a list of function_maybepermanent_obstacks for top-level inline
functions that are compiled in the middle of compiling other functions. */
struct
simple_obstack_stack
*
toplev_inline_obstacks
;
/* This is a list of function_maybepermanent_obstacks for inline functions
nested in the current function that were compiled in the middle of
compiling other functions. */
struct
simple_obstack_stack
*
inline_obstacks
;
/* The contents of the current function definition are allocated
/* The contents of the current function definition are allocated
in this obstack, and all are freed at the end of the function.
in this obstack, and all are freed at the end of the function.
For top-level functions, this is temporary_obstack.
For top-level functions, this is temporary_obstack.
...
@@ -315,12 +326,15 @@ gcc_obstack_init (obstack)
...
@@ -315,12 +326,15 @@ gcc_obstack_init (obstack)
}
}
/* Save all variables describing the current status into the structure *P.
/* Save all variables describing the current status into the structure *P.
This is used before starting a nested function. */
This is used before starting a nested function.
CONTEXT is the decl_function_context for the function we're about to
compile; if it isn't current_function_decl, we have to play some games. */
void
void
save_tree_status
(
p
,
toplevel
)
save_tree_status
(
p
,
context
)
struct
function
*
p
;
struct
function
*
p
;
int
toplevel
;
tree
context
;
{
{
p
->
all_types_permanent
=
all_types_permanent
;
p
->
all_types_permanent
=
all_types_permanent
;
p
->
momentary_stack
=
momentary_stack
;
p
->
momentary_stack
=
momentary_stack
;
...
@@ -333,16 +347,42 @@ save_tree_status (p, toplevel)
...
@@ -333,16 +347,42 @@ save_tree_status (p, toplevel)
p
->
expression_obstack
=
expression_obstack
;
p
->
expression_obstack
=
expression_obstack
;
p
->
saveable_obstack
=
saveable_obstack
;
p
->
saveable_obstack
=
saveable_obstack
;
p
->
rtl_obstack
=
rtl_obstack
;
p
->
rtl_obstack
=
rtl_obstack
;
p
->
inline_obstacks
=
inline_obstacks
;
if
(
!
toplevel
)
if
(
context
==
current_function_decl
)
/* Objects that need to be saved in this function can be in the nonsaved
obstack of the enclosing function since they can't possibly be needed
once it has returned. */
function_maybepermanent_obstack
=
function_obstack
;
else
{
{
/* Objects that need to be saved in this function can be in the nonsaved
/* We're compiling a function which isn't nested in the current
obstack of the enclosing function since they can't possibly be needed
function. We need to create a new maybepermanent_obstack for this
once it has returned. */
function, since it can't go onto any of the existing obstacks. */
function_maybepermanent_obstack
=
function_obstack
;
struct
simple_obstack_stack
**
head
;
maybepermanent_firstobj
struct
simple_obstack_stack
*
current
;
=
(
char
*
)
obstack_finish
(
function_maybepermanent_obstack
);
}
if
(
context
==
NULL_TREE
)
head
=
&
toplev_inline_obstacks
;
else
{
struct
function
*
f
=
find_function_data
(
context
);
head
=
&
f
->
inline_obstacks
;
}
current
=
((
struct
simple_obstack_stack
*
)
xmalloc
(
sizeof
(
struct
simple_obstack_stack
)));
current
->
obstack
=
(
struct
obstack
*
)
xmalloc
(
sizeof
(
struct
obstack
));
function_maybepermanent_obstack
=
current
->
obstack
;
gcc_obstack_init
(
function_maybepermanent_obstack
);
current
->
next
=
*
head
;
*
head
=
current
;
}
maybepermanent_firstobj
=
(
char
*
)
obstack_finish
(
function_maybepermanent_obstack
);
function_obstack
=
(
struct
obstack
*
)
xmalloc
(
sizeof
(
struct
obstack
));
function_obstack
=
(
struct
obstack
*
)
xmalloc
(
sizeof
(
struct
obstack
));
gcc_obstack_init
(
function_obstack
);
gcc_obstack_init
(
function_obstack
);
...
@@ -359,26 +399,22 @@ save_tree_status (p, toplevel)
...
@@ -359,26 +399,22 @@ save_tree_status (p, toplevel)
This is used after a nested function. */
This is used after a nested function. */
void
void
restore_tree_status
(
p
,
toplevel
)
restore_tree_status
(
p
)
struct
function
*
p
;
struct
function
*
p
;
int
toplevel
;
{
{
all_types_permanent
=
p
->
all_types_permanent
;
all_types_permanent
=
p
->
all_types_permanent
;
momentary_stack
=
p
->
momentary_stack
;
momentary_stack
=
p
->
momentary_stack
;
obstack_free
(
&
momentary_obstack
,
momentary_function_firstobj
);
obstack_free
(
&
momentary_obstack
,
momentary_function_firstobj
);
if
(
!
toplevel
)
/* Free saveable storage used by the function just compiled and not
{
saved.
/* Free saveable storage used by the function just compiled and not
saved.
CAUTION: This is in function_obstack of the containing function.
So we must be sure that we never allocate from that obstack during
CAUTION: This is in function_obstack of the containing function.
the compilation of a nested function if we expect it to survive
So we must be sure that we never allocate from that obstack during
past the nested function's end. */
the compilation of a nested function if we expect it to survive
obstack_free
(
function_maybepermanent_obstack
,
maybepermanent_firstobj
);
past the nested function's end. */
obstack_free
(
function_maybepermanent_obstack
,
maybepermanent_firstobj
);
}
obstack_free
(
function_obstack
,
0
);
obstack_free
(
function_obstack
,
0
);
free
(
function_obstack
);
free
(
function_obstack
);
...
@@ -392,6 +428,7 @@ restore_tree_status (p, toplevel)
...
@@ -392,6 +428,7 @@ restore_tree_status (p, toplevel)
expression_obstack
=
p
->
expression_obstack
;
expression_obstack
=
p
->
expression_obstack
;
saveable_obstack
=
p
->
saveable_obstack
;
saveable_obstack
=
p
->
saveable_obstack
;
rtl_obstack
=
p
->
rtl_obstack
;
rtl_obstack
=
p
->
rtl_obstack
;
inline_obstacks
=
p
->
inline_obstacks
;
}
}
/* Start allocating on the temporary (per function) obstack.
/* Start allocating on the temporary (per function) obstack.
...
@@ -408,6 +445,7 @@ temporary_allocation ()
...
@@ -408,6 +445,7 @@ temporary_allocation ()
expression_obstack
=
function_obstack
;
expression_obstack
=
function_obstack
;
rtl_obstack
=
saveable_obstack
=
function_maybepermanent_obstack
;
rtl_obstack
=
saveable_obstack
=
function_maybepermanent_obstack
;
momentary_stack
=
0
;
momentary_stack
=
0
;
inline_obstacks
=
0
;
}
}
/* Start allocating on the permanent obstack but don't
/* Start allocating on the permanent obstack but don't
...
@@ -535,6 +573,17 @@ permanent_allocation (function_end)
...
@@ -535,6 +573,17 @@ permanent_allocation (function_end)
obstack_free
(
function_maybepermanent_obstack
,
maybepermanent_firstobj
);
obstack_free
(
function_maybepermanent_obstack
,
maybepermanent_firstobj
);
obstack_free
(
&
temp_decl_obstack
,
temp_decl_firstobj
);
obstack_free
(
&
temp_decl_obstack
,
temp_decl_firstobj
);
/* Free up the maybepermanent_obstacks for any of our nested functions
which were compiled at a lower level. */
while
(
inline_obstacks
)
{
struct
simple_obstack_stack
*
current
=
inline_obstacks
;
inline_obstacks
=
current
->
next
;
obstack_free
(
current
->
obstack
,
0
);
free
(
current
->
obstack
);
free
(
current
);
}
current_obstack
=
&
permanent_obstack
;
current_obstack
=
&
permanent_obstack
;
expression_obstack
=
&
permanent_obstack
;
expression_obstack
=
&
permanent_obstack
;
rtl_obstack
=
saveable_obstack
=
&
permanent_obstack
;
rtl_obstack
=
saveable_obstack
=
&
permanent_obstack
;
...
...
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