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