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

📄 types.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
    2L,				/* bt_longdoubleimaginary */
    2L,				/* bt_pointer16 */
    2L,				/* bt_pointer32 */
    2L,				/* bt_struct    */
    2L,				/* bt_union     */
    2L,				/* bt_func      */
    2L,				/* bt_bitfield  */
    2L,				/* bt_ubitfield */
    1L,				/* bt_bbitfield */
    2L				/* bt_ellipsis - used for alignment suitable for all types */
};

static SIZE *g_alignments = &alignments[0];

#endif /* CPU_DEFINED */

/*
 *  Creste a function node
 */
static FUNC *mk_func P2(FUNCCALL, kind, BLOCK *, params)
{
    FUNC *fp = (FUNC *) galloc (sizeof (FUNC));

    if (fp)
    {
	fp->kind = kind;
	fp->lst = (params ? params : mk_block ());
    }
    return fp;
}

/*****************************************************************************/

/*
 *   returns true it tp is an integral type,
 *   otherwise return false.
 */

BOOL is_integral_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    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:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}


#ifdef FLOAT_SUPPORT

/*
 *   returns true if the type is a floating type,
 *   otherwise it returns false.
 */

BOOL is_floating_type P1 (const TYP *, tp)
{
    return is_real_floating_type (tp) || is_complex_type (tp);
}


/*
 *   returns true if the type is a real floating type,
 *   otherwise it returns false.
 */

BOOL is_real_floating_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_float:
    case bt_double:
    case bt_longdouble:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}


/*
 *   returns true if the type is a complex type
 *   otherwise it returns false
 */
BOOL is_complex_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_floatcomplex:
    case bt_doublecomplex:
    case bt_longdoublecomplex:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}
#endif	/* FLOAT_SUPPORT */

/*
 *   returns true if the type is an arithmetic type,
 *   otherwise it returns false.
 */
BOOL is_arithmetic_type P1 (const TYP *, tp)
{
    return (is_integral_type (tp)
#ifdef FLOAT_SUPPORT
	    || is_floating_type (tp)
#endif /* FLOAT_SUPPORT */
	);
}


/*
 *   returns true if the type is a function, otherwise returns false.
 */

BOOL is_function_type P1 (const TYP *, tp)
{
    if (tp == NIL_TYP) {
	return FALSE;
    }
    /* functions are implicitly converted to pointers to functions */
    return (is_func (tp)) ||
	(is_pointer_type (tp) && is_func (referenced_type (tp)));
}


/*
 *   returns true if the type is a scalar type,
 *   otherwise returns false.
 */
BOOL is_scalar_type P1 (const TYP *, tp)
{
    return (is_arithmetic_type (tp) ||
	    is_pointer_type (tp) || is_bitfield_type (tp));
}


/*
 *   returns true is the type is an object type,
 *   otherwise returns false.
 */

BOOL is_object_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_func:
	return FALSE;
    default:
	break;
    }
    return TRUE;
}


/*
 *   returns true if the type is a struct or union,
 *   otherwise returns false.
 */

BOOL is_structure_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_struct:
    case bt_union:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}


/*
 *  returns true is the type is an anonymous struct or union,
 *  otherwise returns false.
 */

BOOL is_anonymous_structure P1 (const TYP *, tp)
{
    if (is_structure_type (tp)) {
	const CHAR *name = nameoftype (tp);

	return ((name == stp_struct.sname) || (name == stp_union.sname));
    }
    return FALSE;
}

/*
 *   returns true if the type is a pointer type,
 *   otherwise it returns false.
 */

BOOL is_pointer_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_pointer32:
    case bt_pointer16:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}


/*
 *   returns type if the type is an array,
 *   otherwise returns false.
 */

BOOL is_array_type P1 (const TYP *, tp)
{
    return (is_pointer_type (tp) && is_derived_type (tp));
}


/*
 *   return true if the type is an array with
 *   a variable length, otherwise returns false
 */
BOOL is_variable_array_type P1 (const TYP *, tp)
{
    return is_array_type (tp) && 0;
}

/*
 *   returns true if tp is a signed type,
 *   otherwise it returns false.
 */

BOOL is_signed_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_char:
    case bt_schar:
    case bt_short:
    case bt_int16:
    case bt_int32:
    case bt_long:
    case bt_longlong:
    case bt_bitfield:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}

