cgtype.c

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

C
610
字号

    type = TypeModFlags( type, &mod_flags );
    switch( type->id ) {
      case TYP_BOOL :
        size = TARGET_BOOL;
        break;
      case TYP_ERROR :
      case TYP_UCHAR :
      case TYP_SCHAR :
        size = TARGET_CHAR;
        break;
      case TYP_WCHAR :
      case TYP_USHORT :
      case TYP_SSHORT :
        size = TARGET_SHORT;
        break;
      case TYP_SINT :
        size = TARGET_INT;
        break;
      case TYP_UINT :
        size = TARGET_UINT;
        break;
      case TYP_ULONG :
        size = TARGET_ULONG;
        break;
      case TYP_SLONG :
        size = TARGET_LONG;
        break;
      case TYP_ULONG64 :
        size = TARGET_ULONG64;
        break;
      case TYP_SLONG64 :
        size = TARGET_LONG64;
        break;
      case TYP_FLOAT :
        size = TARGET_FLOAT;
        break;
      case TYP_DOUBLE :
        size = TARGET_DOUBLE;
        break;
      case TYP_LONG_DOUBLE :
        size = TARGET_LONG_DOUBLE;
        break;
      case TYP_POINTER :
        if( ( ! ref_as_ptr ) && ( type->flag & TF1_REFERENCE ) ) {
            size = cgSize( type->of, FALSE );
        } else {
            type = TypeModFlags( type->of, &mod_flags );
            if( type->id == TYP_FUNCTION ) {
                size = code_ptr_size( mod_flags );
            } else {
                size = data_ptr_size( mod_flags );
            }
        }
        break;
      case TYP_BITFIELD :
        size = cgSize( type->of, TRUE );
        break;
      case TYP_ARRAY :
        size = type->u.a.array_size;
        if( type->flag & TF1_ZERO_SIZE ) {
            DbgAssert( type->u.a.array_size == 1 );
            size = 0;
        } else {
            size *= cgSize( type->of, FALSE );
        }
        break;
      case TYP_CLASS :
        if( TypeDefined( type ) ) {
            size = type->u.c.info->size;
        } else {
            size = 0;
        }
        break;
      case TYP_FUNCTION :
        size = code_ptr_size( mod_flags );
        break;
      case TYP_MEMBER_POINTER :
        size = CgCodePtrSize() + 2 * TARGET_UINT;
        break;
      default :
        size = 0;
        break;
    }
    return( size );
}


target_size_t CgTypeSize(       // COMPUTE SIZE OF A TYPE IN USE
    TYPE type )                 // - type
{
    return cgSize( type, FALSE );
}


target_size_t CgMemorySize(     // COMPUTE SIZE OF A TYPE IN MEMORY
    TYPE type )                 // - type
{
    return cgSize( type, TRUE );
}


unsigned CgTypeSym(             // COMPUTE OUTPUT TYPE FOR SYMBOL
    SYMBOL sym )                // - the symbol
{
    TYPE type = sym->sym_type;
    if( SymIsArgument( sym )
     && NULL != StructType( type )
     && OMR_CLASS_REF == ObjModelArgument( type ) ) {
        type = MakeReferenceTo( type );
    }
    return CgTypeOutput( type );
}


unsigned CgTypePtrSym(          // COMPUTE OUTPUT TYPE OF POINTER TO SYMBOL
    SYMBOL sym )                // - symbol
{
    type_flag mod_flags;        // - modifier flags
    TYPE type;                  // - unmodified type
    unsigned codegen_type;      // - code-gen type

    type = TypeModFlags( sym->sym_type, &mod_flags );
    if( type->id == TYP_FUNCTION ) {
        if( mod_flags & TF1_NEAR ) {
            codegen_type = T_NEAR_CODE_PTR;
        } else if( mod_flags & TF1_FAR ) {
            codegen_type = T_LONG_CODE_PTR;
        } else {
            codegen_type = T_CODE_PTR;
        }
    } else {
        if( mod_flags & TF1_NEAR ) {
            codegen_type = T_NEAR_POINTER;
        } else if( mod_flags & TF1_FAR ) {
            codegen_type = T_LONG_POINTER;
        } else if( mod_flags & TF1_HUGE ) {
            codegen_type = T_HUGE_POINTER;
        } else {
            codegen_type = T_POINTER;
        }
    }
    return codegen_type;
}


