pragma redefine_extname, v3
Martin v. Loewis
martin@v.loewis.de
Sun Feb 3 18:35:00 GMT 2002
Attached is revision 3 of the redefine_extname patch. The following
changes were implemented:
- correct commentary, and
- enable the feature on Solaris only.
Regards,
Martin
2002-02-03 Martin v. Löwis <loewis@informatik.hu-berlin.de>
* c-decl.c (finish_decl): Look for external name.
(c_handle_pragma_extname): New function.
* c-lang.c (LANG_HOOKS_HANDLE_PRAGMA_EXTNAME): Redefine.
* c-pragma.c (langhooks.h): Include.
(handle_pragma_redefine_extname): New function.
(init_pragma): Register it.
* c-pragma.h (HANDLE_PRAGMA_REDEFINE_EXTNAME): Define.
* c-tree.h (c_handle_pragma_extname): Declare.
* langhooks-def.h (LANG_HOOKS_HANDLE_PRAGMA_EXTNAME): Define.
* langhooks.h (struct lang_hooks): Add handle_pragma_extname.
* tree.c (struct extname, EXTNAME_HASH_INITIAL_SIZE,
extname_hash_table): Define.
(add_external_name, find_external_name, extname_eq,
extname_hash): New functions.
(init_obstacks): Create extname_hash_table.
* tree.h (add_external_name, find_external_name): Declare.
* config/sparc/sol2.h (HANDLE_PRAGMA_REDEFINE_EXTNAME): Define.
(CPP_PREDEFINES): Add __PRAGMA_REDEFINE_EXTNAME.
* config/i386/sol2.h: Likewise.
* cp/lang.c (LANG_HOOKS_HANDLE_PRAGMA_EXTNAME): Redefine.
* cp/tree.h (cp_handle_pragma_extname): Declare.
* cp/decl.c (cp_finish_decl): Look for external name.
(cp_handle_pragma_extname): New function.
* doc/extend.texi: Document pragma redefine_extname.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-decl.c,v
retrieving revision 1.294
diff -u -r1.294 c-decl.c
--- c-decl.c 2002/02/02 00:14:31 1.294
+++ c-decl.c 2002/02/03 12:09:20
@@ -3593,11 +3593,24 @@
tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
const char *asmspec = 0;
+ tree extname;
/* If a name was specified, get the string. */
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
+ if (!DECL_CONTEXT (decl))
+ {
+ extname = find_external_name (DECL_NAME (decl));
+ if (extname)
+ {
+ if (asmspec_tree)
+ error_with_decl (decl, "'%s' has both extname and asm spec.");
+ else
+ asmspec = IDENTIFIER_POINTER (extname);
+ }
+ }
+
/* If `start_decl' didn't like having an initialization, ignore it now. */
if (init != 0 && DECL_INITIAL (decl) == 0)
init = 0;
@@ -7434,4 +7447,24 @@
{
tree t = build_tree_list (NULL_TREE, void_type_node);
return t;
+}
+
+/* Handle #pragma redefine_extname. */
+void
+c_handle_pragma_extname (old, new)
+ tree old, new;
+{
+ tree decl = IDENTIFIER_GLOBAL_VALUE (old);
+ if (decl)
+ {
+ /* If DECL_ASSEMBLER_NAME has been used already, it will be equal to the
+ decl_name. Unfortunately, we cannot test whether it was used to emit
+ code already. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && DECL_ASSEMBLER_NAME (decl) != new
+ && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
+ warning ("#pragma redefine_extname conflicts with declaration");
+ SET_DECL_ASSEMBLER_NAME (decl, new);
+ }
+ add_external_name (old, new);
}
Index: c-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-lang.c,v
retrieving revision 1.74
diff -u -r1.74 c-lang.c
--- c-lang.c 2001/12/17 22:43:40 1.74
+++ c-lang.c 2002/02/03 12:09:20
@@ -65,6 +65,8 @@
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
anon_aggr_type_p
+#undef LANG_HOOKS_HANDLE_PRAGMA_EXTNAME
+#define LANG_HOOKS_HANDLE_PRAGMA_EXTNAME c_handle_pragma_extname
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-pragma.c,v
retrieving revision 1.46
diff -u -r1.46 c-pragma.c
--- c-pragma.c 2001/11/13 03:20:58 1.46
+++ c-pragma.c 2002/02/03 12:09:20
@@ -32,6 +32,7 @@
#include "c-lex.h"
#include "output.h"
#include "tm_p.h"
+#include "langhooks.h"
#define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
#define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
@@ -302,6 +303,37 @@
}
#endif
+#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
+
+static void
+handle_pragma_redefine_extname (dummy)
+ cpp_reader *dummy ATTRIBUTE_UNUSED;
+{
+ tree oldname, newname, 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");
+
+ if (lang_hooks.handle_pragma_extname)
+ lang_hooks.handle_pragma_extname (oldname, newname);
+ else
+ warning ("pragma redefine_extname not supported");
+}
+#endif
+
void
init_pragma ()
{
@@ -310,6 +342,9 @@
#endif
#ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
+#endif
+#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+ cpp_register_pragma (parse_in, 0, "redefine_extname", handle_pragma_redefine_extname);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-tree.h,v
retrieving revision 1.80
diff -u -r1.80 c-tree.h
--- c-tree.h 2002/01/11 11:31:03 1.80
+++ c-tree.h 2002/02/03 12:09:20
@@ -214,6 +214,7 @@
extern tree c_begin_compound_stmt PARAMS ((void));
extern void c_expand_deferred_function PARAMS ((tree));
extern void c_expand_decl_stmt PARAMS ((tree));
+extern void c_handle_pragma_extname PARAMS ((tree, tree));
/* in c-objc-common.c */
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks-def.h,v
retrieving revision 1.8
diff -u -r1.8 langhooks-def.h
--- langhooks-def.h 2001/12/05 23:48:10 1.8
+++ langhooks-def.h 2002/02/03 12:09:21
@@ -82,6 +82,7 @@
#define LANG_HOOKS_PRINT_TYPE lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_IDENTIFIER lhd_print_tree_nothing
#define LANG_HOOKS_SET_YYDEBUG lhd_set_yydebug
+#define LANG_HOOKS_HANDLE_PRAGMA_EXTNAME 0
/* Tree inlining hooks. */
#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES lhd_tree_inlining_walk_subtrees
@@ -151,7 +152,8 @@
LANG_HOOKS_PRINT_IDENTIFIER, \
LANG_HOOKS_SET_YYDEBUG, \
LANG_HOOKS_TREE_INLINING_INITIALIZER, \
- LANG_HOOKS_TREE_DUMP_INITIALIZER \
+ LANG_HOOKS_TREE_DUMP_INITIALIZER, \
+ LANG_HOOKS_HANDLE_PRAGMA_EXTNAME \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/langhooks.h,v
retrieving revision 1.15
diff -u -r1.15 langhooks.h
--- langhooks.h 2001/12/05 23:48:10 1.15
+++ langhooks.h 2002/02/03 12:09:21
@@ -154,6 +154,9 @@
struct lang_hooks_for_tree_dump tree_dump;
+ /* Process a #pragma redefine_extname directive. */
+ void (*handle_pragma_extname) PARAMS((tree, tree));
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.236
diff -u -r1.236 tree.c
--- tree.c 2002/02/02 00:14:30 1.236
+++ tree.c 2002/02/03 12:09:23
@@ -167,6 +167,20 @@
static void type_hash_mark PARAMS ((const void *));
static int mark_tree_hashtable_entry PARAMS((void **, void *));
+/* Hashtable for external names. */
+
+struct extname
+{
+ tree ident;
+ tree extname;
+};
+
+#define EXTNAME_HASH_INITIAL_SIZE 50
+htab_t extname_hash_table;
+
+static int extname_eq PARAMS ((const void*, const void*));
+static unsigned int extname_hash PARAMS ((const void*));
+
/* If non-null, these are language-specific helper functions for
unsave_expr_now. If present, LANG_UNSAVE is called before its
argument (an UNSAVE_EXPR) is to be unsaved, and all other
@@ -189,6 +203,38 @@
tree global_trees[TI_MAX];
tree integer_types[itk_none];
+/* Record the association between a name and an external name. */
+
+void
+add_external_name (old, new)
+ tree old, new;
+{
+ struct extname *h, in;
+ void **loc;
+ in.ident = old;
+ loc = htab_find_slot_with_hash (extname_hash_table, &in,
+ (hashval_t)old, INSERT);
+ h = xmalloc(sizeof(struct extname));
+ h->ident = old;
+ h->extname = new;
+ *(struct extname**)loc = h;
+}
+
+/* Find the external name, given the original name. */
+
+tree
+find_external_name (old)
+ tree old;
+{
+ struct extname in, *h;
+ in.ident = old;
+ h = (struct extname*)htab_find_with_hash (extname_hash_table, &in,
+ (hashval_t)old);
+ if (h)
+ return h->extname;
+ return NULL;
+}
+
/* Set the DECL_ASSEMBLER_NAME for DECL. */
void
set_decl_assembler_name (decl)
@@ -231,6 +277,11 @@
ggc_add_tree_root (global_trees, TI_MAX);
ggc_add_tree_root (integer_types, itk_none);
+ /* Initialize hash table of external names. */
+ extname_hash_table = htab_create (EXTNAME_HASH_INITIAL_SIZE,
+ extname_hash,
+ extname_eq, 0);
+
/* Set lang_set_decl_set_assembler_name to a default value. */
lang_set_decl_assembler_name = set_decl_assembler_name;
}
@@ -3342,6 +3393,24 @@
++i;
return i;
+}
+
+/* Returns the hash value of an identifier in the extname. */
+
+static unsigned int
+extname_hash (item)
+ const void *item;
+{
+ return (hashval_t)(((const struct extname *) item)->ident);
+}
+
+static int
+extname_eq (va, vb)
+ const void *va;
+ const void *vb;
+{
+ return ((const struct extname *)va)->ident
+ == ((const struct extname *)vb)->ident;
}
/* Nonzero if integer constants T1 and T2
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.303
diff -u -r1.303 tree.h
--- tree.h 2002/02/02 00:14:31 1.303
+++ tree.h 2002/02/03 12:09:25
@@ -2723,6 +2723,8 @@
extern tree get_callee_fndecl PARAMS ((tree));
extern void set_decl_assembler_name PARAMS ((tree));
extern int type_num_arguments PARAMS ((tree));
+extern void add_external_name PARAMS ((tree, tree));
+extern tree find_external_name PARAMS ((tree));
/* In stmt.c */
Index: config/i386/sol2.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/sol2.h,v
retrieving revision 1.19
diff -u -r1.19 sol2.h
--- config/i386/sol2.h 2002/01/27 04:18:10 1.19
+++ config/i386/sol2.h 2002/02/03 12:09:26
@@ -73,10 +73,12 @@
#undef WINT_TYPE_SIZE
#define WINT_TYPE_SIZE BITS_PER_WORD
+#define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
+
/* Add "sun" to the list of symbols defined for SVR4. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
- "-Dunix -D__svr4__ -D__SVR4 -Dsun -Asystem=svr4"
+ "-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/egcs/gcc/config/sparc/sol2.h,v
retrieving revision 1.34
diff -u -r1.34 sol2.h
--- config/sparc/sol2.h 2001/12/28 09:55:14 1.34
+++ config/sparc/sol2.h 2002/02/03 12:09:26
@@ -31,9 +31,11 @@
#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 \
+"-Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME\
-Asystem=unix -Asystem=svr4"
#undef CPP_SUBTARGET_SPEC
Index: cp/cp-lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-lang.c,v
retrieving revision 1.9
diff -u -r1.9 cp-lang.c
--- cp/cp-lang.c 2001/12/05 23:48:14 1.9
+++ cp/cp-lang.c 2002/02/03 12:09:26
@@ -91,6 +91,8 @@
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals
+#undef LANG_HOOKS_HANDLE_PRAGMA_EXTNAME
+#define LANG_HOOKS_HANDLE_PRAGMA_EXTNAME cp_handle_pragma_extname
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.677
diff -u -r1.677 cp-tree.h
--- cp/cp-tree.h 2002/02/01 19:32:46 1.677
+++ cp/cp-tree.h 2002/02/03 12:09:29
@@ -3781,6 +3781,7 @@
extern void register_dtor_fn PARAMS ((tree));
extern tmpl_spec_kind current_tmpl_spec_kind PARAMS ((int));
extern tree cp_fname_init PARAMS ((const char *));
+extern void cp_handle_pragma_extname PARAMS ((tree, tree));
/* in decl2.c */
extern void init_decl2 PARAMS ((void));
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.856
diff -u -r1.856 decl.c
--- cp/decl.c 2002/02/01 19:51:42 1.856
+++ cp/decl.c 2002/02/03 12:09:36
@@ -8055,6 +8055,7 @@
tree ttype = NULL_TREE;
const char *asmspec = NULL;
int was_readonly = 0;
+ tree extname;
if (! decl)
{
@@ -8067,6 +8068,19 @@
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
+ if (CP_DECL_CONTEXT (decl) == global_namespace
+ && DECL_LANGUAGE (decl) == lang_c)
+ {
+ extname = find_external_name (DECL_NAME (decl));
+ if (extname)
+ {
+ if (asmspec_tree)
+ error_with_decl (decl, "'%s' has both extname and asm spec.");
+ else
+ asmspec = IDENTIFIER_POINTER (extname);
+ }
+ }
+
if (init && TREE_CODE (init) == NAMESPACE_DECL)
{
error ("cannot initialize `%D' to namespace `%D'",
@@ -14775,4 +14789,50 @@
{
/* A missing noreturn is ok for the `main' function. */
return DECL_MAIN_P (decl);
+}
+
+/* Handle #pragma redefine_extname. */
+void
+cp_handle_pragma_extname (old, new)
+ tree old, new;
+{
+ tree decl = IDENTIFIER_GLOBAL_VALUE (old);
+ if (decl && TREE_CODE (decl) == OVERLOAD)
+ {
+ tree overload = decl;
+ decl = NULL;
+ for (; overload; overload = OVL_NEXT (overload))
+ if (DECL_LANGUAGE (OVL_CURRENT (overload)) == lang_c)
+ {
+ if (decl)
+ {
+ error ("Both '%D' and '%D' apply to extname",
+ decl, OVL_CURRENT (overload));
+ return;
+ }
+ else
+ decl = OVL_CURRENT (overload);
+ }
+ }
+
+ if (decl)
+ {
+ if (TREE_CODE (decl) != FUNCTION_DECL
+ && TREE_CODE (decl) != VAR_DECL)
+ error ("#pragma redefine_extname applied to '%D'", decl);
+ else
+ {
+ /* The compiler will access the assembler name immediately
+ after the declaration, so we cannot tell whether it
+ was a user-assigned name or a defaulted one. Therefore,
+ warn only if the names differ. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && DECL_ASSEMBLER_NAME (decl) != new
+ && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
+ warning ("#pragma redefine_extname conflicts with declaration");
+
+ SET_DECL_ASSEMBLER_NAME (decl, new);
+ }
+ }
+ add_external_name (old, new);
}
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/extend.texi,v
retrieving revision 1.59
diff -u -r1.59 extend.texi
--- doc/extend.texi 2002/01/28 20:07:00 1.59
+++ doc/extend.texi 2002/02/03 12:14:31
@@ -5740,6 +5740,7 @@
@menu
* ARM Pragmas::
* Darwin Pragmas::
+* Solaris Pragmas::
@end menu
@node ARM Pragmas
@@ -5802,6 +5803,23 @@
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 macro 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 Unnamed Fields
More information about the Gcc-patches
mailing list