analtype.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 794 行 · 第 1/2 页

C
794
字号
#define ENTRY_SSHORT        TYP_SINT,
#define ENTRY_USHORT        CNV( TYP_UINT, TYP_SINT ),
#define ENTRY_SINT          TYP_SINT,
#define ENTRY_UINT          TYP_UINT,
#define ENTRY_SLONG         TYP_SLONG,
#define ENTRY_ULONG         TYP_ULONG,
#define ENTRY_SLONG64       TYP_SLONG64,
#define ENTRY_ULONG64       TYP_ULONG64,
#define ENTRY_FLOAT         TYP_FLOAT,
#define ENTRY_DOUBLE        TYP_DOUBLE,
#define ENTRY_LONG_DOUBLE   TYP_LONG_DOUBLE,
#define ENTRY_ENUM          TYP_ERROR,
#define ENTRY_POINTER       TYP_ERROR,
#define ENTRY_TYPEDEF       TYP_ERROR,
#define ENTRY_CLASS         TYP_ERROR,
#define ENTRY_BITFIELD      TYP_ERROR,
#define ENTRY_FUNCTION      TYP_ERROR,
#define ENTRY_ARRAY         TYP_ERROR,
#define ENTRY_DOT_DOT_DOT   TYP_ERROR,
#define ENTRY_VOID          TYP_ERROR,
#define ENTRY_MODIFIER      TYP_ERROR,
#define ENTRY_MEMBER_POINTER TYP_ERROR,
#define ENTRY_GENERIC       TYP_ERROR,

static type_id intPromo[] = {   // Table of integral promotions
    #include "type_arr.h"
};

#undef CNV


static type_id integralPromote( // GET type_id AFTER INTEGRAL PROMOTION
    TYPE type )                 // - original type
{
    return intPromo[ TypedefModifierRemove( type ) -> id ];
}


TYPE TypeBinArithResult(        // TYPE OF BINARY ARITHMETIC RESULT
    TYPE op1,                   // - type[1]
    TYPE op2 )                  // - type[2]
{
    type_id id1;                // - id for type(1)
    type_id id2;                // - id for type(2)

    id1 = integralPromote( op1 );
    id2 = integralPromote( op2 );
    if( id1 > id2 ) {
        type_id tmp;
        tmp = id1;
        id1 = id2;
        id2 = tmp;
    }
#if _CPU == 386
    if( ( id1 == TYP_UINT ) && ( id2 == TYP_SLONG ) ) {
        id2 = TYP_ULONG;
    }
#endif
    return GetBasicType( id2 );
}


TYPE TypeUnArithResult(         // TYPE OF UNARY ARITHMETIC RESULT
    TYPE op1 )                  // - type
{
    return GetBasicType( integralPromote( op1 ) );
}

TYPE PointerTypeEquivalent( TYPE type )
/*************************************/
{
    type = TypedefModifierRemove( type );
    switch( type->id ) {
    case TYP_POINTER:
        /* this allows references also */
    case TYP_ARRAY:
    case TYP_FUNCTION:
        return( type );
    }
    return( NULL );
}


CTD TypeCommonDerivation(       // GET COMMON TYPE DERIVATION FOR TWO TYPES
    TYPE type1,                 // - type [1] (left)
    TYPE type2 )                // - type [2] (right)
{
    CTD retn;                   // - return: CTD_...
    SCOPE scope1;               // - scope for type[1]
    SCOPE scope2;               // - scope for type[2]

    scope1 = TypeScope( StructType( type1 ) );
    if( NULL == scope1 ) {
        retn = CTD_NO;
    } else {
        scope2 = TypeScope( StructType( type2 ) );
        if( scope1 == scope2 ) {
            retn = CTD_LEFT;
        } else if( NULL == scope2 ) {
            retn = CTD_NO;
        } else {
            switch( ScopeDerived( scope1, scope2 ) ) {
              case DERIVED_YES :
                retn = CTD_LEFT;
                break;
              case DERIVED_YES_BUT_VIRTUAL :
                retn = CTD_LEFT_VIRTUAL;
                break;
              case DERIVED_YES_BUT_AMBIGUOUS :
                retn = CTD_LEFT_AMBIGUOUS;
                break;
              case DERIVED_YES_BUT_PRIVATE :
                retn = CTD_LEFT_PRIVATE;
                break;
              case DERIVED_YES_BUT_PROTECTED :
                retn = CTD_LEFT_PROTECTED;
                break;
              case DERIVED_NO :
                switch( ScopeDerived( scope2, scope1 ) ) {
                  case DERIVED_YES :
                    retn = CTD_RIGHT;
                    break;
                  case DERIVED_YES_BUT_VIRTUAL :
                    retn = CTD_RIGHT_VIRTUAL;
                    break;
                  case DERIVED_YES_BUT_AMBIGUOUS :
                    retn = CTD_RIGHT_AMBIGUOUS;
                    break;
                  case DERIVED_YES_BUT_PRIVATE :
                    retn = CTD_RIGHT_PRIVATE;
                    break;
                  case DERIVED_YES_BUT_PROTECTED :
                    retn = CTD_RIGHT_PROTECTED;
                    break;
                  case DERIVED_NO :
                    retn = CTD_NO;
                    break;
                }
            }
        }
    }
    return retn;
}


boolean TypeRequiresCtorParm(   // TEST IF EXTRA CTOR PARM REQUIRED
    TYPE type )                 // - the type
{
    return TypeHasVirtualBases( type );
}


boolean PointerToFuncEquivalent( // TEST IF EQUIVALENT TO PTR(FUNCTION)
    TYPE type )
{
    boolean retn;               // - return: TRUE ==> equiv. to ptr to funct.
    type_flag not_used;

    type = TypedefModifierRemove( type );
    if( type->id == TYP_FUNCTION ) {
        retn = TRUE;
    } else if( PointerTypeEquivalent( type ) ) {
        type = TypePointedAt( type, &not_used );
        if( type->id == TYP_FUNCTION ) {
            retn = TRUE;
        } else {
            retn = FALSE;
        }
    }
    return retn;
}


