static struct type *dbx_alloc_type (int[2], struct objfile *);
-static long read_huge_number (char **, int, int *);
+static long read_huge_number (char **, int, int *, int);
static struct type *error_type (char **, struct objfile *);
static struct type *read_type (char **, struct objfile *);
-static struct type *read_range_type (char **, int[2], struct objfile *);
+static struct type *read_range_type (char **, int[2], int, struct objfile *);
static struct type *read_sun_builtin_type (char **, int[2], struct objfile *);
if (**pp == '(')
{
(*pp)++;
- typenums[0] = read_huge_number (pp, ',', &nbits);
+ typenums[0] = read_huge_number (pp, ',', &nbits, 0);
if (nbits != 0)
return -1;
- typenums[1] = read_huge_number (pp, ')', &nbits);
+ typenums[1] = read_huge_number (pp, ')', &nbits, 0);
if (nbits != 0)
return -1;
}
else
{
typenums[0] = 0;
- typenums[1] = read_huge_number (pp, 0, &nbits);
+ typenums[1] = read_huge_number (pp, 0, &nbits, 0);
if (nbits != 0)
return -1;
}
init_type (TYPE_CODE_INT, TARGET_INT_BIT / TARGET_CHAR_BIT,
TYPE_FLAG_UNSIGNED, "unsigned int", NULL);
- if (BELIEVE_PCC_PROMOTION_TYPE)
+ /* If PCC says a parameter is a short or a char, it is
+ really an int. */
+ if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
+ && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
{
- /* This is defined on machines (e.g. sparc) where we
- should believe the type of a PCC 'short' argument,
- but shouldn't believe the address (the address is the
- address of the corresponding int).
-
- My guess is that this correction, as opposed to
- changing the parameter to an 'int' (as done below,
- for PCC on most machines), is the right thing to do
- on all machines, but I don't want to risk breaking
- something that already works. On most PCC machines,
- the sparc problem doesn't come up because the calling
- function has to zero the top bytes (not knowing
- whether the called function wants an int or a short),
- so there is little practical difference between an
- int and a short (except perhaps what happens when the
- GDB user types "print short_arg = 0x10000;").
-
- Hacked for SunOS 4.1 by gnu@cygnus.com. In 4.1, the
- compiler actually produces the correct address (we
- don't need to fix it up). I made this code adapt so
- that it will offset the symbol if it was pointing at
- an int-aligned location and not otherwise. This way
- you can use the same gdb for 4.0.x and 4.1 systems.
-
- If the parameter is shorter than an int, and is
- integral (e.g. char, short, or unsigned equivalent),
- and is claimed to be passed on an integer boundary,
- don't believe it! Offset the parameter's address to
- the tail-end of that integer. */
-
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
- && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (pcc_promotion_type))
- {
- SYMBOL_VALUE (sym) += TYPE_LENGTH (pcc_promotion_type)
- - TYPE_LENGTH (SYMBOL_TYPE (sym));
- }
- break;
- }
- else
- {
- /* If PCC says a parameter is a short or a char,
- it is really an int. */
- if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (pcc_promotion_type)
- && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
- {
- SYMBOL_TYPE (sym) =
- TYPE_UNSIGNED (SYMBOL_TYPE (sym))
- ? pcc_unsigned_promotion_type
- : pcc_promotion_type;
- }
- break;
+ SYMBOL_TYPE (sym) =
+ TYPE_UNSIGNED (SYMBOL_TYPE (sym))
+ ? pcc_unsigned_promotion_type
+ : pcc_promotion_type;
}
+ break;
}
case 'P':
break;
case 'r': /* Range type */
- type = read_range_type (pp, typenums, objfile);
+ type = read_range_type (pp, typenums, type_size, objfile);
if (typenums[0] != -1)
*dbx_lookup_type (typenums) = type;
break;
the sign bit out, and usable as a valid index into
the array. Remove the sign bit here. */
new_sublist->fn_field.voffset =
- (0x7fffffff & read_huge_number (pp, ';', &nbits)) + 2;
+ (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2;
if (nbits != 0)
return 0;
{
int nbits;
- FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits);
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ';', &nbits,
+ 0);
if (nbits != 0)
return 0;
}
{
int nbits;
- FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits);
+ FIELD_BITPOS (fip->list->field) = read_huge_number (pp, ',', &nbits, 0);
if (nbits != 0)
{
stabs_general_complaint ("bad structure-type format");
return;
}
- FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits);
+ FIELD_BITSIZE (fip->list->field) = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
{
stabs_general_complaint ("bad structure-type format");
ALLOCATE_CPLUS_STRUCT_TYPE (type);
{
int nbits;
- TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits);
+ TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0);
if (nbits != 0)
return 0;
}
corresponding to this baseclass. Always zero in the absence of
multiple inheritance. */
- FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits);
+ FIELD_BITPOS (new->field) = read_huge_number (pp, ',', &nbits, 0);
if (nbits != 0)
return 0;
}
{
int nbits;
- TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits);
+ TYPE_LENGTH (type) = read_huge_number (pp, 0, &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
}
(*pp)++;
adjustable = 1;
}
- lower = read_huge_number (pp, ';', &nbits);
+ lower = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
(*pp)++;
adjustable = 1;
}
- upper = read_huge_number (pp, ';', &nbits);
+ upper = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
p++;
name = obsavestring (*pp, p - *pp, &objfile->objfile_obstack);
*pp = p + 1;
- n = read_huge_number (pp, ',', &nbits);
+ n = read_huge_number (pp, ',', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
by this type, except that unsigned short is 4 instead of 2.
Since this information is redundant with the third number,
we will ignore it. */
- read_huge_number (pp, ';', &nbits);
+ read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
/* The second number is always 0, so ignore it too. */
- read_huge_number (pp, ';', &nbits);
+ read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
/* The third number is the number of bits for this type. */
- type_bits = read_huge_number (pp, 0, &nbits);
+ type_bits = read_huge_number (pp, 0, &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
/* The type *should* end with a semicolon. If it are embedded
/* The first number has more details about the type, for example
FN_COMPLEX. */
- details = read_huge_number (pp, ';', &nbits);
+ details = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
/* The second number is the number of bytes occupied by this type */
- nbytes = read_huge_number (pp, ';', &nbits);
+ nbytes = read_huge_number (pp, ';', &nbits, 0);
if (nbits != 0)
return error_type (pp, objfile);
and that character is skipped if it does match.
If END is zero, *PP is left pointing to that character.
+ If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if
+ the number is represented in an octal representation, assume that
+ it is represented in a 2's complement representation with a size of
+ TWOS_COMPLEMENT_BITS.
+
If the number fits in a long, set *BITS to 0 and return the value.
If not, set *BITS to be the number of bits in the number and return 0.
If encounter garbage, set *BITS to -1 and return 0. */
static long
-read_huge_number (char **pp, int end, int *bits)
+read_huge_number (char **pp, int end, int *bits, int twos_complement_bits)
{
char *p = *pp;
int sign = 1;
+ int sign_bit;
long n = 0;
+ long sn = 0;
int radix = 10;
char overflow = 0;
int nbits = 0;
int c;
long upper_limit;
+ int twos_complement_representation = radix == 8 && twos_complement_bits > 0;
if (*p == '-')
{
while ((c = *p++) >= '0' && c < ('0' + radix))
{
if (n <= upper_limit)
- {
- n *= radix;
- n += c - '0'; /* FIXME this overflows anyway */
- }
+ {
+ if (twos_complement_representation)
+ {
+ /* Octal, signed, twos complement representation. In this case,
+ sn is the signed value, n is the corresponding absolute
+ value. signed_bit is the position of the sign bit in the
+ first three bits. */
+ if (sn == 0)
+ {
+ sign_bit = (twos_complement_bits % 3 + 2) % 3;
+ sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
+ }
+ else
+ {
+ sn *= radix;
+ sn += c - '0';
+ }
+
+ if (sn < 0)
+ n = -sn;
+ }
+ else
+ {
+ /* unsigned representation */
+ n *= radix;
+ n += c - '0'; /* FIXME this overflows anyway */
+ }
+ }
else
- overflow = 1;
+ overflow = 1;
/* This depends on large values being output in octal, which is
what GCC does. */
{
if (bits)
*bits = 0;
- return n * sign;
+ if (twos_complement_representation)
+ return sn;
+ else
+ return n * sign;
}
/* It's *BITS which has the interesting information. */
return 0;
}
static struct type *
-read_range_type (char **pp, int typenums[2], struct objfile *objfile)
+read_range_type (char **pp, int typenums[2], int type_size,
+ struct objfile *objfile)
{
char *orig_pp = *pp;
int rangenums[2];
/* The remaining two operands are usually lower and upper bounds
of the range. But in some special cases they mean something else. */
- n2 = read_huge_number (pp, ';', &n2bits);
- n3 = read_huge_number (pp, ';', &n3bits);
+ n2 = read_huge_number (pp, ';', &n2bits, type_size);
+ n3 = read_huge_number (pp, ';', &n3bits, type_size);
if (n2bits == -1 || n3bits == -1)
return error_type (pp, objfile);
/* Number of bits in the type. */
int nbits = 0;
+ /* If a type size attribute has been specified, the bounds of
+ the range should fit in this size. If the lower bounds needs
+ more bits than the upper bound, then the type is signed. */
+ if (n2bits <= type_size && n3bits <= type_size)
+ {
+ if (n2bits == type_size && n2bits > n3bits)
+ got_signed = 1;
+ else
+ got_unsigned = 1;
+ nbits = type_size;
+ }
/* Range from 0 to <large number> is an unsigned large integral type. */
- if ((n2bits == 0 && n2 == 0) && n3bits != 0)
+ else if ((n2bits == 0 && n2 == 0) && n3bits != 0)
{
got_unsigned = 1;
nbits = n3bits;