mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-26 01:29:20 +08:00
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
This commit is contained in:
parent
c15c18c581
commit
3fa3c4bd5d
@ -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.
|
||||
|
@ -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. */
|
||||
|
@ -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)))
|
||||
{
|
||||
|
@ -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
|
||||
|
132
gcc/cp/mangle.c
132
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:
|
||||
|
@ -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.
|
||||
|
28
gcc/testsuite/g++.dg/abi/mangle13.C
Normal file
28
gcc/testsuite/g++.dg/abi/mangle13.C
Normal file
@ -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 } }
|
12
gcc/testsuite/g++.dg/abi/mangle14.C
Normal file
12
gcc/testsuite/g++.dg/abi/mangle14.C
Normal file
@ -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" }
|
14
gcc/testsuite/g++.dg/abi/mangle15.C
Normal file
14
gcc/testsuite/g++.dg/abi/mangle15.C
Normal file
@ -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 } }
|
3
gcc/testsuite/g++.dg/init/array6.C
Normal file
3
gcc/testsuite/g++.dg/init/array6.C
Normal file
@ -0,0 +1,3 @@
|
||||
// { dg-do compile }
|
||||
|
||||
char arr [][4] = { "one", "two" };
|
Loading…
Reference in New Issue
Block a user