/*
 *   returns true if tp is an unsigned type,
 *   otherwise it returns false.
 */

BOOL is_unsigned_type P1 (const TYP *, tp)
{
    switch (tp->type) {
    case bt_bool:
    case bt_ulonglong:
    case bt_ulong:
    case bt_uint32:
    case bt_uint16:
    case bt_ushort:
    case bt_uchar:
    case bt_charu:
    case bt_pointer16:
    case bt_pointer32:
    case bt_ubitfield:
    case bt_bbitfield:
	return TRUE;
    default:
	break;
    }
    return FALSE;
}

static BOOL is_compatible_proto P2 (const BLOCK *, block1, const BLOCK *, block2)
{
    SYM    *sp1 = symbolsof (block1);
    SYM    *sp2 = symbolsof (block2);

    if (sp1 == sp2) {
	return TRUE;
    }
    if ((sp1 == NIL_SYM) || (sp2 == NIL_SYM)) {
	return TRUE;
    }
    while ((sp1 != NIL_SYM) && (sp2 != NIL_SYM)) {
	if (!is_compatible_type (typeof (sp1), typeof (sp2))) {
	    return FALSE;
	}
	sp1 = nextsym (sp1);
	sp2 = nextsym (sp2);
    }
    return (sp1 == sp2);
}

static BOOL is_equal_proto P2 (const SYM *, sp1, const SYM *, sp2)
{
    if (sp1 == sp2) {
	return TRUE;
    }
    if ((sp1 == NIL_SYM) || (sp2 == NIL_SYM)) {
	return TRUE;
    }
    while ((sp1 != NIL_SYM) && (sp2 != NIL_SYM)) {
	if (!is_equal_type (typeof (sp1), typeof (sp2))) {
	    return FALSE;
	}
	sp1 = nextsym (sp1);
	sp2 = nextsym (sp2);
    }

    return (sp1 == sp2);
}

BOOL is_equal_type P2 (const TYP *, tp1, const TYP *, tp2)
{
    if (tp1 == tp2) {
	return TRUE;
    }
    if (tp1 == NIL_TYP || tp2 == NIL_TYP) {
	return FALSE;
    }
    if (!is_same_type (tp1, tp2)) {
	return FALSE;
    }
    if (tp1->qual != tp2->qual) {
	return FALSE;
    }
    switch (tp1->type) {
    case bt_pointer16:
    case bt_pointer32:
	return is_equal_type (referenced_type (tp1), referenced_type (tp2));
    case bt_func:
	return is_equal_type (returned_type (tp1), returned_type (tp2)) &&
	    is_equal_proto (parametersof (tp1), parametersof (tp2));
    case bt_struct:
    case bt_union:
	return (members (tp1) == members (tp2));
    default:
	break;
    }
    return TRUE;
}

TYP    *qualify_type P2 (TYP *, tp, QUALIFIER, qualifier)
{
    if (tp != NIL_TYP)
    {
	if (qualifier != tp->qual) {
	    TYP    *tp1 = tp;
	    QUALIFIER q = tp1->qual;

	    tp1->qual = qualifier;
	    tp = mk_type (tp1, tp1->btp);
	    tp1->qual = q;
	}
    }
    return tp;
}

/*
 * ANSI 3.1.2.6
 *   A composite type can be constructed from two types that are compatible;
 *   it is a type that is compatible with both of the two types and
 *   satisfies the following conditions:
 *
 *       If one type is an array of know size, the composite type is an
 *       array of that size.
 *
 *       If only one type is a function type with a parameter list (a
 *       function prototype), the composite type is a function prototype
 *       with the parameter list.
 *
 *       If both types are function types with parameter type lists, the
 *       type of each parameter in the composite parameter type list
 *       is the composite type of the corresponding parameters.
 *
 *   These rules apply recursively to the types from which the two
 *   types are derived.
 */
