cgtype.c

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

C
610
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"
#include "cgdata.h"
#include "cgfront.h"
#include "codegen.h"
#include "initdefs.h"
#include "objmodel.h"

// get name consistency
//
#define T_NR_CODE_PTR       T_NEAR_CODE_PTR
#define T_FR_CODE_PTR       T_LONG_CODE_PTR
#define T_HG_CODE_PTR       T_LONG_CODE_PTR
#define T_NR_POINTER        T_NEAR_POINTER
#define T_FR_POINTER        T_LONG_POINTER
#define T_HG_POINTER        T_HUGE_POINTER
#define T_FAR16_POINTER     T_NEAR_POINTER
#define T_FAR16_CODE_PTR    T_NEAR_POINTER
#define TARGET_HG_POINTER   TARGET_FAR_POINTER
#define TARGET_FR_POINTER   TARGET_FAR_POINTER
#define TARGET_NR_POINTER   TARGET_NEAR_POINTER

#define PTR_NEAR            PTR_NR
#define PTR_FAR             PTR_FR
#define PTR_HUGE            PTR_HG
#define PTR_LONG            PTR_FR

#define PTR_TYPE(name,diff) __PASTE( PTR, name )           // - pointer types
typedef enum
#include "ptrtypes.h"
PTR_CLASS;

#define PTR_TYPE(name,diff) __PASTE3( T, name, _POINTER )  // - CG data types
static unsigned ptr_dg_type[] =
#include "ptrtypes.h"
;

#define PTR_TYPE(name,diff) __PASTE3( T, name, _CODE_PTR ) // - CG code types
static unsigned ptr_cg_type[] =
#include "ptrtypes.h"
;

#define PTR_TYPE(name,diff) __PASTE3( TARGET, name, _POINTER ) // - sizes
static target_size_t ptr_size[] =
#include "ptrtypes.h"
;

#define PTR_TYPE(name,diff) diff            // - TYPE for difference
static TYPE *ptr_diff_type[] =
#include "ptrtypes.h"
;

static CGREFNO defined_type     // next refno for defined types
            = T_FIRST_FREE;
static CGREFNO cg_member_ptr    // CG type for member pointers
            = NULL_CGREFNO;
static PTR_CLASS defaultDataPtrClass;// default data pointer type
static PTR_CLASS defaultCodePtrClass;// default code pointer type


boolean IsBigData(              // TEST IF DEFAULT MEMORY MODEL IS BIG DATA
    void )
{
    return( ( TargetSwitches & BIG_DATA ) != 0 );
}


#define __HUGE_DATA_SWITCHES    ( BIG_CODE | BIG_DATA | CHEAP_POINTER )
#define __HUGE_DATA_SETTING     ( BIG_CODE | BIG_DATA             )
boolean IsHugeData(             // TEST IF DEFAULT MEMORY MODEL IS HUGE DATA
    void )
{
    return( ( TargetSwitches & __HUGE_DATA_SWITCHES ) == __HUGE_DATA_SETTING );
}


boolean IsBigCode(              // TEST IF DEFAULT MEMORY MODEL IS BIG CODE
    void )
{
    return TargetSwitches & BIG_CODE;
}


static PTR_CLASS ptr_type(      // CLASSIFY POINTER TYPE
    type_flag mod_flags,        // - modifier flags
    PTR_CLASS ptr_class )       // - default classification
{
    if( mod_flags & TF1_MEM_MODEL ) {
        if( mod_flags & ( TF1_NEAR | TF1_BASED | TF1_FAR16 ) ) {
            ptr_class = PTR_NEAR;
        } else if( mod_flags & TF1_FAR ) {
            ptr_class = PTR_LONG;
        } else if( mod_flags & TF1_HUGE ) {
            ptr_class = PTR_HUGE;
        }
    }
    return( ptr_class );
}

#define data_ptr_type( mf ) ( ptr_type( (mf), defaultDataPtrClass ) )
#define code_ptr_type( mf ) ( ptr_type( (mf), defaultCodePtrClass ) )


TYPE CgStripType(               // STRIP ONE LEVEL OF TYPE INFORMATION
    TYPE type )                 // - type
{
    return( TypedefModifierRemove( type )->of );
}


static unsigned cg_new_type(    // GET NEW TYPE FOR CODE GENERATOR
    unsigned size,              // - size of type
    unsigned alignment )        // - alignment of type
{
    unsigned retn;              // - returned type

    // should be fatal error on overflow!
    retn = defined_type++;
    DbgAssert( defined_type != 0 );
    BEDefType( retn, alignment, size );
    return( retn );
}


static unsigned cg_defined_type( // GET DEFINED TYPE
    TYPE type,                  // - C++ type
    CGREFNO *refno )            // - addr( reference # for type )
{
    CGREFNO retn;               // - returned type

    retn = *refno;
    if( retn == NULL_CGREFNO ) {
        retn = cg_new_type( CgMemorySize( type ), CgMemorySize( AlignmentType( type ) ) );
        *refno = retn;
    }
    return( retn );
}


unsigned CgTypeOutput(          // COMPUTE TYPE FOR CODE GENERATOR
    TYPE type )                 // - C++ type
{
    unsigned retn;              // - return type (code generator)
    type_flag mod_flags;        // - modifier flags

    type = TypeModFlags( type, &mod_flags );
    switch( type->id ) {
      case TYP_SCHAR :
        retn = T_INT_1;
        break;
      case TYP_BOOL :
        retn = TY_BOOLEAN;
        break;
      case TYP_UCHAR :
        retn = T_UINT_1;
        break;
      case TYP_UINT :
        retn = TY_UNSIGNED;
        break;
      case TYP_USHORT :
      case TYP_WCHAR :
        retn = T_UINT_2;
        break;
      case TYP_SINT :
        retn = T_INTEGER;
        break;
      case TYP_SSHORT :
        retn = T_INT_2;
        break;
      case TYP_ULONG :
        retn = T_UINT_4;
        break;
      case TYP_SLONG :
        retn = T_INT_4;
        break;
      case TYP_ULONG64 :
        retn = T_UINT_8;
        break;
      case TYP_SLONG64 :
        retn = T_INT_8;
        break;
      case TYP_FLOAT :
        retn = T_SINGLE;
        break;
      case TYP_LONG_DOUBLE :
        retn = TY_DOUBLE;           // change later when long-double support
        break;
      case TYP_DOUBLE :
        retn = TY_DOUBLE;
        break;
      case TYP_POINTER :
        type = TypeModFlags( type->of, &mod_flags );
        if( type->id == TYP_FUNCTION ) {
            retn = ptr_cg_type[ code_ptr_type( mod_flags ) ];
        } else {
            retn = ptr_dg_type[ data_ptr_type( mod_flags ) ];
        }
        break;
      case TYP_ARRAY :
        retn = cg_defined_type( type, &type->u.a.refno );
        break;
      case TYP_CLASS :
        retn = cg_defined_type( type, &type->u.c.info->refno );
        break;
      case TYP_FUNCTION :
        retn = ptr_cg_type[ code_ptr_type( mod_flags ) ];
        break;
      case TYP_MEMBER_POINTER :
        retn = cg_defined_type( type, &cg_member_ptr );
        break;
      default:
        retn = T_INTEGER;
        break;
    }
    return( retn );
}


boolean IsCgTypeAggregate(      // CAN TYPE CAN BE INITIALIZED AS AGGREGATE?
    TYPE type,                  // - C++ type
    boolean string )            // - array of string not aggregate
{
    boolean retn = FALSE;       // - TRUE if aggregate
    CLASSINFO *info;            // - info part of class type

    type = TypedefModifierRemove( type );
    switch( type->id ) {
      case TYP_ARRAY :
        if( string && TypeIsCharString( type ) ) break;
        retn = TRUE;
        break;
      case TYP_BITFIELD :
        retn = TRUE;
        break;
      case TYP_CLASS :
        info = type->u.c.info;
        if( info->corrupted ) break;
        if( info->bases != NULL ) break;
        if( info->size != type->u.c.info->vsize ) break;
        if( info->last_vfn != 0 ) break;
        if( info->last_vbase != 0 ) break;
        if( info->has_data == 0 ) break;
        if( TypeNeedsCtor( type ) ) break;
        retn = TRUE;
        break;
    }
    return( retn );
}


#define code_ptr_size( mf ) ( ptr_size[ code_ptr_type( (mf) ) ] )
#define data_ptr_size( mf ) ( ptr_size[ data_ptr_type( (mf) ) ] )


target_size_t CgDataPtrSize(    // SIZE OF DEFAULT DATA POINTER
    void )
{
    return( data_ptr_size( TF1_NULL ) );
}


target_size_t CgCodePtrSize(    // SIZE OF DEFAULT CODE POINTER
    void )
{
    return( code_ptr_size( TF1_NULL ) );
}


static target_size_t cgSize(    // COMPUTE SIZE OF A TYPE
    TYPE type,                  // - type
    boolean ref_as_ptr )        // - TRUE ==> treat reference as pointer
{
    type_flag mod_flags;        // - modifier flags
    target_size_t size;         // - size of type

⌨️ 快捷键说明

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