aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-07-15 14:38:15 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-07-15 14:38:15 -0400
commit34bbc4c502157fb08e6eba1d09380e2599ec3720 (patch)
tree1ee707547ea5521e317e522ed83b170324ec4a05 /gcc/cp
parentd022c55a4b8bdac385efadf42ba2a374c5960418 (diff)
downloadgcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.zip
gcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.tar.gz
gcc-34bbc4c502157fb08e6eba1d09380e2599ec3720.tar.bz2
PR c++/71814 - mangling sizeof... (sP and sZ)
gcc/cp/ * mangle.c (write_expression): Handle sizeof... an argument pack. libiberty/ * cp-demangle.c (cplus_demangle_operators): Add sP and sZ. (d_print_comp_inner): Handle them. (d_template_args_1): Split out from d_template_args. (d_args_length): New. From-SVN: r238389
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/mangle.c71
2 files changed, 64 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1ef3812..eb4f0b9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2016-07-15 Jason Merrill <jason@redhat.com>
+ PR c++/71814
+ * mangle.c (write_expression): Handle sizeof... an argument pack.
+
PR c++/71718
* pt.c (push_tinst_level_loc): Set at_eof before fatal_error.
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 0e44409..8205da9 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2767,17 +2767,67 @@ write_expression (tree expr)
write_mangled_name (expr, false);
write_char ('E');
}
- else if (TREE_CODE (expr) == SIZEOF_EXPR
- && SIZEOF_EXPR_TYPE_P (expr))
+ else if (TREE_CODE (expr) == SIZEOF_EXPR)
{
- write_string ("st");
- write_type (TREE_TYPE (TREE_OPERAND (expr, 0)));
- }
- else if (TREE_CODE (expr) == SIZEOF_EXPR
- && TYPE_P (TREE_OPERAND (expr, 0)))
- {
- write_string ("st");
- write_type (TREE_OPERAND (expr, 0));
+ tree op = TREE_OPERAND (expr, 0);
+
+ if (PACK_EXPANSION_P (op))
+ {
+ if (abi_warn_or_compat_version_crosses (11))
+ G.need_abi_warning = true;
+ if (abi_version_at_least (11))
+ {
+ /* sZ rather than szDp. */
+ write_string ("sZ");
+ write_expression (PACK_EXPANSION_PATTERN (op));
+ return;
+ }
+ }
+
+ if (SIZEOF_EXPR_TYPE_P (expr))
+ {
+ write_string ("st");
+ write_type (TREE_TYPE (op));
+ }
+ else if (ARGUMENT_PACK_P (op))
+ {
+ tree args = ARGUMENT_PACK_ARGS (op);
+ int length = TREE_VEC_LENGTH (args);
+ if (abi_warn_or_compat_version_crosses (10))
+ G.need_abi_warning = true;
+ if (abi_version_at_least (10))
+ {
+ /* sP <template-arg>* E # sizeof...(T), size of a captured
+ template parameter pack from an alias template */
+ write_string ("sP");
+ for (int i = 0; i < length; ++i)
+ write_template_arg (TREE_VEC_ELT (args, i));
+ write_char ('E');
+ }
+ else
+ {
+ /* In GCC 5 we represented this sizeof wrong, with the effect
+ that we mangled it as the last element of the pack. */
+ tree arg = TREE_VEC_ELT (args, length-1);
+ if (TYPE_P (op))
+ {
+ write_string ("st");
+ write_type (arg);
+ }
+ else
+ {
+ write_string ("sz");
+ write_expression (arg);
+ }
+ }
+ }
+ else if (TYPE_P (TREE_OPERAND (expr, 0)))
+ {
+ write_string ("st");
+ write_type (TREE_OPERAND (expr, 0));
+ }
+ else
+ goto normal_expr;
}
else if (TREE_CODE (expr) == ALIGNOF_EXPR
&& TYPE_P (TREE_OPERAND (expr, 0)))
@@ -2947,6 +2997,7 @@ write_expression (tree expr)
}
else
{
+ normal_expr:
int i, len;
const char *name;