This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Clean up unresolved class references in ObjC


For a very long time, objc-act.c has had several bits of raw assembly
language in it, left over from the days when NeXT was contributing
code into FSF GCC.  Anyway, this code inevitably broke when PIC was
introduced, and NeXT made a proper target macro to fix the problem.
This patch just brings the macro into FSF GCC, suitably modernized and
documented.  It only comes into play when -fnext-runtime, no effect
on GNU runtime.  Committed to mainline only.

Stan

2001-04-28  Stan Shebs  <shebs@apple.com>

        * objc/objc-act.c (handle_class_ref): Rewrite to flush target
        specific code and use new macro ASM_DECLARE_UNRESOLVED_REFERENCE.
        * config/darwin.h (ASM_DECLARE_UNRESOLVED_REFERENCE): Define.
        * tm.texi (ASM_DECLARE_UNRESOLVED_REFERENCE): Document.

Index: tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tm.texi,v
retrieving revision 1.183
diff -c -3 -p -r1.183 tm.texi
*** tm.texi	2001/04/28 11:35:04	1.183
--- tm.texi	2001/04/28 23:52:51
*************** in a category); and @var{sel_name} is th
*** 6270,6275 ****
--- 6270,6282 ----
  
  On systems where the assembler can handle quoted names, you can use this
  macro to provide more human-readable names.
+ 
+ @findex ASM_DECLARE_UNRESOLVED_REFERENCE
+ @item ASM_DECLARE_UNRESOLVED_REFERENCE (@var{stream}, @var{name})
+ A C statement (sans semicolon) to output to the stdio stream
+ @var{stream} commands to declare that the label @var{name} is an
+ unresolved Objective-C class reference.  This is only needed for targets
+ whose linkers have special support for NeXT-style runtimes.
  @end table
  
  @node Initialization
Index: config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 darwin.h
*** darwin.h	2001/04/28 22:18:06	1.2
--- darwin.h	2001/04/28 23:52:51
*************** void alias_section (name, alias)			\
*** 648,662 ****
      }									\
    while (0)
  
! #define DECLARE_UNRESOLVED_REFERENCE(NAME)				\
!     do { extern FILE* asm_out_file; 					\
! 	 if (asm_out_file) {						\
  	   if (flag_pic)						\
! 	     fprintf (asm_out_file, "\t.lazy_reference ");		\
  	   else								\
! 	     fprintf (asm_out_file, "\t.reference ");			\
! 	   assemble_name (asm_out_file, NAME);				\
! 	   fprintf (asm_out_file, "\n");				\
  	 }                                                              \
         } while (0)
  
--- 648,662 ----
      }									\
    while (0)
  
! #define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME)			\
!     do { 								\
! 	 if (FILE) {							\
  	   if (flag_pic)						\
! 	     fprintf (FILE, "\t.lazy_reference ");			\
  	   else								\
! 	     fprintf (FILE, "\t.reference ");				\
! 	   assemble_name (FILE, NAME);					\
! 	   fprintf (FILE, "\n");					\
  	 }                                                              \
         } while (0)
  
Index: objc/objc-act.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/objc/objc-act.c,v
retrieving revision 1.76
diff -c -3 -p -r1.76 objc-act.c
*** objc-act.c	2001/04/13 01:42:39	1.76
--- objc-act.c	2001/04/28 23:52:53
*************** handle_class_ref (chain)
*** 8355,8400 ****
       tree chain;
  {
    const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
!   if (! flag_next_runtime)
!     {
!       tree decl;
!       char *string = (char *) alloca (strlen (name) + 30);
!       tree exp;
  
!       sprintf (string, "%sobjc_class_name_%s",
! 	       (flag_next_runtime ? "." : "__"), name);
  
!       /* Make a decl for this name, so we can use its address in a tree.  */
!       decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
!       DECL_EXTERNAL (decl) = 1;
!       TREE_PUBLIC (decl) = 1;
  
!       pushdecl (decl);
!       rest_of_decl_compilation (decl, 0, 0, 0);
  
!       /* Make following constant read-only (why not)?  */
!       readonly_data_section ();
  
!       exp = build1 (ADDR_EXPR, string_type_node, decl);
  
!       /* Align the section properly.  */
!       assemble_constant_align (exp);
  
!       /* Inform the assembler about this new external thing.  */
!       assemble_external (decl);
  
!       /* Output a constant to reference this address.  */
!       output_constant (exp, int_size_in_bytes (string_type_node));
!     }
!   else
!     {
!       /* This overreliance on our assembler (i.e. lack of portability)
! 	 should be dealt with at some point.  The GNU strategy (above)
! 	 won't work either, but it is a start.  */
!       char *string = (char *) alloca (strlen (name) + 30);
!       sprintf (string, ".reference .objc_class_name_%s", name);
!       assemble_asm (my_build_string (strlen (string) + 1, string));
!     }
  }
  
  static void
--- 8355,8397 ----
       tree chain;
  {
    const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
!   char *string = (char *) alloca (strlen (name) + 30);
!   tree decl;
!   tree exp;
  
!   sprintf (string, "%sobjc_class_name_%s",
! 	   (flag_next_runtime ? "." : "__"), name);
  
! #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
!   if (flag_next_runtime)
!     {
!       ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
!       return;
!     }
! #endif
  
!   /* Make a decl for this name, so we can use its address in a tree.  */
!   decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
!   DECL_EXTERNAL (decl) = 1;
!   TREE_PUBLIC (decl) = 1;
  
!   pushdecl (decl);
!   rest_of_decl_compilation (decl, 0, 0, 0);
  
!   /* Make following constant read-only, but only for GNU runtime.  */
!   if (!flag_next_runtime)
!     readonly_data_section ();
  
!   exp = build1 (ADDR_EXPR, string_type_node, decl);
  
!   /* Align the section properly.  */
!   assemble_constant_align (exp);
  
!   /* Inform the assembler about this new external thing.  */
!   assemble_external (decl);
! 
!   /* Output a constant to reference this address.  */
!   output_constant (exp, int_size_in_bytes (string_type_node));
  }
  
  static void


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]