OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Dec 2003 11:57:30 +0000 (11:57 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 15 Dec 2003 11:57:30 +0000 (11:57 +0000)
PR c++/13241
C++ ABI change. Mangling of symbols in expressions.
* mangle.c (write_mangled_name): Add top_level flag. Rework for
nested and unnested mangling. Deal with abi version 1 and version
2 differences.
(write_expression): Adjust write_mangled_name call.
(mangle_decl_string): Use write_mangled_name for all non-type decls.
testsuite:
PR c++/13241
* g++.dg/abi/mangle18-1.C: New test.
* g++.dg/abi/mangle18-2.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/mangle18-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/mangle18-2.C [new file with mode: 0644]

index 732273e..5d70a54 100644 (file)
@@ -1,3 +1,13 @@
+2003-12-15  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/13241
+       C++ ABI change. Mangling of symbols in expressions.
+       * mangle.c (write_mangled_name): Add top_level flag. Rework for
+       nested and unnested mangling. Deal with abi version 1 and version
+       2 differences.
+       (write_expression): Adjust write_mangled_name call.
+       (mangle_decl_string): Use write_mangled_name for all non-type decls.
+
 2003-12-14  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/10779
index ff8e6ea..a20757e 100644 (file)
@@ -158,7 +158,7 @@ static void mangle_call_offset (const tree, const tree);
 
 /* Functions for emitting mangled representations of things.  */
 
-static void write_mangled_name (const tree);
+static void write_mangled_name (const tree, bool);
 static void write_encoding (const tree);
 static void write_name (tree, const int);
 static void write_unscoped_name (const tree);
@@ -602,27 +602,66 @@ find_substitution (tree node)
 }
 
 
-/*  <mangled-name>      ::= _Z <encoding>  */
+/* TOP_LEVEL is true, if this is being called at outermost level of
+  mangling. It should be false when mangling a decl appearing in an
+  expression within some other mangling.
+  
+  <mangled-name>      ::= _Z <encoding>  */
 
 static inline void
