mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an argument.

* mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
	argument.
	(write_signed_number): New macro.
	(write_unsigned_number): Likewise.
	(write_source_name): Use them.
	(write_number): Handle signed and unsigned values.
	(write_integer_cst): Use tree_int_cst_sgn, and use
	write_unsigned_number or write_signed_number as appropriate.
	(write_discriminator): Use write_unsigned_number or
	write_signed_number as appropriate.
	(write_template_arg_literal): Likewise.
	(write_array_type): Use tree_low_cst.
	(write_template_parm):  Use write_unsigned_number or
	write_signed_number as appropriate.
	(write_substitution): Adjust call to write_number.
	(write_type): Get the TYPE_MAIN_VARIANT before mangling it.
	(write_expression): Handle non-type template arguments of
	reference type correctly.
	(mangle_thunk): Use write_signed_number.

	* mangle.c (find_substition): Don't mangle objects with typename
	substitutions (e.g. "cin" as "Si").

Co-Authored-By: Mark Mitchell <mark@codesourcery.com>

From-SVN: r34488
This commit is contained in:
Chip Salzenberg 2000-06-11 03:57:18 +00:00 committed by Mark Mitchell
parent 4d870388ff
commit 82a362d0a4
3 changed files with 170 additions and 94 deletions

View File

@ -1,3 +1,31 @@
2000-06-09 Chip Salzenberg <chip@valinux.com>
Mark Mitchell <mark@codesourcery.com>
* mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
argument.
(write_signed_number): New macro.
(write_unsigned_number): Likewise.
(write_source_name): Use them.
(write_number): Handle signed and unsigned values.
(write_integer_cst): Use tree_int_cst_sgn, and use
write_unsigned_number or write_signed_number as appropriate.
(write_discriminator): Use write_unsigned_number or
write_signed_number as appropriate.
(write_template_arg_literal): Likewise.
(write_array_type): Use tree_low_cst.
(write_template_parm): Use write_unsigned_number or
write_signed_number as appropriate.
(write_substitution): Adjust call to write_number.
(write_type): Get the TYPE_MAIN_VARIANT before mangling it.
(write_expression): Handle non-type template arguments of
reference type correctly.
(mangle_thunk): Use write_signed_number.
2000-06-09 Chip Salzenberg <chip@valinux.com>
* mangle.c (find_substition): Don't mangle objects with typename
substitutions (e.g. "cin" as "Si").
2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
* call.c (add_candidate): Use ggc_alloc_cleared.

View File

