cvtypes.c

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

C
1,915
字号
/****************************************************************************
*
*                            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:  Emit CodeView type information.
*
****************************************************************************/


#include "standard.h"
#include "string.h"
#include "coderep.h"
#include "cgdefs.h"
#include "sysmacro.h"
#include "symdbg.h"
#include "model.h"
#include "typedef.h"
#include "ocentry.h"
#include "objrep.h"
#include "zoiks.h"
#include "cvdbg.h"
#include "dbgstrct.h"
#define BY_CG
#include "feprotos.h"
#include "cgprotos.h"

struct lf_info {
     char       size;
     lf_values  code;
} lf_info;

static struct lf_info LFInfo[LFG_LAST] = {
    #define _LFMAC( n, N, c )    { sizeof( lf_##n ), c },
    #include "cv4types.h"
    #undef _LFMAC
};

extern  void        FEPtrBase(sym_handle);
extern  void        BuffWSLString(char*);
extern  uint        Length(char*);
extern  byte        *Copy(void*,void*,uint);
extern  seg_id      SetOP(seg_id);
extern  void        SetBigLocation( long_offset loc );
extern  long_offset AskBigLocation( void );
extern  void        ChkDbgSegSize( offset, bool );
extern  void        DataInt(short_offset);
extern  void        LocDump( dbg_loc );
extern  dbg_loc     LocDupl( dbg_loc );
extern  void        DBLocFini( dbg_loc loc );
extern  offset      LocSimpField( dbg_loc );
extern  void        DataBytes(unsigned_32,byte*);
extern  type_def    *TypeAddress(cg_type);
extern  void        CVSymIConst( char *nm, long val, dbg_type tipe );
extern  void        CVSymIConst64( char *nm, signed_64 val, dbg_type tipe );
extern  void        CVOutSymICon( cv_out *out, char *nm, long val, dbg_type tipe );
extern  void        CVOutSym( cv_out *out, sym_handle sym );
extern  void        CVOutBck( cv_out *out, bck_info *bck, offset add,  dbg_type tipe );
extern  void        CVOutLocal( cv_out *out, name *t, int disp,  dbg_type tipe );


extern  uint        TypeIdx;
extern  seg_id      CVTypes;


static  void    BuffWrite( cv_out *out, void *to )
/************************************************/
{
    int     len;
    seg_id  old;

    len = (char *)to - out->beg;
    old = SetOP( out->seg );
    DataBytes( len, out->beg );
    out->beg = to;
    SetOP( old );
}

static  void   BuffSkip( cv_out *out, void *to )
/**********************************************/
{
    out->beg = to;
}

static  void    BuffEnd( cv_out *out )
/************************************/
{
    int     len;
    seg_id  old;

    len = out->ptr - out->beg;
    old = SetOP( out->seg );
    DataBytes( len, out->beg );
    SetOP( old );
}

static  void    *BuffInc( cv_out *out, int size )
/***********************************************/
{
    void    *ptr;

    ptr = out->ptr;
    out->ptr += size;
    return( ptr );
}

static  void  *AlignBuff( cv_out *out )
/*** round out->ptr up to align size ***/
{
    int     len;
    int     len4;
    char    *ptr;

    ptr = out->ptr;
    len = ptr - out->buff;
    len4 = ((len+CV_ALIGN-1)& -CV_ALIGN);
    len = ((len+CV_ALIGN-1)& -CV_ALIGN) - len;
    for( ; len > 0; --len ) {
        *ptr = (LF_PAD0 | len);
        ++ptr;
    }
    out->ptr = ptr;
    return( ptr );
}


static  void    SegReloc( seg_id seg,  sym_handle sym )
/*****************************************************/
{
    seg_id      old;

    old = SetOP( seg );
    FEPtrBase( sym );
    SetOP( old );
}

static  void    *StartType( cv_out *out, lfg_index what )
/*******************************************************/
{
    lf_common   *ptr;

    ptr = (lf_common *)out->ptr;
    out->ptr += LFInfo[what].size;
    ptr->code = LFInfo[what].code;
    ++ptr; /* start of ct_... */
    return( ptr );
}

static  void    NewTypeString( cv_out *out )
/******************************************/
{
    out->seg = CVTypes;
    out->ptr = &out->buff[sizeof( u2 )];  /*skip length*/
    out->beg = out->buff;
}

