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]
Other format: [Raw text]

[CFT] solaris and tru64 renaming pragmas


The following borrows heavily from Martin v. Loewis' work to
support the Solaris redefine_extname, but does it in a way
that does not touch anything but the C and C++ front ends.

As yet I've only tried it on the attached tests, but will
be starting a solaris bootstrap shortly.  I no longer have
access to tru64 machines, so I can't test that at all...


r~


	* c-pragma.c (maybe_apply_renaming_pragma): New.
	(handle_pragma_redefine_extname, pending_redefine_extname): New.
	(handle_pragma_extern_prefix, pragma_extern_prefix): New.
	(init_pragma): Register them.
	* c-pragma.h (maybe_apply_renaming_pragma): Declare.
	* c-decl.c (finish_decl): Call it.
	* cp/decl.c (cp_finish_decl): Likewise.
	* doc/extend.texi: Document the new pragmas.

	* config/alpha/osf.h (CPP_SUBTARGET_SPEC): Add __EXTERN_PREFIX.
	(HANDLE_PRAGMA_EXTERN_PREFIX): New.

	* config/i386/sol2.h (CPP_PREDEFINES): Add __PRAGMA_REDEFINE_EXTNAME.
	(HANDLE_PRAGMA_REDEFINE_EXTNAME): New.
	* config/sparc/sol2.h: Likewise.

	* g++.dg/other/pragma-ep-1.C: New.
	* g++.dg/other/pragma-re-1.C: New.
	* gcc.dg/pragma-ep-1.c, gcc.dg/pragma-ep-2.c: New.
	* gcc.dg/pragma-re-1.c, gcc.dg/pragma-re-2.c: New.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.306
diff -c -p -d -r1.306 c-decl.c
*** c-decl.c	2002/03/15 07:09:43	1.306
--- c-decl.c	2002/03/20 22:50:45
*************** finish_decl (decl, init, asmspec_tree)
*** 3453,3458 ****
--- 3453,3460 ----
    const char *asmspec = 0;
  
    /* If a name was specified, get the string.  */
+   if (current_binding_level == global_binding_level)
+     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
    if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.48
diff -c -p -d -r1.48 c-pragma.c
*** c-pragma.c	2002/03/15 07:09:53	1.48
--- c-pragma.c	2002/03/20 22:50:45
*************** maybe_apply_pragma_weak (decl)
*** 351,356 ****
--- 351,470 ----
  }
  #endif /* HANDLE_PRAGMA_WEAK */
  
