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 + -
显示快捷键?