Commit 3fa3c4bd by Mark Mitchell Committed by Mark Mitchell

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
parent c15c18c5
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> 2002-10-15 Jason Merrill <jason@redhat.com>
* call.c (call_builtin_trap): New fn. * call.c (call_builtin_trap): New fn.
......
...@@ -3481,6 +3481,8 @@ typedef struct operator_name_info_t ...@@ -3481,6 +3481,8 @@ typedef struct operator_name_info_t
const char *name; const char *name;
/* The mangled name of the operator. */ /* The mangled name of the operator. */
const char *mangled_name; const char *mangled_name;
/* The arity of the operator. */
int arity;
} operator_name_info_t; } operator_name_info_t;
/* A mapping from tree codes to operator name information. */ /* A mapping from tree codes to operator name information. */
......
...@@ -7836,7 +7836,7 @@ reshape_init (tree type, tree *initp) ...@@ -7836,7 +7836,7 @@ reshape_init (tree type, tree *initp)
return old_init; return old_init;
} }
if (TREE_CODE (old_init) == STRING_CST if (TREE_CODE (old_init_value) == STRING_CST
&& TREE_CODE (type) == ARRAY_TYPE && TREE_CODE (type) == ARRAY_TYPE
&& char_type_p (TREE_TYPE (type))) && char_type_p (TREE_TYPE (type)))
{ {
......
...@@ -263,7 +263,8 @@ init_operators () ...@@ -263,7 +263,8 @@ init_operators ()
: &operator_name_info[(int) CODE]); \ : &operator_name_info[(int) CODE]); \
oni->identifier = identifier; \ oni->identifier = identifier; \
oni->name = NAME; \ oni->name = NAME; \
oni->mangled_name = MANGLING; oni->mangled_name = MANGLING; \
oni->arity = ARITY;
#include "operators.def" #include "operators.def"
#undef DEF_OPERATOR #undef DEF_OPERATOR
......
...@@ -166,6 +166,7 @@ static void write_nested_name PARAMS ((tree)); ...@@ -166,6 +166,7 @@ static void write_nested_name PARAMS ((tree));
static void write_prefix PARAMS ((tree)); static void write_prefix PARAMS ((tree));
static void write_template_prefix PARAMS ((tree)); static void write_template_prefix PARAMS ((tree));
static void write_unqualified_name PARAMS ((tree)); static void write_unqualified_name PARAMS ((tree));
static void write_conversion_operator_name (tree);
static void write_source_name PARAMS ((tree)); static void write_source_name PARAMS ((tree));
static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned)); static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned));
static void write_number PARAMS ((unsigned HOST_WIDE_INT, int, static void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
...@@ -1016,8 +1017,7 @@ write_unqualified_name (decl) ...@@ -1016,8 +1017,7 @@ write_unqualified_name (decl)
} }
else else
type = TREE_TYPE (DECL_NAME (decl)); type = TREE_TYPE (DECL_NAME (decl));
write_string ("cv"); write_conversion_operator_name (type);
write_type (type);
} }
else if (DECL_OVERLOADED_OPERATOR_P (decl)) else if (DECL_OVERLOADED_OPERATOR_P (decl))
{ {
...@@ -1033,6 +1033,15 @@ write_unqualified_name (decl) ...@@ -1033,6 +1033,15 @@ write_unqualified_name (decl)
write_source_name (DECL_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. /* Non-termial <source-name>. IDENTIFIER is an IDENTIFIER_NODE.
<source-name> ::= </length/ number> <identifier> */ <source-name> ::= </length/ number> <identifier> */
...@@ -1780,24 +1789,37 @@ static void ...@@ -1780,24 +1789,37 @@ static void
write_template_args (args) write_template_args (args)
tree args; tree args;
{ {
int i;
int length = TREE_VEC_LENGTH (args);
MANGLE_TRACE_TREE ("template-args", 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 int i;
argument list. */ int length = TREE_VEC_LENGTH (args);
args = TREE_VEC_ELT (args, length - 1); my_friendly_assert (length > 0, 20000422);
length = TREE_VEC_LENGTH (args);
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'); write_char ('E');
} }
...@@ -1807,7 +1829,9 @@ write_template_args (args) ...@@ -1807,7 +1829,9 @@ write_template_args (args)
<expr-primary> ::= <template-param> <expr-primary> ::= <template-param>
::= L <type> <value number> E # literal ::= 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 static void
write_expression (expr) write_expression (expr)
...@@ -1859,6 +1883,75 @@ write_expression (expr) ...@@ -1859,6 +1883,75 @@ write_expression (expr)
write_string ("st"); write_string ("st");
write_type (TREE_OPERAND (expr, 0)); 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 else
{ {
int i; int i;
...@@ -1880,7 +1973,7 @@ write_expression (expr) ...@@ -1880,7 +1973,7 @@ write_expression (expr)
code = TREE_CODE (expr); code = TREE_CODE (expr);
} }
/* If it wasn't any of those, recursively expand the expression. */ /* If it wasn't any of those, recursively expand the expression. */
write_string (operator_name_info[(int) code].mangled_name); write_string (operator_name_info[(int) code].mangled_name);
...@@ -1904,7 +1997,12 @@ write_expression (expr) ...@@ -1904,7 +1997,12 @@ write_expression (expr)
if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE) if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
write_source_name (TREE_OPERAND (expr, 1)); write_source_name (TREE_OPERAND (expr, 1));
else 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; break;
default: default:
......
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> 2002-10-14 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/empty8.C: New test. * g++.dg/abi/empty8.C: New test.
2002-10-15 Nathan Sidwell <nathan@codesourcery.com> 2002-10-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/init/ctor1.C: New test. * g++.dg/init/ctor1.C: New test.
......
// { 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 } }
// { 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" }
// { 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 } }
// { dg-do compile }
char arr [][4] = { "one", "two" };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment