dwrefer.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 207 行

C
207
字号
/****************************************************************************
*
*                            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 "dwpriv.h"
#include "dwrefer.h"
#include "dwhandle.h"
#include "dwutils.h"
#include "dwmem.h"

#define myWrite( __b, __l )     CLIWrite( DW_DEBUG_REF, __b, __l )

/*
    We use these delayed_ref structures to avoid emitting sequences such
    as:
        REF_BEGIN_SCOPE
        REF_END_SCOPE
    (Basically to avoid emitting null reference information.)
*/

struct delayed_ref {
    struct delayed_ref *        next;
    debug_ref                   offset;
    uint                        scope;
};


static void emitDelayed(
    dw_client                   cli )
{
    struct delayed_ref *        cur;
    char                        buf[ 1 + MAX_LEB128 ];
    char *                      end;

    /* delayed_refs are stacked up; we want to emit them in FIFO order */
    cur = ReverseChain( cli->references.delayed );
    while( cur ) {
        buf[0] = REF_BEGIN_SCOPE;
        WriteRef( buf + 1, cur->offset );
        myWrite( buf, 1 + sizeof( debug_ref ) );
        cur = CarveFreeLink( cli->references.delay_carver, cur );
    }
    cli->references.delayed = 0;
    if( cli->references.delayed_file ) {
        buf[ 0 ] = REF_SET_FILE;
        end = ULEB128( buf + 1, cli->references.delayed_file );
        myWrite( buf, end - buf );
        cli->references.delayed_file = 0;
    }
}


void StartRef(
    dw_client                   cli )
{
    struct delayed_ref *        new;

    /*
        We just stack up the StartRef until we find that we have to actually
        emit it.
    */
    new = CarveAlloc( cli, cli->references.delay_carver );
    new->next = cli->references.delayed;
    cli->references.delayed = new;
    new->offset = CLITell( DW_DEBUG_INFO ) - cli->section_base[ DW_DEBUG_INFO ];
    new->scope = cli->references.scope;
    ++cli->references.scope;
}


void EndRef(
    dw_client                   cli )
{
    struct delayed_ref *        this;
    char                        buf[1];

    /*
        We have to check if we actually emitted a REF_START_REF
        for this scope
    */
    --cli->references.scope;
    this = cli->references.delayed;
    if( this != NULL && this->scope == cli->references.scope ) {
        cli->references.delayed =
            CarveFreeLink( cli->references.delay_carver, this );
    } else {
        buf[ 0 ] = REF_END_SCOPE;
        myWrite( buf, sizeof( buf ) );
    }
}



void DWENTRY DWReference(
    dw_client                   cli,
    dw_linenum                  line,
    dw_column                   column,
    dw_handle                   dependant )
{
    dw_linenum_delta            line_delta;
    dw_column_delta             column_delta;
    char                        buf[ 1 + MAX_LEB128 ];
    char *                      end;

    /*
        We actually have a reference for this scope, so emit all the
        delayed REF_START_REFS.
    */
    emitDelayed( cli );

    line_delta = line - cli->references.line;
    cli->references.line = line;
    if( line_delta < 0
        || line_delta >= ( 255 - REF_CODE_BASE ) / REF_COLUMN_RANGE ) {
        buf[ 0 ] = REF_ADD_LINE;
        end = LEB128( buf + 1, line_delta );
        myWrite( buf, end - buf );
        cli->references.column = 0;
        line_delta = 0;
    } else if( line_delta != 0 ) {
        cli->references.column = 0;
    }
    column_delta = column - cli->references.column;
    cli->references.column = column;
    if( column_delta < 0 || column_delta >= REF_COLUMN_RANGE ) {
        buf[ 0 ] = REF_ADD_COLUMN;
        end = LEB128( buf + 1, column_delta );
        myWrite( buf, end - buf );
        column_delta = 0;
    }
    _Assert( line_delta >= 0
        && line_delta * REF_COLUMN_RANGE <= 255 - REF_CODE_BASE-REF_COLUMN_RANGE
        && column_delta >= 0
        && column_delta < REF_COLUMN_RANGE );
    buf[ 0 ] = REF_CODE_BASE + line_delta * REF_COLUMN_RANGE + column_delta;
    myWrite( buf, 1 );
    HandleReference( cli, dependant, DW_DEBUG_REF );
}


void SetReferenceFile(
    dw_client                   cli,
    uint                        file )
{
    cli->references.delayed_file = file;
}


void InitReferences(
    dw_client                   cli )
{
    cli->references.line = 1;
    cli->references.column = 1;
    cli->references.delayed = NULL;
    cli->references.delay_carver =
        CarveCreate( cli, sizeof( struct delayed_ref ), 16 );
    cli->references.scope = 0;
    cli->references.delayed_file = 0;

    CLISeek( DW_DEBUG_REF, sizeof( uint_32 ), DW_SEEK_CUR );
}


void FiniReferences(
    dw_client                   cli )
{
    char                        buf[ sizeof( uint_32 ) ];
    long                        size;

    size = CLITell( DW_DEBUG_REF ) - sizeof( uint_32 ) -
        cli->section_base[ DW_DEBUG_REF ];
    WriteU32( buf, size );
    CLISeek( DW_DEBUG_REF, cli->section_base[ DW_DEBUG_REF ], DW_SEEK_SET );
    CLIWrite( DW_DEBUG_REF, buf, sizeof( buf ) );
    CLISeek( DW_DEBUG_REF, 0, DW_SEEK_END );

    CarveDestroy( cli, cli->references.delay_carver );
}

⌨️ 快捷键说明

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