OSDN Git Service

2009-10-30 Jerry Quinn <jlquinn@optonline.net>
authorjlquinn <jlquinn@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Oct 2009 12:20:38 +0000 (12:20 +0000)
committerjlquinn <jlquinn@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Oct 2009 12:20:38 +0000 (12:20 +0000)
* libsupc++/tinfo.cc (operator=(const type_info&)): Revert 153734.
* libsupc++/typeinfo (type_info::name()): Likewise.
* libsupc++/tinfo2.cc (before):  Likewise.

2009-10-30  Jerry Quinn  <jlquinn@optonline.net>

* mangle.c (mangle_type_string_for_rtti): Revert 153734.
(needs_fake_anon): Likewise.
(write_name): Likewise.
(write_nested_name): Likewise.
* cp-tree.h (mangle_type_string_for_rtti): Likewise.
(get_anonymous_namespace): Likewise.
* name-lookup.c (get_anonymous_namespace_name): Likewise.
* rtti.c (tinfo_name): Likewise.
(tinfo_base_init): Likewise.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/mangle.c
gcc/cp/name-lookup.c
gcc/cp/rtti.c
libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/tinfo.cc
libstdc++-v3/libsupc++/tinfo2.cc
libstdc++-v3/libsupc++/typeinfo

index 6367f51..676b431 100644 (file)
@@ -1,3 +1,15 @@
+2009-10-30  Jerry Quinn  <jlquinn@optonline.net>
+
+       * mangle.c (mangle_type_string_for_rtti): Revert 153734.
+       (needs_fake_anon): Likewise.
+       (write_name): Likewise.
+       (write_nested_name): Likewise.
+       * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+       (get_anonymous_namespace): Likewise.
+       * name-lookup.c (get_anonymous_namespace_name): Likewise.
+       * rtti.c (tinfo_name): Likewise.
+       (tinfo_base_init): Likewise.
+
 2009-10-30  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/41863
index 4ffd899..5c51a6f 100644 (file)
@@ -4517,6 +4517,7 @@ extern tree type_promotes_to                      (tree);
 extern tree perform_qualification_conversions  (tree, tree);
 
 /* in name-lookup.c */
+extern tree get_anonymous_namespace_name       (void);
 extern tree pushdecl                           (tree);
 extern tree pushdecl_maybe_friend              (tree, bool);
 extern void maybe_push_cleanup_level           (tree);
@@ -5298,7 +5299,7 @@ extern tree merge_exception_specifiers            (tree, tree);
 /* in mangle.c */
 extern void init_mangle                                (void);
 extern void mangle_decl                                (tree);
-extern const char *mangle_type_string          (tree);
+extern const char *mangle_type_string_for_rtti (tree);
 extern tree mangle_typeinfo_for_type           (tree);
 extern tree mangle_typeinfo_string_for_type    (tree);
 extern tree mangle_vtbl_for_type               (tree);
index 7489665..874df74 100644 (file)
@@ -105,6 +105,10 @@ typedef struct GTY(()) globals {
 
 static GTY (()) globals G;
 
+/* Whether or not to pretend that a static function is in an anonymous
+   namespace.  */
+static bool fake_anon_scope;
+
 /* The obstack on which we build mangled names.  */
 static struct obstack *mangle_obstack;
 
@@ -730,6 +734,20 @@ write_encoding (const tree decl)
     }
 }
 
+/* Since we now use strcmp to compare typeinfos on all targets because of
+   the RTLD_LOCAL problem, we need to munge the typeinfo name used for
+   local classes of static functions to fix g++.dg/abi/local1.C.  We do
+   that by pretending that the function is in an anonymous namespace.  */
+
+static bool
+needs_fake_anon (const_tree decl)
+{
+  /* Pretend there's an anonymous namespace right around a static
+     function if we're mangling for RTTI.  */
+  return (fake_anon_scope && !TREE_PUBLIC (decl)
+         && TREE_CODE (decl) == FUNCTION_DECL);
+}
+
 /* Lambdas can have a bit more context for mangling, specifically VAR_DECL
    or PARM_DECL context, which doesn't belong in DECL_CONTEXT.  */
 
@@ -773,13 +791,18 @@ write_name (tree decl, const int ignore_local_scope)
 
   context = decl_mangling_context (decl);
 
