diff options
-rw-r--r-- | gcc/cp/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 116 | ||||
-rw-r--r-- | gcc/cp/operators.def | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/mangle30.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/auto6.C | 71 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic4.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/variadic42.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/utf-mangle.C | 8 | ||||
-rw-r--r-- | gcc/tree.h | 2 | ||||
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/demangle.h | 4 | ||||
-rw-r--r-- | libiberty/ChangeLog | 19 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 298 | ||||
-rw-r--r-- | libiberty/cp-demangle.h | 2 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 32 | ||||
-rw-r--r-- | libstdc++-v3/ChangeLog | 4 | ||||
-rw-r--r-- | libstdc++-v3/config/abi/pre/gnu.ver | 12 |
17 files changed, 487 insertions, 138 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dc18acc4fb0..222693f2a52 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 7b4c30344cc..c0282d8ade5 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -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); diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index 9c2dd8b2ca1..20c74d88220 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -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 index 00000000000..f0b83dbe929 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle30.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/auto6.C b/gcc/testsuite/g++.dg/cpp0x/auto6.C index 713583a1a48..d2bcfedb63c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/auto6.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto6.C @@ -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() ); } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic4.C b/gcc/testsuite/g++.dg/cpp0x/variadic4.C index 6c15a6de92d..9257a92d5b9 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic4.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic4.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic42.C b/gcc/testsuite/g++.dg/cpp0x/variadic42.C index 4c6c7673d80..47d9b66da58 100644 --- a/gcc/testsuite/g++.dg/cpp0x/variadic42.C +++ b/gcc/testsuite/g++.dg/cpp0x/variadic42.C @@ -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_" } } diff --git a/gcc/testsuite/g++.dg/ext/utf-mangle.C b/gcc/testsuite/g++.dg/ext/utf-mangle.C index bb5e3822adc..a131887882a 100644 --- a/gcc/testsuite/g++.dg/ext/utf-mangle.C +++ b/gcc/testsuite/g++.dg/ext/utf-mangle.C @@ -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:" } } diff --git a/gcc/tree.h b/gcc/tree.h index 85704e69094..44bc3f0f282 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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 diff --git a/include/ChangeLog b/include/ChangeLog index 64b0a6caeeb..20da6186ff0 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -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 diff --git a/include/demangle.h b/include/demangle.h index 146d778e097..0ea639d62ba 100644 --- a/include/demangle.h +++ b/include/demangle.h @@ -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. */ diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index e6980aea132..b0c1c203ac5 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -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. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 3d292f07d0a..3fa5f1f21d3 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -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; diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h index 8622f29ca89..aad37437400 100644 --- a/libiberty/cp-demangle.h +++ b/libiberty/cp-demangle.h @@ -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 diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 9358204d2bd..d9efbc0d24e 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -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) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 153e6947eb7..7ab200becd4 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -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. diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 56fa9be3e6e..024fcfd4086 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -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; |