@ -157,7 +157,8 @@ static void write_template_prefix PARAMS ((tree));
static void write_component PARAMS ((tree));
static void write_unqualified_name PARAMS ((tree));
static void write_source_name PARAMS ((tree));
static void write_number PARAMS ((int, int));
static void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
unsigned int));
static void write_integer_cst PARAMS ((tree));
static void write_identifier PARAMS ((char *));
static void write_special_name_constructor PARAMS ((tree));
@ -219,6 +220,14 @@ static tree mangle_special_for_type PARAMS ((tree, const char *));
|| TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \
&& TREE_VALUE (NODE1) == TREE_VALUE (NODE2))
/* Write out a signed quantity in base 10. */
#define write_signed_number(NUMBER) \
write_number (NUMBER, /*unsigned_p=*/0, 10)
/* Write out an unsigned quantity in base 10. */
#define write_unsigned_number(NUMBER) \
write_number (NUMBER, /*unsigned_p=*/1, 10)
/* Produce debugging output of current substitution candidates. */
static void
@ -441,7 +450,7 @@ find_substitution (node)
/* Check for std::basic_string. */
if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
{
if (type)
if (TYPE_P (node))
{
/* If this is a type (i.e. a fully-qualified template-id),
check for
@ -473,7 +482,7 @@ find_substitution (node)
}
/* Check for basic_{i,o,io}stream. */
if (type
if (TYPE_P (node)
&& CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED
&& CLASS_TYPE_P (type)
&& CLASSTYPE_USE_TEMPLATE (type)
@ -510,7 +519,7 @@ find_substitution (node)
}
/* Check for namespace std. */
if (decl&& DECL_NAMESPACE_STD_P (decl))
if (decl && DECL_NAMESPACE_STD_P (decl))
{
write_string ("St");
return 1;
@ -518,7 +527,6 @@ find_substitution (node)
/* Now check the list of available substitutions for this mangling
operation. */
for (i = 0; i < size; ++i)
{
tree candidate = VARRAY_TREE (G.substitutions, i);
@ -604,7 +612,9 @@ static void
write_name (decl)
tree decl;
{
tree context = CP_DECL_CONTEXT (decl);
tree context;
context = CP_DECL_CONTEXT (decl);
MANGLE_TRACE_TREE ("name", decl);
@ -913,7 +923,7 @@ write_source_name (identifier)
if (IDENTIFIER_TEMPLATE (identifier))
identifier = IDENTIFIER_TEMPLATE (identifier);
write_number (IDENTIFIER_LENGTH (identifier), 10);
write_unsigned_number (IDENTIFIER_LENGTH (identifier));
write_identifier (IDENTIFIER_POINTER (identifier));
}
@ -922,20 +932,22 @@ write_source_name (identifier)
<number> ::= [n] </decimal integer/> */
static void
write_number (number, base)
int number;
int base;
write_number (number, unsigned_p, base)
unsigned HOST_WIDE_INT number;
int unsigned_p;
unsigned int base;
{
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n;
int m = 1;
unsigned HOST_WIDE_INT n;
unsigned HOST_WIDE_INT m = 1;
if (number < 0)
if (!unsigned_p && (HOST_WIDE_INT) number < 0)
{
write_char ('n');
number = -number;
number = -((HOST_WIDE_INT) number);
}
/* Figure out how many digits there are. */
n = number;
while (n >= base)
{
@ -943,6 +955,7 @@ write_number (number, base)
m *= base;
}
/* Write them out. */
while (m > 0)
{
int digit = number / m;
@ -960,7 +973,14 @@ static inline void
write_integer_cst (cst)
tree cst;
{
write_number (tree_low_cst (cst, TREE_UNSIGNED (TREE_TYPE (cst))), 10);
if (tree_int_cst_sgn (cst) >= 0)
{
if (TREE_INT_CST_HIGH (cst) != 0)
sorry ("mangling very large integers");
write_unsigned_number (TREE_INT_CST_LOW (cst));
}
else
write_signed_number (tree_low_cst (cst, 0));
}
/* Non-terminal <identifier>.
@ -1086,7 +1106,7 @@ write_discriminator (discriminator)
/* The number is omitted for discriminator == 1. Beyond 1, the
numbering starts at 0. */
if (discriminator > 1)
write_number (discriminator - 2, 10);
write_unsigned_number (discriminator - 2);
}
}
@ -1151,7 +1171,7 @@ write_type (type)
if (find_substitution (type))
return;
if (write_CV_qualifiers_for_type (type) > 0)
/* If TYPE was CV-qualified, we just wrote the qualifiers; now
mangle the unqualified type. The recursive call is needed here
@ -1159,85 +1179,90 @@ write_type (type)
candidates. */
write_type (TYPE_MAIN_VARIANT (type));
else
switch (TREE_CODE (type))
{
case VOID_TYPE:
case BOOLEAN_TYPE:
case INTEGER_TYPE: /* Includes wchar_t. */
case REAL_TYPE:
/* If this is a typedef, TYPE may not be one of
the standard builtin type nodes, but an alias of one. Use
TYPE_MAIN_VARIANT to get to the underlying builtin type. */
write_builtin_type (TYPE_MAIN_VARIANT (type));
++is_builtin_type;
break;
{
/* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type);
case COMPLEX_TYPE:
write_char ('C');
write_type (TREE_TYPE (type));
break;
switch (TREE_CODE (type))
{
case VOID_TYPE:
case BOOLEAN_TYPE:
case INTEGER_TYPE: /* Includes wchar_t. */
case REAL_TYPE:
/* If this is a typedef, TYPE may not be one of
the standard builtin type nodes, but an alias of one. Use
TYPE_MAIN_VARIANT to get to the underlying builtin type. */
write_builtin_type (TYPE_MAIN_VARIANT (type));
++is_builtin_type;
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
write_function_type (type, 1);
break;
case COMPLEX_TYPE:
write_char ('C');
write_type (TREE_TYPE (type));
break;
case UNION_TYPE:
case RECORD_TYPE:
case ENUMERAL_TYPE:
/* A pointer-to-member function is represented as a special
RECORD_TYPE, so check for this first. */
if (TYPE_PTRMEMFUNC_P (type))
write_pointer_to_member_type (type);
else
write_class_enum_type (type);
break;
case FUNCTION_TYPE:
case METHOD_TYPE:
write_function_type (type, 1);
break;
case TYPENAME_TYPE:
/* We handle TYPENAME_TYPEs like ordinary nested names. */
write_nested_name (TYPE_STUB_DECL (type));
break;
case UNION_TYPE:
case RECORD_TYPE:
case ENUMERAL_TYPE:
/* A pointer-to-member function is represented as a special
RECORD_TYPE, so check for this first. */
if (TYPE_PTRMEMFUNC_P (type))
write_pointer_to_member_type (type);
else
write_class_enum_type (type);
break;
case ARRAY_TYPE:
write_array_type (type);
break;
case TYPENAME_TYPE:
/* We handle TYPENAME_TYPEs like ordinary nested names. */
write_nested_name (TYPE_STUB_DECL (type));
break;
case POINTER_TYPE:
/* A pointer-to-member variable is represented by a POINTER_TYPE
to an OFFSET_TYPE, so check for this first. */
if (TYPE_PTRMEM_P (type))
write_pointer_to_member_type (type);
else
{
write_char ('P');
write_type (TREE_TYPE (type));
}
break;
case ARRAY_TYPE:
write_array_type (type);
break;
case REFERENCE_TYPE:
write_char ('R');
write_type (TREE_TYPE (type));
break;
case POINTER_TYPE:
/* A pointer-to-member variable is represented by a POINTER_TYPE
to an OFFSET_TYPE, so check for this first. */
if (TYPE_PTRMEM_P (type))
write_pointer_to_member_type (type);
else
{
write_char ('P');
write_type (TREE_TYPE (type));
}
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
write_template_param (type);
break;
case REFERENCE_TYPE:
write_char ('R');
write_type (TREE_TYPE (type));
break;
case TEMPLATE_TEMPLATE_PARM:
write_template_template_param (type);
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))
write_template_args
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_PARM_INDEX:
write_template_param (type);
break;
case OFFSET_TYPE:
write_pointer_to_member_type (build_pointer_type (type));
break;
case TEMPLATE_TEMPLATE_PARM:
write_template_template_param (type);
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))
write_template_args
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break;
default:
my_friendly_abort (20000409);
}
case OFFSET_TYPE:
write_pointer_to_member_type (build_pointer_type (type));
break;
default:
my_friendly_abort (20000409);
}
}
/* Types other than builtin types are substitution candidates. */
if (!is_builtin_type)
@ -1564,8 +1589,17 @@ write_expression (expr)
if (TREE_CODE (expr) == ADDR_EXPR
&& TREE_TYPE (expr)
&& TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE)
expr = TREE_OPERAND (expr, 0);
{
expr = TREE_OPERAND (expr, 0);
if (DECL_P (expr))
{
write_expression (expr);
return;
}
code = TREE_CODE (expr);
}
/* If it wasn't any of those, recursively expand the expression. */
write_string (operator_name_info[(int) code].mangled_name);
@ -1610,9 +1644,9 @@ write_template_arg_literal (value)
if (same_type_p (type, boolean_type_node))
{
if (value == boolean_false_node || integer_zerop (value))
write_number (0, 10);
write_unsigned_number (0);
else if (value == boolean_true_node)
write_number (1, 10);
write_unsigned_number (1);
else
my_friendly_abort (20000412);
}
@ -1633,7 +1667,9 @@ write_template_arg_literal (value)
size_t i;
for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
write_number (((unsigned char *)
&TREE_REAL_CST (value))[i], 16);
&TREE_REAL_CST (value))[i],
/*unsigned_p=*/1,
16);
#endif
}
else
@ -1732,7 +1768,7 @@ write_array_type (type)
array. */
max = TYPE_MAX_VALUE (index_type);
if (TREE_CODE (max) == INTEGER_CST)
write_number (TREE_INT_CST_LOW (max) + 1, 10);
write_unsigned_number (tree_low_cst (max, 1));
else
write_expression (TREE_OPERAND (max, 0));
}
@ -1786,7 +1822,7 @@ write_template_param (parm)
/* NUMBER as it appears in the mangling is (-1)-indexed, with the
earliest template param denoted by `_'. */
if (parm_index > 0)
write_number (parm_index - 1, 10);
write_unsigned_number (parm_index - 1);
write_char ('_');
}
@ -1831,7 +1867,7 @@ write_substitution (seq_id)
write_char ('S');
if (seq_id > 0)
write_number (seq_id - 1, 36);
write_number (seq_id - 1, /*unsigned=*/1, 36);
write_char ('_');
}
@ -2063,14 +2099,14 @@ mangle_thunk (fn_decl, offset, vcall_offset)
write_char ('h');
/* For either flavor, write the offset to this. */
write_number (offset, 10);
write_signed_number (offset);
write_char ('_');
/* For a virtual thunk, add the vcall offset. */
if (vcall_offset != 0)
{
/* Virtual thunk. Write the vcall offset and base type name. */
write_number (vcall_offset, 10);
write_signed_number (vcall_offset);
write_char ('_');
}

View File

@ -0,0 +1,12 @@
// Build don't link:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
struct S {};
struct X {};
void f () {
typedef X Y;
S<Y> s;
}