static  void    NewType( cv_out *out )
/************************************/
{
    out->ptr = out->buff;   /* no length field */
    out->beg = out->buff;
}

static  int  EndSub( cv_out *out )
/*** write out a member of a subfield (don't write a length) ***/
/* return length so it can be backpatched to list head       ***/
/* reset buff to start **/
{
    int             len;
    seg_id          old;
    long_offset     here;

    AlignBuff( out );
    len = out->ptr - out->buff;
    if( _IsModel( DBG_TYPES ) ) {
        old = SetOP( CVTypes );
        here = AskBigLocation();
        DataBytes( len, out->buff );
        SetOP( old );
    }
    out->ptr = out->buff;
    return( len );
}

static  long_offset   EndTypeString( cv_out *out )
/************************************************/
{
    seg_id          old;
    int             len;
    long_offset     here;

    if( _IsModel( DBG_TYPES ) ) {
        AlignBuff( out );
        len = out->ptr - out->buff;
        *((u2 *)&out->buff[0]) = len-sizeof( u2 );  /* set type rec len*/
        old = SetOP( CVTypes );
        here = AskBigLocation();
        DataBytes( len, out->buff );
        SetOP( old );
    }
    return( here );
}

extern  void    CVEndType( cv_out *out )
/**************************************/
{
    int     len;

    AlignBuff( out );
    len = out->ptr - out->buff;
    *((u2 *)&out->buff[0]) = len-sizeof( u2 );  /* set type rec len*/
}

static  void    PatchLen( long_offset where, u2 what )
/********** back patch field list length ************/
{
    long_offset         here;
    seg_id              old;

    old = SetOP( CVTypes );
    here = AskBigLocation();
    SetBigLocation( where );
    DataInt( what );
    SetBigLocation( here );
    SetOP( old );
}

static  void PutFld2( cv_out *out, short num )
/********************************************/
{
    *((short*)out->ptr) = num;  /* set an imbedded num */
    out->ptr += sizeof( short );
}

static void PutFldSized( cv_out *out, int size, unsigned_32 val )
/***************************************************************/
{
    switch( size ) {
    case 1:
        *((u1*)out->ptr) = val;  /* out 1 */
        out->ptr += sizeof( u1 );
        break;
    case 2:
        *((u2*)out->ptr) = val;  /* out 2 */
        out->ptr += sizeof( u2 );
        break;
    case 4:
        *((u4*)out->ptr) = val;   /* out 4 */
        out->ptr += sizeof( u4 );
        break;
    }
}

static void PutLFInt( cv_out *out, enum cv_psize size, unsigned_32 val )
/**********************************************************************/
{
    switch( size ) {
    case CV_IB1:
        *((u1*)out->ptr) = val;  /* out 1 */
        out->ptr += sizeof( u1 );
        break;
    case CV_IB2:
        *((u2*)out->ptr) = val;  /* out 2 */
        out->ptr += sizeof( u2 );
        break;
    case CV_IB4:
        *((u4*)out->ptr) = val;   /* out 4 */
        out->ptr += sizeof( u4 );
        break;
    }
}

static lf_values   LFIntType( int size )
/**************************************/
{
    lf_values itipe ;

    switch( size ) {
    case 4:
        itipe = LF_TINT4;
        break;
    case 2:
        itipe = LF_TSHORT;
        break;
    case 1:
        itipe = LF_TCHAR;
        break;
    default:
        Zoiks( ZOIKS_106 ); /* bad pointer */
    }
    return( itipe );
}

extern void CVPutINum( cv_out *out, signed_32 num )
/*************************************************/
{
    char       *ptr;
#define LC( what, to )   *((to *)&what)
    if( num >= 0 && num < 0x00008000 ){
        *((u2*)out->ptr) = num;  /* out num as is */
        out->ptr += sizeof( u2 );
        return;
    }
    ptr = out->ptr;
    if( num >= -128 && num <= 127 ) {
        LC( ptr[0],u2 ) = LF_CHAR;
        LC( ptr[2],u1 ) = num;
        ptr += sizeof(u2) + sizeof( u1 );
    }else if( num >= -32768 && num <= 32767 ) {
        LC( ptr[0],u2 ) = LF_SHORT;
        LC( ptr[2],u2 ) = num;
        ptr += sizeof(u2) + sizeof( u2 );
    }else if( num > 0 && num <= 0x0000ffff ){
        LC( ptr[0],u2 ) = LF_USHORT;
        LC( ptr[2],u2 ) = num;
        ptr += sizeof(u2) + sizeof( u2 );
    }else{
        LC( ptr[0],u2 ) = LF_LONG;
        LC( ptr[2],u4 ) = num;
        ptr += sizeof(u2) + sizeof( u4 );
    }
    out->ptr = ptr;
#undef LC
}

