mangle.c (is_std_substitution): Check for abi_tag.
authorJason Merrill <jason@redhat.com>
Fri, 26 Sep 2014 19:57:37 +0000 (15:57 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 26 Sep 2014 19:57:37 +0000 (15:57 -0400)
gcc/cp/
* mangle.c (is_std_substitution): Check for abi_tag.
libiberty/
* cp-demangle.c (d_substitution): Handle abi tags on abbreviation.

From-SVN: r215647

gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/testsuite/g++.dg/abi/abi-tag9.C [new file with mode: 0644]
libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/testsuite/demangle-expected

index a11a52009b70bd4f8b3527c8498f1bcee52a455d..126c14836b4af51763d4abf498323563678ee196 100644 (file)
@@ -1,3 +1,7 @@
+2014-09-26  Jason Merrill  <jason@redhat.com>
+
+       * mangle.c (find_substitution): Use write_abi_tags.
+
 2014-09-25  Marek Polacek  <polacek@redhat.com>
 
        PR c++/61945
index 9703d1ceb726b0bb86dc56d5846cdf4013b62d0b..6e6aa8a5734b5b7b8a14d898edd948cdd6fb98f3 100644 (file)
@@ -512,6 +512,7 @@ find_substitution (tree node)
   const int size = vec_safe_length (G.substitutions);
   tree decl;
   tree type;
+  const char *abbr = NULL;
 
   if (DEBUG_MANGLE)
     fprintf (stderr, "  ++ find_substitution (%s at %p)\n",
@@ -530,13 +531,10 @@ find_substitution (tree node)
   if (decl
       && is_std_substitution (decl, SUBID_ALLOCATOR)
       && !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
-    {
-      write_string ("Sa");
-      return 1;
-    }
+    abbr = "Sa";
 
   /* Check for std::basic_string.  */
-  if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
+  else if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
     {
       if (TYPE_P (node))
        {
@@ -555,26 +553,20 @@ find_substitution (tree node)
                                               SUBID_CHAR_TRAITS)
                  && is_std_substitution_char (TREE_VEC_ELT (args, 2),
                                               SUBID_ALLOCATOR))
-               {
-                 write_string ("Ss");
-                 return 1;
-               }
+               abbr = "Ss";
            }
        }
       else
        /* Substitute for the template name only if this isn't a type.  */
-       {
-         write_string ("Sb");
-         return 1;
-       }
+       abbr = "Sb";
     }
 
   /* Check for basic_{i,o,io}stream.  */
-  if (TYPE_P (node)
-      && cp_type_quals (type) == TYPE_UNQUALIFIED
-      && CLASS_TYPE_P (type)
-      && CLASSTYPE_USE_TEMPLATE (type)
-      && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
+  else if (TYPE_P (node)
+          && cp_type_quals (type) == TYPE_UNQUALIFIED
+          && CLASS_TYPE_P (type)
+          && CLASSTYPE_USE_TEMPLATE (type)
+          && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
     {
       /* First, check for the template
         args <char, std::char_traits<char> > .  */
@@ -587,35 +579,29 @@ find_substitution (tree node)
        {
          /* Got them.  Is this basic_istream?  */
          if (is_std_substitution (decl, SUBID_BASIC_ISTREAM))
-           {
-             write_string ("Si");
-             return 1;
-           }
+           abbr = "Si";
          /* Or basic_ostream?  */
          else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM))
-           {
-             write_string ("So");
-             return 1;
-           }
+           abbr = "So";
          /* Or basic_iostream?  */
          else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM))
-           {
-             write_string ("Sd");
-             return 1;
-           }
+           abbr = "Sd";
        }
     }
 
   /* Check for namespace std.  */
-  if (decl && DECL_NAMESPACE_STD_P (decl))
+  else if (decl && DECL_NAMESPACE_STD_P (decl))
     {
       write_string ("St");
       return 1;
     }
 
+  tree tags = NULL_TREE;
+  if (OVERLOAD_TYPE_P (node))
+    tags = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (type));
   /* Now check the list of available substitutions for this mangling
      operation.  */
-  for (i = 0; i < size; ++i)
+  if (!abbr || tags) for (i = 0; i < size; ++i)
     {
       tree candidate = (*G.substitutions)[i];
       /* NODE is a matched to a candidate if it's the same decl node or
@@ -630,8 +616,19 @@ find_substitution (tree node)
        }
     }
 
-  /* No substitution found.  */
-  return 0;
+  if (!abbr)
+    /* No substitution found.  */
+    return 0;
+
+  write_string (abbr);
+  if (tags)
+    {
+      /* If there are ABI tags on the abbreviation, it becomes
+        a substitution candidate.  */
+      write_abi_tags (tags);
+      add_substitution (node);
+    }
+  return 1;
 }
 
 
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag9.C b/gcc/testsuite/g++.dg/abi/abi-tag9.C
new file mode 100644 (file)
index 0000000..9ec78a9
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-final { scan-assembler "_Z1fSsB3fooS_" } }
+
+namespace std {
+  template <class T> struct char_traits {};
+  template <class T> struct allocator {};
+  template <class T, class U, class V>
+  struct __attribute ((abi_tag ("foo"))) basic_string { };
+  typedef basic_string<char,char_traits<char>,allocator<char> > string;
+}
+
+void f(std::string,std::string) {}
index 53d967e6d70c7ac6c4125807bc8c0375400a865b..829f684d393540aa99c1c3cd7f253d4e8a567419 100644 (file)
@@ -1,3 +1,7 @@
+2014-09-26  Jason Merrill  <jason@redhat.com>
+
+       * cp-demangle.c (d_substitution): Handle abi tags on abbreviation.
+
 2014-09-26  Max Ostapenko  <m.ostapenko@partner.samsung.com>
 
        * pex-common.h (struct pex_funcs): Add new parameter for open_write field.
index 4ecdb1ee439e83cc8bfddaa47619f650398b4937..77c2cee9d176015ffd681b43e9f55db00b2801f4 100644 (file)
@@ -3687,6 +3687,7 @@ d_substitution (struct d_info *di, int prefix)
            {
              const char *s;
              int len;
+             struct demangle_component *c;
 
              if (p->set_last_name != NULL)
                di->last_name = d_make_sub (di, p->set_last_name,
@@ -3702,7 +3703,15 @@ d_substitution (struct d_info *di, int prefix)
                  len = p->simple_len;
                }
              di->expansion += len;
-             return d_make_sub (di, s, len);
+             c = d_make_sub (di, s, len);
+             if (d_peek_char (di) == 'B')
+               {
+                 /* If there are ABI tags on the abbreviation, it becomes
+                    a substitution candidate.  */
+                 c = d_abi_tags (di, c);
+                 d_add_substitution (di, c);
+               }
+             return c;
            }
        }
 
index f8420efac901ecd4f40c191cee3867f2047c0e49..a030685de0894e130e784e609b8cb0e612d5857d 100644 (file)
@@ -4353,3 +4353,6 @@ xxx
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
+--format=gnu-v3
+_Z1fSsB3fooS_
+f(std::string[abi:foo], std::string[abi:foo])