dbg.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,518 行 · 第 1/3 页

C
1,518
字号
/****************************************************************************
*
*                            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 "preproc.h"
#include "cgfront.h"
#include "cgdata.h"
#include "datainit.h"
#include "vbuf.h"
#include "fmttype.h"
#include "fmtsym.h"
#include "dbg.h"
#include "ring.h"
#include "ptree.h"
#include "errdefns.h"
#include "template.h"
#include "vstk.h"
#include "iosupp.h"
#include "codegen.h"
#include "initdefs.h"
#ifndef NDEBUG
#include "pragdefn.h"
#endif


#define F_ADDR      "%x"
#define F_NAME      "%s"
#define F_DECIMAL   "%d"
#define F_HEX       "%x"
#define F_BADDR     "[" F_ADDR "]"
#define F_PTR       "(" F_ADDR ")"
#define F_HEX_1     "(%x)"
#define F_HEX_2     "(%x)"
#define F_HEX_4     "(%x)"
#define F_S64       "(%i64d)"
#define F_STRING    "(" F_NAME ")"
#define F_QSTRING   "('" F_NAME "')"
#define F_EOL       "\n"
#define F_NL        "\n    "
#define F_TGT_OFFSET F_HEX_2
#define F_TGT_SIZE   F_HEX_4
#define F_FLOAT     "(%g)"
#define F_POINTS    "->"
#define F_INSTR     "%20s"
#define F_BUF_FMT   "[%3x-%4x]"
#define F_CPP_FLOAT "(%s)"


char *DbgSymNameFull(           // GET FULL SYMBOL NAME
    SYMBOL sym )                // - symbol
{
    VBUF vbuf;                  // - variable-sized buffer
    static char name[ 1024 ];   // - debugging buffer
    static char* name_ptr;

    if( sym == NULL ) {
        name_ptr = "**NULL**";
    } else {
        FormatSym( sym, &vbuf );
        stpcpy( name, vbuf.buf );
        VbufFree( &vbuf );
        name_ptr = name;
    }
    return name_ptr;
}


char *DbgSymNameShort(          // GET Short SYMBOL NAME
    SYMBOL sym )                // - symbol
{
    extern char *FEName( SYMBOL );
    return FEName( sym );
}


static void printToken(         // PRINT CURRENT TOKEN
    void )
{
    if( CurToken == T_ID ) {
        printf( "T_ID = '%s'\n", Buffer );
    } else if( CurToken == T_STRING ) {
        printf( "T_STRING = \"%s\"\n", Buffer );
    } else if( CurToken == T_LSTRING ) {
        printf( "T_LSTRING = L\"%s\"\n", Buffer );
    } else if( CurToken == T_CONSTANT ) {
        printf( "T_CONSTANT of type(%d) '%s'\n", ConstType, Buffer );
    } else {
        printf( "'%s'\n", Tokens[ CurToken ] );
    }
}


void DumpToken(                 // DUMP A TOKEN
    void )
{
    if( PragDbgToggle.dump_tokens ) {
        printf( "Token(%3d) Line(%4d) Column(%3d) ", CurToken, TokenLine
              , TokenColumn );
        printToken();
    }
}


void DumpMacToken(              // DUMP A MACRO TOKEN
    void )
{
    if( PragDbgToggle.dump_mtokens ) {
        printf( "MacroToken(%3d) Line(%4d) Column(%3d) ", CurToken, TokenLine
              , TokenColumn );
        printToken();
    }
}


void DumpMacPush(               // DUMP PUSH OF MACRO
    const void *p_mac,          // - macro being pushed
    const void**p_args )        // - arguments
{
    MEDEFN const *mac = p_mac;        // - macro being pushed
    const char**args = p_args;  // - arguments
    unsigned count;
    if( PragDbgToggle.dump_mtokens ) {
        printf( "Macro Push: %s", mac->macro_name );
        if( ( mac->macro_defn != 0 ) && ( args != NULL ) ) {
            count = mac->parm_count;
            if( count == 1 ) {
                printf( " = %s", *args );
            } else if( count > 0 ) {
                printf( "( " );
                for( ; --count; ) {
                    printf( "%s%s", *args++, (count>1) ? ", " : " " );
                }
                printf( ")" );
            }
        }
        printf( "\n" );
    }
}



void DumpMDefn(                 // DUMP MACRO DEFINITION
    char *p )                   // - definition
    {
        int c;

        for(; p;) {
            if( *p == 0 ) break;
            switch( *p ) {
            case T_CONSTANT:
                ++p;
                switch( *p ) {
                  case TYP_FLOAT :
                  case TYP_DOUBLE :
                  case TYP_LONG_DOUBLE :
                    break;
                  case TYP_CHAR:
                  case TYP_SCHAR:
                  case TYP_UCHAR:
                  case TYP_WCHAR:
                  case TYP_SSHORT:
                  case TYP_USHORT:
                  case TYP_SINT:
                  case TYP_UINT:
                    p += sizeof( target_int );
                    break;
                  default:
                    p += sizeof( target_long );
                }
            case T_ID:
                ++p;
                for(;;) {
                    c = *p++;
                    if( c == '\0' ) break;
                    putchar( c );
                }
                continue;
            case T_STRING:
                ++p;
                putchar( '\"' );
                for(;;) {
                    c = *p++;
                    if( c == '\0' ) break;
                    putchar( c );
                }
                putchar( '\"' );
                continue;
            case T_WHITE_SPACE:
                ++p;
                putchar( ' ' );
                continue;
            case T_BAD_CHAR:
                ++p;
                putchar( *p++ );
                continue;
            case T_MACRO_PARM:
                ++p;
                printf( "parm#%c", '1' + *p++ );
                continue;
            default:
                printf( "%s", Tokens[ *p ] );
                ++p;
                continue;
            }
        }
        putchar( '\n' );
    }


char *DbgOperator(              // GET CGOP NAME
    CGOP number )               // - index for name
{
    char *name;                 // - name

    static char *opnames[] ={   // - opcode names (binary,unary)
    #include "ppopsnam.h"
    };

    if( number < CO_MAX_OPCODES ) {
        name = opnames[ number ];
    } else if( ( number > CO_NAMES ) && ( number < CO_MAX_NAMES ) ) {
        name = opnames[ number - CO_NAMES + CO_MAX_OPCODES - 1 ];
    } else {
        name = "***INVALID***";
    }
    return( name );
}


char *DbgIcOpcode(              // GET IC OPCODE
    unsigned opcode )           // - opcode
{
    char *name;                 // - name for opcode
    #include "inames.h"         // - defined opcodes

    if( opcode >= IC_END ) {
        name = "BAD OPCODE";
    } else {
        name = ic_names[ opcode ];
    }
    return name;
}

enum                            // types of opcodes
{   DBG_OPCODE_NUL              // - no operand
,   DBG_OPCODE_BIN              // - binary #
,   DBG_OPCODE_STR              // - string
,   DBG_OPCODE_CON              // - floating constant
,   DBG_OPCODE_SYM              // - symbol
,   DBG_OPCODE_SCP              // - scope
,   DBG_OPCODE_TYP              // - type
,   DBG_OPCODE_SRC              // - source file
};

#define IC( code, type ) DBG_OPCODE_##type
static uint_8 optypes[] =
    #include "ic.h"


void DumpCgFront(               // DUMP GENERATED CODE
    const char *prefix,         // - name added to print line
    DISK_ADDR disk_blk,         // - disk block
    DISK_OFFSET offset,         // - disk offset
    void *instruction )         // - intermediate code
{
    CGINTER *ins;               // - instruction
    char *opcode;               // - opcode
    unsigned uvalue;            // - value with opcode

    ins = instruction;
    opcode = DbgIcOpcode( ins->opcode );
    if( ins->opcode >= IC_END ) {
        uvalue = ins->value.uvalue;
    } else {
        if( ins->opcode == IC_EOF ) {
            uvalue = 0;
        } else {
            uvalue = ins->value.uvalue;
        }
    }
    switch( optypes[ ins->opcode ] ) {
      case DBG_OPCODE_SYM :
        printf(                 F_NAME
                " "             F_BUF_FMT
                " "             F_INSTR
                " "             F_HEX_4
                " "             F_NAME F_EOL
              , prefix
              , disk_blk, offset
              , opcode
              , uvalue
              , DbgSymNameFull( ins->value.pvalue ) );
        break;
      case DBG_OPCODE_TYP :
      { VBUF fmt_prefix, fmt_suffix;
        FormatType( ins->value.pvalue, &fmt_prefix, &fmt_suffix );
        printf(                 F_NAME
                " "             F_BUF_FMT
                " "             F_INSTR
                " "             F_HEX_4
                " %s<id>%s" F_EOL
              , prefix
              , disk_blk, offset
              , opcode
              , uvalue
              , fmt_prefix.buf
              , fmt_suffix.buf );
        VbufFree( &fmt_prefix );
        VbufFree( &fmt_suffix );
      } break;
      case DBG_OPCODE_NUL :
        printf(                 F_NAME
                " "             F_BUF_FMT
                " "             F_INSTR F_EOL
              , prefix
              , disk_blk, offset
              , opcode );
        break;
      case DBG_OPCODE_SRC :
      {
        printf(                 F_EOL F_NAME
                " "             F_BUF_FMT
                " "             F_INSTR
                " "             F_NAME F_EOL
              , prefix
              , disk_blk, offset
              , opcode
              , SrcFileFullName( ins->value.pvalue ) );
      } break;
      case DBG_OPCODE_SCP :
        printf(                 F_NAME
                " "             F_BUF_FMT
                " "             F_INSTR
                " "             "scope: " F_HEX F_EOL
              , prefix
              , disk_blk, offset
              , opcode
              , uvalue );
        break;
      case DBG_OPCODE_STR :
      case DBG_OPCODE_CON :
      case DBG_OPCODE_BIN :
        switch( ins->opcode ) {
          case IC_OPR_BINARY :
          case IC_OPR_UNARY :
            printf(                 F_NAME
                    " "             F_BUF_FMT
                    " "             F_INSTR
                    " "             F_NAME F_EOL
                  , prefix
                  , disk_blk, offset
                  , opcode
                  , DbgOperator( ins->value.uvalue ) );
            break;
          case IC_DBG_LINE :
            printf(                 F_NAME
                    " "             F_BUF_FMT
                    " "             F_INSTR
                    " "             F_DECIMAL F_EOL F_EOL
                  , prefix
                  , disk_blk, offset
                  , opcode
                  , uvalue );
            break;
          default :
            printf(                 F_NAME
                    " "             F_BUF_FMT
                    " "             F_INSTR
                    " "             F_HEX F_EOL
                  , prefix
                  , disk_blk, offset
                  , opcode
                  , uvalue );
            break;
        }
        break;
      default :
        CFatal( "**** UNDEFINED OPCODE TYPE *****" );
        break;
    }
}

static void dumpTemplateInfo( TEMPLATE_INFO *tinfo )
{
    TEMPLATE_SPECIALIZATION *tprimary;
    VBUF prefix, suffix;
    int i;
    char delim;

    tprimary = RingFirst( tinfo->specializations );
    printf( "    TEMPLATE_INFO" F_BADDR
            " defn"         F_PTR
            " num_args"     F_HEX_4
                            F_EOL
          , tinfo
          , tprimary->defn
          , tprimary->num_args
          );
    printf( "  " );
    delim = '<';
    for( i = 0; i < tprimary->num_args; ++i ) {
        FormatType( tprimary->type_list[i], &prefix, &suffix );
        printf( "%c %s<id> %s", delim, prefix.buf, suffix.buf );
        VbufFree( &prefix );
        VbufFree( &suffix );
        delim = ',';
    }
    printf( ">\n" );
}

static void dumpNameSpaceInfo( NAME_SPACE *ns )
{
    printf( "    NAME_SPACE" F_BADDR
            " scope"         F_PTR
            " all"           F_PTR
            " name"          F_PTR
                             F_EOL
          , ns
          , ns->scope
          , ns->all
          , ns->sym
          );
}

static void dumpLocation( TOKEN_LOCN *locn )
{
    if( locn->src_file != NULL ) {
        printf( "    " );
        DbgDumpTokenLocn( locn );
        printf( F_EOL );
    }
}


//
//  SYMBOL-TABLE FUNCTIONS
//
void DumpSymbol(                // DUMP SYMBOL ENTRY
    void *_sym )                // - symbol
{
    SYMBOL sym = _sym;
    VBUF vbuf;

    static char const *ids[] = {
        #define SC_DEF(a) #a
        SC_DEFS
        #undef SC_DEF
    };

    if( sym != NULL ) {
        FormatSym( sym, &vbuf );
        printf( "SYMBOL"        F_BADDR
                " next"         F_PTR
                " thread"       F_PTR
                " sym_type"     F_PTR
                " name"         F_PTR
                " cg_handle"    F_PTR
                F_NL
                " u"            F_PTR
                " id="          F_STRING
                " flag"         F_HEX_1
                " flag2"        F_HEX_1
                " segid"        F_HEX_2
                F_NL
                " symbol-name=" F_QSTRING
                F_EOL
              , sym
              , sym->next
              , sym->thread
              , sym->sym_type
              , sym->name
              , ( sym->flag2 & SF2_TOKEN_LOCN ) ? sym->locn->cg_handle : 0
              , sym->u.tinfo
              , ids[sym->id]
              , sym->flag
              , sym->flag2
              , sym->segid

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?