* c-common.h (has_c_linkage): New interface.
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Jun 2004 08:34:54 +0000 (08:34 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 20 Jun 2004 08:34:54 +0000 (08:34 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83405 138bc75d-0d04-0410-961f-82ee72b054a4

27 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/builtins.c
gcc/c-common.h
gcc/c-cppbuiltin.c
gcc/c-decl.c
gcc/c-objc-common.c
gcc/c-pragma.c
gcc/cgraphunit.c
gcc/config/alpha/osf.h
gcc/config/sol2.h
gcc/cp/ChangeLog
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/method.c
gcc/cp/name-lookup.c
gcc/cp/typeck.c
gcc/doc/extend.texi
gcc/system.h
gcc/target-def.h
gcc/target.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/expr/enum1.C
gcc/testsuite/g++.dg/opt/const3.C
gcc/testsuite/g++.dg/other/pragma-re-1.C

index 50cc613..acb2bff 100644 (file)
@@ -1,3 +1,41 @@
+2004-06-20  Zack Weinberg  <zack@codesourcery.com>
+
+       * 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.
+
 2004-06-19  Roger Sayle  <roger@eyesopen.com>
 
        * builtins.c (fold_builtin_unordered_cmp): Take an EXP argument
 
 2004-06-18  Richard Henderson  <rth@redhat.com>
 
-       PR c++/16036 
+       PR c++/16036
        * gimple-low.c (lower_function_body): Generate return statement for
        fall off the end of the function here ...
        * tree-cfg.c (make_edges): ... instead of here.
        UTAG_RETHROWEXC_VAR, UTAG_EVALONCE_VAR, struct val_stack,
        catch_count_stack, exc_binding_stack, if_nesting_count,
        blk_nesting_count, objc_enter_block, objc_exit_block,
-       objc_declare_variable, val_stack_push, val_stack_pop, 
+       objc_declare_variable, val_stack_push, val_stack_pop,
        objc_build_try_enter_fragment, objc_build_extract_expr,
        objc_build_try_exit_fragment, objc_build_extract_fragment,
-       objc_build_try_prologue, objc_build_try_epilogue, 
+       objc_build_try_prologue, objc_build_try_epilogue,
        objc_build_catch_stmt, objc_build_catch_epilogue,
        objc_build_finally_prologue, objc_build_finally_epilogue,
        objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
        * tree-ssa-operands.h (struct def_optype_d):  Change underlying type.
        (struct use_optype_d):  Change underlying type.
        (def_operand_p, use_operand_p):  New types for pointers to operands.
-       (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP, 
+       (USE_OP, DEF_OP, V_MAY_DEF_RESULT, V_MAY_DEF_OP, VUSE_OP,
        V_MUST_DEF_OP):  Use new pointer type instead of dereferencing directly.
-       (USE_FROM_PTR, DEF_FROM_PTR):  New macros to "dereference" operand 
+       (USE_FROM_PTR, DEF_FROM_PTR):  New macros to "dereference" operand
        pointer types.
        (SET_USE, SET_DEF):  New macros to set operands from their pointer.
        (SET_USE_OP, SET_DEF_OP, SET_V_MAY_DEF_RESULT, SET_V_MAY_DEF_OP,
        * tree.h (duplicate_ssa_name): Declare.
 
 2004-06-17  David Ayers  <d.ayers@inode.at>
+
        * c-parse.in: Unify Objective-C token names.
 
 2004-06-17  Zack Weinberg  <zack@codesourcery.com>
index 75b3686..6c21b66 100644 (file)
@@ -1381,8 +1381,9 @@ c-aux-info.o : c-aux-info.c  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_
     $(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_H) coretypes.h $(TM_H)           \
                $< $(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 55619e1..0959b1f 100644 (file)
@@ -6202,9 +6202,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       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 b1c49b1..91a1886 100644 (file)
@@ -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);
 \f
 /* Switches common to the C front ends.  */
 
index b70653c..3f0f688 100644 (file)
@@ -32,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #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 ac8c5b7..cbf5795 100644 (file)
@@ -2382,7 +2382,6 @@ builtin_function (const char *name, tree type, int function_code,
   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 f1faeef..731e063 100644 (file)
@@ -314,3 +314,9 @@ c_objc_common_truthvalue_conversion (tree expr)
   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 31a17a1..93836ea 100644 (file)
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #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 ATTRIBUTE_UNUSED)
 }
 #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_reader *dummy ATTRIBUTE_UNUSED)
   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 *dummy ATTRIBUTE_UNUSED)
   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 *dummy ATTRIBUTE_UNUSED)
 tree
 maybe_apply_renaming_pragma (tree decl, tree asmname)
 {
-  tree oldname;
-
-  /* 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
+  tree *p, t;
+
+  /* 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] == '*')
+  /* 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 *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);
+      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 80fe8ce..67001f0 100644 (file)
@@ -804,7 +804,6 @@ cgraph_expand_function (struct cgraph_node *node)
     {
       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 f8b4eca..04b7bf1 100644 (file)
@@ -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 5dc489d..1ff6308 100644 (file)
@@ -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 73ead05..e3048d3 100644 (file)
@@ -1,3 +1,21 @@
+2004-06-20  Zack Weinberg  <zack@codesourcery.com>
+
+       * 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.
+
 2004-06-19  Richard Henderson  <rth@redhat.com>
 
        * cp-gimplify.c: Remove unnecessary prototypes.
@@ -15,7 +33,7 @@
        (finish_cond): Rewrite to handle template DECL_STMTs specially.
        Assume that non-template decls go land before the conditional.
        (simplify_loop_decl_cond): Likewise.
-       (begin_if_stmt, finish_if_stmt_cond, begin_while_stmt, 
+       (begin_if_stmt, finish_if_stmt_cond, begin_while_stmt,
        finish_while_stmt_cond, finish_for_init_stmt, finish_for_cond,
        begin_switch_stmt, finish_switch_cond): Update to match.
 
                * cp-tree.h: Fix typo.
 
                * cp-tree.h: Include cgraph.h
-               (DECL_NEEDED_P): Use cgraph_*node on the decl instead of 
+               (DECL_NEEDED_P): Use cgraph_*node on the decl instead of
                TREE_SYMBOL_REFERENCED on the DECL_ASSEMBLER_NAME of the decl.
 
 2004-06-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/15554
        * pt.c (tsubst_copy): Do not try to substitute for an enumeration
-       constant in a non-dependent context. 
-       
+       constant in a non-dependent context.
+
        PR c++/15057
        * except.c (build_throw): Ensure that temp_expr has been
        initialized.
        * decl2.c (maybe_emit_vtables): If TARGET_WEAK_NOT_IN_ARCHIVE_TOC
        is nonzero, and if we see a noninline definition of a key method,
        make the vtables nonweak.
-       
+
 2004-06-02  Matt Austern  <austern@apple.com>
 
        * cp-tree.h (instantiate_decl): new boolean parameter,
        change it to an implicit instantiation.
        (instantiate_pending_templates): Add new argument to instantiate_decl.
        * tree.c (cp_cannot_inline_tree_fn): Likewise.
-       
+
 2004-06-02  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * cp-tree.h: Fix typo.
index eb0e221..757ca08 100644 (file)
@@ -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 7a0c41d..1838c82 100644 (file)
@@ -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 b794b9e..dfdfe56 100644 (file)
@@ -1259,7 +1259,7 @@ duplicate_decls (tree newdecl, tree olddecl)
            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 olddecl)
             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 olddecl)
        {
          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 olddecl)
              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 tree_code operator_code, tree type)
   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 7e6e54e..e978a54 100644 (file)
@@ -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 364cc06..357ea86 100644 (file)
@@ -71,20 +71,6 @@ init_method (void)
 {
   init_mangle ();
 }
-
-\f
-/* 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);
-}
-
 \f
 /* Return a this or result adjusting thunk to FUNCTION.  THIS_ADJUSTING
    indicates whether it is a this or result adjusting thunk.
index 401f650..1b755c9 100644 (file)
@@ -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 bcdd316..9504083 100644 (file)
@@ -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 204c64b..6c8ea7d 100644 (file)
@@ -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, except that this pragma may appear
 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 d51c328..abbfb41 100644 (file)
@@ -579,7 +579,8 @@ extern int snprintf (char *, size_t, const char *, ...);
        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 40e9610..c537c9f 100644 (file)
@@ -381,6 +381,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    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, Boston, MA 02111-1307, USA.
   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 3b9af5d..902db41 100644 (file)
@@ -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 3061f06..3cee377 100644 (file)
@@ -1,6 +1,12 @@
+2004-06-20  Zack Weinberg  <zack@codesourcery.com>
+
+       * g++.dg/expr/enum1.C, g++.dg/opt/const3.C: Declare abort with
+       extern "C".
+       * g++.dg/other/pragma-re-1.C: Add comments.
+
 2004-06-19  Bud Davis  <bdavis9659@comcast.net>
-        PR gfortran/16080
+
+       PR gfortran/16080
        * gfortran.fortran-torture/execute/read_null_string.f90: New file.
 
 2004-06-19  Andrew Pinski  <pinskia@physics.uc.edu>
index df2a823..40dc5fa 100644 (file)
@@ -1,6 +1,6 @@
 // { dg-do run }
 
-void abort();
+extern "C" void abort();
 int main()
 {
     enum { shelf = 4 } t = shelf;
index a3539ab..c7c0a16 100644 (file)
@@ -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 ec567f9..b29ac99 100644 (file)
@@ -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;