extern  void        CVPutINum64( cv_out *out, signed_64 val )
/***********************************************************/
{
    char       *ptr;
#define LC( what, to )   *((to *)&what)
    if( val.u._32[I64HI32] == 0 || val.u._32[I64HI32] == -1 ) {
        CVPutINum( out, val.u._32[I64LO32] );
    } else {
        ptr = out->ptr;
        LC( ptr[0],u2 ) = LF_QUADWORD;
        LC( ptr[2],u4 ) = val.u._32[I64LO32];
        LC( ptr[6],u4 ) = val.u._32[I64HI32];
        ptr += sizeof(u2) + sizeof( u8 );
        out->ptr = ptr;
    }
#undef LC
}
extern  void        CVPutStr( cv_out *out, char *str )
/****************************************************/
{
    int     len;

    len = strlen( str );
    len &= 0xff;
    *((char*)out->ptr) = len;
    out->ptr += sizeof( char );
    memcpy( out->ptr, str, len );
    out->ptr += len;
}

extern  void        CVPutNullStr( cv_out *out )
/*********************************************/
{
    *((char*)out->ptr) = 0;
    out->ptr += sizeof( char );
}


static  lf_values   LFSignedSize( signed_32 num )
/***********************************************/
{
    cv_primitive    index;

    index.s = 0;
    index.f.mode = CV_DIRECT;
    index.f.type = CV_SIGNED;
    if( num >= -128 && num <= 127 ) {
        index.f.size = CV_IB1;
    } else if( num >= -32768 && num <= 32767 ) {
         index.f.size = CV_IB2;
    } else {
         index.f.size =  CV_IB4;
    }
    return( index.s );
}

static  lf_values    LFSignedRange( signed_32 lo, signed_32 hi )
/**************************************************************/
{
    cv_primitive    index;

    index.s = 0;
    index.f.mode = CV_DIRECT;
    index.f.type = CV_SIGNED;
    if( lo >= -128 && hi <= 127 ) {
        index.f.size = CV_IB1;
    } else if( lo >= -32768 && hi <= 32767 ) {
         index.f.size = CV_IB2;
    } else {
         index.f.size =  CV_IB4;
    }
    return( index.s );
}

extern  dbg_type    CVFtnType( char *name, dbg_ftn_type tipe )
/************************************************************/
{
    unsigned        size;
    cv_primitive    index;

    name = name;
    index.s = 0;
    index.f.mode = CV_DIRECT;
    index.f.type = CV_COMPLEX;
    size = (tipe & 0x0f)+1;
    if( size == 4 ){
        index.f.size = CV_RC32;
    }else if( size == 8 ){
        index.f.size = CV_RC32;
    }
    return( index.s );
}

#define MAX_REAL_NAME  7
static char const RealNames[MAX_REAL_NAME][17] = {
    "int",
    "unsigned int",
    "signed int",
    "char",
    "__int64",
    "unsigned __int64",
    "signed __int64",
};

extern  dbg_type    CVScalar( char *name, cg_type tipe )
/******************************************************/
{
    type_def          *tipe_addr;
    int                length;
    cv_primitive       index;
    int                count;

    index.s = 0;  /* set bits to 0 */
    if( strcmp( name, "__segment" ) == 0 ){
        index.s = LF_TSEGMENT;
    }else if( strcmp( name, "void" ) == 0 ){
        index.s = LF_TVOID;
    }else{
        tipe_addr = TypeAddress( tipe );
        length = tipe_addr->length;
        index.f.mode =  CV_DIRECT;
        if( tipe_addr->attr & TYPE_FLOAT ) {
            index.f.type = CV_REAL;
            if( length == 4 ) {
                index.f.size  =  CV_RC32;
            } else if( length == 8 ) {
                index.f.size = CV_RC64;
            }
        } else {
            for( count =  0; count < MAX_REAL_NAME; ++count ) {
                if( strcmp( name, RealNames[count] ) == 0 ) {
                    index.f.type =  CV_REALLYINT;
                    if( length == 1 ) {

⌨️ 快捷键说明

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