[cd]tor collection from c

Richard Henderson rth@cygnus.com
Tue Nov 7 17:33:00 GMT 2000


This has been broken since the functions-as-trees conversion.
Current code would emit rtl instead of building trees, which
would get thrown away when we expanded the still null functions.

Tested on alpha-osf4.


r~


        * c-lang.c (start_cdtor, finish_cdtor): New functions.
        (finish_file): Use them in building constructor/destructor functions.

        * config/alpha/alpha.h (HAS_INIT_SECTION, LD_INIT_SWITCH,
        LD_FINI_SWITCH): Move ...
        * config/alpha/osf.h: ... here.
        * config/alpha/alpha-interix.h: Don't undef them.

Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
retrieving revision 1.34
diff -c -p -d -r1.34 c-lang.c
*** c-lang.c	2000/10/18 05:45:35	1.34
--- c-lang.c	2000/11/08 01:27:07
*************** lookup_objc_ivar (id)
*** 183,245 ****
    return 0;
  }
  
  /* Called at end of parsing, but before end-of-file processing.  */
  
  void
  finish_file ()
  {
  #ifndef ASM_OUTPUT_CONSTRUCTOR
-   extern tree static_ctors;
- #endif
- #ifndef ASM_OUTPUT_DESTRUCTOR
-   extern tree static_dtors;
- #endif
-   extern tree build_function_call                 PARAMS ((tree, tree));
- #if !defined(ASM_OUTPUT_CONSTRUCTOR) || !defined(ASM_OUTPUT_DESTRUCTOR)
-   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
- #endif
- #ifndef ASM_OUTPUT_CONSTRUCTOR
    if (static_ctors)
      {
!       tree fnname = get_file_function_name ('I');
!       start_function (void_list_node_1,
! 		      build_parse_node (CALL_EXPR, fnname, 
! 					tree_cons (NULL_TREE, NULL_TREE, 
! 						   void_list_node_1),
! 					NULL_TREE),
! 		      NULL_TREE, NULL_TREE);
!       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_1,
! 		      build_parse_node (CALL_EXPR, fnname, 
! 					tree_cons (NULL_TREE, NULL_TREE,
! 						   void_list_node_1),
! 					NULL_TREE),
! 		      NULL_TREE, NULL_TREE);
!       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
    
--- 183,268 ----
    return 0;
  }
  
+ #if !defined(ASM_OUTPUT_CONSTRUCTOR) || !defined(ASM_OUTPUT_DESTRUCTOR)
+ extern tree static_ctors;
+ extern tree static_dtors;
+ 
+ static tree start_cdtor		PARAMS ((int));
+ static void finish_cdtor	PARAMS ((tree));
+ 
+ static tree
+ start_cdtor (method_type)
+      int method_type;
+ {
+   tree fnname = get_file_function_name (method_type);
+   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
+   tree body;
+ 
+   start_function (void_list_node_1,
+ 		  build_parse_node (CALL_EXPR, fnname, 
+ 				    tree_cons (NULL_TREE, NULL_TREE, 
+ 					       void_list_node_1),
+ 				    NULL_TREE),
+ 		  NULL_TREE, NULL_TREE);
+   store_parm_decls ();
+ 
+   current_function_cannot_inline
+     = "static constructors and destructors cannot be inlined";
+ 
+   body = c_begin_compound_stmt ();
+ 
+   pushlevel (0);
+   clear_last_expr ();
+   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+ 
+   return body;
+ }
+ 
+ static void
+ finish_cdtor (body)
+      tree body;
+ {
+   tree scope;
+   tree block;
+ 
+   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+   block = poplevel (0, 0, 0); 
+   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
+   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
+ 
+   RECHAIN_STMTS (body, COMPOUND_BODY (body)); 
+ 
+   finish_function (0);
+ }
+ #endif
+ 
  /* Called at end of parsing, but before end-of-file processing.  */
  
  void
  finish_file ()
  {
  #ifndef ASM_OUTPUT_CONSTRUCTOR
    if (static_ctors)
      {
!       tree body = start_cdtor ('I');
  
        for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
! 	c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
! 						 NULL_TREE));
  
!       finish_cdtor (body);
      }
  #endif
  #ifndef ASM_OUTPUT_DESTRUCTOR
    if (static_dtors)
      {
!       tree body = start_cdtor ('D');
  
        for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
! 	c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
! 						 NULL_TREE));
  
!       finish_cdtor (body);
      }
  #endif
    
Index: config/alpha/alpha-interix.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/alpha-interix.h,v
retrieving revision 1.8
diff -c -p -d -r1.8 alpha-interix.h
*** alpha-interix.h	2000/11/02 23:29:08	1.8
--- alpha-interix.h	2000/11/08 01:27:07
*************** Boston, MA 02111-1307, USA.  */
*** 62,73 ****
  #undef PUT_SDB_BLOCK_START
  #undef PUT_SDB_BLOCK_END
  
- /* the following are OSF linker (not gld) specific... we don't want them */
- #undef HAS_INIT_SECTION
- #undef LD_INIT_SWITCH
- #undef LD_FINI_SWITCH
- 
- 
  /* The following are needed for C++, but also needed for profiling */
  
  /* Support const sections and the ctors and dtors sections for g++.
--- 62,67 ----
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/alpha.h,v
retrieving revision 1.110
diff -c -p -d -r1.110 alpha.h
*** alpha.h	2000/11/02 23:29:08	1.110
--- alpha.h	2000/11/08 01:27:07
*************** do {							\
*** 2525,2535 ****
  
  #define ALIGN_SYMTABLE_OFFSET(OFFSET) (((OFFSET) + 7) & ~7)
  
- /* The linker will stick __main into the .init section.  */
- #define HAS_INIT_SECTION
- #define LD_INIT_SWITCH "-init"
- #define LD_FINI_SWITCH "-fini"
- 
  /* The system headers under Alpha systems are generally C++-aware.  */
  #define NO_IMPLICIT_EXTERN_C
  
--- 2525,2530 ----
Index: config/alpha/osf.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/alpha/osf.h,v
retrieving revision 1.12
diff -c -p -d -r1.12 osf.h
*** osf.h	2000/11/02 23:29:08	1.12
--- osf.h	2000/11/08 01:27:07
*************** __enable_execute_stack (addr)						\
*** 144,146 ****
--- 144,151 ----
  /* Digital UNIX V4.0E (1091)/usr/include/sys/types.h 4.3.49.9 1997/08/14 */
  #define SIZE_TYPE	"long unsigned int"
  #define PTRDIFF_TYPE	"long int"
+ 
+ /* The linker will stick __main into the .init section.  */
+ #define HAS_INIT_SECTION
+ #define LD_INIT_SWITCH "-init"
+ #define LD_FINI_SWITCH "-fini"


More information about the Gcc-patches mailing list