]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/37376, other mangling issues
authorJason Merrill <jason@redhat.com>
Mon, 6 Oct 2008 22:29:42 +0000 (18:29 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 6 Oct 2008 22:29:42 +0000 (18:29 -0400)
gcc/cp/:
        PR c++/37376, other mangling issues
        * mangle.c (write_type): Update TYPE_PACK_EXPANSION mangling.
        (write_member_name): Break out from...
        (write_expression): ...here.  Handle dependent COMPONENT_REF.
        (write_template_arg): Wrap an argument pack in 'I'/'E'.
        (write_builtin_type): Update char16/32_t mangling.
        (write_nested_name, write_prefix): Don't forget template args
        for typename types.
        * operators.def: Add ARROW_EXPR, update COMPONENT_REF and
        EXPR_PACK_EXPANSION.
libstdc++-v3/:
        * config/abi/pre/gnu.ver: Update char16/32_t manglings.
include/:
        * demangle.h (enum demangle_component_type): Add
        DEMANGLE_COMPONENT_PACK_EXPANSION.
libiberty/:
        * cp-demangle.c (struct d_print_info): Add pack_index.
        (d_dump): Add DEMANGLE_COMPONENT_PACK_EXPANSION.
        (d_make_comp): Likewise.  DEMANGLE_COMPONENT_ARGLIST and
        DEMANGLE_COMPONENT_TEMPLATE_ARGLIST can have two null args.
        (cplus_demangle_builtin_types): Add char16/32_t.
        (cplus_demangle_type): Recognize them.
        (d_template_args): Handle empty argument packs.
        (d_template_arg): Handle argument packs.
        (d_expression): Handle dependent name.
        (d_index_template_argument): New fn.
        (d_lookup_template_argument): New fn.
        (d_find_pack, d_pack_length): New fn.
        (d_print_subexpr): Split out...
        (d_print_comp): ...from here.  Use d_*_template_argument.
        Handle empty arg lists.  Support pack expansions.
        * cp-demangle.h (D_BUILTIN_TYPE_COUNT): Increase to 32.

From-SVN: r140916

17 files changed:
gcc/cp/ChangeLog
gcc/cp/mangle.c
gcc/cp/operators.def
gcc/testsuite/g++.dg/abi/mangle30.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/auto6.C
gcc/testsuite/g++.dg/cpp0x/variadic4.C
gcc/testsuite/g++.dg/cpp0x/variadic42.C
gcc/testsuite/g++.dg/ext/utf-mangle.C
gcc/tree.h
include/ChangeLog
include/demangle.h
libiberty/ChangeLog
libiberty/cp-demangle.c
libiberty/cp-demangle.h
libiberty/testsuite/demangle-expected
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver

index dc18acc4fb0d9b5851561c515876cff6ddaf52b9..222693f2a525ab55cc35415a5a84d959b62b3ca2 100644 (file)
@@ -1,3 +1,16 @@
+2008-10-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37376, other mangling issues
+       * mangle.c (write_type): Update TYPE_PACK_EXPANSION mangling.
+       (write_member_name): Break out from...
+       (write_expression): ...here.  Handle dependent COMPONENT_REF.
+       (write_template_arg): Wrap an argument pack in 'I'/'E'.
+       (write_builtin_type): Update char16/32_t mangling.
+       (write_nested_name, write_prefix): Don't forget template args
+       for typename types.
+       * operators.def: Add ARROW_EXPR, update COMPONENT_REF and 
+       EXPR_PACK_EXPANSION.
+
 2008-10-06  Aldy Hernandez  <aldyh@redhat.com>
 
        * typeck.c (build_x_indirect_ref): Add location argument.
index 7b4c30344cce5e4ad1c69f3b8e086a712a105c52..c0282d8ade51bd7cb02ffaad93767be24af02baf 100644 (file)
@@ -887,6 +887,20 @@ write_nested_name (const tree decl)
       write_template_prefix (decl);
       write_template_args (TI_ARGS (template_info));
     }
+  else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+    {
+      tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+       {
+         write_template_prefix (decl);
+         write_template_args (TREE_OPERAND (name, 1));
+       }
+      else
+       {
+         write_prefix (CP_DECL_CONTEXT (decl));
+         write_unqualified_name (decl);
+       }
+    }
   else
     {
       /* No, just use <prefix>  */
@@ -953,6 +967,20 @@ write_prefix (const tree node)
       write_template_prefix (decl);
       write_template_args (TI_ARGS (template_info));
     }
