📄 types.c
字号:
}
return (is_compatible_type
(referenced_type (tp1), referenced_type (tp2)));
case bt_func:
return is_compatible_type (returned_type (tp1), returned_type (tp2))
&& is_compatible_proto (parameters (tp1), parameters (tp2));
case bt_struct:
case bt_union:
return (members (tp1) == members (tp2));
default:
break;
}
return TRUE;
}
/*
* perform the integral promotions and return the type
*/
TYP *promote_type P1 (TYP *, tp)
{
switch (tp->type) {
case bt_bool:
case bt_charu:
case bt_uchar:
case bt_ushort:
if (is_same_size (tp, tp_int)) {
return tp_uint;
}
/*lint -fallthrough */
case bt_char:
case bt_schar:
case bt_short:
return tp_int;
case bt_float:
return tp_double;
case bt_pointer16:
case bt_pointer32:
return tp;
case bt_func:
/* always passed by reference, never by value */
return tp_func;
default:
break;
}
return tp;
}
/*
* perform the unary conversions and return the type
*/
TYP *unary_conversion P1 (TYP *, tp)
{
switch (tp->type) {
case bt_bool:
case bt_charu:
case bt_uchar:
case bt_ushort:
if (is_same_size (tp, tp_int)) {
return tp_uint;
}
/*lint -fallthrough */
case bt_char:
case bt_schar:
case bt_short:
return tp_int;
case bt_pointer16:
case bt_pointer32:
/* always passed by reference, never by value */
return tp_pointer;
case bt_func:
/* always passed by reference, never by value */
return tp_func;
default:
break;
}
return tp;
}
/*
* returns type if the size of the type is not known.
* There is a complication that "copied" types (i.e. ones
* with qualifiers) might have been copied before the size
* was known so we need to calculate it now!.
*/
BOOL is_incomplete_type P1 (TYP *, tp)
{
if (is_unknown_size (tp)) {
if (is_structure_type (tp) && (membersof (tp) != NIL_SYM)) {
/* the tag must be in the tag table */
SYM *sp = tag_search (nameoftype (tp));
tp->size = typeof (sp)->size;
return is_incomplete_type (tp);
}
return TRUE;
}
return FALSE;
}
#ifndef SYNTAX_CORRECT
/*
* ensure that the size of ep is known.
*/
void check_complete P1 (TYP *, tp)
{
if (is_incomplete_type (tp)) {
message (ERR_SIZE);
}
}
/*
* Check that tp1 has all the qualifiers of tp2
*/
void check_qualifiers P2 (const TYP *, tp1, const TYP *, tp2)
{
if (!is_pointer_type (tp1) || !is_pointer_type (tp2)) {
return;
}
if ((tp1->btp->qual & tp2->btp->qual) != tp2->btp->qual) {
message (ERR_QUAL);
}
}
#endif /* SYNTAX_CORRECT */
TYP *copy_type P1 (const TYP *, tp)
{
TYP *ret_tp;
if (tp == NIL_TYP) {
return NIL_TYP;
}
ret_tp = (TYP *) galloc (sizeof (TYP));
*ret_tp = *tp;
set_nexttyp (ret_tp, NIL_TYP);
switch (tp->type) {
case bt_pointer16:
case bt_pointer32:
set_referenced_type (ret_tp, copy_type (referenced_type (tp)));
break;
case bt_func:
set_returned_type (ret_tp, copy_type (returned_type (tp)));
set_function (ret_tp, mk_func (funckind (tp), NULL));
break;
default:
break;
}
return ret_tp;
}
static unsigned hash P1 (const TYP *, tp)
{
return ((unsigned) tp >> (unsigned) 2 & (MAXTYPEKEY - (unsigned) 1));
}
/*
* Checks to see if the value 'i' of type 'tp1' is within the
* range supported by the type 'tp2'. This routine is only valid
* to be called for scalar types as these are the only ones which
* have a "range".
*/
BOOL is_constant_in_type_range P3 (IVAL, i, const TYP *, tp1, const TYP *,
tp2)
{
RANGE *rp2;
RANGE range;
if (!is_scalar_type (tp2)) {
return FALSE;
}
#ifdef FLOAT_SUPPORT
if (is_real_floating_type (tp2))
return TRUE;
#endif /* FLOAT_SUPPORT */
if (is_pointer_type (tp2))
return TRUE;
if (is_bitfield_type (tp2)) {
if (is_signed_type (tp2)) {
range.low = -(IVAL) (1UL << ((int) bitfield_width (tp2))) - 1L;
range.high =
(IVAL) (1UL << ((int) bitfield_width (tp2) - 1)) - 1L;
} else {
range.low = 0L;
range.high = (IVAL) (1UL << (int) bitfield_width (tp2)) - 1L;
}
rp2 = ⦥
} else {
rp2 = rangeof (tp2);
}
if (is_signed_type (tp1) && is_signed_type (tp2)) {
return ((rp2->low <= i) && (i <= rp2->high));
}
if (is_unsigned_type (tp1) && is_unsigned_type (tp2)) {
return (((UVAL) rp2->low <= (UVAL) i)
&& ((UVAL) i <= (UVAL) rp2->high));
}
if (is_signed_type (tp1) && is_unsigned_type (tp2)) {
return (((UVAL) rp2->low <= (UVAL) i)
&& ((UVAL) i <= (UVAL) rp2->high));
}
/* is_unsigned_type (tp1) && is_signed_type (tp2) */
return ((UVAL)i <= (UVAL)rp2->high);
}
/*
* Returns TRUE is tp2 is a sub-type of tp1, i.e tp1 can contain
* all values of tp2
*/
BOOL is_subtype P2 (const TYP *, tp1, const TYP *, tp2)
{
if (is_integral_type (tp1) && is_integral_type (tp2)) {
RANGE *rp = rangeof (tp2);
return (is_constant_in_type_range (rp->low, tp2, tp1) &&
is_constant_in_type_range (rp->high, tp2, tp1));
}
return FALSE;
}
#if 0
/*
* Creates a range node for a type.
*/
RANGE *mk_range P2 (IVAL, low, IVAL, high)
{
RANGE *rp;
rp = (RANGE *) galloc (sizeof (RANGE));
rp->low = low;
rp->high = high;
return rp;
}
#endif
TYP *mk_type P2 (const TYP *, tp1, TYP *, btp)
{
TYP *tp;
unsigned keyno;
if (tp1 == NIL_TYP)
return NIL_TYP;
keyno = hash (tp1);
/*
* Look to see if this type has already been defined
*/
switch (tp1->type) {
case bt_bool:
case bt_void:
case bt_char:
case bt_schar:
case bt_uchar:
case bt_charu:
case bt_short:
case bt_int16:
case bt_ushort:
case bt_uint16:
case bt_pointer16:
case bt_long:
case bt_int32:
case bt_longlong:
case bt_ulong:
case bt_uint32:
case bt_ulonglong:
case bt_pointer32:
for (tp = hashtable[keyno]; tp; tp = nexttyp (tp)) {
if ((btp != NIL_TYP) && is_func (btp)) {
continue;
}
if (is_same_type (tp, tp1) &&
(tp->qual == tp1->qual) &&
is_same_size (tp, tp1) &&
(tp->btp == btp) &&
(is_enum (tp) == is_enum (tp1)) &&
(is_derived_type (tp) == is_derived_type (tp1))) {
return tp;
}
}
break;
default:
break;
}
tp = (TYP *) galloc (sizeof (TYP));
if (tp == NULL) {
return NULL;
}
*tp = stp_void;
tp->size = tp1->size;
tp->type = tp1->type;
tp->qual = tp1->qual;
set_nameoftype (tp, nameoftype (tp1));
tp->btp = btp;
if (is_derived_type (tp1)) {
set_derived (tp);
}
if (is_enum (tp1)) {
set_enum (tp);
}
switch (tp->type) {
case bt_func:
set_function (tp, mk_func (fc_normal, parameters (tp1)));
break;
case bt_struct:
case bt_union:
tp->t.structure = (STRUCT *) galloc (sizeof (STRUCT));
if (tp->t.structure != NULL)
{
if ((tp1 != NIL_TYP) && (tp1->t.structure != NULL) && members (tp1)) {
set_members (tp, members (tp1));
} else {
set_members (tp, mk_block ());
}
}
break;
case bt_bool:
set_range (tp, &range_bool);
break;
case bt_char:
case bt_schar:
set_range (tp, &range_schar);
break;
case bt_uchar:
case bt_charu:
set_range (tp, &range_uchar);
break;
case bt_short:
case bt_int16:
set_range (tp, &range_short);
break;
case bt_ushort:
case bt_uint16:
case bt_pointer16:
set_range (tp, &range_ushort);
break;
case bt_long:
case bt_int32:
set_range (tp, &range_long);
break;
case bt_ulong:
case bt_uint32:
case bt_pointer32:
set_range (tp, &range_ulong);
break;
case bt_longlong:
set_range (tp, &range_longlong);
break;
case bt_ulonglong:
set_range (tp, &range_ulonglong);
break;
default:
break;
}
set_nexttyp (tp, hashtable[keyno]);
hashtable[keyno] = tp;
return tp;
}
void size_type P1 (TYP *, tp)
{
TYP *rtp;
if (tp == NIL_TYP) {
return;
}
if (is_array_type (tp)) {
rtp = referenced_type (tp);
size_type (rtp);
if (rtp != NIL_TYP &&
(array_index (tp) != UNKNOWN_SIZE) && (!is_unknown_size (rtp))) {
tp->size = rtp->size * array_index (tp);
}
}
}
/*
* Calculate the alignment requirements of the specified type
*/
SIZE alignment_of_type P1 (const TYP *, tp)
{
SYM *sp;
SIZE algn, al;
switch (tp->type) {
case bt_struct:
case bt_union:
if (align_option) {
/* align structures to the alignment of the worst aligned member */
algn = g_alignments[bt_char];;
for (sp = membersof (tp); sp != NIL_SYM; sp = nextsym (sp)) {
al = alignment_of_type (typeof (sp));
if (al > algn) {
algn = al;
}
}
return algn;
}
/*lint -fallthrough */
case bt_void:
case bt_bool:
case bt_char:
case bt_charu:
case bt_uchar:
case bt_schar:
case bt_short:
case bt_ushort:
case bt_int16:
case bt_uint16:
case bt_int32:
case bt_uint32:
case bt_long:
case bt_longlong:
case bt_ulong:
case bt_ulonglong:
case bt_float:
case bt_double:
case bt_longdouble:
case bt_floatcomplex:
case bt_floatimaginary:
case bt_doublecomplex:
case bt_doubleimaginary:
case bt_longdoublecomplex:
case bt_longdoubleimaginary:
case bt_func:
return g_alignments[tp->type];
case bt_pointer16:
case bt_pointer32:
return is_array_type (tp) ? alignment_of_type (referenced_type (tp)) :
g_alignments[tp->type];
case bt_bitfield:
case bt_ubitfield:
return alignment_of_type (tp_int);
case bt_bbitfield:
return alignment_of_type (tp_bool);
default:
CANNOT_REACH_HERE ();
return 0L; /*lint !e527*/ /* unreachable */
}
}
void initialize_types P0 (void)
{
#ifdef LONGLONG
#ifdef LONGLONG_BOOTSTRAP
{
UVAL uval;
range_ulong.low = 0;
uval = (UVAL) 0xFFFFFFFFUL;
range_ulong.high = (IVAL) uval;
range_ulonglong.low = 0;
uval = 0;
range_ulonglong.high = (IVAL) ~uval;
uval = 1;
range_longlong.low = (IVAL) (uval << 63);
uval = 0;
range_longlong.high = (IVAL) ((~uval) >> 1);
};
#endif /* LONGLONG_BOOTSTRAP */
#endif /* LONGLONG */
if (short_option) {
/*
* set 'int' and 'enum' type
*/
stp_int.type = bt_int16;
stp_uint.type = bt_uint16;
stp_int.size = 2L;
stp_uint.size = 2L;
}
#ifdef INTEL_86
if (small_option) {
stp_pointer.type = bt_pointer16;
stp_string.type = bt_pointer16;
stp_array.type = bt_pointer16;
stp_pointer.size = 2L;
stp_string.size = 2L;
stp_func.size = 2L;
}
#endif /* INTEL_86 */
if (uchar_option) {
stp_char.type = bt_charu;
}
tp_void = mk_type (&stp_void, NIL_TYP);
tp_long = mk_type (&stp_long, NIL_TYP);
tp_ulong = mk_type (&stp_ulong, NIL_TYP);
tp_char = mk_type (&stp_char, NIL_TYP);
tp_uchar = mk_type (&stp_uchar, NIL_TYP);
tp_schar = mk_type (&stp_schar, NIL_TYP);
tp_short = mk_type (&stp_short, NIL_TYP);
tp_ushort = mk_type (&stp_ushort, NIL_TYP);
tp_int = mk_type (&stp_int, NIL_TYP);
tp_uint = mk_type (&stp_uint, NIL_TYP);
tp_float = mk_type (&stp_float, NIL_TYP);
tp_double = mk_type (&stp_double, NIL_TYP);
if (longdouble_option) {
tp_longdouble = mk_type (&stp_longdouble, NIL_TYP);
} else {
tp_longdouble = tp_double;
}
tp_size = mk_type (&STP_SIZE, NIL_TYP);
tp_ptrdiff = mk_type (&STP_PTRDIFF, NIL_TYP);
tp_wchar = mk_type (&STP_WIDE, NIL_TYP);
tp_string = mk_type (&stp_string, tp_char);
tp_conststring = mk_type (&stp_conststring, tp_char);
tp_wstring = mk_type (&stp_pointer, tp_wchar);
tp_func = mk_type (&stp_func, tp_int);
tp_pointer = mk_type (&stp_pointer, tp_void);
tp_array = mk_type (&stp_array, NIL_TYP);
tp_enum = mk_type (&stp_enum, NIL_TYP);
tp_struct = &stp_struct;
tp_union = &stp_union;
tp_ellipsis = mk_type (&stp_ellipsis, NIL_TYP);
tp_bool = mk_type (&stp_bool, NULL);
tp_longlong = mk_type (&stp_longlong, NULL);
tp_ulonglong = mk_type (&stp_ulonglong, NULL);
tp_floatcomplex = mk_type (&stp_floatcomplex, NULL);
tp_floatimaginary = mk_type (&stp_floatimaginary, NULL);
tp_doublecomplex = mk_type (&stp_doublecomplex, NULL);
tp_doubleimaginary = mk_type (&stp_doubleimaginary, NULL);
tp_longdoublecomplex = mk_type (&stp_longdoublecomplex, NULL);
tp_longdoubleimaginary = mk_type (&stp_longdoubleimaginary, NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -