wat2can1.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,387 行 · 第 1/3 页
C
1,387 行
/****************************************************************************
*
* 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 <malloc.h>
#include <string.h>
#include <watcom.h>
#include "womp.h"
#include "genutil.h"
#include "watdbg.h"
#include "segment.h"
#include "myassert.h"
#include "cantype.h"
#include "canaddr.h"
#include "memutil.h"
#include "namemgr.h"
#include "cansymb.h"
#include "canmisc.h"
#include "array.h"
#ifndef NDEBUG
#include <io.h>
#include <fcntl.h>
#endif
/*
The type map is implemented with variable sized arrays. (array.h)
*/
typedef struct {
type_handle hdl;
} type_map_elm;
/*
The offset map is a list of DDSymbols->data offsets of CODE_BLOCKs and
their symb_handle.
*/
typedef struct offset_map {
struct offset_map *next;
uint_16 offset;
symb_handle hdl;
} offset_map;
/*
These structures maintain the current position within ddTypes->data
or DDSymbols->data according to the boolean parsingTypes.
*/
struct pos {
struct pos *next; /* stack of positions */
uint_8 *ptr; /* pointer to current position */
uint_8 *start_rec; /* start of the current record */
uint_8 *finish; /* done when wat->ptr == wat->finish */
uint_16 index; /* index of the current record */
uint_8 rec_len; /* length of the current record*/
};
#define endOfRecord() ( wat->ptr - wat->start_rec == wat->rec_len )
/*
Some pointers we'll allocate memory for
*/
STATIC type_handle unDefdType;
STATIC type_handle *stbHdl; /* table of 128 type_handles */
STATIC struct pos *wat;
STATIC int parsingTypes; /* boolean */
STATIC offset_map *offsetMap;
STATIC symb_handle headSymb;
STATIC seghdr *ddTypes;
STATIC seghdr *ddSymbols;
STATIC array_hdr *typeMap;
STATIC type_map_elm typeMapDef;
/*
When we've processed a record, we splat the record type. The different
types indicate whether to count the record towards indexes or not.
(indicies are not used during the symbol parsing)
*/
enum {
SPLAT = 0xf0,
SPLAT_COUNT = 0xf0,
SPLAT_DONT_COUNT = 0xf1
};
#define splatRec( ch ) ( wat->ptr[-1] = (ch) )
/*
Routines to move through types buffer
*/
STATIC uint_8 get8( void ) {
return( *(wat->ptr++) );
}
STATIC uint_16 get16( void ) {
uint_16 word;
word = ReadU16( wat->ptr );
wat->ptr += 2;
return( word );
}
STATIC uint_32 get32( void ) {
uint_32 dword;
dword = ReadU32( wat->ptr );
wat->ptr += 4;
return( dword );
}
STATIC uint_16 getIndex( void ) {
uint_16 index;
index = get8();
if( index & 0x80 ) {
index = ( ( index & 0x7f ) << 8 ) | get8();
}
return( index );
}
STATIC addr_handle getAddr32( void ) {
addr_handle addr;
if( parsingTypes ) {
addr = CanACreateHdl( ddTypes, wat->ptr - ddTypes->data, 4 );
} else {
addr = CanACreateHdl( ddSymbols, wat->ptr - ddSymbols->data, 4 );
}
wat->ptr += 4;
return( addr );
}
STATIC addr_handle getAddr48( void ) {
addr_handle addr;
if( parsingTypes ) {
addr = CanACreateHdl( ddTypes, wat->ptr - ddTypes->data, 6 );
} else {
addr = CanACreateHdl( ddSymbols, wat->ptr - ddSymbols->data, 6 );
}
wat->ptr += 6;
return( addr );
}
STATIC name_handle hdlName( void ) {
unsigned len;
uint_8 *p;
len = wat->rec_len - ( wat->ptr - wat->start_rec );
if( len > 0 ) {
p = wat->ptr;
wat->ptr += len;
return( NameAdd( p, len ) );
} else {
return( NAME_NULL );
}
}
STATIC uint_8 hdlScope( void ) {
unsigned len;
uint_8 *p;
len = wat->rec_len - ( wat->ptr - wat->start_rec );
if( len > 0 ) {
p = wat->ptr;
wat->ptr += len;
if( memcmp( p, "struct", len ) == 0 ) {
return( CANT_SCOPE_STRUCT );
} else if( memcmp( p, "union", len ) == 0 ) {
return( CANT_SCOPE_UNION );
} else if( memcmp( p, "enum", len ) == 0 ) {
return( CANT_SCOPE_ENUM );
} else if( memcmp( p, "class", len ) == 0 ) {
Fatal( MSG_CPP_EXTENSION );
} else {
p[len] = 0;
Fatal( MSG_UNS_SCOPE, p );
}
}
return( CANT_SCOPE_NULL );
}
/*
Routines to manage the stack of buffer positions
*/
STATIC void pushPosn( void ) {
struct pos *new;
new = MemAlloc( sizeof( *new ) );
*new = *wat;
new->next = wat;
wat = new;
}
STATIC void popPosn( void ) {
struct pos *next;
next = wat->next;
/**/myassert( next != NULL );
MemFree( wat );
wat = next;
}
/*
Routines to move about in the buffer
*/
STATIC int countOrNot( uint_8 type_class ) {
/**/myassert( parsingTypes );
switch( type_class & 0xf0 ) {
case WAT_STRUCTURE:
case WAT_ENUMERATED:
case SPLAT:
if( type_class & 0x0f ) {
return( 0 );
}
break;
}
return( 1 );
}
STATIC void seekIndex( uint_16 index ) {
uint_16 walk_index;
uint_8 *walk_ptr;
/**/myassert( parsingTypes );
if( wat->index > index ) {
walk_ptr = ddTypes->data;
walk_index = 1;
} else {
walk_ptr = wat->start_rec;
walk_index = wat->index;
}
while( walk_index < index ) {
if( walk_ptr[0] > 1 ) {
walk_index += countOrNot( walk_ptr[1] );
}
walk_ptr += walk_ptr[0];
}
while( countOrNot( walk_ptr[1] ) == 0 ) {
walk_ptr += walk_ptr[0];
}
wat->index = index;
wat->ptr = walk_ptr;
}
STATIC uint_8 nextRec( void ) {
for(;;) {
wat->start_rec = wat->ptr;
wat->rec_len = get8();
if( wat->rec_len > 1 ) {
return( get8() );
}
/**/ never_reach();
}
}
/*
Routines to handle the mapping of a watcom index to a type_handle.
mapIdx() takes care of forward references.
*/
STATIC void mapAdd( type_handle hdl ) {
/*
add to map the mapping wat->index --> hdl
*/
type_map_elm *elm;
elm = ArrNewElm( typeMap, (size_t)wat->index );
elm->hdl = hdl;
}
STATIC void initTypeMap( void ) {
type_map_elm *elm;
typeMapDef.hdl = unDefdType;
typeMap = ArrCreate( sizeof( type_map_elm ), &typeMapDef );
elm = ArrNewElm( typeMap, (size_t)0 );
elm->hdl = CANT_NULL;
}
STATIC type_handle mapIdx( uint_16 index ) {
type_map_elm *elm;
type_handle hdl;
elm = ArrNewElm( typeMap, (size_t)index );
hdl = elm->hdl;
if( hdl == unDefdType ) { /* aha! forward reference! */
/**/ myassert( parsingTypes );
pushPosn(); /* recursively take care of it */
seekIndex( index );
parseType();
popPosn();
elm = ArrAccess( typeMap, (size_t)index );
hdl = elm->hdl;
/**/ myassert( hdl != unDefdType );
}
return( hdl );
}
STATIC void finiTypeMap( void ) {
ArrDestroy( typeMap );
}
/*
Routines for parsing Watcom Type information
*/
STATIC type_handle stbToCanT( uint_8 stb ) {
/*
convert a scalar_type_byte to a scalar cant
*/
bitsize size;
uint_8 class;
type_handle hdl;
#define SS(x) ((x)>>WAT_STB_CLASS_SHIFT)
if( stbHdl[ stb ] != unDefdType ) {
return( stbHdl[ stb ] );
}
class = SS( stb & WAT_STB_CLASS_FIELD );
/**/myassert( class <= 4 );
size = ( ( stb & WAT_STB_SIZE_FIELD ) + 1 ) * 8;
switch( class ) {
case SS(WAT_STB_CLASS_SINT): hdl = CanTInteger( size,1 );break;
case SS(WAT_STB_CLASS_UINT): hdl = CanTInteger( size,0 );break;
case SS(WAT_STB_CLASS_FLOAT): hdl = CanTReal( size ); break;
case SS(WAT_STB_CLASS_VOID): hdl = CanTVoid(); break;
case SS(WAT_STB_CLASS_COMPLEX): hdl = CanTComplex( size ); break;
}
stbHdl[ stb ] = hdl;
return( hdl );
#undef SS
}
STATIC void typeTypeName( uint_8 type_class ) {
type_handle new_hdl;
uint_8 scope;
type_handle type_hdl;
name_handle name_hdl;
type_class &= 0x0f; /* we're interested in low nibble */
switch( type_class ) {
case WAT_TN_SCALAR:
type_hdl = stbToCanT( get8() );
name_hdl = hdlName();
if( name_hdl == NAME_NULL ) { /* no name for type */
mapAdd( type_hdl );
} else {
mapAdd( CanTTypeDef( CANT_NULL, type_hdl, name_hdl ) );
}
break;
case WAT_TN_SCOPE:
/* FIXME this is a kludge!! */
mapAdd( 0xff00 | hdlScope() );
break;
case WAT_TN_NAME:
new_hdl = CanTReserve();
mapAdd( new_hdl );
scope = (uint_8)mapIdx( getIndex() );
type_hdl = mapIdx( getIndex() );
name_hdl = hdlName();
CanTReUse( new_hdl );
CanTTypeDef( type_hdl, name_hdl, scope );
break;
default:
/**/ never_reach();
}
/**/myassert( endOfRecord() );
}
STATIC void typeArray( uint_8 type_class ) {
type_handle new_hdl;
type_handle index_type;
type_handle base_type;
type_handle lo_type;
type_handle hi_type;
addr_handle bounds;
uint_32 high;
new_hdl = CanTReserve();
mapAdd( new_hdl );
type_class &= 0x0f; /* we're interested in low nibble */
switch( type_class ) {
case WAT_AY_BYTE_INDEX:
high = (uint_32)get8();
base_type = mapIdx( getIndex() );
CanTReUse( new_hdl );
CanTArrayZ( base_type, high );
break;
case WAT_AY_WORD_INDEX:
high = (uint_32)get16();
base_type = mapIdx( getIndex() );
CanTReUse( new_hdl );
CanTArrayZ( base_type, high ); /* 01-may-91 AFS */
break;
case WAT_AY_LONG_INDEX:
high = get32();
base_type = mapIdx( getIndex() );
CanTReUse( new_hdl );
CanTArrayZ( base_type, high ); /* 01-may-91 AFS */
break;
case WAT_AY_TYPE_INDEX:
index_type = mapIdx( getIndex() );
base_type = mapIdx( getIndex() );
CanTReUse( new_hdl );
CanTArray( base_type, index_type );
break;
case WAT_AY_DESC_INDEX:
lo_type = stbToCanT( get8() );
hi_type = stbToCanT( get8() );
bounds = getAddr32();
base_type = mapIdx( getIndex() );
CanTReUse( new_hdl );
CanTArrayD( base_type, lo_type, hi_type, bounds );
break;
case WAT_AY_DESC_INDEX_386:
lo_type = stbToCanT( get8() );
hi_type = stbToCanT( get8() );
bounds = getAddr48();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?