-write_mangled_name (const tree decl)
+write_mangled_name (const tree decl, bool top_level)
 {
   MANGLE_TRACE_TREE ("mangled-name", decl);
 
-  if (DECL_LANG_SPECIFIC (decl)
-      && DECL_EXTERN_C_FUNCTION_P (decl)
-      && ! DECL_OVERLOADED_OPERATOR_P (decl))
-    /* The standard notes:
-         "The <encoding> of an extern "C" function is treated like
-        global-scope data, i.e. as its <source-name> without a type."
-       We cannot write overloaded operators that way though,
-       because it contains characters invalid in assembler.  */
-    write_source_name (DECL_NAME (decl));
+  if (/* The names of `extern "C"' functions are not mangled.  */
+      DECL_EXTERN_C_FUNCTION_P (decl)
+      /* But overloaded operator names *are* mangled.  */
+      && !DECL_OVERLOADED_OPERATOR_P (decl))
+    {
+    unmangled_name:;
+      
+      if (top_level)
+       write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
+      else
+       {
+         /* The standard notes: "The <encoding> of an extern "C"
+             function is treated like global-scope data, i.e. as its
+             <source-name> without a type."  We cannot write
+             overloaded operators that way though, because it contains
+             characters invalid in assembler.  */
+         if (abi_version_at_least (2))
+           write_string ("_Z");
+         else
+           G.need_abi_warning = true;
+         write_source_name (DECL_NAME (decl));
+       }
+    }
+  else if (TREE_CODE (decl) == VAR_DECL
+          /* The names of global variables aren't mangled.  */
+          && (CP_DECL_CONTEXT (decl) == global_namespace
+              /* And neither are `extern "C"' variables.  */
+              || DECL_EXTERN_C_P (decl)))
+    {
+      if (top_level || abi_version_at_least (2))
+       goto unmangled_name;
+      else
+       {
+         G.need_abi_warning = true;
+         goto mangled_name;
+       }
+    }
   else
-    /* C++ name; needs to be mangled.  */
     {
+    mangled_name:;
       write_string ("_Z");
       write_encoding (decl);
+      if (DECL_LANG_SPECIFIC (decl)
+         && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
+             || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
+       /* We need a distinct mangled name for these entities, but
+          we should never actually output it.  So, we append some
+          characters the assembler won't like.  */
+       write_string (" *INTERNAL* ");
     }
 }
 
@@ -1895,7 +1934,7 @@ write_expression (tree expr)
       if (code == CONST_DECL)
        G.need_abi_warning = 1;
       write_char ('L');
-      write_mangled_name (expr);
+      write_mangled_name (expr, false);
       write_char ('E');
     }
   else if (TREE_CODE (expr) == SIZEOF_EXPR 
@@ -2365,29 +2404,9 @@ mangle_decl_string (const tree decl)
 
   if (TREE_CODE (decl) == TYPE_DECL)
     write_type (TREE_TYPE (decl));
-  else if (/* The names of `extern "C"' functions are not mangled.  */
-          (DECL_EXTERN_C_FUNCTION_P (decl)
-           /* But overloaded operator names *are* mangled.  */
-           && !DECL_OVERLOADED_OPERATOR_P (decl))
-          /* The names of global variables aren't mangled either.  */
-          || (TREE_CODE (decl) == VAR_DECL
-              && CP_DECL_CONTEXT (decl) == global_namespace)
-          /* And neither are `extern "C"' variables.  */
-          || (TREE_CODE (decl) == VAR_DECL
-              && DECL_EXTERN_C_P (decl)))
-    write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
   else
-    {
-      write_mangled_name (decl);
-      if (DECL_LANG_SPECIFIC (decl)
-         && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
-             || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
-       /* We need a distinct mangled name for these entities, but
-          we should never actually output it.  So, we append some
-          characters the assembler won't like.  */
-       write_string (" *INTERNAL* ");
-    }
-
+    write_mangled_name (decl, true);
+  
   result = finish_mangling (/*warn=*/true);
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_decl_string = '%s'\n\n", result);
index d44759f..2d2d7cc 100644 (file)
@@ -1,3 +1,9 @@
+2003-12-15  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/13241
+       * g++.dg/abi/mangle18-1.C: New test.
+       * g++.dg/abi/mangle18-2.C: New test.
+
 2003-12-15  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        PR optimization/10312
diff --git a/gcc/testsuite/g++.dg/abi/mangle18-1.C b/gcc/testsuite/g++.dg/abi/mangle18-1.C
new file mode 100644 (file)
index 0000000..2e7b3a8
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=2" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
+
+// PR 13241
+// mangled template arguments that are external objects incorrectly
+
+extern "C" void Foo ();
+namespace NMS 
+{
+  extern "C" int V;
+}
+
+template <void (*)()> struct S {};
+template <int *> struct T {};
+
+void f (S<Foo>){}
+// { dg-final { scan-assembler "\n_Z1f1SIXadL_Z3FooEEE:" } }
+
+void g (T<&NMS::V>){}
+// { dg-final { scan-assembler "\n_Z1g1TIXadL_Z1VEEE:" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle18-2.C b/gcc/testsuite/g++.dg/abi/mangle18-2.C
new file mode 100644 (file)
index 0000000..be2b6b5
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-fabi-version=1 -Wabi" }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 30 Nov 2003 <nathan@codesourcery.com>
+
+// PR 13241
+// mangled template arguments that are external objects incorrectly
+
+extern "C" void Foo ();
+namespace NMS 
+{
+  extern "C" int V;
+}
+
+template <void (*)()> struct S {};
+template <int *> struct T {};
+
+void f (S<Foo>){} // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_Z1f1SIXadL3FooEEE:" } }
+
+void g (T<&NMS::V>){}  // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_Z1g1TIXadL_ZN3NMS1VEEEE:" } }