#if 0 // not used
boolean TypeIsCppFunc(          // TEST IF C++ FUNCTION TYPE
    TYPE type )                 // - type to be tested
{
    boolean retn;               // - return: TRUE ==> C++ function

    type = FunctionDeclarationType( type );
    if( type == NULL ) {
        retn = FALSE;
    } else if( type->flag & TF1_PLUSPLUS ) {
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return retn;
}
#endif


TYPE TypeFunctionCalled(        // GET FUNCTION DECLARATION TYPE CALLED
    TYPE type )                 // - function type called
{
    TYPE pted;                  // - NULL or type pointed at

    type = TypeReferenced( type );
    pted = TypePointedAtModified( type );
    if( NULL != pted ) {
        type = pted;
    }
    return FunctionDeclarationType( type );
}


TYPE TypeThisForCall(           // GET "THIS" TYPE FOR A CALL
    PTREE this_node,            // - this node
    SYMBOL sym )                // - function being called
{
    TYPE this_type;             // - target type for "this"

    this_type = SymClass( sym );
    if( ExprIsLvalue( this_node ) ) {
        this_type = MakeReferenceTo( this_type );
    } else {
        this_type = MakePointerTo( this_type );
    }
    return this_type;
}


static CLASSINFO* getClassInfo( // GET CLASS INFO FOR GOOD ELEMENTAL TYPE
    TYPE type )                 // - type
{
    CLASSINFO* info;            // - information for class
    TYPE artype;                // - NULL or array type

    if( type == NULL ) {
        info = NULL;
    } else {
        artype = ArrayType( type );
        if( artype != NULL ) {
            type = ArrayBaseType( artype );
        }
        type = StructType( type );
        if( type == NULL ) {
            info = NULL;
        } else {
            info = TypeClassInfo( type );
            if( info->corrupted ) {
                info = NULL;
            }
        }
    }
    return info;
}


boolean TypeRequiresRWMemory(   // TEST IF TYPE MUST BE IN NON-CONST STORAGE
    TYPE type )                 // - type
{
    CLASSINFO* info;            // - information for class
    boolean retn;               // - TRUE ==> requires CTOR'ING

    retn = FALSE;
    info = getClassInfo( type );
    if( info != NULL ) {
        if( info->needs_ctor || info->needs_dtor || info->has_mutable ) {
            retn = TRUE;
        }
    }
    return retn;
}


boolean TypeRequiresCtoring(    // TEST IF TYPE MUST BE CTOR'ED
    TYPE type )                 // - type
{
    CLASSINFO* info;            // - information for class
    boolean retn;               // - TRUE ==> requires CTOR'ING

    info = getClassInfo( type );
    if( info == NULL ) {
        retn = FALSE;
    } else if( info->needs_ctor ) {
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return retn;
}


boolean TypeRequiresDtoring(    // TEST IF TYPE MUST BE DTOR'ED
    TYPE type )                 // - type
{
    CLASSINFO* info;            // - information for class
    boolean retn;               // - TRUE ==> requires CTOR'ING

    info = getClassInfo( type );
    if( info == NULL ) {
        retn = FALSE;
    } else if( info->needs_dtor ) {
        retn = TRUE;
    } else {
        retn = FALSE;
    }
    return retn;
}

static TYPE augmentWithNear(    // AUGMENT TYPE WITH TF1_NEAR, IF REQ'D
    TYPE type )                 // - type to be augmented
{
    type_flag flags;            // - existing flags

    TypeGetActualFlags( type, &flags );
    if( 0 == ( flags & TF1_MEM_MODEL ) ) {
        type = MakeModifiedType( type, TF1_NEAR );
    }
    return type;
}


TYPE TypeAutoDefault(           // ADD NEAR QUALIFIER FOR AUTO SYMBOL
    TYPE type,                  // - a type
    PTREE expr )                // - possible PT_SYMBOL of SC_AUTO
{
#if 0
    if( PtreeOpFlags( expr ) & PTO_RVALUE ) {
        type = augmentWithNear( type );
    } else if( expr->op == PT_SYMBOL ) {
#else
    if( expr->op == PT_SYMBOL ) {
#endif
        SYMBOL sym = expr->u.symcg.symbol;
        if( sym->id == SC_AUTO ) {
            type_flag flags;
            TypeGetActualFlags( sym->sym_type, &flags );
            if( 0 == ( flags & TF1_MEM_MODEL ) ) {
                type = augmentWithNear( type );
            }
        }
    }
    return type;
}


TYPE TypeForLvalue              // GET TYPE FOR LVALUE
    ( PTREE expr )              // - lvalue expression
{
    TYPE type_expr;             // - expression type
    TYPE type_lv;               // - type of LVALUE

    type_expr = NodeType( expr );
    type_lv = TypeReference( type_expr );
    DbgVerify( type_lv != NULL, "TypeForLvalue -- not lvalue" );
    return type_lv;
}


boolean ExprIsLvalue            // TEST IF EXPRESSION IS LVALUE
    ( PTREE expr )              // - expression
{
    boolean retn;               // - return: TRUE ==> is lvalue

    if( expr->flags & PTF_LVALUE ) {
        retn = TRUE;
    } else {
#ifndef NDEBUG
        TYPE type_expr;
        TYPE type_lv;
        type_expr = NodeType( expr );
        type_lv = TypeReference( type_expr );
        retn = NULL != type_lv;
#else
        retn = NULL != TypeForLvalue( expr );
#endif
    }
    return retn;
}


boolean TypeDefedNonAbstract    // REQUIRE DEFINED, NON-ABSTRACT TYPE
    ( TYPE type                 // - the type
    , PTREE expr                // - NULL or expression for error
    , MSG_NUM msg_abstract      // - message when abstract
    , MSG_NUM msg_undefed )     // - message when undefined
{
    boolean retn;               // - return: TRUE ==> defined & non-abstract

    expr = expr;
    if( ! TypeDefined( type ) ) {
        CErr1( msg_undefed );
        InfClassDecl( type );
        return FALSE;
    } else if( AbstractClassType( type ) ) {
        CErr1( msg_abstract );
        InfClassDecl( type );
        ScopeNotePureFunctions( type );
        return FALSE;
    } else {
        retn = TRUE;
    }
    return retn;
}

⌨️ 快捷键说明

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