TYP    *composite_type P2 (TYP *, tp1, TYP *, tp2)
{
    SYM    *sp1, *sp2;

    if (!is_equal_type (tp1, tp2)) {
	return tp1;		/* error path */
    }
    if (tp1 == tp2) {
	return tp1;
    }
    switch (tp1->type) {
    case bt_pointer16:
    case bt_pointer32:
	/*
	 *   Combine the pointed at types.
	 */
	set_referenced_type (tp1,
			     composite_type (referenced_type (tp1),
					     referenced_type (tp2)));

	if (is_array_type (tp1)) {
	    if (is_unknown_size (tp1)) {
		/*
		 *   tp1 is an array with unknown size ... return
		 *   tp2 as it might have a known size.
		 */
		return tp2;
	    }
	    if (is_unknown_size (tp2)) {
		/*
		 *   tp2 is an array with unknown size ... return
		 *   tp1 as it has a known size.
		 */
		return tp1;
	    }
	}
	break;
    case bt_func:
	/*
	 *   Combine the function return types.
	 */
	set_returned_type (tp1,
			   composite_type (returned_type (tp1),
					   returned_type (tp2)));
	set_returned_type (tp2, returned_type (tp1));

	sp1 = parametersof (tp1);
	if (sp1 == NIL_SYM) {
	    /*
	     *       tp1 has no parameters so return tp2 ... it might have
	     */
	    return tp2;
	}
	sp2 = parametersof (tp2);
	if (sp2 == NIL_SYM) {
	    /*
	     *       tp2 has no parameters so return tp1 ... it does
	     */
	    return tp1;
	}
	/*
	 *   Now combine the type information for the function parameters
	 */
	while (sp1 != NIL_SYM && sp2 != NIL_SYM) {
	    set_type (sp1, composite_type (typeof (sp1), typeof (sp2)));
	    set_type (sp2, typeof (sp1));
	    sp1 = nextsym (sp1);
	    sp2 = nextsym (sp2);
	}
	break;
    default:
	break;
    }
    return tp1;
}

/*
 * This is used to tell valid if two types are compatible with each other.
 *
 * ANSI 3.1.2.6
 *      Two types have compatible type if their types are the same.
 *      Two structure, union, or enumeration types declared in separate
 *      translation units are compatible if they have the same number of
 *      members, the same member names, and compatible member types; for
 *      two structures, the members shall be in the same order; for two
 *      structures or unions, te bit-fields shall have the same widths;
 *      for two enumerations, the members shall have the same values.
 *
 *      All declarations that refer to the same object or function shall have
 *      compatible type; otherwise the behaviour is undefined.
 *
 * ANSI 3.5.3
 *      for two qualified types to be compatible, both shall have the
 *      identically qualified version of a compatible type;  the order of the
 *      qualifiers within a list of specifiers or qualifiers does not
 *      affect the specified type.
 *
 * ANSI 3.5.4.1
 *      for two pointers to be compatible, both shall be identically qualified
 *      and both shall be pointers to compatible types.
 *
 * ANSI 3.5.4.2
 *      For two arrays to be compatible, both shall have compatible element
 *      types, and if both size specifiers are present they shall have the
 *      same value.
 *
 * ANSI 3.5.4.3
 *      for two function type to be compatible, both shall specify compatible
 *      return types.  Moreover, the parameter type lists, if both are
 *      present, shall agree in the number of parameters and in use of the
 *      ellipsis terminator; corresponding parameters shall have compatible
 *      types.  If one type has a parameter list and the other type is
 *      specified by a function declarator that is not part of a function
 *      definition and that contains an empty identifier list, the
 *      parameter list shall not have an ellipsis terminator and the type
 *      of each parameter shall be compatible with the type that results
 *      from the application of the default argument promotions.  If one type
 *      has a parameter type list and the other type is specified by a function
 *      definition that contains a (possibly empty) identifier list, both
 *      shall agree in the numbe of parameters, and the type of each
 *      prototype argument shall be compatible with the type that results
 *      from the application of the default argument promotions to the type
 *      of the corresponding identifier.
 */
BOOL is_compatible_type P2 (const TYP *, tp1, const TYP *, tp2)
{
    if (tp1 == tp2) {
	return TRUE;
    }
    if (tp1 == NIL_TYP || tp2 == NIL_TYP) {
	return FALSE;
    }
    if (!is_same_type (tp1, tp2)) {
	return FALSE;
    }
    switch (tp1->type) {
    case bt_pointer16:
    case bt_pointer32:
	if (is_void (referenced_type (tp1))
	    || is_void (referenced_type (tp2))) {
	    return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -