ppact.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 2,617 行 · 第 1/5 页
CPP
2,617 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
////////////////////////////////////////////////////////////////////////////
// PPACT -- pretty-print code-generation actions file
//
// 94/08/09 -- J.W.Welch -- initial version
// 94/08/19 -- J.W.Welch -- support CGBackName, CALLBACK
// 94/10/02 -- J.W.Welch -- generalize scanning
// 94/10/04 -- J.W.Welch -- support new CGInitCall format
// 95/02/08 -- J.W.Welch -- support CGSelect
// 95/03/13 -- J.W.Welch -- ALPHA: support CgVarargsBasePtr
// 95/03/23 -- J.W.Welch -- ALPHA: support CGStackAlloc
// 95/03/28 -- J.W.Welch -- ALPHA: remove CGStackAlloc
//
// 95/10/03 -- J.W.Welch -- use TRPRTDLL.DLL
// 96/03/29 -- J.W.Welch -- handle operator (), etc. as a name
//
////////////////////////////////////////////////////////////////////////////
// #pragma inline_depth 0
#pragma warning 549 9
#include <ctype.h>
#include <malloc.h>
#include <process.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "setimpl.h"
#include "set.h"
#ifdef TRPRTDLL
#include <treesupp.h>
#pragma library ( "..\test\trpr\trprtdll.lib" );
#else
#pragma library ( "ppact.lib" );
#endif
typedef unsigned CgId; // id for a node
const char BOX_LINE_VERT = 179;
const char BOX_LINE_HORI = 196;
const char BOX_CORNER_UP = 218;
const char BOX_CORNER_DN = 192;
const char BOX_OPCODE_UP = 217;
const char BOX_OPCODE_DN = 191;
const char BOX_OPCODE_UD = 180;
const char BOX_TEE_UP = 193;
const char BOX_TEE_DOWN = 194;
const char BOX_TEE_RIGHT = 195;
#ifdef TRPRTDLL
const char OPCODE_ARG[] = "ARG";
const char OPCODE_TRASH[] = "TRASH";
const char OPCODE_DONE[] = "DONE";
#else
const char OPCODE_ARG[] = "Arg";
const char OPCODE_TRASH[] = { 237, 27, 0 };
const char OPCODE_DONE[] = { 17, 0 };
#endif
////////////////////////////////////////////////////////////////////////////
//
// Support
//
////////////////////////////////////////////////////////////////////////////
char* stpcpy // STRING COPY
( char* tgt // - target
, char const* src ) // - source
{
for( ; ; ) {
*tgt = *src;
if( '\0' == *src ) break;
++ src;
++ tgt;
}
return tgt;
}
////////////////////////////////////////////////////////////////////////////
//
// Options
//
////////////////////////////////////////////////////////////////////////////
struct Options
{
unsigned verbose :1; // verbose printing
unsigned actions :1; // echo actions file
#ifndef NDEBUG
unsigned pstack :1; // dump pstack
#endif
Options() // CONSTRUCTOR
: verbose( 0 )
, actions( 0 )
#ifndef NDEBUG
, pstack(0)
#endif
{
}
};
static Options options; // program options
////////////////////////////////////////////////////////////////////////////
//
// MemAlloc -- template for allocations
//
////////////////////////////////////////////////////////////////////////////
template< class CLS >
struct MemAlloc {
static Set<CLS> _free;
void* operator new( size_t );
void operator delete( void* );
};
template< class CLS >
void* MemAlloc<CLS>::operator new( size_t ) // OPERATOR NEW
{
CLS* retn;
if( _free.empty() ) {
retn = (CLS*)malloc( sizeof( CLS ) );
} else {
retn = _free.first();
_free.erase( retn );
}
return (void*)retn;
}
template< class CLS >
void MemAlloc<CLS>::operator delete( void* item ) // OPERATOR DELETE
{
if( 0 != item ) {
_free.insert( (CLS*)item );
}
}
template< class CLS >
static Set<CLS> MemAlloc<CLS>::_free;
////////////////////////////////////////////////////////////////////////////
//
// Varray -- variable-sized array template
//
////////////////////////////////////////////////////////////////////////////
template< class CLS >
struct Varray {
CLS* _array; // array
unsigned _bound; // bound
Varray(); // CONSTRUCTOR
~Varray(); // DESTRUCTOR
CLS& operator [] ( unsigned ); // SUBSCRIPT OPERATOR
CLS const & operator [] ( unsigned ) const; // SUBSCRIPT OPERATOR
};
template< class CLS >
Varray<CLS>::Varray // CONSTRUCTOR
( void )
: _array( 0 )
, _bound( 0 )
{
}
template< class CLS >
Varray<CLS>::~Varray // DESTRUCTOR
( void )
{
delete[] _array;
}
template< class CLS >
CLS& Varray<CLS>::operator [] // SUBSCRIPT OPERATOR
( unsigned index )
{
if( index >= _bound ) {
CLS* newarr = new CLS[ index + 10 ];
if( 0 != _array ) {
::memcpy( newarr, _array, _bound * sizeof( CLS ) );
delete[] _array;
}
_array = newarr;
_bound = index + 10;
}
return _array[ index ];
}
template< class CLS >
CLS const & Varray<CLS>::operator [] // SUBSCRIPT OPERATOR
( unsigned index )
const
{
return _array[ index ];
}
////////////////////////////////////////////////////////////////////////////
//
// Stk -- very simple stack template
//
////////////////////////////////////////////////////////////////////////////
template< class CLS >
struct Stk
{
Varray<CLS> _stack; // stack data
unsigned _sp; // stack index
Stk() // CONSTRUCTOR
: _sp( 0 )
{
}
CLS& operator[] // SUBSCRIPT
( unsigned index )
{
return _stack[ index ];
}
CLS const & operator[] // SUBSCRIPT
( unsigned index )
const
{
return _stack[ index ];
}
int empty() const; // TEST IF EMPTY
CLS& pop(); // PUSH THE STACK
CLS& push(); // POP THE STACK
CLS& top(); // ACCESS TOP ELEMENT
};
template< class CLS >
int Stk<CLS>::empty // PUSH THE STACK
( void )
const
{
return _sp == 0;
}
template< class CLS >
CLS& Stk<CLS>::push // PUSH THE STACK
( void )
{
++ _sp;
return _stack[ _sp - 1 ];
}
template< class CLS >
CLS& Stk<CLS>::pop // POP THE STACK
( void )
{
-- _sp;
return _stack[ _sp ];
}
template< class CLS >
CLS& Stk<CLS>::top // ACCESS TOP ELEMENT
( void )
{
return _stack[ _sp - 1 ];
}
////////////////////////////////////////////////////////////////////////////
//
// Str -- very simple string class
//
////////////////////////////////////////////////////////////////////////////
struct Str
{
char* _str; // allocated string
Str( const char*, unsigned ); // CONSTRUCTOR
Str() // CONSTRUCTOR
: _str( 0 )
{
}
Str( const char * src ) // CONSTRUCTOR
: _str( 0 )
{
if( 0 != src ) {
*this = Str( src, ::strlen( src ) );
}
}
Str( Str const & src ) // CONSTRUCTOR
: _str( 0 )
{
*this = src;
}
~Str() // DESTRUCTOR
{
delete[] _str;
}
char& operator [] ( unsigned index ) // operator []
{
return _str[ index ];
}
operator char const * () const // conversion to const char*
{
return _str;
}
operator char* () // conversion to char*
{
return _str;
}
Str& operator = ( Str const & ); // assignment
};
Str::Str // CONSTRUCTOR
( const char* text
, unsigned size )
: _str( 0 )
{
if( text != 0 && size != 0 ) {
_str = new char[ size + 1 ];
_str[ size ] = '\0';
::memcpy( _str, text, size );
}
}
Str& Str::operator = // ASSIGNMENT
( Str const & src )
{
if( this != &src ) {
delete[] _str;
if( src._str == 0 ) {
_str = 0;
} else {
unsigned size = ::strlen( src._str );
if( size == 0 ) {
_str = 0;
} else {
_str = new char[ size + 1 ];
_str[ size ] = '\0';
::memcpy( _str, src._str, size );
}
}
}
return *this;
}
////////////////////////////////////////////////////////////////////////////
//
// Edge information for printing
//
////////////////////////////////////////////////////////////////////////////
enum EdgeType // types of edges
{ edge_none // - no edge
, edge_right_prt // - right edge (printing)
, edge_right_blank // - right edge (blank)
, edge_left_prt // - left edge (printing)
, edge_left_blank // - left edge (blank)
, edge_arg // - argument edge
, edge_call // - call edge
};
////////////////////////////////////////////////////////////////////////////
//
// ExpOp -- abstract expression operand
//
////////////////////////////////////////////////////////////////////////////
struct ExpOp {
enum PrtType // types of printing
{ PRT_NONE = 0x00 // - nothing
, PRT_BEFORE_RIGHT = 0x01 // - before: print right
, PRT_ACTUAL_SELF = 0x02 // - actual: print self
, PRT_ACTUAL_RIGHT = 0x04 // - actual: print right
, PRT_ACTUAL_LEFT = 0x08 // - actual: print left
, PRT_AFTER_LEFT = 0x10 // - after: print left
// , PRT_UNDER_LEFT = 0x20 // - after: print left, but under
, PRT_CALL = 0x20 // - call
, PRT_ARG = 0x40 // - argument
, PRT_CALL_OR_ARG = PRT_CALL | PRT_ARG
};
Str _type; // type for operand
CgId _id; // id
static Set<ExpOp> _live; // top-level live expressions
ExpOp( Str const & type // CONSTRUCTOR
, CgId id );
virtual ~ExpOp() // DESTRUCTOR
{
}
static void addLive( ExpOp* item ) // ADD LIVE EXPRESSION
{
_live.insert( item );
}
static ExpOp* find( CgId id ); // FIND LIVE EXPRESSION
virtual
ExpOp* nodeLeft() const; // GET 0 OR LEFT NODE
virtual
char * nodeName( char * ) const = 0;// GET NAME OF NODE
virtual
ExpOp* nodeRight() const; // GET 0 OR RIGHT NODE
static ExpOp* popLive( CgId id ); // FIND AND REMOVE LIVE EXPRESSION
void print( FILE* ); // PRINT AN ENTRY
virtual
void printAfter( FILE* ); // PRINT AN ENTRY (AFTER)
static void printAfter // PRINT INDENTED ENTRY (AFTER)
( FILE* out
, ExpOp* operand );
virtual
void printActual( FILE* ); // PRINT AN ENTRY (ACTUAL)
virtual
void printBefore( FILE* ); // PRINT AN ENTRY (BEFORE)
static
void print( FILE*, ExpOp* ); // PRINT INDENTED ENTRY
static
void printIndentation( FILE* ); // PRINT INDENTATION CHARACTERS
virtual
PrtType printType() const; // DETERMINE PRINTING TYPE
static
void removeLive( ExpOp* op ) // REMOVE LIVE EXPRESSION
{
_live.erase( op );
}
static void verifyEmpty( FILE* ); // VERIFY ALL LIVE EXPR'S DELETED
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?