📄 types.c
字号:
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 + -