parent
34cd1bd74c
commit
2c5f4139a9
|
@ -271,6 +271,32 @@ decl_attributes (decl, attributes)
|
|||
else
|
||||
warning_with_decl (decl, "`transparent_union' attribute ignored");
|
||||
}
|
||||
else if (TREE_VALUE (a) == get_identifier ("constructor")
|
||||
|| TREE_VALUE (a) == get_identifier ("__constructor__"))
|
||||
{
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL
|
||||
|| TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
|
||||
|| decl_function_context (decl))
|
||||
{
|
||||
error_with_decl (decl,
|
||||
"`constructor' attribute meaningless for non-function %s");
|
||||
continue;
|
||||
}
|
||||
DECL_STATIC_CONSTRUCTOR (decl) = 1;
|
||||
}
|
||||
else if (TREE_VALUE (a) == get_identifier ("destructor")
|
||||
|| TREE_VALUE (a) == get_identifier ("__destructor__"))
|
||||
{
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL
|
||||
|| TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
|
||||
|| decl_function_context (decl))
|
||||
{
|
||||
error_with_decl (decl,
|
||||
"`destructor' attribute meaningless for non-function %s");
|
||||
continue;
|
||||
}
|
||||
DECL_STATIC_DESTRUCTOR (decl) = 1;
|
||||
}
|
||||
else if (TREE_CODE (name) != TREE_LIST)
|
||||
{
|
||||
#ifdef VALID_MACHINE_ATTRIBUTE
|
||||
|
|
29
gcc/c-decl.c
29
gcc/c-decl.c
|
@ -400,6 +400,10 @@ static int keep_next_if_subblocks;
|
|||
|
||||
static struct binding_level *label_level_chain;
|
||||
|
||||
/* Functions called automatically at the beginning and end of execution. */
|
||||
|
||||
tree static_ctors, static_dtors;
|
||||
|
||||
/* Forward declarations. */
|
||||
|
||||
static tree grokparms (), grokdeclarator ();
|
||||
|
@ -1744,6 +1748,12 @@ duplicate_decls (newdecl, olddecl)
|
|||
if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
|
||||
DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
|
||||
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL)
|
||||
{
|
||||
DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
|
||||
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
|
||||
}
|
||||
|
||||
pop_obstacks ();
|
||||
}
|
||||
/* If cannot merge, then use the new type and qualifiers,
|
||||
|
@ -6749,6 +6759,25 @@ finish_function (nested)
|
|||
DECL_ARGUMENTS (fndecl) = 0;
|
||||
}
|
||||
|
||||
if (DECL_STATIC_CONSTRUCTOR (fndecl))
|
||||
{
|
||||
#ifndef ASM_OUTPUT_CONSTRUCTOR
|
||||
if (! flag_gnu_linker)
|
||||
static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors);
|
||||
else
|
||||
#endif
|
||||
assemble_constructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
||||
}
|
||||
if (DECL_STATIC_DESTRUCTOR (fndecl))
|
||||
{
|
||||
#ifndef ASM_OUTPUT_DESTRUCTOR
|
||||
if (! flag_gnu_linker)
|
||||
static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors);
|
||||
else
|
||||
#endif
|
||||
assemble_destructor (IDENTIFIER_POINTER (DECL_NAME (fndecl)));
|
||||
}
|
||||
|
||||
if (! nested)
|
||||
{
|
||||
/* Let the error reporting routines know that we're outside a
|
||||
|
|
50
gcc/c-lang.c
50
gcc/c-lang.c
|
@ -127,3 +127,53 @@ GNU_xref_end ()
|
|||
{
|
||||
fatal ("GCC does not yet support XREF");
|
||||
}
|
||||
|
||||
/* called at end of parsing, but before end-of-file processing. */
|
||||
void
|
||||
finish_file ()
|
||||
{
|
||||
extern tree static_ctors, static_dtors;
|
||||
extern tree get_file_function_name ();
|
||||
extern tree build_function_call PROTO((tree, tree));
|
||||
tree void_list_node = build_tree_list (NULL_TREE, void_type_node);
|
||||
#ifndef ASM_OUTPUT_CONSTRUCTOR
|
||||
if (static_ctors)
|
||||
{
|
||||
tree fnname = get_file_function_name ('I');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname, void_list_node,
|
||||
NULL_TREE),
|
||||
0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_function (0);
|
||||
|
||||
assemble_constructor (IDENTIFIER_POINTER (fnname));
|
||||
}
|
||||
#endif
|
||||
#ifndef ASM_OUTPUT_DESTRUCTOR
|
||||
if (static_dtors)
|
||||
{
|
||||
tree fnname = get_file_function_name ('D');
|
||||
start_function (void_list_node,
|
||||
build_parse_node (CALL_EXPR, fnname, void_list_node,
|
||||
NULL_TREE),
|
||||
0);
|
||||
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
|
||||
store_parm_decls ();
|
||||
|
||||
for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
|
||||
expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
|
||||
NULL_TREE));
|
||||
|
||||
finish_function (0);
|
||||
|
||||
assemble_destructor (IDENTIFIER_POINTER (fnname));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -258,9 +258,7 @@ extern void yyprint ();
|
|||
program: /* empty */
|
||||
{ if (pedantic)
|
||||
pedwarn ("ANSI C forbids an empty source file");
|
||||
ifobjc
|
||||
objc_finish ();
|
||||
end ifobjc
|
||||
finish_file ();
|
||||
}
|
||||
| extdefs
|
||||
{
|
||||
|
@ -268,9 +266,7 @@ end ifobjc
|
|||
get us back to the global binding level. */
|
||||
while (! global_bindings_p ())
|
||||
poplevel (0, 0, 0);
|
||||
ifobjc
|
||||
objc_finish ();
|
||||
end ifobjc
|
||||
finish_file ();
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -537,7 +537,7 @@ objc_fatal ()
|
|||
}
|
||||
|
||||
void
|
||||
objc_finish ()
|
||||
finish_file ()
|
||||
{
|
||||
if (doing_objc_thang)
|
||||
finish_objc (); /* Objective-C finalization */
|
||||
|
|
|
@ -22,7 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
|
||||
/* used by yyparse */
|
||||
|
||||
void objc_finish PROTO((void));
|
||||
void finish_file PROTO((void));
|
||||
tree start_class PROTO((enum tree_code, tree, tree, tree));
|
||||
tree continue_class PROTO((tree));
|
||||
void finish_class PROTO((tree));
|
||||
|
|
|
@ -943,6 +943,11 @@ struct tree_type
|
|||
alternative would be passed. */
|
||||
#define DECL_TRANSPARENT_UNION(NODE) ((NODE)->decl.transparent_union)
|
||||
|
||||
/* Used in FUNCTION_DECLs to indicate that they should be run automatically
|
||||
at the beginning or end of execution. */
|
||||
#define DECL_STATIC_CONSTRUCTOR(NODE) ((NODE)->decl.static_ctor_flag)
|
||||
#define DECL_STATIC_DESTRUCTOR(NODE) ((NODE)->decl.static_dtor_flag)
|
||||
|
||||
/* Additional flags for language-specific uses. */
|
||||
#define DECL_LANG_FLAG_0(NODE) ((NODE)->decl.lang_flag_0)
|
||||
#define DECL_LANG_FLAG_1(NODE) ((NODE)->decl.lang_flag_1)
|
||||
|
@ -979,7 +984,9 @@ struct tree_decl
|
|||
unsigned common_flag : 1;
|
||||
unsigned defer_output : 1;
|
||||
unsigned transparent_union : 1;
|
||||
/* room for four more */
|
||||
unsigned static_ctor_flag : 1;
|
||||
unsigned static_dtor_flag : 1;
|
||||
/* room for two more */
|
||||
|
||||
unsigned lang_flag_0 : 1;
|
||||
unsigned lang_flag_1 : 1;
|
||||
|
|
Loading…
Reference in New Issue