+  gcc_assert (context != NULL_TREE);
+
+  /* If we need a fake anonymous namespace, force the nested name path.  */
+  if (needs_fake_anon (decl) && context == global_namespace)
+    context = error_mark_node;
+
   /* A decl in :: or ::std scope is treated specially.  The former is
      mangled using <unscoped-name> or <unscoped-template-name>, the
      latter with a special substitution.  Also, a name that is
      directly in a local function scope is also mangled with
      <unscoped-name> rather than a full <nested-name>.  */
-  if (context == NULL
-      || context == global_namespace
+  if (context == global_namespace
       || DECL_NAMESPACE_STD_P (context)
       || (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
     {
@@ -797,6 +820,9 @@ write_name (tree decl, const int ignore_local_scope)
     }
   else
     {
+      if (context == error_mark_node)
+       context = global_namespace;
+
       /* Handle local names, unless we asked not to (that is, invoked
         under <local-name>, to handle only the part of the name under
         the local scope).  */
@@ -809,10 +835,10 @@ write_name (tree decl, const int ignore_local_scope)
             directly in that function's scope, either decl or one of
             its enclosing scopes.  */
          tree local_entity = decl;
-         while (context != NULL && context != global_namespace)
+         while (context != global_namespace)
            {
              /* Make sure we're always dealing with decls.  */
-             if (context != NULL && TYPE_P (context))
+             if (TYPE_P (context))
                context = TYPE_NAME (context);
              /* Is this a function?  */
              if (TREE_CODE (context) == FUNCTION_DECL
@@ -857,7 +883,6 @@ write_unscoped_name (const tree decl)
       /* If not, it should be either in the global namespace, or directly
         in a local function scope.  */
       gcc_assert (context == global_namespace
-                 || context != NULL
                  || TREE_CODE (context) == FUNCTION_DECL);
 
       write_unqualified_name (decl);
@@ -929,6 +954,9 @@ write_nested_name (const tree decl)
     {
       /* No, just use <prefix>  */
       write_prefix (DECL_CONTEXT (decl));
+      if (needs_fake_anon (decl))
+       /* Pretend this static function is in an anonymous namespace.  */
+       write_source_name (get_anonymous_namespace_name ());
       write_unqualified_name (decl);
     }
   write_char ('E');
@@ -2984,15 +3012,18 @@ mangle_decl (const tree decl)
   SET_DECL_ASSEMBLER_NAME (decl, id);
 }
 
-/* Generate the mangled representation of TYPE.  */
+/* Generate the mangled representation of TYPE for the typeinfo name.  */
 
 const char *
-mangle_type_string (const tree type)
+mangle_type_string_for_rtti (const tree type)
 {
   const char *result;
 
   start_mangling (type);
+  /* Mangle in a fake anonymous namespace if necessary.  */
+  fake_anon_scope = true;
   write_type (type);
+  fake_anon_scope = false;
   result = finish_mangling (/*warn=*/false);
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
index 8089427..9a69912 100644 (file)
@@ -62,19 +62,14 @@ static GTY(()) tree anonymous_namespace_name;
 
 /* Initialize anonymous_namespace_name if necessary, and return it.  */
 
-static tree
+tree
 get_anonymous_namespace_name (void)
 {
   if (!anonymous_namespace_name)
     {
       /* The anonymous namespace has to have a unique name
         if typeinfo objects are being compared by name.  */
-      if (! flag_weak || ! SUPPORTS_ONE_ONLY)
-       anonymous_namespace_name = get_file_function_name ("N");
-      else
-       /* The demangler expects anonymous namespaces to be called
-          something starting with '_GLOBAL__N_'.  */
-       anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
+      anonymous_namespace_name = get_file_function_name ("N");
     }
   return anonymous_namespace_name;
 }
index fad3144..8dde479 100644 (file)
@@ -102,7 +102,7 @@ VEC(tree,gc) *unemitted_tinfo_decls;
 static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
 
 static tree ifnonnull (tree, tree);
-static tree tinfo_name (tree, bool);
+static tree tinfo_name (tree);
 static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
 static tree throw_bad_typeid (void);
@@ -349,30 +349,16 @@ build_typeid (tree exp)
   return exp;
 }
 
-/* Generate the NTBS name of a type.  If MARK_PRIVATE, put a '*' in front so that
-   comparisons will be done by pointer rather than string comparison.  */
+/* Generate the NTBS name of a type.  */
 static tree
-tinfo_name (tree type, bool mark_private)
+tinfo_name (tree type)
 {
   const char *name;
-  int length;
   tree name_string;
 
-  name = mangle_type_string (type);
-  length = strlen (name);
-
-  if (mark_private)
-    {
-      /* Inject '*' at beginning of name to force pointer comparison.  */
-      char* buf = (char*) XALLOCAVEC (char, length + 1);
-      buf[0] = '*';
-      memcpy (buf + 1, name, length);
-      name_string = build_string (length + 1, buf);
-    }
-  else
-    name_string = build_string (length, name);
-
-  return fix_string_type (name_string);
+  name = mangle_type_string_for_rtti (type);
+  name_string = fix_string_type (build_string (strlen (name) + 1, name));
+  return name_string;
 }
 
 /* Return a VAR_DECL for the internal ABI defined type_info object for
@@ -853,12 +839,13 @@ tinfo_base_init (tinfo_s *ti, tree target)
   tree vtable_ptr;
 
   {
-    tree name_name, name_string;
+    tree name_name;
 
     /* Generate the NTBS array variable.  */
     tree name_type = build_cplus_array_type
                     (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
                     NULL_TREE);
+    tree name_string = tinfo_name (target);
 
     /* Determine the name of the variable -- and remember with which
        type it is associated.  */
@@ -875,7 +862,6 @@ tinfo_base_init (tinfo_s *ti, tree target)
     DECL_TINFO_P (name_decl) = 1;
     set_linkage_according_to_type (target, name_decl);
     import_export_decl (name_decl);
-    name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
     DECL_INITIAL (name_decl) = name_string;
     mark_used (name_decl);
     pushdecl_top_level_and_finish (name_decl, name_string);
index 972a44d..a59710d 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-30  Jerry Quinn  <jlquinn@optonline.net>
+
+       * libsupc++/tinfo.cc (operator=(const type_info&)): Revert 153734.
+       * libsupc++/typeinfo (type_info::name()): Likewise.
+       * libsupc++/tinfo2.cc (before):  Likewise.
+
 2009-10-28  Jerry Quinn  <jlquinn@optonline.net>
 
        * libsupc++/tinfo.cc (operator=(const type_info&)): Compare by
index d939a3f..1ce6f8f 100644 (file)
@@ -41,8 +41,7 @@ operator== (const std::type_info& arg) const
 #if __GXX_MERGED_TYPEINFO_NAMES
   return name () == arg.name ();
 #else
-  return (&arg == this)
-    || (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ()) == 0));
+  return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
 #endif
 }
 
index 0182c6c..4b01037 100644 (file)
@@ -37,8 +37,7 @@ type_info::before (const type_info &arg) const
 #if __GXX_MERGED_TYPEINFO_NAMES
   return name () < arg.name ();
 #else
-  return (name ()[0] == '*') ? name () < arg.name ()
-    :  __builtin_strcmp (name (), arg.name ()) < 0;
+  return __builtin_strcmp (name (), arg.name ()) < 0;
 #endif
 }
 
index f7f9d4e..4c47043 100644 (file)
@@ -94,7 +94,7 @@ namespace std
     /** Returns an @e implementation-defined byte string; this is not
      *  portable between compilers!  */
     const char* name() const
-    { return __name[0] == '*' ? __name + 1 : __name; }
+    { return __name; }
 
 #if !__GXX_TYPEINFO_EQUALITY_INLINE
     // In old abi, or when weak symbols are not supported, there can
@@ -110,15 +110,12 @@ namespace std
     // we can run into cases where type_info names aren't merged,
     // so we still need to do string comparison.
     bool before(const type_info& __arg) const
-    { return (__name[0] == '*' && __arg.__name[0] == '*')
-       ? __name < __arg.__name
-       : __builtin_strcmp (__name, __arg.__name) < 0; }
+    { return __builtin_strcmp (__name, __arg.__name) < 0; }
 
     bool operator==(const type_info& __arg) const
     {
       return ((__name == __arg.__name)
-             || (__name[0] != '*' &&
-                 __builtin_strcmp (__name, __arg.__name) == 0));
+             || __builtin_strcmp (__name, __arg.__name) == 0);
     }
   #else
     // On some targets we can rely on type_info's NTBS being unique,