⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 types.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
	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 = &range;
    } 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 + -