+  else if (TREE_CODE (TREE_TYPE (decl)) == TYPENAME_TYPE)
+    {
+      tree name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (decl));
+      if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+       {
+         write_template_prefix (decl);
+         write_template_args (TREE_OPERAND (name, 1));
+       }
+      else
+       {
+         write_prefix (CP_DECL_CONTEXT (decl));
+         write_unqualified_name (decl);
+       }
+    }
   else
     /* Not templated.  */
     {
@@ -982,6 +1010,9 @@ write_template_prefix (const tree node)
   /* Find the template decl.  */
   if (decl_is_template_id (decl, &template_info))
     templ = TI_TEMPLATE (template_info);
+  else if (TREE_CODE (type) == TYPENAME_TYPE)
+    /* For a typename type, all we have is the name.  */
+    templ = DECL_NAME (decl);
   else
     {
       gcc_assert (CLASSTYPE_TEMPLATE_ID_P (type));
@@ -1020,11 +1051,13 @@ write_template_prefix (const tree node)
     return;
 
   /* In G++ 3.2, the name of the template template parameter was used.  */
-  if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+  if (TREE_TYPE (templ)
+      && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
       && !abi_version_at_least (2))
     G.need_abi_warning = true;
 
-  if (TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
+  if (TREE_TYPE (templ)
+      && TREE_CODE (TREE_TYPE (templ)) == TEMPLATE_TEMPLATE_PARM
       && abi_version_at_least (2))
     write_template_param (TREE_TYPE (templ));
   else
@@ -1636,7 +1669,7 @@ write_type (tree type)
              break;
 
             case TYPE_PACK_EXPANSION:
-              write_string ("U10__variadic");
+              write_string ("Dp");
               write_type (PACK_EXPANSION_PATTERN (type));
               break;
 
@@ -1750,9 +1783,9 @@ write_builtin_type (tree type)
       if (type == wchar_type_node)
        write_char ('w');
       else if (type == char16_type_node)
-       write_string ("u8char16_t");
+       write_string ("Ds");
       else if (type == char32_type_node)
-       write_string ("u8char32_t");
+       write_string ("Di");
       else if (TYPE_FOR_JAVA (type))
        write_java_integer_type_codes (type);
       else
@@ -2009,6 +2042,35 @@ write_template_args (tree args)
   write_char ('E');
 }
 
+/* Write out the
+   <unqualified-name>
+   <unqualified-name> <template-args>
+   part of SCOPE_REF or COMPONENT_REF mangling.  */
+
+static void
+write_member_name (tree member)
+{
+  if (TREE_CODE (member) == IDENTIFIER_NODE)
+    write_source_name (member);
+  else if (DECL_P (member))
+    {
+      /* G++ 3.2 incorrectly put out both the "sr" code and
+        the nested name of the qualified name.  */
+      G.need_abi_warning = 1;
+      write_unqualified_name (member);
+    }
+  else if (TREE_CODE (member) == TEMPLATE_ID_EXPR)
+    {
+      tree name = TREE_OPERAND (member, 0);
+      if (TREE_CODE (name) == OVERLOAD)
+       name = OVL_FUNCTION (name);
+      write_member_name (name);
+      write_template_args (TREE_OPERAND (member, 1));
+    }
+  else
+    write_expression (member);
+}
+
 /* <expression> ::= <unary operator-name> <expression>
                ::= <binary operator-name> <expression> <expression>
                ::= <expr-primary>
@@ -2161,6 +2223,20 @@ write_expression (tree expr)
            write_template_args (template_args);
        }
     }
+  else if (code == COMPONENT_REF)
+    {
+      tree ob = TREE_OPERAND (expr, 0);
+
+      if (TREE_CODE (ob) == ARROW_EXPR)
+       {
+         code = ARROW_EXPR;
+         ob = TREE_OPERAND (ob, 0);
+       }
+
+      write_string (operator_name_info[(int)code].mangled_name);
+      write_expression (ob);
+      write_member_name (TREE_OPERAND (expr, 1));
+    }
   else
     {
       int i;
@@ -2198,8 +2274,12 @@ write_expression (tree expr)
        case CAST_EXPR:
          write_type (TREE_TYPE (expr));
          if (!TREE_OPERAND (expr, 0))
-         /* "T()" is mangled as "T(void)".  */
+           /* "T()" is mangled as "T(void)".  */
            write_char ('v');
+         else if (list_length (TREE_OPERAND (expr, 0)) > 1)
+           /* FIXME the above hack for T() needs to be replaced with
+              something more general.  */
+           sorry ("mangling function-style cast with more than one argument");
          else
            write_expression (TREE_VALUE (TREE_OPERAND (expr, 0)));
          break;
@@ -2213,27 +2293,7 @@ write_expression (tree expr)
        /* Handle pointers-to-members specially.  */
        case SCOPE_REF:
          write_type (TREE_OPERAND (expr, 0));
-         if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
-           write_source_name (TREE_OPERAND (expr, 1));
-         else if (TREE_CODE (TREE_OPERAND (expr, 1)) == TEMPLATE_ID_EXPR)
-           {
-             tree template_id;
-             tree name;
-
-             template_id = TREE_OPERAND (expr, 1);
-             name = TREE_OPERAND (template_id, 0);
-             /* FIXME: What about operators?  */
-             gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
-             write_source_name (TREE_OPERAND (template_id, 0));
-             write_template_args (TREE_OPERAND (template_id, 1));
-           }
-         else
-           {
-             /* G++ 3.2 incorrectly put out both the "sr" code and
-                the nested name of the qualified name.  */
-             G.need_abi_warning = 1;
-             write_encoding (TREE_OPERAND (expr, 1));
-           }
+         write_member_name (TREE_OPERAND (expr, 1));
          break;
 
        default:
@@ -2338,8 +2398,10 @@ write_template_arg (tree node)
       /* Expand the template argument pack. */
       tree args = ARGUMENT_PACK_ARGS (node);
       int i, length = TREE_VEC_LENGTH (args);
+      write_char ('I');
       for (i = 0; i < length; ++i)
         write_template_arg (TREE_VEC_ELT (args, i));
+      write_char ('E');
     }
   else if (TYPE_P (node))
     write_type (node);
index 9c2dd8b2ca1d08f3b888eb2deacc3b9fe76ad6cd..20c74d882201dd4f1f5aca91c4433b17e61f03c5 100644 (file)
@@ -125,7 +125,8 @@ DEF_SIMPLE_OPERATOR ("&&", TRUTH_ANDIF_EXPR, "aa", 2)
 DEF_SIMPLE_OPERATOR ("||", TRUTH_ORIF_EXPR, "oo", 2)
 DEF_SIMPLE_OPERATOR (",", COMPOUND_EXPR, "cm", 2)
 DEF_SIMPLE_OPERATOR ("->*", MEMBER_REF, "pm", 2)
-DEF_SIMPLE_OPERATOR ("->", COMPONENT_REF, "pt", 2)
+DEF_SIMPLE_OPERATOR ("->", ARROW_EXPR, "pt", 2)
+DEF_SIMPLE_OPERATOR (".", COMPONENT_REF, "dt", 2)
 DEF_SIMPLE_OPERATOR ("[]", ARRAY_REF, "ix", 2)
 DEF_SIMPLE_OPERATOR ("++", POSTINCREMENT_EXPR, "pp", 2)
 DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2)
@@ -152,4 +153,4 @@ DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3)
 DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", -1)
 
 /* Variadic templates extension. */
-DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "pu", 1)
+DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1)
diff --git a/gcc/testsuite/g++.dg/abi/mangle30.C b/gcc/testsuite/g++.dg/abi/mangle30.C
new file mode 100644 (file)
index 0000000..f0b83db
--- /dev/null
@@ -0,0 +1,22 @@
+// Test for mangling of template args in a typename type.
+
+struct A
+{
+  template <class T>
+  struct B
+  {
+    typedef T myT;
+  };
+};
+
+struct C {};
+
+template <class T>
+void f (T t, typename T::template B<C>::myT u, typename T::template B<int>::myT v);
+
+int main()
+{
+  f (A(), C(), 1);
+}
+
+// { dg-final { scan-assembler "_Z1fI1AEvT_NS1_1BI1CE3myTENS2_IiE3myTE" } }
index 713583a1a48ab1082197e4c8731bf74ad66c58ba..d2bcfedb63c658e04a644d0687521dc31c712f69 100644 (file)
@@ -1,3 +1,4 @@
+// Tests for late-specified return type.
 // { dg-options "-std=c++0x" }
 
 auto f() -> int
@@ -12,17 +13,81 @@ auto add(T t, U u) -> decltype (t+u)
 }
 
 template<class T, class U>
-decltype(T()+U()) add2(T t, U u);
+decltype(T()+U()) add2(T t, U u)
+{
+  return t+u;
+}
 
 template <class T, class U>
-U g (T, U);
+U ag (T, U)
+{
+  return U();
+}
 
 template<class T, class U>
-auto add3(T t, U u) -> decltype (g(t,u));
+auto add3(T t, U u) -> decltype (ag(t,u))
+{
+  return ag(t,u);
+}
+
+template <class T>
+struct A
+{
+  T f() {}
+  template <class U>
+  T g() {}
+  template <class V>
+  struct B
+  {
+    int MEM;
+  };
+};
+
+template <class T>
+auto f(T* t) -> decltype (t->f())
+{
+  return t->f();
+}
+
+template <class T>
+auto g(T t) -> decltype (t.f())
+{
+  return t.f();
+}
+
+template <class T, class U>
+auto h(T t, U u) -> decltype (t.template g<U>())
+{
+  return t.template g<U>();
+}
+
+struct D { };
+struct C: public A<int>::B<D>
+{
+};
+
+template <class T, class U, class V>
+auto k(T t, U u, V v) -> decltype (t.U::template B<V>::MEM)
+{
+  return t.U::template B<V>::MEM;
+}
+
+A<int> a, *p;
 
 int main()
 {
+  // { dg-final { scan-assembler "_Z3addIidEDTplsTT_sTT0_ES0_S1_" } }
   auto i = add(1, 2.0);
+  // { dg-final { scan-assembler "_Z4add2IidEDTplcvT_vcvT0_vES0_S1_" } }
   auto i2 = add2(1, 2.0);
+  // { dg-final { scan-assembler "_Z4add3IidEDTclL_Z2agEsTT_sTT0_EES0_S1_" } }
   auto i3 = add3(1, 2.0);
+  // { dg-final { scan-assembler "_Z1fI1AIiEEDTclptsTPT_1fEES3_" } }
+  f(p);
+  // { dg-final { scan-assembler "_Z1gI1AIiEEDTcldtsTT_1fEES2_" } }
+  g(a);
+  // { dg-final { scan-assembler "_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_" } }
+  h(a,1.0);
+  // { dg-final { scan-assembler "_Z1kI1C1AIiE1DEDtdtsTT_srNT0_1BIT1_EE3MEMES4_S5_S7_" } }
+  k( C(), A<int>(), D() );
 }
index 6c15a6de92d57b6b4b490fbc1a0bbeedfd0ba803..9257a92d5b9bcc8cfb3aae60b66fcf50b721fd07 100644 (file)
@@ -9,7 +9,7 @@ void f_two(tuple<int, float>) {}
 void f_nested(tuple<int, tuple<double, char>, float>) { }
 
 
-// { dg-final { scan-assembler "_Z6f_none5tupleIE" } }
-// { dg-final { scan-assembler "_Z5f_one5tupleIiE" } }
-// { dg-final { scan-assembler "_Z5f_two5tupleIifE" } }
-// { dg-final { scan-assembler "_Z8f_nested5tupleIiS_IdcEfE" } }
+// { dg-final { scan-assembler "_Z6f_none5tupleIIEE" } }
+// { dg-final { scan-assembler "_Z5f_one5tupleIIiEE" } }
+// { dg-final { scan-assembler "_Z5f_two5tupleIIifEE" } }
+// { dg-final { scan-assembler "_Z8f_nested5tupleIIiS_IIdcEEfEE" } }
index 4c6c7673d80e3d64e5219a1dec0321308d4d382b..47d9b66da58bfc21b466d90d3695a6622ea8eaf6 100644 (file)
@@ -8,5 +8,5 @@ void g()
   f<int*, float*, double*>(0, 0, 0);
   f<int*>(0,0,0);
 }
-// { dg-final { scan-assembler "_Z1fIPiPfPdEvU10__variadicT_" } }
-// { dg-final { scan-assembler "_Z1fIPiiiEvU10__variadicT_" } }
+// { dg-final { scan-assembler "_Z1fIIPiPfPdEEvDpT_" } }
+// { dg-final { scan-assembler "_Z1fIIPiiiEEvDpT_" } }
index bb5e3822adcad68f78e2b54bc53dc7681edb0d79..a131887882a15a8b04878d826ca81f06f1745364 100644 (file)
@@ -8,7 +8,7 @@ void f1 (char32_t c) {}
 void f2 (char16_t *s) {}
 void f3 (char32_t *s) {}
 
-// { dg-final { scan-assembler "_Z2f0u8char16_t:" } }
-// { dg-final { scan-assembler "_Z2f1u8char32_t:" } }
-// { dg-final { scan-assembler "_Z2f2Pu8char16_t:" } }
-// { dg-final { scan-assembler "_Z2f3Pu8char32_t:" } }
+// { dg-final { scan-assembler "_Z2f0Ds:" } }
+// { dg-final { scan-assembler "_Z2f1Di:" } }
+// { dg-final { scan-assembler "_Z2f2PDs:" } }
+// { dg-final { scan-assembler "_Z2f3PDi:" } }
index 85704e690949cdabc187cab4fdbe75dadac5360f..44bc3f0f2828725afd10e6024f44be0f0e999620 100644 (file)
@@ -2559,7 +2559,7 @@ struct tree_memory_partition_tag GTY(())
 /* For a FUNCTION_DECL, holds the tree of BINDINGs.
    For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK.
    For a VAR_DECL, holds the initial value.
-   For a PARM_DECL, not used--default
+   For a PARM_DECL, used for DECL_ARG_TYPE--default
    values for parameters are encoded in the type of the function,
    not in the PARM_DECL slot.
    For a FIELD_DECL, this is used for enumeration values and the C
index 64b0a6caeeba8e1adc4593e40d2c0c4c5ee76804..20da6186ff0fec1e7902caa55def7d6f5db00b53 100644 (file)
@@ -1,3 +1,8 @@
+2008-10-06  Jason Merrill  <jason@redhat.com>
+
+       * demangle.h (enum demangle_component_type): Add
+       DEMANGLE_COMPONENT_PACK_EXPANSION.
+
 2008-09-09  Jason Merrill  <jason@redhat.com>
 
        * demangle.h (enum demangle_component_type): Add
index 146d778e0974ec54cc532218d1e86672ca067ce2..0ea639d62ba370f36e44b30835a0f2afb0ae41c7 100644 (file)
@@ -372,7 +372,9 @@ enum demangle_component_type
   /* A name formed by a single character.  */
   DEMANGLE_COMPONENT_CHARACTER,
   /* A decltype type.  */
-  DEMANGLE_COMPONENT_DECLTYPE
+  DEMANGLE_COMPONENT_DECLTYPE,
+  /* A pack expansion.  */
+  DEMANGLE_COMPONENT_PACK_EXPANSION
 };
 
 /* Types which are only used internally.  */
index e6980aea1329d0bcaf7aad8fc9be9535fea57b26..b0c1c203ac5b78c5702c15f4f4ffd048fd04ee40 100644 (file)
@@ -1,3 +1,22 @@
+2008-10-06  Jason Merrill  <jason@redhat.com>
+
+       * cp-demangle.c (struct d_print_info): Add pack_index.
+       (d_dump): Add DEMANGLE_COMPONENT_PACK_EXPANSION.
+       (d_make_comp): Likewise.  DEMANGLE_COMPONENT_ARGLIST and
+       DEMANGLE_COMPONENT_TEMPLATE_ARGLIST can have two null args.
+       (cplus_demangle_builtin_types): Add char16/32_t.
+       (cplus_demangle_type): Recognize them.
+       (d_template_args): Handle empty argument packs.
+       (d_template_arg): Handle argument packs.
+       (d_expression): Handle dependent name.
+       (d_index_template_argument): New fn.
+       (d_lookup_template_argument): New fn.
+       (d_find_pack, d_pack_length): New fn.
+       (d_print_subexpr): Split out...
+       (d_print_comp): ...from here.  Use d_*_template_argument.
+       Handle empty arg lists.  Support pack expansions.
+       * cp-demangle.h (D_BUILTIN_TYPE_COUNT): Increase to 32.
+
 2008-09-09  Jason Merrill  <jason@redhat.com>
 
        * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_DECLTYPE.
index 3d292f07d0a915c456ea996c77f8c86da393d947..3fa5f1f21d3b2e30e2a6df7e3f01df7e69451bd6 100644 (file)
@@ -299,6 +299,9 @@ struct d_print_info
   struct d_print_mod *modifiers;
   /* Set to 1 if we saw a demangling error.  */
   int demangle_failure;
+  /* The current index into any template argument packs we are using
+     for printing.  */
+  int pack_index;
 };
 
 #ifdef CP_DEMANGLE_DEBUG
@@ -663,6 +666,9 @@ d_dump (struct demangle_component *dc, int indent)
     case DEMANGLE_COMPONENT_DECLTYPE:
       printf ("decltype\n");
       break;
+    case DEMANGLE_COMPONENT_PACK_EXPANSION:
+      printf ("pack expansion\n");
+      break;
     }
 
   d_dump (d_left (dc), indent + 2);
@@ -806,11 +812,10 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_COMPLEX:
     case DEMANGLE_COMPONENT_IMAGINARY:
     case DEMANGLE_COMPONENT_VENDOR_TYPE:
-    case DEMANGLE_COMPONENT_ARGLIST:
-    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
     case DEMANGLE_COMPONENT_CAST:
     case DEMANGLE_COMPONENT_JAVA_RESOURCE:
     case DEMANGLE_COMPONENT_DECLTYPE:
+    case DEMANGLE_COMPONENT_PACK_EXPANSION:
       if (left == NULL)
        return NULL;
       break;
@@ -831,6 +836,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_RESTRICT_THIS:
     case DEMANGLE_COMPONENT_VOLATILE_THIS:
     case DEMANGLE_COMPONENT_CONST_THIS:
+    case DEMANGLE_COMPONENT_ARGLIST:
+    case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
       break;
 
       /* Other types should not be seen here.  */
@@ -1433,6 +1440,7 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "da", NL ("delete[]"),  1 },
   { "de", NL ("*"),         1 },
   { "dl", NL ("delete"),    1 },
+  { "dt", NL ("."),         2 },
   { "dv", NL ("/"),         2 },
   { "eO", NL ("^="),        2 },
   { "eo", NL ("^"),         2 },
@@ -1875,21 +1883,24 @@ cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
   /* n */ { NL ("__int128"),   NL ("__int128"),        D_PRINT_DEFAULT },
   /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
            D_PRINT_DEFAULT },
-  /* The decimal floating point and half-precision floating point types
-     don't use the normal builtin type encoding, they're just stuck into
-     holes in the table for convenience.  */
-  /* p */ { NL ("decimal32"),  NL ("decimal32"),       D_PRINT_DEFAULT },
-  /* q */ { NL ("decimal64"),  NL ("decimal64"),       D_PRINT_DEFAULT },
-  /* r */ { NL ("decimal128"), NL ("decimal128"),      D_PRINT_DEFAULT },
+  /* p */ { NULL, 0,           NULL, 0,                D_PRINT_DEFAULT },
+  /* q */ { NULL, 0,           NULL, 0,                D_PRINT_DEFAULT },
+  /* r */ { NULL, 0,           NULL, 0,                D_PRINT_DEFAULT },
   /* s */ { NL ("short"),      NL ("short"),           D_PRINT_DEFAULT },
   /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
-  /* u */ { NL ("half"),       NL ("half"),            D_PRINT_FLOAT },
+  /* u */ { NULL, 0,           NULL, 0,                D_PRINT_DEFAULT },
   /* v */ { NL ("void"),       NL ("void"),            D_PRINT_VOID },
   /* w */ { NL ("wchar_t"),    NL ("char"),            D_PRINT_DEFAULT },
   /* x */ { NL ("long long"),  NL ("long"),            D_PRINT_LONG_LONG },
   /* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
            D_PRINT_UNSIGNED_LONG_LONG },
   /* z */ { NL ("..."),                NL ("..."),             D_PRINT_DEFAULT },
+  /* 26 */ { NL ("decimal32"), NL ("decimal32"),       D_PRINT_DEFAULT },
+  /* 27 */ { NL ("decimal64"), NL ("decimal64"),       D_PRINT_DEFAULT },
+  /* 28 */ { NL ("decimal128"),        NL ("decimal128"),      D_PRINT_DEFAULT },
+  /* 29 */ { NL ("half"),      NL ("half"),            D_PRINT_FLOAT },
+  /* 30 */ { NL ("char16_t"),  NL ("char16_t"),        D_PRINT_DEFAULT },
+  /* 31 */ { NL ("char32_t"),  NL ("char32_t"),        D_PRINT_DEFAULT },
 };
 
 CP_STATIC_IF_GLIBCPP_V3
@@ -2070,30 +2081,38 @@ cplus_demangle_type (struct d_info *di)
          
        case 'p':
          /* Pack expansion.  */
-         return NULL;
+         ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
+                            cplus_demangle_type (di), NULL);
+         break;
          
        case 'f':
-         /* 32-bit DFP */
-         ret = d_make_builtin_type (di,
-                                    &cplus_demangle_builtin_types['p' - 'a']);
+         /* 32-bit decimal floating point */
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
        case 'd':
-         /* 64-bit decimal floating point */
-         ret = d_make_builtin_type (di,
-                                    &cplus_demangle_builtin_types['q' - 'a']);
+         /* 64-bit DFP */
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[27]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
        case 'e':
          /* 128-bit DFP */
-         ret = d_make_builtin_type (di,
-                                    &cplus_demangle_builtin_types['r' - 'a']);
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[28]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
        case 'h':
          /* 16-bit half-precision FP */