static
target_size_t cgPtrSize(        // COMPUTE SIZE OF A POINTER
    TYPE type )                 // - type
{
    type_flag mod_flags;        // - modifier flags
    unsigned size;              // - size of the type

    type = TypeModFlags( type, &mod_flags );
    switch( type->id ) {
      case TYP_ARRAY :
      case TYP_POINTER :
        TypeModFlags( type->of, &mod_flags );
        size = data_ptr_size( mod_flags );
        break;
      case TYP_FUNCTION :
        size = code_ptr_size( mod_flags );
        break;
      default :
        size = 0;
        break;
    }
    return( size );
}


TYPE TypePointerDiff(           // GET TYPE FOR DIFFERENCE OF POINTERS
    TYPE type )                 // - node for a type
{
    type_flag flag;             // - flags, when modifier

    type = TypeModFlags( type, &flag );
    switch( type->id ) {
      case TYP_ARRAY :
      case TYP_POINTER :
        TypeModFlags( type->of, &flag );
        type = *ptr_diff_type[ data_ptr_type( flag ) ];
        break;
      case TYP_FUNCTION :
        type = *ptr_diff_type[ code_ptr_type( flag ) ];
        break;
      default :
        type = NULL;
        break;
    }
    return( type );
}


static target_size_t cgTypeTruncSize( // GET SIZE FOR TRUNCATION
    TYPE type )                 // - type to be sized
{
    target_size_t size;         // - size of element
    type_flag flags;            // - flags for a type

    switch( TypedefModifierRemove( type )->id ) {
      case TYP_ARRAY :
      case TYP_FUNCTION :
      case TYP_POINTER :
        TypePointedAt( type, &flags );
        if( flags & ( TF1_BASED | TF1_FAR16 ) ) {
            type = TypeConvertFromPcPtr( type );
        }
        size = cgPtrSize( type );
        break;
      default :
        size = CgTypeSize( type );
        break;
    }
    return( size );
}


unsigned CgTypeTruncation(      // GET CNV_... FOR TRUNCATION
    TYPE tgt,                   // - target type
    TYPE src )                  // - source type
{
    unsigned retn;              // - CNV_OK or CNV_OK_TRUNC
    type_flag src_flags;        // - flags for pointed source type
    type_flag tgt_flags;        // - flags for pointed target type
    TYPE umod;                  // - unmodified type for item
    TYPE ptr_type;              // - pointer type

    umod = TypePointedAt( tgt, &tgt_flags );
    if( ( umod != NULL ) && ( tgt_flags & ( TF1_BASED | TF1_FAR16 ) ) ) {
        retn = CNV_OK;
    } else {
        umod = TypePointedAt( src, &src_flags );
        if( ( umod != NULL ) && ( src_flags & ( TF1_BASED | TF1_FAR16 ) ) ) {
            src = TypeConvertFromPcPtr( src );
        }
        if( cgTypeTruncSize( tgt ) < cgTypeTruncSize( src ) ) {
            retn = CNV_OK_TRUNC;
            if( tgt_flags & TF1_NEAR ) {
                if( src_flags & (TF1_FAR|TF1_HUGE) ) {
                    ptr_type = PointerTypeEquivalent( src );
                    if( ptr_type->id == TYP_POINTER ) {
                        /* far to near cnv of a ptr/ref */
                        if( ( ptr_type->flag & TF1_FAR_BUT_NEAR ) != 0 ) {
                            /* but the far is really near */
                            retn = CNV_OK;
                        }
                    }
                }
            }
        } else {
            retn = CNV_OK;
        }
    }
    return( retn );
}


unsigned CgTypeOffset(          // GET CODEGEN TYPE FOR AN OFFSET
    void )
{
#if _INTEL_CPU
  #if _CPU == 386
    return T_UINT_4;
  #else
    return T_UINT_2;
  #endif
#elif _CPU == _AXP
    return T_UINT_4;
#else
    #error bad target
#endif
}


static void init(               // MODULE INITIALIZATION
    INITFINI* defn )            // - definition
{
    defn = defn;
    defined_type = T_FIRST_FREE;
    cg_member_ptr = NULL_CGREFNO;
#if _CPU == _AXP
    defaultDataPtrClass = PTR_NEAR;
    defaultCodePtrClass = PTR_NEAR;
#elif _INTEL_CPU
    defaultDataPtrClass = PTR_NEAR;
    defaultCodePtrClass = PTR_NEAR;
    if(( TargetSwitches & FLAT_MODEL ) == 0 ) {
        if( IsHugeData() ) {
            defaultDataPtrClass = PTR_HUGE;
        } else if( IsBigData() ) {
            defaultDataPtrClass = PTR_LONG;
        }
        if( IsBigCode() ) {
            defaultCodePtrClass = PTR_LONG;
        }
    }
#else
    #error bad target
#endif
}


INITDEFN( cg_typing, init, InitFiniStub )

⌨️ 快捷键说明

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