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);
} }
} }
...@@ -1151,7 +1171,7 @@ write_type (type) ...@@ -1151,7 +1171,7 @@ write_type (type)
if (find_substitution (type)) if (find_substitution (type))
return; return;
if (write_CV_qualifiers_for_type (type) > 0) if (write_CV_qualifiers_for_type (type) > 0)
/* If TYPE was CV-qualified, we just wrote the qualifiers; now /* If TYPE was CV-qualified, we just wrote the qualifiers; now
mangle the unqualified type. The recursive call is needed here mangle the unqualified type. The recursive call is needed here
...@@ -1159,85 +1179,90 @@ write_type (type) ...@@ -1159,85 +1179,90 @@ write_type (type)
candidates. */ candidates. */
write_type (TYPE_MAIN_VARIANT (type)); write_type (TYPE_MAIN_VARIANT (type));
else else
switch (TREE_CODE (type)) {
{ /* See through any typedefs. */
case VOID_TYPE: type = TYPE_MAIN_VARIANT (type);
case BOOLEAN_TYPE:
case INTEGER_TYPE: /* Includes wchar_t. */ switch (TREE_CODE (type))
case REAL_TYPE: {
/* If this is a typedef, TYPE may not be one of case VOID_TYPE:
the standard builtin type nodes, but an alias of one. Use case BOOLEAN_TYPE:
TYPE_MAIN_VARIANT to get to the underlying builtin type. */ case INTEGER_TYPE: /* Includes wchar_t. */
write_builtin_type (TYPE_MAIN_VARIANT (type)); case REAL_TYPE:
++is_builtin_type; /* If this is a typedef, TYPE may not be one of
break; the standard builtin type nodes, but an alias of one. Use
TYPE_MAIN_VARIANT to get to the underlying builtin type. */
case COMPLEX_TYPE: write_builtin_type (TYPE_MAIN_VARIANT (type));
write_char ('C'); ++is_builtin_type;
write_type (TREE_TYPE (type)); break;
break;
case COMPLEX_TYPE:
case FUNCTION_TYPE: write_char ('C');
case METHOD_TYPE: write_type (TREE_TYPE (type));
write_function_type (type, 1); break;
break;
case FUNCTION_TYPE:
case UNION_TYPE: case METHOD_TYPE:
case RECORD_TYPE: write_function_type (type, 1);
case ENUMERAL_TYPE: break;
/* A pointer-to-member function is represented as a special
RECORD_TYPE, so check for this first. */ case UNION_TYPE:
if (TYPE_PTRMEMFUNC_P (type)) case RECORD_TYPE:
write_pointer_to_member_type (type); case ENUMERAL_TYPE:
else /* A pointer-to-member function is represented as a special
write_class_enum_type (type); RECORD_TYPE, so check for this first. */
break; if (TYPE_PTRMEMFUNC_P (type))
write_pointer_to_member_type (type);
case TYPENAME_TYPE: else
/* We handle TYPENAME_TYPEs like ordinary nested names. */ write_class_enum_type (type);
write_nested_name (TYPE_STUB_DECL (type)); break;
break;
case TYPENAME_TYPE:
case ARRAY_TYPE: /* We handle TYPENAME_TYPEs like ordinary nested names. */
write_array_type (type); write_nested_name (TYPE_STUB_DECL (type));
break; break;
case POINTER_TYPE: case ARRAY_TYPE:
/* A pointer-to-member variable is represented by a POINTER_TYPE write_array_type (type);
to an OFFSET_TYPE, so check for this first. */ break;
if (TYPE_PTRMEM_P (type))
write_pointer_to_member_type (type); case POINTER_TYPE:
else /* A pointer-to-member variable is represented by a POINTER_TYPE
{ to an OFFSET_TYPE, so check for this first. */
write_char ('P'); if (TYPE_PTRMEM_P (type))
write_type (TREE_TYPE (type)); write_pointer_to_member_type (type);
} else
break; {
write_char ('P');
case REFERENCE_TYPE: write_type (TREE_TYPE (type));
write_char ('R'); }
write_type (TREE_TYPE (type)); break;
break;
case REFERENCE_TYPE:
case TEMPLATE_TYPE_PARM: write_char ('R');
case TEMPLATE_PARM_INDEX: write_type (TREE_TYPE (type));
write_template_param (type); break;
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM: case TEMPLATE_PARM_INDEX:
write_template_template_param (type); write_template_param (type);
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)) break;
write_template_args
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))); case TEMPLATE_TEMPLATE_PARM:
break; write_template_template_param (type);
if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type))
case OFFSET_TYPE: write_template_args
write_pointer_to_member_type (build_pointer_type (type)); (TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break; break;
default: case OFFSET_TYPE:
my_friendly_abort (20000409); write_pointer_to_member_type (build_pointer_type (type));
} break;
default:
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,8 +1589,17 @@ write_expression (expr) ...@@ -1564,8 +1589,17 @@ 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