aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-10-15 23:59:23 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-10-15 23:59:23 +0000
commit3fa3c4bd5ddac8b45f59dee4c35400c2a5739e9e (patch)
tree0134f16c7bc733a94804996062fde94ce3d4b0f6 /gcc
parentc15c18c5815a10afc6057038d2a50053083a5491 (diff)
downloadgcc-3fa3c4bd5ddac8b45f59dee4c35400c2a5739e9e.zip
gcc-3fa3c4bd5ddac8b45f59dee4c35400c2a5739e9e.tar.gz
gcc-3fa3c4bd5ddac8b45f59dee4c35400c2a5739e9e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/cp/lex.c3
-rw-r--r--gcc/cp/mangle.c132
-rw-r--r--gcc/testsuite/ChangeLog10
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle13.C28
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle14.C12
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle15.C14
-rw-r--r--gcc/testsuite/g++.dg/init/array6.C3
10 files changed, 198 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 211f275..c529abb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2002-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ * 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 <jason@redhat.com>
* call.c (call_builtin_trap): New fn.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c834440..52f921c 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 d122dfb..70d5d31 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 bab2988..4558940 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 76fd5f7..642bc73 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 <source-name>. IDENTIFIER is an IDENTIFIER_NODE.
<source-name> ::= </length/ number> <identifier> */
@@ -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)
<expr-primary> ::= <template-param>
::= L <type> <value number> E # literal
- ::= L <mangled-name> E # external name */
+ ::= L <mangled-name> E # external name
+ ::= sr <type> <unqualified-name>
+ ::= sr <type> <unqualified-name> <template-args> */
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 20de763..50f478fc5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,7 +1,15 @@
+2002-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ * 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 <mark@codesourcery.com>
* g++.dg/abi/empty8.C: New test.
-
+
2002-10-15 Nathan Sidwell <nathan@codesourcery.com>
* 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 0000000..716c4c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle13.C
@@ -0,0 +1,28 @@
+// { dg-options "-fabi-version=0" }
+
+struct A {
+ template <typename T> int f ();
+ int operator+();
+ operator int ();
+ template <typename T>
+ int operator-();
+};
+
+typedef int (A::*P)();
+
+template <P> struct S {};
+
+template <typename T> void g (S<&T::template f<int> >) {}
+template <typename T> void g (S<&T::operator+ >) {}
+template <typename T> void g (S<&T::operator int>) {}
+template <typename T> void g (S<&T::template operator- <double> >) {}
+
+template void g<A> (S<&A::f<int> >);
+template void g<A> (S<&A::operator+>);
+template void g<A> (S<&A::operator int>);
+template void g<A> (S<&A::operator-<double> >);
+
+// { 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 0000000..8e2bfdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle14.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-Wabi" }
+
+struct A {
+ template <typename T> int f ();
+};
+
+typedef int (A::*P)();
+
+template <P> struct S {};
+
+void g (S<&A::f<int> >) {} // { 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 0000000..3c112e2
--- /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 <typename T> int f ();
+};
+
+typedef int (A::*P)();
+
+template <P> struct S {};
+
+void g (S<&A::f<int> >) {}
+
+// { 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 0000000..1b04709
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array6.C
@@ -0,0 +1,3 @@
+// { dg-do compile }
+
+char arr [][4] = { "one", "two" };