+ #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+ static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
+ 
+ static tree pending_redefine_extname;
+ 
+ /* #pragma redefined_extname oldname newname */
+ static void
+ handle_pragma_redefine_extname (dummy)
+      cpp_reader *dummy ATTRIBUTE_UNUSED;
+ {
+   tree oldname, newname, decl, x;
+   enum cpp_ttype t;
+ 
+   if (c_lex (&oldname) != CPP_NAME)
+     {
+       warning ("malformed #pragma redefine_extname, ignored");
+       return;
+     }
+   if (c_lex (&newname) != CPP_NAME)
+     {
+       warning ("malformed #pragma redefine_extname, ignored");
+       return;
+     }
+   t = c_lex (&x);
+   if (t != CPP_EOF)
+     warning ("junk at end of #pragma redefine_extname");
+ 
+   decl = identifier_global_value (oldname);
+   if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+     {
+       if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ 	  && DECL_ASSEMBLER_NAME (decl) != newname)
+         warning ("#pragma redefine_extname conflicts with declaration");
+       SET_DECL_ASSEMBLER_NAME (decl, newname);
+     }
+   else
+     pending_redefine_extname
+       = tree_cons (oldname, newname, pending_redefine_extname);
+ }
+ #endif
+ 
+ #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+ static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
+ 
+ static tree pragma_extern_prefix;
+ 
+ /* #pragma extern_prefix "prefix" */
+ static void
+ handle_pragma_extern_prefix (dummy)
+      cpp_reader *dummy ATTRIBUTE_UNUSED;
+ {
+   tree prefix, x;
+   enum cpp_ttype t;
+ 
+   if (c_lex (&prefix) != CPP_STRING)
+     {
+       warning ("malformed #pragma extern_prefix, ignored");
+       return;
+     }
+   t = c_lex (&x);
+   if (t != CPP_EOF)
+     warning ("junk at end of #pragma extern_prefix");
+ 
+   pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 0 ? prefix : NULL);
+ }
+ #endif
+ 
+ /* Hook from the front ends to apply the results of one of the preceeding
+    pragmas that rename variables.  */
+ 
+ tree
+ maybe_apply_renaming_pragma (decl, asmname)
+      tree decl, asmname;
+ {
+   tree oldname, *p, t;
+ 
+   /* Copied from the check in set_decl_assembler_name.  */
+   if (TREE_CODE (decl) == FUNCTION_DECL
+       || (TREE_CODE (decl) == VAR_DECL 
+           && (TREE_STATIC (decl) 
+               || DECL_EXTERNAL (decl) 
+               || TREE_PUBLIC (decl))))
+     oldname = DECL_ASSEMBLER_NAME (decl);
+   else
+     return asmname;
+ 
+ #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+   for (p = &pending_redefine_extname; (t = *p) ; p = &TREE_CHAIN (t))
+     if (oldname == TREE_PURPOSE (t))
+       {
+ 	const char *newname = IDENTIFIER_POINTER (TREE_VALUE (t));
+ 
+ 	if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
+           warning ("#pragma redefine_extname conflicts with declaration");
+ 	*p = TREE_CHAIN (t);
+ 
+ 	return build_string (strlen (newname), newname);
+       }
+ #endif
+ 
+ #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+   if (pragma_extern_prefix && !asmname)
+     {
+       char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
+ 			IDENTIFIER_POINTER (oldname), NULL);
+       asmname = build_string (strlen (x), x);
+       free (x);
+       return asmname;
+     }
+ #endif
+ 
+   return asmname;
+ }
+ 
  void
  init_pragma ()
  {
*************** init_pragma ()
*** 361,366 ****
--- 475,491 ----
    cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
    ggc_add_tree_root (&pending_weaks, 1);
  #endif
+ #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+   cpp_register_pragma (parse_in, 0, "redefine_extname",
+ 		       handle_pragma_redefine_extname);
+   ggc_add_tree_root (&pending_redefine_extname, 1);
+ #endif
+ #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
+   cpp_register_pragma (parse_in, 0, "extern_prefix",
+ 		       handle_pragma_extern_prefix);
+   ggc_add_tree_root (&pragma_extern_prefix, 1);
+ #endif
+ 
  #ifdef REGISTER_TARGET_PRAGMAS
    REGISTER_TARGET_PRAGMAS (parse_in);
  #endif
Index: c-pragma.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.h,v
retrieving revision 1.28
diff -c -p -d -r1.28 c-pragma.h
*** c-pragma.h	2002/03/15 07:09:53	1.28
--- c-pragma.h	2002/03/20 22:50:45
*************** extern void cpp_register_pragma PARAMS (
*** 54,58 ****
--- 54,59 ----
  #endif
  
  extern void maybe_apply_pragma_weak PARAMS ((tree));
+ extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
  
  #endif /* GCC_C_PRAGMA_H */
Index: config/alpha/osf.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/osf.h,v
retrieving revision 1.22
diff -c -p -d -r1.22 osf.h
*** osf.h	2001/08/12 20:36:21	1.22
--- osf.h	2002/03/20 22:50:45
*************** Boston, MA 02111-1307, USA.  */
*** 47,53 ****
  
  #undef CPP_SUBTARGET_SPEC
  #define CPP_SUBTARGET_SPEC \
! "%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat)"
  
  /* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf.  */
  
--- 47,54 ----
  
  #undef CPP_SUBTARGET_SPEC
  #define CPP_SUBTARGET_SPEC \
! "%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4} %(cpp_xfloat) \
! -D__EXTERN_PREFIX"
  
  /* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf.  */
  
*************** __enable_execute_stack (addr)						\
*** 209,211 ****
--- 210,216 ----
  /* Handle #pragma weak and #pragma pack.  */
  #undef HANDLE_SYSV_PRAGMA
  #define HANDLE_SYSV_PRAGMA 1
+ 
+ /* Handle #pragma extern_prefix.  Technically only needed for Tru64 5.x,
+    but easier to manipulate preprocessor bits from here.  */
+ #define HANDLE_PRAGMA_EXTERN_PREFIX 1
Index: config/i386/sol2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/sol2.h,v
retrieving revision 1.20
diff -c -p -d -r1.20 sol2.h
*** sol2.h	2002/02/27 18:47:31	1.20
--- sol2.h	2002/03/20 22:50:45
*************** Boston, MA 02111-1307, USA.  */
*** 73,82 ****
  #undef	WINT_TYPE_SIZE
  #define	WINT_TYPE_SIZE BITS_PER_WORD
  
! /* Add "sun" to the list of symbols defined for SVR4.  */
  #undef CPP_PREDEFINES
  #define CPP_PREDEFINES \
!   "-Dunix -D__svr4__ -D__SVR4 -Dsun -Asystem=svr4"
  
  /* Solaris 2/Intel as chokes on #line directives.  */
  #undef CPP_SPEC
--- 73,83 ----
  #undef	WINT_TYPE_SIZE
  #define	WINT_TYPE_SIZE BITS_PER_WORD
  
! #define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
! 
  #undef CPP_PREDEFINES
  #define CPP_PREDEFINES \
!   "-Dunix -D__svr4__ -D__SVR4 -Dsun -D__PRAGMA_REDEFINE_EXTNAME -Asystem=svr4"
  
  /* Solaris 2/Intel as chokes on #line directives.  */
  #undef CPP_SPEC
Index: config/sparc/sol2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sol2.h,v
retrieving revision 1.38
diff -c -p -d -r1.38 sol2.h
*** sol2.h	2002/03/03 21:10:05	1.38
--- sol2.h	2002/03/20 22:50:45
*************** Boston, MA 02111-1307, USA.  */
*** 31,39 ****
  #undef	WINT_TYPE_SIZE
  #define	WINT_TYPE_SIZE BITS_PER_WORD
  
  #undef CPP_PREDEFINES
  #define CPP_PREDEFINES \
! "-Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 \
  -Asystem=unix -Asystem=svr4"
  
  #undef CPP_SUBTARGET_SPEC
--- 31,41 ----
  #undef	WINT_TYPE_SIZE
  #define	WINT_TYPE_SIZE BITS_PER_WORD
  
+ #define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
+ 
  #undef CPP_PREDEFINES
  #define CPP_PREDEFINES \
! "-Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME \
  -Asystem=unix -Asystem=svr4"
  
  #undef CPP_SUBTARGET_SPEC
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.878
diff -c -p -d -r1.878 decl.c
*** decl.c	2002/03/18 14:36:10	1.878
--- decl.c	2002/03/20 22:50:46
*************** cp_finish_decl (decl, init, asmspec_tree
*** 8071,8076 ****
--- 8071,8078 ----
      }
  
    /* If a name was specified, get the string.  */
+   if (current_binding_level == global_binding_level)
+     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
    if (asmspec_tree)
      asmspec = TREE_STRING_POINTER (asmspec_tree);
  
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.67
diff -c -p -d -r1.67 extend.texi
*** extend.texi	2002/03/03 05:20:02	1.67
--- extend.texi	2002/03/20 22:50:46
*************** for further explanation.
*** 5998,6003 ****
--- 5998,6005 ----
  @menu
  * ARM Pragmas::
  * Darwin Pragmas::
+ * Solaris Pragmas::
+ * Tru64 Pragmas::
  @end menu
  
  @node ARM Pragmas
*************** This pragma declares variables to be pos
*** 6060,6065 ****
--- 6062,6105 ----
  produce warnings for the listed variables.  The effect is similar to
  that of the @code{unused} attribute, except that this pragma may appear
  anywhere within the variables' scopes.
+ @end table
+ 
+ @node Solaris Pragmas
+ @subsection Solaris Pragmas
+ 
+ For compatibility with the SunPRO compiler, the following pragma
+ is supported.
+ 
+ @table @code
+ @item redefine_extname @var{oldname} @var{newname}
+ @cindex pragma, redefine_extname
+ 
+ This pragma gives the C function @var{oldname} the assembler label
+ @var{newname}.  The pragma must appear before the function declaration.
+ This pragma is equivalent to the asm labels extension (@pxref{Asm
+ Labels}).  The preprocessor defines @code{__PRAGMA_REDEFINE_EXTNAME}
+ if the pragma is available.
+ @end table
+ 
+ @node Tru64 Pragmas
+ @subsection Tru64 Pragmas
+ 
+ For compatibility with the Compaq C compiler, the following pragma
+ is supported.
+ 
+ @table @code
+ @item extern_prefix @var{string}
+ @cindex pragma, extern_prefix
+ 
+ This pragma renames all subsequent function and variable declarations
+ such that @var{string} is prepended to the name.  This effect may be
+ terminated by using another @code{extern_prefix} pragma with the 
+ empty string.
+ 
+ This pragma is similar in intent to to the asm labels extension
+ (@pxref{Asm Labels}) in that the system programmer wants to change
+ the assembly-level ABI without changing the source-level API.  The
+ preprocessor defines @code{__EXTERN_PREFIX} if the pragma is available.
  @end table
  
  @node Unnamed Fields
Index: testsuite/g++.dg/other/pragma-ep-1.C
===================================================================
RCS file: pragma-ep-1.C
diff -N pragma-ep-1.C
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-ep-1.C	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,27 ----
+ /* { dg-do compile { target *-*-osf5* } } */
+ /* { dg-final { scan-assembler "xyzzy_one" } } */
+ /* { dg-final { scan-assembler "xyzzy_two" } } */
+ /* { dg-final { scan-assembler "xyzzz_three" } } */
+ /* { dg-final { scan-assembler "four" } } */
+ /* { dg-final { scan-assembler-not "_four" } } */
+ 
+ #ifndef __EXTERN_PREFIX
+ #error
+ #endif
+ 
+ #pragma extern_prefix "xyzzy_"
+ 
+ extern "C" int one(void);
+ extern "C" int two(void);
+ 
+ #pragma extern_prefix "xyzzz_"
+ 
+ extern "C" int three(void);
+ 
+ #pragma extern_prefix ""
+ 
+ extern "C" int four(void);
+ 
+ void *p[] = {
+   (void *) one, (void *) two, (void *) three, (void *) four
+ };
Index: testsuite/g++.dg/other/pragma-re-1.C
===================================================================
RCS file: pragma-re-1.C
diff -N pragma-re-1.C
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-re-1.C	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile { target *-*-solaris* } } */
+ /* { dg-final { scan-assembler "bar" } } */
+ /* { dg-final { scan-assembler-not "foo" } } */
+ /* { dg-final { scan-assembler "_Z3bazv" } } */
+ /* { dg-final { scan-assembler-not "baq" } } */
+ 
+ #ifndef __PRAGMA_REDEFINE_EXTNAME
+ #error 
+ #endif
+ 
+ #pragma redefine_extname foo bar
+ extern "C" int foo(void);
+ void *p = (void *)foo;
+ 
+ #pragma redefine_extname baz baq
+ extern int baz(void);
+ void *q = (void *)baz;
Index: testsuite/gcc.dg/pragma-ep-1.c
===================================================================
RCS file: pragma-ep-1.c
diff -N pragma-ep-1.c
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-ep-1.c	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,27 ----
+ /* { dg-do compile { target *-*-osf5* } } */
+ /* { dg-final { scan-assembler "xyzzy_one" } } */
+ /* { dg-final { scan-assembler "xyzzy_two" } } */
+ /* { dg-final { scan-assembler "xyzzz_three" } } */
+ /* { dg-final { scan-assembler "four" } } */
+ /* { dg-final { scan-assembler-not "_four" } } */
+ 
+ #ifndef __EXTERN_PREFIX
+ #error
+ #endif
+ 
+ #pragma extern_prefix "xyzzy_"
+ 
+ extern int one(void);
+ extern int two(void);
+ 
+ #pragma extern_prefix "xyzzz_"
+ 
+ extern int three(void);
+ 
+ #pragma extern_prefix ""
+ 
+ extern int four(void);
+ 
+ void *p[] = {
+   one, two, three, four
+ };
Index: testsuite/gcc.dg/pragma-ep-2.c
===================================================================
RCS file: pragma-ep-2.c
diff -N pragma-ep-2.c
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-ep-2.c	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,5 ----
+ /* { dg-do compile { target *-*-osf5* } } */
+ 
+ #pragma extern_prefix			/* { dg-warning "malformed" } */
+ #pragma extern_prefix foo		/* { dg-warning "malformed" } */
+ #pragma extern_prefix "foo" 1		/* { dg-warning "junk" } */
Index: testsuite/gcc.dg/pragma-re-1.c
===================================================================
RCS file: pragma-re-1.c
diff -N pragma-re-1.c
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-re-1.c	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile { target *-*-solaris* } } */
+ /* { dg-final { scan-assembler "bar" } } */
+ /* { dg-final { scan-assembler-not "foo" } } */
+ 
+ #ifndef __PRAGMA_REDEFINE_EXTNAME
+ #error 
+ #endif
+ 
+ #pragma redefine_extname foo bar
+ extern int foo(void);
+ void *p = (void *)foo;
Index: testsuite/gcc.dg/pragma-re-2.c
===================================================================
RCS file: pragma-re-2.c
diff -N pragma-re-2.c
*** /dev/null	Tue May  5 13:32:27 1998
--- pragma-re-2.c	Wed Mar 20 14:50:46 2002
***************
*** 0 ****
--- 1,6 ----
+ /* { dg-do compile { target *-*-solaris* } } */
+ 
+ #pragma redefine_extname		/* { dg-warning "malformed" } */
+ #pragma redefine_extname foo		/* { dg-warning "malformed" } */
+ #pragma redefine_extname foo 1		/* { dg-warning "malformed" } */
+ #pragma redefine_extname foo bar 2	/* { dg-warning "junk" } */


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