rewrite.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,211 行 · 第 1/3 页
C
1,211 行
/****************************************************************************
*
* 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 <stddef.h>
#include "errdefns.h"
#include "memmgr.h"
#include "preproc.h"
#include "carve.h"
#include "ptree.h"
#include "yydriver.h"
#include "rewrite.h"
#include "initdefs.h"
#include "pcheader.h"
#include "dbg.h"
#include "context.h"
/*
The "rewrite file" consists of a string of tokens, each of which is
preceded by one or more modifiers. The modifiers are decoded as follows:
byte: b'00000000' -- next bytes are SRCFILE for source file
b'10000000' -- next 4 bytes are fetched as signed value
-- if value > 0
value is column #, fetch token
else
(-value) is line #
b'1xxxxxxx' -- add 'xxxxxx' to line no., column <-- 0
b'0xxxxxxx' -- add 'xxxxxx' to column, fetch token
The sequence for a token is sumarized as:
(a) optional file modifier
(b) optional line modifier
(c) column modifier
(d) token
Most tokens can be represented with their token number. Some need
more information to be saved like:
T_STRING, T_LSTRING, T_ID, T_BAD_CHAR
followed by bytes in token buffer ('\0' terminator)
T_CONSTANT (integral)
followed by <ConstType> <4-byte value> (least significant first)
T_CONSTANT (floating point)
followed by <ConstType> string of flt-pt number ('\0' terminator)
T_BAD_TOKEN
followed by contents of BadTokenInfo
*/
#define CODE_FILE 0x00 // code for SRCFILE
#define CODE_ABS 0x80 // code for line#, col#
#define MASK_ABS_LINE 0x80000000 // mask for absolute line
#define MASK_DELTA_LINE 0x80 // mask for delta line
static REWRITE *currRewrite;
static TOKEN_LOCN *currLocn;
#define BLOCK_REWRITE 8
#define BLOCK_REWRITE_TOKENS 8
#define BLOCK_SRCFILE_HANDLE 8
static carve_t carveREWRITE;
static carve_t carveREWRITE_TOKENS;
static carve_t carveSRCFILE_HANDLE;
static void rewriteInit( INITFINI* defn )
{
defn = defn;
currRewrite = NULL;
carveREWRITE = CarveCreate( sizeof( REWRITE ), BLOCK_REWRITE );
carveREWRITE_TOKENS = CarveCreate( sizeof( REWRITE_TOKENS ),
BLOCK_REWRITE_TOKENS );
carveSRCFILE_HANDLE = CarveCreate( sizeof( SRCFILE_HANDLE ),
BLOCK_SRCFILE_HANDLE );
}
static void rewriteFini( INITFINI* defn )
{
defn = defn;
RewriteFree( currRewrite );
currRewrite = NULL;
#ifndef NDEBUG
CarveVerifyAllGone( carveREWRITE, "REWRITE" );
CarveVerifyAllGone( carveREWRITE_TOKENS, "REWRITE_TOKENS" );
CarveVerifyAllGone( carveSRCFILE_HANDLE, "SRCFILE_HANDLE" );
#endif
CarveDestroy( carveREWRITE );
CarveDestroy( carveREWRITE_TOKENS );
CarveDestroy( carveSRCFILE_HANDLE );
}
INITDEFN( rewriting, rewriteInit, rewriteFini )
void RewriteFree( REWRITE *r )
/****************************/
{
REWRITE_TOKENS *free_rt;
REWRITE_TOKENS *rt;
SRCFILE_HANDLE *h;
SRCFILE_HANDLE *next_h;
if( r == NULL ) {
return;
}
if( ! r->alternate ) {
for( rt = r->list; rt != NULL; ) {
free_rt = rt;
rt = rt->next;
CarveFree( carveREWRITE_TOKENS, free_rt );
}
for( h = r->srcfiles_refd; h != NULL; h = next_h ) {
next_h = h->next;
CarveFree( carveSRCFILE_HANDLE, h );
}
}
CarveFree( carveREWRITE, r );
}
static REWRITE_TOKENS *tokenAlloc( void )
{
REWRITE_TOKENS *rt;
rt = CarveAlloc( carveREWRITE_TOKENS );
rt->next = NULL;
rt->count = 0;
rt->free = FALSE;
return( rt );
}
static void putByte( REWRITE *r, uint_8 v )
{
REWRITE_TOKENS *rt;
rt = r->curr;
if( rt->count == TOKEN_BLOCK_SIZE ) {
REWRITE_TOKENS *new_rt;
new_rt = tokenAlloc();
rt->next = new_rt;
r->curr = new_rt;
rt = new_rt;
}
rt->stream[ rt->count++ ] = v;
}
static void putString( REWRITE *r, char *p )
{
for( ; *p != '\0'; ++p ) {
putByte( r, *p );
}
putByte( r, '\0' );
}
static void putBinary( REWRITE *r, uint_8 *bin, unsigned size )
{
for( ; size > 0; --size, ++bin ) {
putByte( r, *bin );
}
}
static uint_32 newSrcFileHandle( REWRITE *r, SRCFILE src_file )
{
uint_32 index;
SRCFILE_HANDLE *p;
SRCFILE_HANDLE **head;
SRCFILE_HANDLE *e;
index = 0;
head = &(r->srcfiles_refd);
for( p = *head; p != NULL; p = *head ) {
if( p->srcfile == src_file ) {
return( index );
}
++index;
head = &(p->next);
}
e = CarveAlloc( carveSRCFILE_HANDLE );
e->next = NULL;
e->srcfile = src_file;
*head = e;
return( index );
}
static SRCFILE accessSrcFile( REWRITE *r, uint_32 srcfile_index )
{
SRCFILE_HANDLE *p;
for( p = r->srcfiles_refd; p != NULL; p = p->next ) {
if( srcfile_index == 0 ) {
return( p->srcfile );
}
--srcfile_index;
}
return( NULL );
}
static void putSrcFile( REWRITE *r, TOKEN_LOCN *locn )
{
uint_32 srcfile_index;
srcfile_index = newSrcFileHandle( r, locn->src_file );
putByte( r, CODE_FILE );
putBinary( r, (uint_8*)&srcfile_index, sizeof( srcfile_index ) );
locn->line = 0;
locn->column = 0;
}
static void putSrcLocn( REWRITE *r, TOKEN_LOCN *locn )
{
SRCFILE currfile;
uint_32 absolute;
uint_8 code_byte;
currfile = SrcFileCurrent();
if( currfile != locn->src_file ) {
locn->src_file = currfile;
putSrcFile( r, locn );
}
if( ( TokenLine - locn->line ) > 127 ) {
putByte( r, CODE_ABS );
absolute = TokenLine | MASK_ABS_LINE;
putBinary( r, (uint_8*)&absolute, sizeof( absolute ) );
locn->line = TokenLine;
} else if( ( TokenLine - locn->line ) > 0 ) {
code_byte = ( TokenLine - locn->line ) | MASK_DELTA_LINE;
putByte( r, code_byte );
locn->line = TokenLine;
}
if( ( TokenColumn - locn->column ) > 127 ) {
putByte( r, CODE_ABS );
absolute = TokenColumn;
putBinary( r, (uint_8*)&absolute, sizeof( absolute ) );
locn->column = TokenColumn;
} else if( ( TokenColumn - locn->column ) > 0 ) {
code_byte = TokenColumn - locn->column;
putByte( r, code_byte );
locn->column = TokenColumn;
} else { // this guards against token at same col.
putByte( r, CODE_ABS );
absolute = TokenColumn;
putBinary( r, (uint_8*)&absolute, sizeof( absolute ) );
locn->column = TokenColumn;
}
}
static void saveToken( REWRITE *r, TOKEN_LOCN *locn )
{
putSrcLocn( r, locn );
switch( CurToken ) {
case T_STRING:
case T_LSTRING:
case T_ID:
case T_BAD_CHAR:
putByte( r, CurToken );
putString( r, Buffer );
break;
case T_BAD_TOKEN:
putByte( r, CurToken );
putBinary( r, (uint_8*)&BadTokenInfo, sizeof( BadTokenInfo ) );
break;
case T_SAVED_ID:
putByte( r, T_ID );
putString( r, SavedId );
break;
case T_CONSTANT:
putByte( r, CurToken );
putByte( r, ConstType );
switch( ConstType ) {
case TYP_LONG_DOUBLE:
case TYP_DOUBLE:
case TYP_FLOAT:
putString( r, Buffer );
break;
default:
putBinary( r, (uint_8*)&Constant64, sizeof( Constant64 ) );
}
break;
default:
putByte( r, CurToken );
}
}
static REWRITE *newREWRITE( int end_token, TOKEN_LOCN *locn )
{
REWRITE *r;
REWRITE_TOKENS *rt;
r = CarveAlloc( carveREWRITE );
rt = tokenAlloc();
r->list = rt;
r->curr = rt;
r->srcfiles_refd = NULL;
r->token = rt->stream;
r->last_token = end_token;
r->busy = FALSE;
r->free = FALSE;
r->alternate = FALSE;
locn->src_file = SrcFileCurrent();
putSrcFile( r, locn );
return( r );
}
static REWRITE *dupREWRITE( REWRITE *old_r )
{
REWRITE *r;
r = CarveAlloc( carveREWRITE );
r->list = old_r->list;
r->curr = old_r->curr;
r->srcfiles_refd = old_r->srcfiles_refd;
r->token = old_r->token;
r->last_token = old_r->last_token;
r->busy = FALSE;
r->alternate = TRUE;
r->free = FALSE;
return( r );
}
static PTREE recoverToken( PTREE tree )
{
switch( tree->op ) {
case PT_INT_CONSTANT:
case PT_FLOATING_CONSTANT:
/* these cases are not possible in correct C++ programs */
/* Buffer and ConstType should still be set */
CurToken = T_CONSTANT;
break;
case PT_ID:
CurToken = T_SAVED_ID;
SavedId = tree->u.id.name;
break;
case PT_UNARY:
case PT_BINARY:
switch( tree->cgop ) {
case CO_INDIRECT:
CurToken = T_TIMES;
break;
case CO_COLON_COLON:
CurToken = T_COLON_COLON;
break;
case CO_OPERATOR:
CurToken = T_OPERATOR;
break;
case CO_TILDE:
CurToken = T_TILDE;
break;
case CO_NEW:
CurToken = T_NEW;
break;
case CO_DELETE:
CurToken = T_DELETE;
break;
case CO_STORAGE:
return( tree );
default:
#ifndef NDEBUG
CFatal( "recoverToken: unknown tree cgop" );
#endif
return( tree );
}
break;
default:
#ifndef NDEBUG
CFatal( "recoverToken: unknown tree cgop" );
#endif
return( tree );
}
saveToken( currRewrite, currLocn );
return( tree );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?