This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[CFT] solaris and tru64 renaming pragmas
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: loewis at informatik dot hu-berlin dot de, ro at TechFak dot Uni-Bielefeld dot DE
- Date: Wed, 20 Mar 2002 15:04:22 -0800
- Subject: [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" } */