mangle.c (write_chars): New macro.
cp: * mangle.c (write_chars): New macro. (hwint_to_ascii): New function (write_number): Use it. (write_integer_cst): Deal with really big numbers. testsuite: * g++.old-deja/g++.pt/mangle2.C: New test. From-SVN: r41584
This commit is contained in:
parent
cc6e9bc399
commit
0576ec1308
@ -1,3 +1,10 @@
|
||||
2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* mangle.c (write_chars): New macro.
|
||||
(hwint_to_ascii): New function
|
||||
(write_number): Use it.
|
||||
(write_integer_cst): Deal with really big numbers.
|
||||
|
||||
2001-04-25 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* optimize.c (maybe_clone_body): Copy TREE_PUBLIC before emitting
|
||||
|
136
gcc/cp/mangle.c
136
gcc/cp/mangle.c
@ -153,6 +153,7 @@ static void write_prefix PARAMS ((tree));
|
||||
static void write_template_prefix PARAMS ((tree));
|
||||
static void write_unqualified_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 void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
|
||||
unsigned int));
|
||||
static void write_integer_cst PARAMS ((tree));
|
||||
@ -198,6 +199,10 @@ static void write_java_integer_type_codes PARAMS ((tree));
|
||||
#define write_char(CHAR) \
|
||||
obstack_1grow (&G.name_obstack, (CHAR))
|
||||
|
||||
/* Append a sized buffer to the end of the mangled representation. */
|
||||
#define write_chars(CHAR, LEN) \
|
||||
obstack_grow (&G.name_obstack, (CHAR), (LEN))
|
||||
|
||||
/* Append a NUL-terminated string to the end of the mangled
|
||||
representation. */
|
||||
#define write_string(STRING) \
|
||||
@ -1013,6 +1018,38 @@ write_source_name (identifier)
|
||||
write_identifier (IDENTIFIER_POINTER (identifier));
|
||||
}
|
||||
|
||||
/* Convert NUMBER to ascii using base BASE and generating at least
|
||||
MIN_DIGITS characters. BUFFER points to the _end_ of the buffer
|
||||
into which to store the characters. Returns the number of
|
||||
characters generated (these will be layed out in advance of where
|
||||
BUFFER points). */
|
||||
|
||||
static int
|
||||
hwint_to_ascii (number, base, buffer, min_digits)
|
||||
unsigned HOST_WIDE_INT number;
|
||||
unsigned int base;
|
||||
char *buffer;
|
||||
unsigned min_digits;
|
||||
{
|
||||
static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
unsigned digits = 0;
|
||||
|
||||
while (number)
|
||||
{
|
||||
unsigned HOST_WIDE_INT d = number / base;
|
||||
|
||||
*--buffer = base_digits[number - d * base];
|
||||
digits++;
|
||||
number = d;
|
||||
}
|
||||
while (digits < min_digits)
|
||||
{
|
||||
*--buffer = base_digits[0];
|
||||
digits++;
|
||||
}
|
||||
return digits;
|
||||
}
|
||||
|
||||
/* Non-terminal <number>.
|
||||
|
||||
<number> ::= [n] </decimal integer/> */
|
||||
@ -1023,50 +1060,91 @@ write_number (number, unsigned_p, base)
|
||||
int unsigned_p;
|
||||
unsigned int base;
|
||||
{
|
||||
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
unsigned HOST_WIDE_INT n;
|
||||
unsigned HOST_WIDE_INT m = 1;
|
||||
char buffer[sizeof (HOST_WIDE_INT) * 8];
|
||||
unsigned count = 0;
|
||||
|
||||
if (!unsigned_p && (HOST_WIDE_INT) number < 0)
|
||||
{
|
||||
write_char ('n');
|
||||
number = -((HOST_WIDE_INT) number);
|
||||
}
|
||||
|
||||
/* Figure out how many digits there are. */
|
||||
n = number;
|
||||
while (n >= base)
|
||||
{
|
||||
n /= base;
|
||||
m *= base;
|
||||
}
|
||||
|
||||
/* Write them out. */
|
||||
while (m > 0)
|
||||
{
|
||||
int digit = number / m;
|
||||
write_char (digits[digit]);
|
||||
number -= digit * m;
|
||||
m /= base;
|
||||
}
|
||||
|
||||
my_friendly_assert (number == 0, 20000407);
|
||||
count = hwint_to_ascii (number, base, buffer + sizeof (buffer), 1);
|
||||
write_chars (buffer + sizeof (buffer) - count, count);
|
||||
}
|
||||
|
||||
/* Write out an integeral CST in decimal. */
|
||||
/* Write out an integral CST in decimal. Most numbers are small, and
|
||||
representable in a HOST_WIDE_INT. Occasionally we'll have numbers
|
||||
bigger than that, which we must deal with. */
|
||||
|
||||
static inline void
|
||||
write_integer_cst (cst)
|
||||
tree cst;
|
||||
{
|
||||
if (tree_int_cst_sgn (cst) >= 0)
|
||||
int sign = tree_int_cst_sgn (cst);
|
||||
|
||||
if (TREE_INT_CST_HIGH (cst) + (sign < 0))
|
||||
{
|
||||
if (TREE_INT_CST_HIGH (cst) != 0)
|
||||
sorry ("mangling very large integers");
|
||||
write_unsigned_number (TREE_INT_CST_LOW (cst));
|
||||
/* A bignum. We do this in chunks, each of which fits in a
|
||||
HOST_WIDE_INT. */
|
||||
char buffer[sizeof (HOST_WIDE_INT) * 8 * 2];
|
||||
unsigned HOST_WIDE_INT chunk;
|
||||
unsigned chunk_digits;
|
||||
char *ptr = buffer + sizeof (buffer);
|
||||
unsigned count = 0;
|
||||
tree n, base, type;
|
||||
int done;
|
||||
|
||||
/* HOST_WIDE_INT must be at least 32 bits, so 10^9 is
|
||||
representable. */
|
||||
chunk = 1000000000;
|
||||
chunk_digits = 9;
|
||||
|
||||
if (sizeof (HOST_WIDE_INT) >= 8)
|
||||
{
|
||||
/* It is at least 64 bits, so 10^18 is representable. */
|
||||
chunk_digits = 18;
|
||||
chunk *= chunk;
|
||||
}
|
||||
|
||||
type = signed_or_unsigned_type (1, TREE_TYPE (cst));
|
||||
base = build_int_2 (chunk, 0);
|
||||
n = build_int_2 (TREE_INT_CST_LOW (cst), TREE_INT_CST_HIGH (cst));
|
||||
TREE_TYPE (n) = TREE_TYPE (base) = type;
|
||||
|
||||
if (sign < 0)
|
||||
{
|
||||
write_char ('n');
|
||||
n = fold (build1 (NEGATE_EXPR, type, n));
|
||||
}
|
||||
do
|
||||
{
|
||||
tree d = fold (build (FLOOR_DIV_EXPR, type, n, base));
|
||||
tree tmp = fold (build (MULT_EXPR, type, d, base));
|
||||
unsigned c;
|
||||
|
||||
done = integer_zerop (d);
|
||||
tmp = fold (build (MINUS_EXPR, type, n, tmp));
|
||||
c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
|
||||
done ? 1 : chunk_digits);
|
||||
ptr -= c;
|
||||
count += c;
|
||||
n = d;
|
||||
}
|
||||
while (!done);
|
||||
write_chars (ptr, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A small num. */
|
||||
unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (cst);
|
||||
|
||||
if (sign < 0)
|
||||
{
|
||||
write_char ('n');
|
||||
low = -low;
|
||||
}
|
||||
write_unsigned_number (low);
|
||||
}
|
||||
else
|
||||
write_signed_number (tree_low_cst (cst, 0));
|
||||
}
|
||||
|
||||
/* Non-terminal <identifier>.
|
||||
|
@ -1,3 +1,7 @@
|
||||
2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.old-deja/g++.pt/mangle2.C: New test.
|
||||
|
||||
2001-04-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* c-format.c (check_format_info_recurse): Handle
|
||||
|
40
gcc/testsuite/g++.old-deja/g++.pt/mangle2.C
Normal file
40
gcc/testsuite/g++.old-deja/g++.pt/mangle2.C
Normal file
@ -0,0 +1,40 @@
|
||||
// Build don't link:
|
||||
//
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 25 April 2001 <nathan@codesourcery.com>
|
||||
// Origin:pcarlini@unitus.it
|
||||
|
||||
// Bug 2559. We hadn't implemented code to mangle numbers bigger than
|
||||
// HOST_WIDE_INT.
|
||||
|
||||
template<class T, T min_val, T max_val>
|
||||
class integer_traits_base
|
||||
{
|
||||
public:
|
||||
static const bool is_integral = true;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class integer_traits
|
||||
{
|
||||
public:
|
||||
static const bool is_integral = false;
|
||||
};
|
||||
|
||||
template<>
|
||||
class integer_traits<long long>
|
||||
: public integer_traits_base<long long, (-9223372036854775807LL - 1),
|
||||
9223372036854775807LL>
|
||||
{ };
|
||||
|
||||
integer_traits<long long> f;
|
||||
|
||||
template <class T, T value> T foo ()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
void x ()
|
||||
{
|
||||
foo<long long, -9223372036854775807LL> ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user