From 3fa3c4bd5ddac8b45f59dee4c35400c2a5739e9e Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 15 Oct 2002 23:59:23 +0000 Subject: [PATCH] decl.c (reshape_init): Fix typo. * decl.c (reshape_init): Fix typo. * cp-tree.h (operator_name_info_t): Add arity. * lex.c (init_operators): Initialize it. * mangle.c (write_conversion_operator_name): New function. (write_unqualified_name): Use it. (write_template_args): Accept template arguments as a TREE_LIST. (write_expression): Adjust handling of qualified names to match specification. * g++.dg/init/array6.C: New test. * g++.dg/abi/mangle13.C: Likewise. * g++.dg/abi/mangle14.C: Likewise. * g++.dg/abi/mangle15.C: Likewise. From-SVN: r58185 --- gcc/cp/ChangeLog | 12 +++ gcc/cp/cp-tree.h | 2 + gcc/cp/decl.c | 2 +- gcc/cp/lex.c | 3 +- gcc/cp/mangle.c | 132 ++++++++++++++++++++++++---- gcc/testsuite/ChangeLog | 10 ++- gcc/testsuite/g++.dg/abi/mangle13.C | 28 ++++++ gcc/testsuite/g++.dg/abi/mangle14.C | 12 +++ gcc/testsuite/g++.dg/abi/mangle15.C | 14 +++ gcc/testsuite/g++.dg/init/array6.C | 3 + 10 files changed, 198 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/mangle13.C create mode 100644 gcc/testsuite/g++.dg/abi/mangle14.C create mode 100644 gcc/testsuite/g++.dg/abi/mangle15.C create mode 100644 gcc/testsuite/g++.dg/init/array6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 211f275e586..c529abbb323 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2002-10-15 Mark Mitchell + + * decl.c (reshape_init): Fix typo. + + * cp-tree.h (operator_name_info_t): Add arity. + * lex.c (init_operators): Initialize it. + * mangle.c (write_conversion_operator_name): New function. + (write_unqualified_name): Use it. + (write_template_args): Accept template arguments as a TREE_LIST. + (write_expression): Adjust handling of qualified names to match + specification. + 2002-10-15 Jason Merrill * call.c (call_builtin_trap): New fn. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c8344406162..52f921cab84 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3481,6 +3481,8 @@ typedef struct operator_name_info_t const char *name; /* The mangled name of the operator. */ const char *mangled_name; + /* The arity of the operator. */ + int arity; } operator_name_info_t; /* A mapping from tree codes to operator name information. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index d122dfbe3be..70d5d318f33 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7836,7 +7836,7 @@ reshape_init (tree type, tree *initp) return old_init; } - if (TREE_CODE (old_init) == STRING_CST + if (TREE_CODE (old_init_value) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE && char_type_p (TREE_TYPE (type))) { diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index bab29888e8b..4558940d675 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -263,7 +263,8 @@ init_operators () : &operator_name_info[(int) CODE]); \ oni->identifier = identifier; \ oni->name = NAME; \ - oni->mangled_name = MANGLING; + oni->mangled_name = MANGLING; \ + oni->arity = ARITY; #include "operators.def" #undef DEF_OPERATOR diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 76fd5f7e425..642bc735d64 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -166,6 +166,7 @@ static void write_nested_name PARAMS ((tree)); static void write_prefix PARAMS ((tree)); static void write_template_prefix PARAMS ((tree)); static void write_unqualified_name PARAMS ((tree)); +static void write_conversion_operator_name (tree); static void write_source_name PARAMS ((tree)); static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned)); static void write_number PARAMS ((unsigned HOST_WIDE_INT, int, @@ -1016,8 +1017,7 @@ write_unqualified_name (decl) } else type = TREE_TYPE (DECL_NAME (decl)); - write_string ("cv"); - write_type (type); + write_conversion_operator_name (type); } else if (DECL_OVERLOADED_OPERATOR_P (decl)) { @@ -1033,6 +1033,15 @@ write_unqualified_name (decl) write_source_name (DECL_NAME (decl)); } +/* Write the unqualified-name for a conversion operator to TYPE. */ + +static void +write_conversion_operator_name (tree type) +{ + write_string ("cv"); + write_type (type); +} + /* Non-termial . IDENTIFIER is an IDENTIFIER_NODE. ::= */ @@ -1780,24 +1789,37 @@ static void write_template_args (args) tree args; { - int i; - int length = TREE_VEC_LENGTH (args); - MANGLE_TRACE_TREE ("template-args", args); - my_friendly_assert (length > 0, 20000422); + write_char ('I'); - if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) + if (TREE_CODE (args) == TREE_VEC) { - /* We have nested template args. We want the innermost template - argument list. */ - args = TREE_VEC_ELT (args, length - 1); - length = TREE_VEC_LENGTH (args); + int i; + int length = TREE_VEC_LENGTH (args); + my_friendly_assert (length > 0, 20000422); + + if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) + { + /* We have nested template args. We want the innermost template + argument list. */ + args = TREE_VEC_ELT (args, length - 1); + length = TREE_VEC_LENGTH (args); + } + for (i = 0; i < length; ++i) + write_template_arg (TREE_VEC_ELT (args, i)); + } + else + { + my_friendly_assert (TREE_CODE (args) == TREE_LIST, 20021014); + + while (args) + { + write_template_arg (TREE_VALUE (args)); + args = TREE_CHAIN (args); + } } - write_char ('I'); - for (i = 0; i < length; ++i) - write_template_arg (TREE_VEC_ELT (args, i)); write_char ('E'); } @@ -1807,7 +1829,9 @@ write_template_args (args) ::= ::= L E # literal - ::= L E # external name */ + ::= L E # external name + ::= sr + ::= sr */ static void write_expression (expr) @@ -1859,6 +1883,75 @@ write_expression (expr) write_string ("st"); write_type (TREE_OPERAND (expr, 0)); } + else if (abi_version_at_least (2) && TREE_CODE (expr) == SCOPE_REF) + { + tree scope = TREE_OPERAND (expr, 0); + tree member = TREE_OPERAND (expr, 1); + + /* If the MEMBER is a real declaration, then the qualifying + scope was not dependent. Ideally, we would not have a + SCOPE_REF in those cases, but sometimes we do. If the second + argument is a DECL, then the name must not have been + dependent. */ + if (DECL_P (member)) + write_expression (member); + else + { + tree template_args; + + write_string ("sr"); + write_type (scope); + /* If MEMBER is a template-id, separate the template + from the arguments. */ + if (TREE_CODE (member) == TEMPLATE_ID_EXPR) + { + template_args = TREE_OPERAND (member, 1); + member = TREE_OPERAND (member, 0); + if (TREE_CODE (member) == LOOKUP_EXPR) + member = TREE_OPERAND (member, 0); + } + else + template_args = NULL_TREE; + /* Write out the name of the MEMBER. */ + if (IDENTIFIER_TYPENAME_P (member)) + write_conversion_operator_name (TREE_TYPE (member)); + else if (IDENTIFIER_OPNAME_P (member)) + { + int i; + const char *mangled_name = NULL; + + /* Unfortunately, there is no easy way to go from the + name of the operator back to the corresponding tree + code. */ + for (i = 0; i < LAST_CPLUS_TREE_CODE; ++i) + if (operator_name_info[i].identifier == member) + { + /* The ABI says that we prefer binary operator + names to unary operator names. */ + if (operator_name_info[i].arity == 2) + { + mangled_name = operator_name_info[i].mangled_name; + break; + } + else if (!mangled_name) + mangled_name = operator_name_info[i].mangled_name; + } + else if (assignment_operator_name_info[i].identifier + == member) + { + mangled_name + = assignment_operator_name_info[i].mangled_name; + break; + } + write_string (mangled_name); + } + else + write_source_name (member); + /* Write out the template arguments. */ + if (template_args) + write_template_args (template_args); + } + } else { int i; @@ -1880,7 +1973,7 @@ write_expression (expr) code = TREE_CODE (expr); } - + /* If it wasn't any of those, recursively expand the expression. */ write_string (operator_name_info[(int) code].mangled_name); @@ -1904,7 +1997,12 @@ write_expression (expr) if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE) write_source_name (TREE_OPERAND (expr, 1)); else - write_encoding (TREE_OPERAND (expr, 1)); + { + /* 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)); + } break; default: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 20de7631d65..50f478fc586 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,7 +1,15 @@ +2002-10-15 Mark Mitchell + + * g++.dg/init/array6.C: New test. + + * g++.dg/abi/mangle13.C: Likewise. + * g++.dg/abi/mangle14.C: Likewise. + * g++.dg/abi/mangle15.C: Likewise. + 2002-10-14 Mark Mitchell * g++.dg/abi/empty8.C: New test. - + 2002-10-15 Nathan Sidwell * g++.dg/init/ctor1.C: New test. diff --git a/gcc/testsuite/g++.dg/abi/mangle13.C b/gcc/testsuite/g++.dg/abi/mangle13.C new file mode 100644 index 00000000000..716c4c36f41 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle13.C @@ -0,0 +1,28 @@ +// { dg-options "-fabi-version=0" } + +struct A { + template int f (); + int operator+(); + operator int (); + template + int operator-(); +}; + +typedef int (A::*P)(); + +template

struct S {}; + +template void g (S<&T::template f >) {} +template void g (S<&T::operator+ >) {} +template void g (S<&T::operator int>) {} +template void g (S<&T::template operator- >) {} + +template void g (S<&A::f >); +template void g (S<&A::operator+>); +template void g (S<&A::operator int>); +template void g (S<&A::operator- >); + +// { dg-final { scan-assembler _Z1gI1AEv1SIXadsrT_1fIiEEE } } +// { dg-final { scan-assembler _Z1gI1AEv1SIXadsrT_plEE } } +// { dg-final { scan-assembler _Z1gI1AEv1SIXadsrT_cviEE } } +// { dg-final { scan-assembler _Z1gI1AEv1SIXadsrT_miIdEEE } } diff --git a/gcc/testsuite/g++.dg/abi/mangle14.C b/gcc/testsuite/g++.dg/abi/mangle14.C new file mode 100644 index 00000000000..8e2bfddde76 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle14.C @@ -0,0 +1,12 @@ +// { dg-do compile } +// { dg-options "-Wabi" } + +struct A { + template int f (); +}; + +typedef int (A::*P)(); + +template

struct S {}; + +void g (S<&A::f >) {} // { dg-warning "mangle" } diff --git a/gcc/testsuite/g++.dg/abi/mangle15.C b/gcc/testsuite/g++.dg/abi/mangle15.C new file mode 100644 index 00000000000..3c112e263f0 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle15.C @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-fabi-version=0" } + +struct A { + template int f (); +}; + +typedef int (A::*P)(); + +template

struct S {}; + +void g (S<&A::f >) {} + +// { dg-final { scan-assembler _Z1g1SIXadL_ZN1A1fIiEEivEEE } } diff --git a/gcc/testsuite/g++.dg/init/array6.C b/gcc/testsuite/g++.dg/init/array6.C new file mode 100644 index 00000000000..1b04709cb92 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array6.C @@ -0,0 +1,3 @@ +// { dg-do compile } + +char arr [][4] = { "one", "two" };