Commit 82a362d0 by Chip Salzenberg Committed by Mark Mitchell

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
parent 4d870388
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> 2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
* call.c (add_candidate): Use ggc_alloc_cleared. * call.c (add_candidate): Use ggc_alloc_cleared.
......
...@@ -157,7 +157,8 @@ static void write_template_prefix PARAMS ((tree)); ...@@ -157,7 +157,8 @@ static void write_template_prefix PARAMS ((tree));
static void write_component PARAMS ((tree)); static void write_component PARAMS ((tree));
static void write_unqualified_name PARAMS ((tree)); static void write_unqualified_name PARAMS ((tree));
static void write_source_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_integer_cst PARAMS ((tree));
static void write_identifier PARAMS ((char *)); static void write_identifier PARAMS ((char *));
static void write_special_name_constructor PARAMS ((tree)); static void write_special_name_constructor PARAMS ((tree));
...@@ -219,6 +220,14 @@ static tree mangle_special_for_type PARAMS ((tree, const char *)); ...@@ -219,6 +220,14 @@ static tree mangle_special_for_type PARAMS ((tree, const char *));
|| TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \ || TREE_PURPOSE (NODE1) == TREE_PURPOSE (NODE2)) \
&& TREE_VALUE (NODE1) == TREE_VALUE (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. */ /* Produce debugging output of current substitution candidates. */
static void static void
...@@ -441,7 +450,7 @@ find_substitution (node) ...@@ -441,7 +450,7 @@ find_substitution (node)
/* Check for std::basic_string. */ /* Check for std::basic_string. */
if (decl && is_std_substitution (decl, SUBID_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), /* If this is a type (i.e. a fully-qualified template-id),
check for check for
...@@ -473,7 +482,7 @@ find_substitution (node) ...@@ -473,7 +482,7 @@ find_substitution (node)
} }
/* Check for basic_{i,o,io}stream. */ /* Check for basic_{i,o,io}stream. */
if (type if (TYPE_P (node)
&& CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED && CP_TYPE_QUALS (type) == TYPE_UNQUALIFIED
&& CLASS_TYPE_P (type) && CLASS_TYPE_P (type)
&& CLASSTYPE_USE_TEMPLATE (type) && CLASSTYPE_USE_TEMPLATE (type)
...@@ -510,7 +519,7 @@ find_substitution (node) ...@@ -510,7 +519,7 @@ find_substitution (node)
} }
/* Check for namespace std. */ /* Check for namespace std. */
if (decl&& DECL_NAMESPACE_STD_P (decl)) if (decl && DECL_NAMESPACE_STD_P (decl))
{ {
write_string ("St"); write_string ("St");
return 1; return 1;
...@@ -518,7 +527,6 @@ find_substitution (node) ...@@ -518,7 +527,6 @@ find_substitution (node)
/* Now check the list of available substitutions for this mangling /* Now check the list of available substitutions for this mangling
operation. */ operation. */
for (i = 0; i < size; ++i) for (i = 0; i < size; ++i)
{ {
tree candidate = VARRAY_TREE (G.substitutions, i); tree candidate = VARRAY_TREE (G.substitutions, i);
...@@ -604,7 +612,9 @@ static void ...@@ -604,7 +612,9 @@ static void
write_name (decl) write_name (decl)
tree decl; tree decl;
{ {
tree context = CP_DECL_CONTEXT (decl); tree context;
context = CP_DECL_CONTEXT (decl);
MANGLE_TRACE_TREE ("name", decl); MANGLE_TRACE_TREE ("name", decl);
...@@ -913,7 +923,7 @@ write_source_name (identifier) ...@@ -913,7 +923,7 @@ write_source_name (identifier)
if (IDENTIFIER_TEMPLATE (identifier)) if (IDENTIFIER_TEMPLATE (identifier))
identifier = IDENTIFIER_TEMPLATE (identifier); identifier = IDENTIFIER_TEMPLATE (identifier);
write_number (IDENTIFIER_LENGTH (identifier), 10); write_unsigned_number (IDENTIFIER_LENGTH (identifier));
write_identifier (IDENTIFIER_POINTER (identifier)); write_identifier (IDENTIFIER_POINTER (identifier));
} }
...@@ -922,20 +932,22 @@ write_source_name (identifier) ...@@ -922,20 +932,22 @@ write_source_name (identifier)
<number> ::= [n] </decimal integer/> */ <number> ::= [n] </decimal integer/> */
static void static void
write_number (number, base) write_number (number, unsigned_p, base)
int number; unsigned HOST_WIDE_INT number;
int base; int unsigned_p;
unsigned int base;
{ {
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n; unsigned HOST_WIDE_INT n;
int m = 1; unsigned HOST_WIDE_INT m = 1;
if (number < 0) if (!unsigned_p && (HOST_WIDE_INT) number < 0)
{ {
write_char ('n'); write_char ('n');
number = -number; number = -((HOST_WIDE_INT) number);
} }
/* Figure out how many digits there are. */
n = number; n = number;
while (n >= base) while (n >= base)
{ {
...@@ -943,6 +955,7 @@ write_number (number, base) ...@@ -943,6 +955,7 @@ write_number (number, base)
m *= base; m *= base;
} }
/* Write them out. */
while (m > 0) while (m > 0)
{ {
int digit = number / m; int digit = number / m;
...@@ -960,7 +973,14 @@ static inline void ...@@ -960,7 +973,14 @@ static inline void
write_integer_cst (cst) write_integer_cst (cst)
tree 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>. /* Non-terminal <identifier>.
...@@ -1086,7 +1106,7 @@ write_discriminator (discriminator) ...@@ -1086,7 +1106,7 @@ write_discriminator (discriminator)
/* The number is omitted for discriminator == 1. Beyond 1, the /* The number is omitted for discriminator == 1. Beyond 1, the
numbering starts at 0. */ numbering starts at 0. */
if (discriminator > 1) if (discriminator > 1)
write_number (discriminator - 2, 10); write_unsigned_number (discriminator - 2);
} }
} }
...@@ -1159,6 +1179,10 @@ write_type (type) ...@@ -1159,6 +1179,10 @@ write_type (type)
candidates. */ candidates. */
write_type (TYPE_MAIN_VARIANT (type)); write_type (TYPE_MAIN_VARIANT (type));
else else
{
/* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type);
switch (TREE_CODE (type)) switch (TREE_CODE (type))
{ {
case VOID_TYPE: case VOID_TYPE:
...@@ -1238,6 +1262,7 @@ write_type (type) ...@@ -1238,6 +1262,7 @@ write_type (type)
default: default:
my_friendly_abort (20000409); my_friendly_abort (20000409);
} }
}
/* Types other than builtin types are substitution candidates. */ /* Types other than builtin types are substitution candidates. */
if (!is_builtin_type) if (!is_builtin_type)
...@@ -1564,7 +1589,16 @@ write_expression (expr) ...@@ -1564,7 +1589,16 @@ write_expression (expr)
if (TREE_CODE (expr) == ADDR_EXPR if (TREE_CODE (expr) == ADDR_EXPR
&& TREE_TYPE (expr) && TREE_TYPE (expr)
&& TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE) && 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. */ /* 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);
...@@ -1610,9 +1644,9 @@ write_template_arg_literal (value) ...@@ -1610,9 +1644,9 @@ write_template_arg_literal (value)
if (same_type_p (type, boolean_type_node)) if (same_type_p (type, boolean_type_node))
{ {
if (value == boolean_false_node || integer_zerop (value)) if (value == boolean_false_node || integer_zerop (value))
write_number (0, 10); write_unsigned_number (0);
else if (value == boolean_true_node) else if (value == boolean_true_node)
write_number (1, 10); write_unsigned_number (1);
else else
my_friendly_abort (20000412); my_friendly_abort (20000412);
} }
...@@ -1633,7 +1667,9 @@ write_template_arg_literal (value) ...@@ -1633,7 +1667,9 @@ write_template_arg_literal (value)
size_t i; size_t i;
for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i) for (i = 0; i < sizeof (TREE_REAL_CST (value)); ++i)
write_number (((unsigned char *) write_number (((unsigned char *)
&TREE_REAL_CST (value))[i], 16); &TREE_REAL_CST (value))[i],
/*unsigned_p=*/1,
16);
#endif #endif
} }
else else
...@@ -1732,7 +1768,7 @@ write_array_type (type) ...@@ -1732,7 +1768,7 @@ write_array_type (type)
array. */ array. */
max = TYPE_MAX_VALUE (index_type); max = TYPE_MAX_VALUE (index_type);
if (TREE_CODE (max) == INTEGER_CST) if (TREE_CODE (max) == INTEGER_CST)
write_number (TREE_INT_CST_LOW (max) + 1, 10); write_unsigned_number (tree_low_cst (max, 1));
else else
write_expression (TREE_OPERAND (max, 0)); write_expression (TREE_OPERAND (max, 0));
} }
...@@ -1786,7 +1822,7 @@ write_template_param (parm) ...@@ -1786,7 +1822,7 @@ write_template_param (parm)
/* NUMBER as it appears in the mangling is (-1)-indexed, with the /* NUMBER as it appears in the mangling is (-1)-indexed, with the
earliest template param denoted by `_'. */ earliest template param denoted by `_'. */
if (parm_index > 0) if (parm_index > 0)
write_number (parm_index - 1, 10); write_unsigned_number (parm_index - 1);
write_char ('_'); write_char ('_');
} }
...@@ -1831,7 +1867,7 @@ write_substitution (seq_id) ...@@ -1831,7 +1867,7 @@ write_substitution (seq_id)
write_char ('S'); write_char ('S');
if (seq_id > 0) if (seq_id > 0)
write_number (seq_id - 1, 36); write_number (seq_id - 1, /*unsigned=*/1, 36);
write_char ('_'); write_char ('_');
} }
...@@ -2063,14 +2099,14 @@ mangle_thunk (fn_decl, offset, vcall_offset) ...@@ -2063,14 +2099,14 @@ mangle_thunk (fn_decl, offset, vcall_offset)
write_char ('h'); write_char ('h');
/* For either flavor, write the offset to this. */ /* For either flavor, write the offset to this. */
write_number (offset, 10); write_signed_number (offset);
write_char ('_'); write_char ('_');
/* For a virtual thunk, add the vcall offset. */ /* For a virtual thunk, add the vcall offset. */
if (vcall_offset != 0) if (vcall_offset != 0)
{ {
/* Virtual thunk. Write the vcall offset and base type name. */ /* Virtual thunk. Write the vcall offset and base type name. */
write_number (vcall_offset, 10); write_signed_number (vcall_offset);
write_char ('_'); write_char ('_');
} }
......
// 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;
}
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