-         ret = d_make_builtin_type (di,
-                                    &cplus_demangle_builtin_types['u' - 'a']);
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[29]);
+         di->expansion += ret->u.s_builtin.type->len;
+         break;
+       case 's':
+         /* char16_t */
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[30]);
+         di->expansion += ret->u.s_builtin.type->len;
+         break;
+       case 'i':
+         /* char32_t */
+         ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[31]);
          di->expansion += ret->u.s_builtin.type->len;
          break;
        }
@@ -2390,6 +2409,13 @@ d_template_args (struct d_info *di)
   if (! d_check_char (di, 'I'))
     return NULL;
 
+  if (d_peek_char (di) == 'E')
+    {
+      /* An argument pack can be empty.  */
+      d_advance (di, 1);
+      return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, NULL, NULL);
+    }
+
   al = NULL;
   pal = &al;
   while (1)
@@ -2439,6 +2465,10 @@ d_template_arg (struct d_info *di)
     case 'L':
       return d_expr_primary (di);
 
+    case 'I':
+      /* An argument pack.  */
+      return d_template_args (di);
+
     default:
       return cplus_demangle_type (di);
     }
@@ -2452,6 +2482,12 @@ d_exprlist (struct d_info *di)
   struct demangle_component *list = NULL;
   struct demangle_component **p = &list;
 
+  if (d_peek_char (di) == 'E')
+    {
+      d_advance (di, 1);
+      return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
+    }
+
   while (1)
     {
       struct demangle_component *arg = d_expression (di);
@@ -2515,6 +2551,19 @@ d_expression (struct d_info *di)
       d_advance (di, 2);
       return cplus_demangle_type (di);
     }
+  else if (IS_DIGIT (peek))
+    {
+      /* We can get an unqualified name as an expression in the case of
+         a dependent member access, i.e. decltype(T().i).  */
+      struct demangle_component *name = d_unqualified_name (di);
+      if (name == NULL)
+       return NULL;
+      if (d_peek_char (di) == 'I')
+       return d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
+                           d_template_args (di));
+      else
+       return name;
+    }
   else
     {
       struct demangle_component *op;
@@ -3067,6 +3116,123 @@ cplus_demangle_print (int options, const struct demangle_component *dc,
   return dgs.buf;
 }
 
+/* Returns the I'th element of the template arglist ARGS, or NULL on
+   failure.  */
+
+static struct demangle_component *
+d_index_template_argument (struct demangle_component *args, int i)
+{
+  struct demangle_component *a;
+
+  for (a = args;
+       a != NULL;
+       a = d_right (a))
+    {
+      if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+       return NULL;
+      if (i <= 0)
+       break;
+      --i;
+    }
+  if (i != 0 || a == NULL)
+    return NULL;
+
+  return d_left (a);
+}
+
+/* Returns the template argument from the current context indicated by DC,
+   which is a DEMANGLE_COMPONENT_TEMPLATE_PARAM, or NULL.  */
+
+static struct demangle_component *
+d_lookup_template_argument (struct d_print_info *dpi,
+                           const struct demangle_component *dc)
+{
+  if (dpi->templates == NULL)
+    {
+      d_print_error (dpi);
+      return NULL;
+    }
+       
+  return d_index_template_argument
+    (d_right (dpi->templates->template_decl),
+     dc->u.s_number.number);
+}
+
+/* Returns a template argument pack used in DC (any will do), or NULL.  */
+
+static struct demangle_component *
+d_find_pack (struct d_print_info *dpi,
+            const struct demangle_component *dc)
+{
+  struct demangle_component *a;
+  if (dc == NULL)
+    return NULL;
+
+  switch (dc->type)
+    {
+    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+      a = d_lookup_template_argument (dpi, dc);
+      if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+       return a;
+      return NULL;
+
+    case DEMANGLE_COMPONENT_PACK_EXPANSION:
+      return NULL;
+      
+    case DEMANGLE_COMPONENT_NAME:
+    case DEMANGLE_COMPONENT_OPERATOR:
+    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+    case DEMANGLE_COMPONENT_SUB_STD:
+    case DEMANGLE_COMPONENT_CHARACTER:
+      return NULL;
+
+    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+      return d_find_pack (dpi, dc->u.s_extended_operator.name);
+    case DEMANGLE_COMPONENT_CTOR:
+      return d_find_pack (dpi, dc->u.s_ctor.name);
+    case DEMANGLE_COMPONENT_DTOR:
+      return d_find_pack (dpi, dc->u.s_dtor.name);
+
+    default:
+      a = d_find_pack (dpi, d_left (dc));
+      if (a)
+       return a;
+      return d_find_pack (dpi, d_right (dc));
+    }
+}
+
+/* Returns the length of the template argument pack DC.  */
+
+static int
+d_pack_length (const struct demangle_component *dc)
+{
+  int count = 0;
+  while (dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST
+        && d_left (dc) != NULL)
+    {
+      ++count;
+      dc = d_right (dc);
+    }
+  return count;
+}
+
+/* DC is a component of a mangled expression.  Print it, wrapped in parens
+   if needed.  */
+
+static void
+d_print_subexpr (struct d_print_info *dpi,
+                const struct demangle_component *dc)
+{
+  int simple = 0;
+  if (dc->type == DEMANGLE_COMPONENT_NAME)
+    simple = 1;
+  if (!simple)
+    d_append_char (dpi, '(');
+  d_print_comp (dpi, dc);
+  if (!simple)
+    d_append_char (dpi, ')');
+}
+
 /* Subroutine to handle components.  */
 
 static void
@@ -3252,30 +3418,13 @@ d_print_comp (struct d_print_info *dpi,
 
     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
       {
-       long i;
-       struct demangle_component *a;
        struct d_print_template *hold_dpt;
+       struct demangle_component *a = d_lookup_template_argument (dpi, dc);
 
-       if (dpi->templates == NULL)
-         {
-           d_print_error (dpi);
-           return;
-         }
-       i = dc->u.s_number.number;
-       for (a = d_right (dpi->templates->template_decl);
-            a != NULL;
-            a = d_right (a))
-         {
-           if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
-             {
-               d_print_error (dpi);
-               return;
-             }
-           if (i <= 0)
-             break;
-           --i;
-         }
-       if (i != 0 || a == NULL)
+       if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+         a = d_index_template_argument (a, dpi->pack_index);
+
+       if (a == NULL)
          {
            d_print_error (dpi);
            return;
@@ -3289,7 +3438,7 @@ d_print_comp (struct d_print_info *dpi,
        hold_dpt = dpi->templates;
        dpi->templates = hold_dpt->next;
 
-       d_print_comp (dpi, d_left (a));
+       d_print_comp (dpi, a);
 
        dpi->templates = hold_dpt;
 
@@ -3578,7 +3727,8 @@ d_print_comp (struct d_print_info *dpi,
 
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
-      d_print_comp (dpi, d_left (dc));
+      if (d_left (dc) != NULL)
+       d_print_comp (dpi, d_left (dc));
       if (d_right (dc) != NULL)
        {
          d_append_string (dpi, ", ");
@@ -3618,11 +3768,12 @@ d_print_comp (struct d_print_info *dpi,
          d_print_cast (dpi, d_left (dc));
          d_append_char (dpi, ')');
        }
-      d_append_char (dpi, '(');
-      if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST
-         || d_right (dc)->type != DEMANGLE_COMPONENT_BUILTIN_TYPE)
-       d_print_comp (dpi, d_right (dc));
-      d_append_char (dpi, ')');
+      if (d_left (dc)->type == DEMANGLE_COMPONENT_CAST
+         && d_right (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
+       /* type() -- FIXME what about type(multiple,args) */
+       d_append_string (dpi, "()");
+      else
+       d_print_subexpr (dpi, d_right (dc));
       return;
 
     case DEMANGLE_COMPONENT_BINARY:
@@ -3632,15 +3783,6 @@ d_print_comp (struct d_print_info *dpi,
          return;
        }
 
-      if (!strcmp (d_left (dc)->u.s_operator.op->code, "cl"))
-       {
-         d_print_comp (dpi, d_left (d_right (dc)));
-         d_append_string (dpi, " (");
-         d_print_comp (dpi, d_right (d_right (dc)));
-         d_append_char (dpi, ')');
-         return;
-       }
-
       /* We wrap an expression which uses the greater-than operator in
         an extra layer of parens so that it does not get confused
         with the '>' which ends the template parameters.  */
@@ -3649,13 +3791,10 @@ d_print_comp (struct d_print_info *dpi,
          && d_left (dc)->u.s_operator.op->name[0] == '>')
        d_append_char (dpi, '(');
 
-      d_append_char (dpi, '(');
-      d_print_comp (dpi, d_left (d_right (dc)));
-      d_append_string (dpi, ") ");
-      d_print_expr_op (dpi, d_left (dc));
-      d_append_string (dpi, " (");
-      d_print_comp (dpi, d_right (d_right (dc)));
-      d_append_char (dpi, ')');
+      d_print_subexpr (dpi, d_left (d_right (dc)));
+      if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0)
+       d_print_expr_op (dpi, d_left (dc));
+      d_print_subexpr (dpi, d_right (d_right (dc)));
 
       if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
          && d_left (dc)->u.s_operator.op->len == 1
@@ -3676,15 +3815,11 @@ d_print_comp (struct d_print_info *dpi,
          d_print_error (dpi);
          return;
        }
-      d_append_char (dpi, '(');
-      d_print_comp (dpi, d_left (d_right (dc)));
-      d_append_string (dpi, ") ");
+      d_print_subexpr (dpi, d_left (d_right (dc)));
       d_print_expr_op (dpi, d_left (dc));
-      d_append_string (dpi, " (");
-      d_print_comp (dpi, d_left (d_right (d_right (dc))));
-      d_append_string (dpi, ") : (");
-      d_print_comp (dpi, d_right (d_right (d_right (dc))));
-      d_append_char (dpi, ')');
+      d_print_subexpr (dpi, d_left (d_right (d_right (dc))));
+      d_append_string (dpi, " : ");
+      d_print_subexpr (dpi, d_right (d_right (d_right (dc))));
       return;
 
     case DEMANGLE_COMPONENT_TRINARY_ARG1:
@@ -3797,6 +3932,23 @@ d_print_comp (struct d_print_info *dpi,
       d_append_char (dpi, ')');
       return;
 
+    case DEMANGLE_COMPONENT_PACK_EXPANSION:
+      {
+       struct demangle_component *a = d_find_pack (dpi, d_left (dc));
+       int len = d_pack_length (a);
+       int i;
+
+       dc = d_left (dc);
+       for (i = 0; i < len; ++i)
+         {
+           dpi->pack_index = i;
+           d_print_comp (dpi, dc);
+           if (i < len-1)
+             d_append_string (dpi, ", ");
+         }
+      }
+      return;
+
     default:
       d_print_error (dpi);
       return;
index 8622f29ca89ea8c1a2a0d5a13a4751c016be4002..aad37437400248a744566566c9a1a7e57c525906 100644 (file)
@@ -147,7 +147,7 @@ struct d_info
 extern const struct demangle_operator_info cplus_demangle_operators[];
 #endif
 
-#define D_BUILTIN_TYPE_COUNT (26)
+#define D_BUILTIN_TYPE_COUNT (32)
 
 CP_STATIC_IF_GLIBCPP_V3
 const struct demangle_builtin_type_info
index 9358204d2bd5501238c0c8cb2ae2cea9896007bf..d9efbc0d24e08933b0fc073e155b15d972d694f9 100644 (file)
@@ -3345,7 +3345,7 @@ f<X>
 #
 --format=gnu-v3 --no-params
 _ZngILi42EEvN1AIXplT_Li2EEE1TE
-void operator-<42>(A<(42) + (2)>::T)
+void operator-<42>(A<(42)+(2)>::T)
 operator-<42>
 #
 --format=gnu-v3 --no-params
@@ -3385,7 +3385,7 @@ int* const volatile restrict _far
 # 
 --format=gnu-v3 --no-params
 _Z3fooILi2EEvRAplT_Li1E_i
-void foo<2>(int (&) [(2) + (1)])
+void foo<2>(int (&) [(2)+(1)])
 foo<2>
 # 
 --format=gnu-v3 --no-params
@@ -3612,13 +3612,13 @@ hairyfunc5
 # This is from gcc PR 8861
 --format=gnu-v3 --no-params
 _Z1fILi1ELc120EEv1AIXplT_cviLd810000000000000000703DAD7A370C5EEE
-void f<1, (char)120>(A<(1) + ((int)((double)[810000000000000000703DAD7A370C5]))>)
+void f<1, (char)120>(A<(1)+((int)((double)[810000000000000000703DAD7A370C5]))>)
 f<1, (char)120>
 #
 # This is also from gcc PR 8861
 --format=gnu-v3 --no-params
 _Z1fILi1EEv1AIXplT_cvingLf3f800000EEE
-void f<1>(A<(1) + ((int)(-((float)[3f800000])))>)
+void f<1>(A<(1)+((int)(-((float)[3f800000])))>)
 f<1>
 #
 # This is from a libstdc++ debug mode patch.
@@ -3643,7 +3643,7 @@ f
 # confusion with the '>' which ends the template parameters.
 --format=gnu-v3 --no-params
 _Z4dep9ILi3EEvP3fooIXgtT_Li2EEE
-void dep9<3>(foo<((3) > (2))>*)
+void dep9<3>(foo<((3)>(2))>*)
 dep9<3>
 #
 # Watch out for templated version of `operator<'--it needs an extra
@@ -3885,16 +3885,20 @@ java resource java/util/iso4217.properties
 # decltype/param placeholder test
 --format=gnu-v3
 _Z3addIidEDTplsTT_sTT0_ES0_S1_
-decltype ((int) + (double)) add<int, double>(int, double)
-# decltype/T() test
---format=gnu-v3
-_Z4add2IidEDTplcvT_vcvT0_vES0_S1_
-decltype (((int)()) + ((double)())) add2<int, double>(int, double)
+decltype ((int)+(double)) add<int, double>(int, double)
 # decltype/fn call test
 --format=gnu-v3
 _Z4add3IidEDTclL_Z1gEsTT_sTT0_EES0_S1_
-decltype (g (int, double)) add3<int, double>(int, double)
-# Extended floating point types test
+decltype (g(int, double)) add3<int, double>(int, double)
+# new (2008) built in types test
+--format=gnu-v3
+_Z1fDfDdDeDhDsDi
+f(decimal32, decimal64, decimal128, half, char16_t, char32_t)
+# pack expansion test
+--format=gnu-v3
+_Z1fIIPiPfPdEEvDpT_
+void f<int*, float*, double*>(int*, float*, double*)
+# '.' test
 --format=gnu-v3
-_Z1fDfDdDeDh
-f(decimal32, decimal64, decimal128, half)
+_Z1hI1AIiEdEDTcldtsTT_1gIT0_EEES2_S3_
+decltype (((A<int>).(g<double>))()) h<A<int>, double>(A<int>, double)
index 153e6947eb75bd07f448a244a2a1de156440242d..7ab200becd45fdf7759f1abd4b3ac47c52b2a0c3 100644 (file)
@@ -1,3 +1,7 @@
+2008-10-06  Jason Merrill  <jason@redhat.com>
+
+       * config/abi/pre/gnu.ver: Update char16/32_t manglings.
+
 2008-10-05  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * testsuite/20_util/reference_wrapper/invoke.cc: New.
index 56fa9be3e6ef30a72993696c3c14e99d85be65c5..024fcfd40869c172954c586b6f6b03d989e6f2e2 100644 (file)
@@ -1104,12 +1104,12 @@ CXXABI_1.3.2 {
 CXXABI_1.3.3 {
 
     # typeinfo for char16_t and char32_t
-    _ZTIu8char16_t;
-    _ZTIPu8char16_t;
-    _ZTIPKu8char16_t;
-    _ZTIu8char32_t;
-    _ZTIPu8char32_t;
-    _ZTIPKu8char32_t;
+    _ZTIDs;
+    _ZTIPDs;
+    _ZTIPKDs;
+    _ZTIDi;
+    _ZTIPDi;
+    _ZTIPKDi;
 
     # exception_ptr
     _ZNSt15__exception_ptr13exception_ptrC1Ev;