can2td1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 772 行 · 第 1/2 页
C
772 行
/****************************************************************************
*
* 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 <string.h>
#include "womp.h"
#include "turbodbg.h"
#include "genutil.h"
#include "memutil.h"
#include "myassert.h"
#include "objrec.h"
#include "queue.h"
#include "carve.h"
#include "objprs.h"
#include "canmisc.h"
#define BITS_TO_BYTES( b ) ( ( (b) + 7 ) / 8 )
STATIC name_handle realHdl;
STATIC name_handle imagHdl;
/*
Functions for handling the writing of typing information
*/
typedef uint_16 idx_t;
typedef struct type_rec type_rec;
struct type_rec {
type_rec *next;
type_rec *member; /* for type_recs with members */
idx_t idx; /* index of this type */
uint_16 alloc; /* allocated length */
uint_16 len; /* written to length */
uint_8 *data; /* pointer to data */
};
#define TYPE_REC_INC 128
STATIC carve_t typeRecCarver; /* we carve type_recs from here */
STATIC idx_t nextIdx; /* next available index */
STATIC uint_8 *getTrData( type_rec *tr, uint_16 len ) {
uint_16 new_len;
uint_8 *p;
new_len = tr->len + len;
if( new_len > tr->alloc ) {
tr->alloc = new_len + TYPE_REC_INC;
tr->data = MemRealloc( tr->data, new_len + TYPE_REC_INC );
}
p = tr->data + tr->len;
tr->len = new_len;
return( p );
}
STATIC void put8( type_rec *tr, uint_8 byte ) {
uint_8 *p;
p = getTrData( tr, 1 );
p[0] = byte;
}
STATIC void put16( type_rec *tr, uint_16 word ) {
uint_8 *p;
p = getTrData( tr, 2 );
WriteU16( p, word );
}
STATIC void put32( type_rec *tr, uint_32 dword ) {
uint_8 *p;
p = getTrData( tr, 4 );
WriteU32( p, dword );
}
STATIC void putIndex( type_rec *tr, uint_16 word ) {
uint_8 *p;
if( word > 0x7f ) {
p = getTrData( tr, 2 );
p[0] = 0x80 | ( word >> 8 );
p[1] = word & 0xff;
} else {
p = getTrData( tr, 1 );
p[0] = word;
}
}
STATIC void putName( type_rec *tr, name_handle name_hdl ) {
const char *name;
uint_8 *p;
uint_16 len;
name = NameGet( name_hdl );
if( name == NULL ) {
len = 0;
} else {
len = strlen( name );
}
p = getTrData( tr, len + 1 );
p[0] = len;
memcpy( p + 1, name, len );
}
STATIC type_rec *newRec( void ) {
type_rec *new;
new = CarveAlloc( typeRecCarver );
new->alloc = 0;
new->len = 0;
new->data = NULL;
return( new );
}
STATIC type_rec *newType( name_handle name, bitsize size, uint_8 type_id ) {
type_rec *new;
idx_t idx;
type_rec *member;
if( nextIdx < 24 ) {
Fatal( MSG_TOO_MANY_TYPES );
}
new = newRec();
idx = nextIdx;
new->idx = idx;
putIndex( new, idx );
putName( new, name );
put16( new, (uint_16)BITS_TO_BYTES( size ) );
put8( new, type_id );
++nextIdx;
switch( type_id ) {
case TD_ID_SCHAR:
case TD_ID_SINT:
case TD_ID_SLONG:
case TD_ID_UCHAR:
case TD_ID_UINT:
case TD_ID_ULONG:
case TD_ID_PCHAR:
case TD_ID_PARRAY:
case TD_ID_VLSTRUCT:
case TD_ID_VLUNION:
case TD_ID_ENUM:
++nextIdx; /* skip an index */
break;
}
switch( type_id ) {
case TD_ID_STRUCT:
case TD_ID_UNION:
case TD_ID_VLSTRUCT:
case TD_ID_VLUNION:
member = newRec();
member->idx = TD_CMT_STRUCT_DEFN;
break;
case TD_ID_ENUM:
member = newRec();
member->idx = TD_CMT_ENUM_DEFN;
break;
default:
member = NULL;
break;
}
new->member = member;
return( new );
}
STATIC void createComent( type_rec *rec, uint_8 class ) {
obj_rec *coment;
uint_16 len;
coment = Can2TDNewRec( class, 0 );
len = rec->len;
/**/myassert( len > 0 );
ObjAttachData( coment, MemRealloc( rec->data, len ), len );
ObjCanFree( coment );
ObjRSeek( coment, 0 ); /* FIXME should be able to call Can2TDEndRec */
CarveFree( typeRecCarver, rec );
}
STATIC void endType( type_rec *tr ) {
type_rec *member;
member = tr->member;
if( member != NULL ) {
createComent( member, member->idx );
}
createComent( tr, TD_CMT_TYPE_DEFN );
}
/*
Here comes the type conversion code
*/
STATIC type_rec *newLarge( name_handle name, bitsize size,
uint_8 small, uint_8 large ) {
type_rec *tr;
if( size >= 0x10000UL * 8UL ) {
tr = newType( name, size, large );
put16( tr, (uint_32)BITS_TO_BYTES( size ) >> 16 );
} else {
tr = newType( name, size, small );
}
return( tr );
}
STATIC idx_t buildArray( bitsize size ) {
/*
For types which we can't convert we create a C array of uint_8's of
the appropriate size.
*/
type_rec *tr;
idx_t idx;
tr = newLarge( NAME_NULL, size, TD_ID_CARRAY, TD_ID_VLARRAY );
putIndex( tr, TD_TYPE_UNSIGNED_8 );
idx = tr->idx;
endType( tr );
return( idx );
}
STATIC void typ1Integer( cantype *type ) {
/*
Set the extra field to the appropriate Turbo reserved type, or to a type
which we create now
*/
int is_signed;
type_rec *tr;
/**/myassert( type != NULL && type->class == CANT_INTEGER );
is_signed = type->sgned;
if( type->size <= 32 ) {
if( type->size <= 8 ) {
type->extra = TD_TYPE_SIGNED_8;
} else if( type->size <= 16 ) {
type->extra = TD_TYPE_SIGNED_16;
} else {
type->extra = TD_TYPE_SIGNED_32;
}
if( ! is_signed ) {
type->extra += ( TD_TYPE_UNSIGNED_8 - TD_TYPE_SIGNED_8 );
}
} else if( type->size == 64 ) {
tr = newType( NAME_NULL, 1, is_signed ? TD_ID_SQUAD : TD_ID_UQUAD );
type->extra = tr->idx;
endType( tr );
} else {
PrtMsg( WRN|MSG_UNS_SCALAR_SIZE );
type->extra = buildArray( type->size );
}
}
STATIC void typ1Real( cantype *type ) {
/**/myassert( type != NULL && type->class == CANT_REAL );
switch( type->size ) {
case 32: type->extra = TD_TYPE_REAL_32; break;
case 64: type->extra = TD_TYPE_REAL_64; break;
case 80: type->extra = TD_TYPE_REAL_80; break;
case 48: type->extra = TD_TYPE_REAL_48; break;
default:
PrtMsg( WRN|MSG_UNS_SCALAR_SIZE );
type->extra = buildArray( type->size );
break;
}
}
STATIC void typ1Void( cantype *type ) {
/**/myassert( type != NULL && type->class == CANT_VOID );
type->extra = TD_TYPE_VOID;
}
STATIC void typ1Complex( cantype *type ) {
type_rec *tr;
type_rec *member;
idx_t member_type;
/**/myassert( type != NULL && type->class == CANT_COMPLEX );
/*
Since turbo doesn't have a complex type, we'll create a struct
with 2 floats named "real" and "imag".
*/
switch( type->size ) {
case 64: member_type = TD_TYPE_REAL_32; break;
case 128: member_type = TD_TYPE_REAL_64; break;
case 160: member_type = TD_TYPE_REAL_80; break;
case 96: member_type = TD_TYPE_REAL_48; break;
default:
PrtMsg( WRN|MSG_UNS_SCALAR_SIZE );
member_type = buildArray( type->size / 2 );
break;
}
tr = newLarge( NAME_NULL, type->size, TD_ID_STRUCT, TD_ID_VLSTRUCT );
type->extra = tr->idx;
member = tr->member;
put8( member, 0 );
putName( member, realHdl );
putIndex( member, member_type );
put8( member, TD_STRUCT_LAST_MEMBER );
putName( member, imagHdl );
putIndex( member, member_type );
endType( tr );
}
STATIC int typePass1( void *_type, void *parm ) {
cantype *type = _type;
/**/myassert( type != NULL && parm == NULL );
parm = parm;
switch( type->class ) {
case CANT_INTEGER: typ1Integer( type ); break;
case CANT_REAL: typ1Real( type ); break;
case CANT_VOID: typ1Void( type ); break;
case CANT_COMPLEX: typ1Complex( type ); break;
default:
type->extra = 0;
}
return( 0 );
}
/*
Pass 2
*/
STATIC idx_t resolveType( type_handle hdl ) {
cantype *type;
type = CanTFind( hdl );
/**/myassert( type != NULL );
if( type->extra == 0 ) {
int force;
while( type->class == CANT_TYPEDEF &&
type->d.typdef.scope == CANT_SCOPE_NULL ) {
type = CanTFind( type->d.typdef.type );
}
force = 1;
typePass2( type, &force );
}
/**/myassert( type->extra != 0 );
return( type->extra );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?