This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(IMA repairs) Symbol-renaming pragma rewrite and a bunch of fallout
- From: Zack Weinberg <zack at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 20 Jun 2004 01:34:27 -0700
- Subject: (IMA repairs) Symbol-renaming pragma rewrite and a bunch of fallout
This patch is a revision of the patch I sent in last month to make
#pragma extern_prefix and #pragma redefine_extname play nicer both
with each other and with IMA. To refresh, this implements
substantially pickier semantics about what these #pragmas can and
cannot do; these are documented in the patch, and discussed in the
thread starting at <http://gcc.gnu.org/ml/gcc/2004-05/msg00983.html>.
I also converted the associated target macros to hooks, moved the
definitions of the associated "you can use this pragma" builtin macros
to c-cppbuiltin.c, and clarified the documentation.
This had a depressing amount of fallout; fortunately, almost all the
changes necessary on account of fallout are changes we wanted to make
anyway. For instance, I had to make the C++ front end substantially
lazier about instantiating DECL_RTL and DECL_ASSEMBLER_NAME, which
should speed the compiler up a smidge.
I'm not entirely happy with giving two decls the same uid in one place
in cp/decl.c, but it works, only happens under exotic conditions, and
is less invasive than any other alternative.
It is necessary not to clear DECL_ARGUMENTS after expanding a function
so that the C++ front end can correctly mangle its name later. (I'm
not sure precisely what the scenario was here, but it caused libstdc++
to be miscompiled. No, TYPE_ARG_TYPES is not sufficient - it might be
possible to change that later, but again, this is the least invasive
change. In any case, DECL_ARGUMENTS shouldn't be taking up significant
memory compared to function bodies.)
The change to builtins.c allows us to have a builtin whose sole
purpose is to annotate a C library routine with some attributes,
without needing to set its DECL_ASSEMBLER_NAME up front.
The change to config/sol2.h TRANSFER_FROM_TRAMPOLINE just silences an
obnoxious warning.
Bootstrapped i686-linux and sparc-solaris2.8. I do not have
alpha-osf4 systems to test on. This includes my modified version of
Andrew's fix for the bug that Rainer Orth found, though. I'm going to
go ahead and check this in; please let me know if there are problems.
zw
* c-common.h (has_c_linkage): New interface.
* c-cppbuiltin.c: Include target.h.
(c_cpp_builtins): Define __PRAGMA_REDEFINE_EXTNAME and
__PRAGMA_EXTERN_PREFIX when appropriate.
* c-pragma.c: Include target.h.
Document clarified semantics of symbol-renaming #pragmas.
(handle_pragma_redefine_extname, handle_pragma_extern_prefix)
(maybe_apply_renaming_pragma): Rewrite according to clarified
semantics. Always recognize, but do not necessarily execute.
(init_pragma): Unconditionally register symbol-renaming pragmas.
* system.h: Poison HANDLE_PRAGMA_REDEFINE_EXTNAME
and HANDLE_PRAGMA_EXTERN_PREFIX.
* target.h (struct gcc_target): Add handle_pragma_redefine_extname
and handle_pragma_extern_prefix flags.
* target-def.h: Add defaults for TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME
and TARGET_HANDLE_PRAGMA_EXTERN_PREFIX.
* Makefile.in (c-pragma.o, c-cppbuiltin.o): Update dependencies.
* config/sol2.h: Define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME,
not HANDLE_PRAGMA_REDEFINE_EXTNAME.
(TARGET_OS_CPP_BUILTINS): No need to define __PRAGMA_REDEFINE_EXTNAME.
(TRANSFER_FROM_TRAMPOLINE): Prototype mprotect.
* config/alpha/osf.h: Define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX,
not HANDLE_PRAGMA_EXTERN_PREFIX.
(TARGET_OS_CPP_BUILTINS): No need to define __PRAGMA_EXTERN_PREFIX.
* doc/extend.texi (Solaris Pragmas, Tru64 Pragmas): Combine
into one section "Symbol-Renaming Pragmas"; clarify; document
adjusted semantics.
* builtins.c (expand_builtin): Do not issue error for a builtin
with no special case code and no DECL_ASSEMBLER_NAME; just do the
library call.
* c-decl.c (builtin_function): Don't call make_decl_rtl.
* c-objc-common.c (has_c_linkage): Stub implementation.
* cgraphunit.c (cgraph_expand_function)
(cgraph_remove_unreachable_nodes): Don't clear DECL_ARGUMENTS.
cp:
* cp-lang.c (has_c_linkage): Implement.
* cp-tree.h (set_mangled_name_for_decl): Don't prototype.
* decl.c (duplicate_decls): Use COPY_DECL_RTL.
(builtin_function_1): Don't call make_decl_rtl.
(build_cp_library_fn): Don't call set_mangled_name_for_decl.
(grokvardecl): Don't call mangle_decl.
* except.c (nothrow_libfn_p): Look at DECL_NAME, not
DECL_ASSEMBLER_NAME.
* method.c (set_mangled_name_for_decl): Delete.
* name-lookup.c (pushdecl): When a local extern shadows a
file-scope declaration of the same object, give both DECLs the
same DECL_UID.
* typeck.c (cxx_mark_addressable): Don't set TREE_ADDRESSABLE
on DECL_ASSEMBLER_NAME.
testsuite:
* g++.dg/expr/enum1.C, g++.dg/opt/const3.C: Declare abort with
extern "C".
* g++.dg/other/pragma-re-1.C: Add comments.
===================================================================
Index: Makefile.in
--- Makefile.in 19 Jun 2004 15:33:05 -0000 1.1301
+++ Makefile.in 20 Jun 2004 07:58:18 -0000
@@ -1381,8 +1381,9 @@ c-aux-info.o : c-aux-info.c $(CONFIG_H)
$(C_TREE_H) $(FLAGS_H) toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(FLAGS_H) toplev.h $(C_COMMON_H) real.h
-c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
- function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
+c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(TREE_H) function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) \
+ $(C_COMMON_H) $(TARGET_H) gt-c-pragma.h
graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(FLAGS_H) output.h \
$(RTL_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
@@ -1424,8 +1425,8 @@ c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM
$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) version.h $(C_COMMON_H) c-pragma.h $(FLAGS_H) toplev.h langhooks.h \
- output.h except.h real.h $(TM_P_H)
+ $(TREE_H) version.h $(C_COMMON_H) c-pragma.h $(FLAGS_H) toplev.h \
+ langhooks.h output.h except.h real.h $(TARGET_H) $(TM_P_H)
# A file used by all variants of C and some other languages.
===================================================================
Index: builtins.c
--- builtins.c 20 Jun 2004 03:56:05 -0000 1.340
+++ builtins.c 20 Jun 2004 07:58:18 -0000
@@ -6202,9 +6202,7 @@ expand_builtin (tree exp, rtx target, rt
break;
default: /* just do library call, if unknown builtin */
- if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
- error ("built-in function `%s' not currently supported",
- IDENTIFIER_POINTER (DECL_NAME (fndecl)));
+ break;
}
/* The switch statement above can drop through to cause the function
===================================================================
Index: c-common.h
--- c-common.h 19 Jun 2004 19:34:20 -0000 1.238
+++ c-common.h 20 Jun 2004 07:58:18 -0000
@@ -303,6 +303,7 @@ extern int c_expand_decl (tree);
extern int field_decl_cmp (const void *, const void *);
extern void resort_sorted_fields (void *, void *, gt_pointer_operator,
void *);
+extern bool has_c_linkage (tree decl);
/* Switches common to the C front ends. */
===================================================================
Index: c-cppbuiltin.c
--- c-cppbuiltin.c 3 Jun 2004 18:48:22 -0000 1.20
+++ c-cppbuiltin.c 20 Jun 2004 07:58:18 -0000
@@ -32,6 +32,7 @@ Software Foundation, 59 Temple Place - S
#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
#include "toplev.h"
#include "tm_p.h" /* Target prototypes. */
+#include "target.h"
#ifndef TARGET_OS_CPP_BUILTINS
# define TARGET_OS_CPP_BUILTINS()
@@ -409,6 +410,13 @@ c_cpp_builtins (cpp_reader *pfile)
if (c_dialect_objc () && flag_next_runtime)
cpp_define (pfile, "__NEXT_RUNTIME__");
+ /* Show the availability of some target pragmas. */
+ if (flag_mudflap || targetm.handle_pragma_redefine_extname)
+ cpp_define (pfile, "__PRAGMA_REDEFINE_EXTNAME");
+
+ if (targetm.handle_pragma_extern_prefix)
+ cpp_define (pfile, "__PRAGMA_EXTERN_PREFIX");
+
/* A straightforward target hook doesn't work, because of problems
linking that hook's body when part of non-C front ends. */
# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
===================================================================
Index: c-decl.c
--- c-decl.c 18 Jun 2004 01:20:50 -0000 1.510
+++ c-decl.c 20 Jun 2004 07:58:19 -0000
@@ -2382,7 +2382,6 @@ builtin_function (const char *name, tree
DECL_FUNCTION_CODE (decl) = function_code;
if (library_name)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
- make_decl_rtl (decl, NULL);
/* Should never be called on a symbol with a preexisting meaning. */
if (I_SYMBOL_BINDING (id))
===================================================================
Index: c-objc-common.c
--- c-objc-common.c 16 Jun 2004 01:21:21 -0000 1.47
+++ c-objc-common.c 20 Jun 2004 07:58:19 -0000
@@ -314,3 +314,9 @@ c_objc_common_truthvalue_conversion (tre
return c_common_truthvalue_conversion (expr);
}
+/* In C and ObjC, all decls have "C" linkage. */
+bool
+has_c_linkage (tree decl ATTRIBUTE_UNUSED)
+{
+ return true;
+}
===================================================================
Index: c-pragma.c
--- c-pragma.c 13 May 2004 06:39:29 -0000 1.69
+++ c-pragma.c 20 Jun 2004 07:58:19 -0000
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - S
#include "c-common.h"
#include "output.h"
#include "tm_p.h"
+#include "target.h"
#define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
#define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
@@ -350,11 +351,43 @@ maybe_apply_pragma_weak (tree decl ATTRI
}
#endif /* HANDLE_PRAGMA_WEAK */
+/* GCC supports two #pragma directives for renaming the external
+ symbol associated with a declaration (DECL_ASSEMBLER_NAME), for
+ compatibility with the Solaris and Tru64 system headers. GCC also
+ has its own notation for this, __asm__("name") annotations.
+
+ Corner cases of these features and their interaction:
+
+ 1) Both pragmas silently apply only to declarations with external
+ linkage (that is, TREE_PUBLIC || DECL_EXTERNAL). Asm labels
+ do not have this restriction.
+
+ 2) In C++, both #pragmas silently apply only to extern "C" declarations.
+ Asm labels do not have this restriction.
+
+ 3) If any of the three ways of changing DECL_ASSEMBLER_NAME is
+ applied to a decl whose DECL_ASSEMBLER_NAME is already set, and the
+ new name is different, a warning issues and the name does not change.
+
+ 4) The "source name" for #pragma redefine_extname is the DECL_NAME,
+ *not* the DECL_ASSEMBLER_NAME.
+
+ 5) If #pragma extern_prefix is in effect and a declaration occurs
+ with an __asm__ name, the #pragma extern_prefix is silently
+ ignored for that declaration.
+
+ 6) If #pragma extern_prefix and #pragma redefine_extname apply to
+ the same declaration, whichever triggered first wins, and a warning
+ is issued. (We would like to have #pragma redefine_extname always
+ win, but it can appear either before or after the declaration, and
+ if it appears afterward, we have no way of knowing whether a modified
+ DECL_ASSEMBLER_NAME is due to #pragma extern_prefix.) */
+
static GTY(()) tree pending_redefine_extname;
static void handle_pragma_redefine_extname (cpp_reader *);
-/* #pragma redefined_extname oldname newname */
+/* #pragma redefine_extname oldname newname */
static void
handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
@@ -362,44 +395,67 @@ handle_pragma_redefine_extname (cpp_read
enum cpp_ttype t;
if (c_lex (&oldname) != CPP_NAME)
- {
- warning ("malformed #pragma redefine_extname, ignored");
- return;
- }
+ GCC_BAD ("malformed #pragma redefine_extname, ignored");
if (c_lex (&newname) != CPP_NAME)
- {
- warning ("malformed #pragma redefine_extname, ignored");
- return;
- }
+ GCC_BAD ("malformed #pragma redefine_extname, ignored");
t = c_lex (&x);
if (t != CPP_EOF)
warning ("junk at end of #pragma redefine_extname");
+ if (!flag_mudflap && !targetm.handle_pragma_redefine_extname)
+ {
+ if (warn_unknown_pragmas > in_system_header)
+ warning ("#pragma redefine_extname not supported on this target");
+ return;
+ }
+
decl = identifier_global_value (oldname);
- if (decl && (TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == VAR_DECL))
+ if (decl
+ && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
+ && (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL)
+ && has_c_linkage (decl))
{
- if (DECL_ASSEMBLER_NAME_SET_P (decl)
- && DECL_ASSEMBLER_NAME (decl) != newname)
- warning ("#pragma redefine_extname conflicts with declaration");
- change_decl_assembler_name (decl, newname);
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ name = targetm.strip_name_encoding (name);
+
+ if (strcmp (name, IDENTIFIER_POINTER (newname)))
+ warning ("#pragma redefine_extname ignored due to conflict with "
+ "previous rename");
+ }
+ else
+ change_decl_assembler_name (decl, newname);
}
else
- add_to_renaming_pragma_list(oldname, newname);
+ /* We have to add this to the rename list even if there's already
+ a global value that doesn't meet the above criteria, because in
+ C++ "struct foo {...};" puts "foo" in the current namespace but
+ does *not* conflict with a subsequent declaration of a function
+ or variable foo. See g++.dg/other/pragma-re-2.C. */
+ add_to_renaming_pragma_list (oldname, newname);
}
+/* This is called from here and from ia64.c. */
void
add_to_renaming_pragma_list (tree oldname, tree newname)
{
+ tree previous = purpose_member (oldname, pending_redefine_extname);
+ if (previous)
+ {
+ if (TREE_VALUE (previous) != newname)
+ warning ("#pragma redefine_extname ignored due to conflict with "
+ "previous #pragma redefine_extname");
+ return;
+ }
+
pending_redefine_extname
= tree_cons (oldname, newname, pending_redefine_extname);
}
static GTY(()) tree pragma_extern_prefix;
-#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
-static void handle_pragma_extern_prefix (cpp_reader *);
-
/* #pragma extern_prefix "prefix" */
static void
handle_pragma_extern_prefix (cpp_reader *dummy ATTRIBUTE_UNUSED)
@@ -408,18 +464,17 @@ handle_pragma_extern_prefix (cpp_reader
enum cpp_ttype t;
if (c_lex (&prefix) != CPP_STRING)
- {
- warning ("malformed #pragma extern_prefix, ignored");
- return;
- }
+ GCC_BAD ("malformed #pragma extern_prefix, ignored");
t = c_lex (&x);
if (t != CPP_EOF)
warning ("junk at end of #pragma extern_prefix");
- /* Note that the length includes the null terminator. */
- pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
+ if (targetm.handle_pragma_extern_prefix)
+ /* Note that the length includes the null terminator. */
+ pragma_extern_prefix = (TREE_STRING_LENGTH (prefix) > 1 ? prefix : NULL);
+ else if (warn_unknown_pragmas > in_system_header)
+ warning ("#pragma extern_prefix not supported on this target");
}
-#endif
/* Hook from the front ends to apply the results of one of the preceding
pragmas that rename variables. */
@@ -427,56 +482,88 @@ handle_pragma_extern_prefix (cpp_reader
tree
maybe_apply_renaming_pragma (tree decl, tree asmname)
{
- tree oldname;
+ tree *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
+ /* The renaming pragmas are only applied to declarations with
+ external linkage. */
+ if ((TREE_CODE (decl) != FUNCTION_DECL && TREE_CODE (decl) != VAR_DECL)
+ || (!TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl))
+ || !has_c_linkage (decl))
return asmname;
- /* If the name begins with a *, that's a sign of an asmname attached to
- a previous declaration. */
- if (IDENTIFIER_POINTER (oldname)[0] == '*')
- {
- const char *oldasmname = IDENTIFIER_POINTER (oldname) + 1;
- if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldasmname) != 0)
- warning ("asm declaration conflicts with previous rename");
- asmname = build_string (strlen (oldasmname), oldasmname);
+ /* If the DECL_ASSEMBLER_NAME is already set, it does not change,
+ but we may warn about a rename that conflicts. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ {
+ const char *oldname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ oldname = targetm.strip_name_encoding (oldname);
+
+ if (asmname && strcmp (TREE_STRING_POINTER (asmname), oldname))
+ warning ("asm declaration ignored due to "
+ "conflict with previous rename");
+
+ /* Take any pending redefine_extname off the list. */
+ for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
+ if (DECL_NAME (decl) == TREE_PURPOSE (t))
+ {
+ /* Only warn if there is a conflict. */
+ if (strcmp (IDENTIFIER_POINTER (TREE_VALUE (t)), oldname))
+ warning ("#pragma redefine_extname ignored due to "
+ "conflict with previous rename");
+
+ *p = TREE_CHAIN (t);
+ break;
+ }
+ return 0;
}
- {
- tree *p, t;
+ /* Find out if we have a pending #pragma redefine_extname. */
+ for (p = &pending_redefine_extname; (t = *p); p = &TREE_CHAIN (t))
+ if (DECL_NAME (decl) == TREE_PURPOSE (t))
+ {
+ tree newname = TREE_VALUE (t);
+ *p = TREE_CHAIN (t);
- 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 we already have an asmname, #pragma redefine_extname is
+ ignored (with a warning if it conflicts). */
+ if (asmname)
+ {
+ if (strcmp (TREE_STRING_POINTER (asmname),
+ IDENTIFIER_POINTER (newname)) != 0)
+ warning ("#pragma redefine_extname ignored due to "
+ "conflict with __asm__ declaration");
+ return asmname;
+ }
- if (asmname && strcmp (TREE_STRING_POINTER (asmname), newname) != 0)
- warning ("#pragma redefine_extname conflicts with declaration");
- *p = TREE_CHAIN (t);
+ /* Otherwise we use what we've got; #pragma extern_prefix is
+ silently ignored. */
+ return build_string (IDENTIFIER_LENGTH (newname),
+ IDENTIFIER_POINTER (newname));
+ }
- return build_string (strlen (newname), newname);
- }
- }
+ /* If we've got an asmname, #pragma extern_prefix is silently ignored. */
+ if (asmname)
+ return asmname;
-#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
- if (pragma_extern_prefix && !asmname)
+ /* If #pragma extern_prefix is in effect, apply it. */
+ if (pragma_extern_prefix)
{
- char *x = concat (TREE_STRING_POINTER (pragma_extern_prefix),
- IDENTIFIER_POINTER (oldname), NULL);
- asmname = build_string (strlen (x), x);
- free (x);
- return asmname;
+ const char *prefix = TREE_STRING_POINTER (pragma_extern_prefix);
+ size_t plen = TREE_STRING_LENGTH (pragma_extern_prefix) - 1;
+
+ const char *id = IDENTIFIER_POINTER (DECL_NAME (decl));
+ size_t ilen = IDENTIFIER_LENGTH (DECL_NAME (decl));
+
+ char *newname = alloca (plen + ilen + 1);
+
+ memcpy (newname, prefix, plen);
+ memcpy (newname + plen, id, ilen + 1);
+
+ return build_string (plen + ilen, newname);
}
-#endif
- return asmname;
+ /* Nada. */
+ return 0;
}
/* Front-end wrapper for pragma registration to avoid dragging
@@ -498,15 +585,9 @@ init_pragma (void)
#ifdef HANDLE_PRAGMA_WEAK
c_register_pragma (0, "weak", handle_pragma_weak);
#endif
-#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
+
c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
-#else
- if (flag_mudflap)
- c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
-#endif
-#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
-#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS ();
===================================================================
Index: cgraphunit.c
--- cgraphunit.c 6 Jun 2004 13:03:08 -0000 1.65
+++ cgraphunit.c 20 Jun 2004 07:58:19 -0000
@@ -804,7 +804,6 @@ cgraph_expand_function (struct cgraph_no
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
- DECL_ARGUMENTS (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node;
}
}
@@ -965,7 +964,6 @@ cgraph_remove_unreachable_nodes (void)
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
- DECL_ARGUMENTS (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node;
}
while (node->callees)
===================================================================
Index: system.h
--- system.h 12 Jun 2004 05:53:51 -0000 1.214
+++ system.h 20 Jun 2004 07:58:19 -0000
@@ -579,7 +579,8 @@ extern int snprintf (char *, size_t, con
STRUCT_VALUE_INCOMING STRICT_ARGUMENT_NAMING \
PROMOTE_FUNCTION_RETURN PROMOTE_PROTOTYPES STRUCT_VALUE_REGNUM \
SETUP_INCOMING_VARARGS EXPAND_BUILTIN_SAVEREGS \
- DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS
+ DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS \
+ HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
===================================================================
Index: target-def.h
--- target-def.h 9 Jun 2004 15:32:38 -0000 1.79
+++ target-def.h 20 Jun 2004 07:58:19 -0000
@@ -381,6 +381,15 @@ Foundation, 59 Temple Place - Suite 330,
TARGET_GIMPLIFY_VA_ARG_EXPR, \
}
+
+#ifndef TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME
+#define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME 0
+#endif
+
+#ifndef TARGET_HANDLE_PRAGMA_EXTERN_PREFIX
+#define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 0
+#endif
+
/* The whole shebang. */
#define TARGET_INITIALIZER \
{ \
@@ -433,6 +442,8 @@ Foundation, 59 Temple Place - Suite 330,
TARGET_TERMINATE_DW2_EH_FRAME_INFO, \
TARGET_ASM_FILE_START_APP_OFF, \
TARGET_ASM_FILE_START_FILE_DIRECTIVE, \
+ TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME, \
+ TARGET_HANDLE_PRAGMA_EXTERN_PREFIX, \
}
#include "hooks.h"
===================================================================
Index: target.h
--- target.h 10 Jun 2004 15:49:42 -0000 1.91
+++ target.h 20 Jun 2004 07:58:19 -0000
@@ -502,6 +502,12 @@ struct gcc_target
at the beginning of assembly output. */
bool file_start_file_directive;
+ /* True if #pragma redefine_extname is to be supported. */
+ bool handle_pragma_redefine_extname;
+
+ /* True if #pragma extern_prefix is to be supported. */
+ bool handle_pragma_extern_prefix;
+
/* Leave the boolean fields at the end. */
};
===================================================================
Index: config/sol2.h
--- config/sol2.h 31 May 2004 15:15:08 -0000 1.10
+++ config/sol2.h 20 Jun 2004 07:58:19 -0000
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA. */
#undef WINT_TYPE_SIZE
#define WINT_TYPE_SIZE BITS_PER_WORD
-#define HANDLE_PRAGMA_REDEFINE_EXTNAME 1
+#define TARGET_HANDLE_PRAGMA_REDEFINE_EXTNAME 1
/* ??? Note: in order for -compat-bsd to work fully,
we must somehow arrange to fixincludes /usr/ucbinclude
@@ -60,7 +60,6 @@ Boston, MA 02111-1307, USA. */
builtin_define_std ("sun"); \
builtin_define ("__svr4__"); \
builtin_define ("__SVR4"); \
- builtin_define ("__PRAGMA_REDEFINE_EXTNAME"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=svr4"); \
/* For C++ we need to add some additional macro \
@@ -196,6 +195,7 @@ extern void __enable_execute_stack (void
void \
__enable_execute_stack (void *addr) \
{ \
+ extern int mprotect(void *, size_t, int); \
if (!need_enable_exec_stack) \
return; \
else { \
===================================================================
Index: config/alpha/osf.h
--- config/alpha/osf.h 30 Apr 2004 20:09:51 -0000 1.36
+++ config/alpha/osf.h 20 Jun 2004 07:58:19 -0000
@@ -41,7 +41,6 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__digital__"); \
builtin_define ("__arch64__"); \
builtin_define ("_LONGLONG"); \
- builtin_define ("__PRAGMA_EXTERN_PREFIX"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=xpg4"); \
/* Tru64 UNIX V5 has a 16 byte long \
@@ -211,4 +210,4 @@ __enable_execute_stack (void *addr)
/* 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
+#define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 1
===================================================================
Index: cp/cp-lang.c
--- cp/cp-lang.c 16 Jun 2004 01:21:29 -0000 1.80
+++ cp/cp-lang.c 20 Jun 2004 07:58:19 -0000
@@ -353,3 +353,10 @@ void
pop_file_scope (void)
{
}
+
+/* c-pragma.c needs to query whether a decl has extern "C" linkage. */
+bool
+has_c_linkage (tree decl)
+{
+ return DECL_EXTERN_C_P (decl);
+}
===================================================================
Index: cp/cp-tree.h
--- cp/cp-tree.h 19 Jun 2004 19:34:22 -0000 1.980
+++ cp/cp-tree.h 20 Jun 2004 07:58:19 -0000
@@ -3855,7 +3855,6 @@ extern void cxx_finish (void);
/* in method.c */
extern void init_method (void);
-extern void set_mangled_name_for_decl (tree);
extern tree make_thunk (tree, bool, tree, tree);
extern void finish_thunk (tree);
extern void use_thunk (tree, bool);
===================================================================
Index: cp/decl.c
--- cp/decl.c 17 Jun 2004 01:24:03 -0000 1.1220
+++ cp/decl.c 20 Jun 2004 07:58:20 -0000
@@ -1259,7 +1259,7 @@ duplicate_decls (tree newdecl, tree oldd
return NULL_TREE;
/* Replace the old RTL to avoid problems with inlining. */
- SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
+ COPY_DECL_RTL (newdecl, olddecl);
}
/* Even if the types match, prefer the new declarations type
for anticipated built-ins, for exception lists, etc... */
@@ -1288,7 +1288,7 @@ duplicate_decls (tree newdecl, tree oldd
that all remnants of the builtin-ness of this function
will be banished. */
SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
- SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
+ COPY_DECL_RTL (newdecl, olddecl);
}
}
else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
@@ -1827,7 +1827,7 @@ duplicate_decls (tree newdecl, tree oldd
{
SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
COPY_DECL_ASSEMBLER_NAME (newdecl, olddecl);
- SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
+ COPY_DECL_RTL (newdecl, olddecl);
}
if (! types_match || new_defines_function)
{
@@ -1851,7 +1851,7 @@ duplicate_decls (tree newdecl, tree oldd
DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
/* If we're keeping the built-in definition, keep the rtl,
regardless of declaration matches. */
- SET_DECL_RTL (newdecl, DECL_RTL (olddecl));
+ COPY_DECL_RTL (olddecl, newdecl);
}
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
@@ -3183,7 +3183,6 @@ builtin_function_1 (const char* name,
function in the namespace. */
if (libname)
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
- make_decl_rtl (decl, NULL);
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
@@ -3271,7 +3270,6 @@ build_cp_library_fn (tree name, enum tre
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
SET_DECL_LANGUAGE (fn, lang_cplusplus);
- set_mangled_name_for_decl (fn);
return fn;
}
@@ -5829,12 +5827,6 @@ grokvardecl (tree type,
else
DECL_CONTEXT (decl) = scope;
- if (name && scope && current_lang_name != lang_name_c)
- /* We can't mangle lazily here because we don't have any
- way to recover whether or not a variable was `extern
- "C"' later. */
- mangle_decl (decl);
-
if (RIDBIT_SETP (RID_EXTERN, specbits))
{
DECL_THIS_EXTERN (decl) = 1;
===================================================================
Index: cp/except.c
--- cp/except.c 16 Jun 2004 01:21:30 -0000 1.169
+++ cp/except.c 20 Jun 2004 07:58:20 -0000
@@ -841,7 +841,10 @@ nothrow_libfn_p (tree fn)
/* Can't be a C library function. */
return 0;
- id = DECL_ASSEMBLER_NAME (fn);
+ /* Being a C library function, DECL_ASSEMBLER_NAME == DECL_NAME
+ unless the system headers are playing rename tricks, and if
+ they are, we don't want to be confused by them. */
+ id = DECL_NAME (fn);
return !!libc_name_p (IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
}
===================================================================
Index: cp/method.c
--- cp/method.c 16 Jun 2004 01:21:31 -0000 1.285
+++ cp/method.c 20 Jun 2004 07:58:20 -0000
@@ -71,20 +71,6 @@ init_method (void)
{
init_mangle ();
}
-
-
-/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
-
-void
-set_mangled_name_for_decl (tree decl)
-{
- if (processing_template_decl)
- /* There's no need to mangle the name of a template function. */
- return;
-
- mangle_decl (decl);
-}
-
/* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING
indicates whether it is a this or result adjusting thunk.
===================================================================
Index: cp/name-lookup.c
--- cp/name-lookup.c 16 Jun 2004 01:21:31 -0000 1.60
+++ cp/name-lookup.c 20 Jun 2004 07:58:21 -0000
@@ -677,9 +677,15 @@ pushdecl (tree x)
if (decls_match (x, t))
/* The standard only says that the local extern
inherits linkage from the previous decl; in
- particular, default args are not shared. It would
- be nice to propagate inlining info, though. FIXME. */
- TREE_PUBLIC (x) = TREE_PUBLIC (t);
+ particular, default args are not shared. We must
+ also tell cgraph to treat these decls as the same,
+ or we may neglect to emit an "unused" static - we
+ do this by making the DECL_UIDs equal, which should
+ be viewed as a kludge. FIXME. */
+ {
+ TREE_PUBLIC (x) = TREE_PUBLIC (t);
+ DECL_UID (x) = DECL_UID (t);
+ }
}
else if (TREE_CODE (t) == PARM_DECL)
{
===================================================================
Index: cp/typeck.c
--- cp/typeck.c 10 Jun 2004 14:26:17 -0000 1.549
+++ cp/typeck.c 20 Jun 2004 07:58:21 -0000
@@ -4318,7 +4318,6 @@ cxx_mark_addressable (tree exp)
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
return true;
case CONSTRUCTOR:
===================================================================
Index: doc/extend.texi
--- doc/extend.texi 9 Jun 2004 18:34:01 -0000 1.196
+++ doc/extend.texi 20 Jun 2004 07:58:22 -0000
@@ -7197,8 +7197,7 @@ for further explanation.
* ARM Pragmas::
* RS/6000 and PowerPC Pragmas::
* Darwin Pragmas::
-* Solaris Pragmas::
-* Tru64 Pragmas::
+* Symbol-Renaming Pragmas::
@end menu
@node ARM Pragmas
@@ -7282,45 +7281,68 @@ that of the @code{unused} attribute, exc
anywhere within the variables' scopes.
@end table
-@node Solaris Pragmas
-@subsection Solaris Pragmas
+@node Symbol-Renaming Pragmas
+@subsection Symbol-Renaming Pragmas
-For compatibility with the SunPRO compiler, the following pragma
-is supported.
+For compatibility with the Solaris and Tru64 UNIX system headers, GCC
+supports two @code{#pragma} directives which change the name used in
+assembly for a given declaration. These pragmas are only available on
+platforms whose system headers need them. To get this effect on all
+platforms supported by GCC, use the asm labels extension (@pxref{Asm
+Labels}).
@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.
+This pragma gives the C function @var{oldname} the assembly symbol
+@var{newname}. The preprocessor macro @code{__PRAGMA_REDEFINE_EXTNAME}
+will be defined if this pragma is available (currently only on
+Solaris).
-@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{__PRAGMA_EXTERN_PREFIX} if the pragma is
-available.
+This pragma causes all subsequent external function and variable
+declarations to have @var{string} prepended to their assembly symbols.
+This effect may be terminated with another @code{extern_prefix} pragma
+whose argument is an empty string. The preprocessor macro
+@code{__PRAGMA_EXTERN_PREFIX} will be defined if this pragma is
+available (currently only on Tru64 UNIX).
@end table
+These pragmas and the asm labels extension interact in a complicated
+manner. Here are some corner cases you may want to be aware of.
+
+@enumerate
+@item Both pragmas silently apply only to declarations with external
+linkage. Asm labels do not have this restriction.
+
+@item In C++, both pragmas silently apply only to declarations with
+``C'' linkage. Again, asm labels do not have this restriction.
+
+@item If any of the three ways of changing the assembly name of a
+declaration is applied to a declaration whose assembly name has
+already been determined (either by a previous use of one of these
+features, or because the compiler needed the assembly name in order to
+generate code), and the new name is different, a warning issues and
+the name does not change.
+
+@item The @var{oldname} used by @code{#pragma redefine_extname} is
+always the C-language name.
+
+@item If @code{#pragma extern_prefix} is in effect, and a declaration
+occurs with an asm label attached, the prefix is silently ignored for
+that declaration.
+
+@item If @code{#pragma extern_prefix} and @code{#pragma redefine_extname}
+apply to the same declaration, whichever triggered first wins, and a
+warning issues if they contradict each other. (We would like to have
+@code{#pragma redefine_extname} always win, for consistency with asm
+labels, but if @code{#pragma extern_prefix} triggers first we have no
+way of knowing that that happened.)
+@end enumerate
+
@node Unnamed Fields
@section Unnamed struct/union fields within structs/unions.
@cindex struct
===================================================================
Index: testsuite/g++.dg/expr/enum1.C
--- testsuite/g++.dg/expr/enum1.C 20 Aug 2003 07:06:46 -0000 1.1
+++ testsuite/g++.dg/expr/enum1.C 20 Jun 2004 07:58:22 -0000
@@ -1,6 +1,6 @@
// { dg-do run }
-void abort();
+extern "C" void abort();
int main()
{
enum { shelf = 4 } t = shelf;
===================================================================
Index: testsuite/g++.dg/opt/const3.C
--- testsuite/g++.dg/opt/const3.C 13 Nov 2003 09:48:36 -0000 1.1
+++ testsuite/g++.dg/opt/const3.C 20 Jun 2004 07:58:22 -0000
@@ -5,7 +5,7 @@
// { dg-do run }
// { dg-options "-O2" }
-extern void abort(void);
+extern "C" void abort(void);
typedef __SIZE_TYPE__ size_t;
===================================================================
Index: testsuite/g++.dg/other/pragma-re-1.C
--- testsuite/g++.dg/other/pragma-re-1.C 22 Mar 2002 22:51:47 -0000 1.2
+++ testsuite/g++.dg/other/pragma-re-1.C 20 Jun 2004 07:58:22 -0000
@@ -8,10 +8,13 @@
#error
#endif
+/* This one is expected to work. */
#pragma redefine_extname foo bar
extern "C" int foo(void);
void *p = (void *)foo;
+/* This one is expected not to work (redefine_extname
+ can only be applied to extern "C" names). */
#pragma redefine_extname baz baq
extern int baz(void);
void *q = (void *)baz;