cpragaxp.c

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

C
351
字号
/****************************************************************************
*
*                            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 "memmgr.h"
#include "pragdefn.h"
#include "initdefs.h"
#include "cginlibs.h"
#include "cginimps.h"
#include "fnovload.h"
#include "name.h"
#include "asmstmt.h"
#include "asinline.h"
#include "carve.h"
#include "pcheader.h"

static risc_byte_seq *AuxCodeDup( risc_byte_seq *code );

static void pragmaInit(         // INIT PRAGMAS
    INITFINI* defn )            // - definition
{
    defn = defn;
    PragInit();
    if( ! CompFlags.dll_subsequent ) {
        AsmInit();
    }
    SetAuxDefaultInfo();
}

static void pragmaFini(         // FINISH PRAGMAS
    INITFINI* defn )            // - definition
{
    defn = defn;
    AsmFini();
    CgInfoFreeLibs();
    CgInfoFreeImports();
    CgInfoFreeImportsS();
}


INITDEFN( pragmas, pragmaInit, pragmaFini )


void PragAux(                   // #PRAGMA AUX ...
    void )
{
}


boolean PragmaChangeConsistent( // TEST IF PRAGMA CHANGE IS CONSISTENT
    AUX_INFO *oldp,             // - pragma (old)
    AUX_INFO *newp )            // - pragma (new)
{
    if( oldp == NULL ) {
        oldp = &DefaultInfo;
    }
    if( oldp == newp ) {
        return TRUE;
    }
    return FALSE;
}

boolean PragmaOKForInlines(     // TEST IF PRAGMA IS SUITABLE FOR INLINED FN
    struct aux_info *fnp )      // - pragma
{
    if( fnp->code != NULL ) {
        return( FALSE );
    }
    return( TRUE );
}

boolean PragmaOKForVariables(   // TEST IF PRAGMA IS SUITABLE FOR A VARIABLE
    AUX_INFO *datap )           // - pragma
{
    AUX_INFO *def_info;

    // only the obj_name can be set for variables everything else is
    // specific to functions except for "__cdecl"
    if( datap == &CdeclInfo ) {
        return( TRUE );
    }
    def_info = &DefaultInfo;
    if( datap->cclass != def_info->cclass ) {
        return( FALSE );
    }
    if( datap->code != def_info->code ) {
        return( FALSE );
    }
    if( datap->flags != def_info->flags ) {
        return( FALSE );
    }
    return( TRUE );
}

// The following defines which flags are to be ignored when checking
// a pragma call classes for equivalence.
//
#define CALL_CLASS_IGNORE ( 0                       \
                          | NO_MEMORY_CHANGED       \
                          | NO_MEMORY_READ          \
                          )

boolean PragmasTypeEquivalent(  // TEST IF TWO PRAGMAS ARE TYPE-EQUIVALENT
    AUX_INFO *inf1,             // - pragma [1]
    AUX_INFO *inf2 )            // - pragma [2]
{
    if( inf1 == NULL ) {
        inf1 = &DefaultInfo;
    }
    if( inf2 == NULL ) {
        inf2 = &DefaultInfo;
    }
    if( inf1 == inf2 ) {
        return TRUE;
    }
    return
           ( ( inf1->cclass & ~CALL_CLASS_IGNORE ) ==
             ( inf2->cclass & ~CALL_CLASS_IGNORE ) )
        && ( inf1->flags == inf2->flags );
}

boolean AsmSysInsertFixups( VBUF *code )
/**************************************/
{
    SYMBOL sym;
    boolean uses_auto;
    asmreloc *curr;
    asmreloc *next;
    byte_seq_reloc *cg_relocs;
    byte_seq_reloc *new_reloc;
    risc_byte_seq *seq;

    seq = CMemAlloc( offsetof( risc_byte_seq, data ) + code->used );
    seq->length = code->used;
    memcpy( seq->data, code->buf, code->used );
    cg_relocs = NULL;
    uses_auto = FALSE;
    for( curr = AsmRelocs; curr != NULL; curr = next ) {
        next = curr->next;
        sym = ScopeASMUseSymbol( curr->name, &uses_auto );
        if( sym != NULL ) {
            new_reloc = CMemAlloc( sizeof( *new_reloc ) );
            new_reloc->off = curr->offset;
            new_reloc->type = curr->type;
            new_reloc->sym = sym;
            new_reloc->next = cg_relocs;
            cg_relocs = new_reloc;
        }
        AsmFree( curr );
    }
    AsmRelocs = NULL;
    seq->relocs = cg_relocs;
    CurrInfo->code = seq;
    return( uses_auto );
}

static void AuxCopy(           // COPY AUX STRUCTURE
    AUX_INFO *to,               // - destination
    AUX_INFO *from )            // - source
{
    freeAuxInfo( to );
    *to = *from;
    to->parms = AuxParmDup( from->parms );
    to->objname = AuxObjnameDup( from->objname );
    to->code = AuxCodeDup( from->code );
}

AUX_INFO *AsmSysCreateAux( char *name )
/*************************************/
{
    CreateAux( name );
    AuxCopy( CurrInfo, &WatcallInfo );
    CurrInfo->use = 1;
    CurrEntry->info = CurrInfo;
    return( CurrInfo );
}

void AsmSysUsesAuto( void )
/*************************/
{
    ScopeASMUsesAuto();
}

void AsmSysInit( void )
/*********************/
{
    AsmCodeAddress = 0;
}

void AsmSysFini( void )
/*********************/
{

}

char const *AsmSysDefineByte( void )
/**********************************/
{
    return( ".byte" );
}

void AsmSysDone( void )
/*********************/
{
    PragEnding( FALSE );
}

enum sym_state AsmQueryExternal( char *name )
/*******************************************/
{
    SYMBOL sym;
    enum sym_state state;

    state = SYM_UNDEFINED;
    sym = ScopeASMLookup( name );
    if( sym != NULL ) {
        if( SymIsAutomatic( sym ) ) {
            state = SYM_STACK;
        } else {
            state = SYM_EXTERNAL;
        }
    }
    return( state );
}

void AsmSysPCHWriteCode( AUX_INFO *info )
/***************************************/
{
    SYMBOL sym;
    byte_seq_reloc *reloc;
    risc_byte_seq *code;
    unsigned code_size;

    code = info->code;
    if( code == NULL ) {
        /* no code */
        PCHWriteUInt( 0 );
        return;
    }
    code_size = offsetof( risc_byte_seq, data ) + code->length;
    PCHWriteUInt( code_size );
    PCHWrite( code, code_size );
    for( reloc = code->relocs; reloc != NULL; reloc = reloc->next ) {
        sym = SymbolGetIndex( reloc->sym );
        PCHWrite( &sym, sizeof( sym ) );
        PCHWrite( &reloc->off, sizeof( reloc->off ) );
        PCHWrite( &reloc->type, sizeof( reloc->type ) );
    }
    sym = SymbolGetIndex( NULL );
    PCHWrite( &sym, sizeof( sym ) );
}

void AsmSysPCHReadCode( AUX_INFO *info )
/**************************************/
{
    cv_index si;
    byte_seq_reloc *reloc;
    byte_seq_reloc **head;
    risc_byte_seq *code;
    unsigned code_size;

    code_size = PCHReadUInt();
    if( code_size == 0 ) {
        info->code = NULL;
        return;
    }
    code = CMemAlloc( code_size );
    info->code = code;
    PCHRead( code, code_size );
    code->relocs = NULL;
    head = &(code->relocs);
    for(;;) {
        PCHLocateCVIndex( si );
        if( si == CARVE_NULL_INDEX ) break;
        reloc = CMemAlloc( sizeof( *reloc ) );
        reloc->next = NULL;
        *head = reloc;
        head = &(reloc->next);
        reloc->sym = SymbolMapIndex( (SYMBOL) si );
        PCHRead( &reloc->off, sizeof( reloc->off ) );
        PCHRead( &reloc->type, sizeof( reloc->type ) );
    }
}

static risc_byte_seq *AuxCodeDup(        // DUPLICATE AUX CODE
    risc_byte_seq *code )
{
    byte_seq_len code_length;
    byte_seq_len size;
    risc_byte_seq *new_code;
    byte_seq_reloc *reloc;
    byte_seq_reloc *new_reloc;

    if( code == NULL ) {
        return( code );
    }
    code_length = code->length;
    size = offsetof( risc_byte_seq, data ) + code_length;
    new_code = (risc_byte_seq *)vctsave( (char *)code, size );
    new_code->relocs = NULL;
    for( reloc = code->relocs; reloc != NULL; reloc = reloc->next ) {
        new_reloc = CMemAlloc( sizeof( *new_reloc ) );
        new_reloc->next = new_code->relocs;
        new_reloc->sym = reloc->sym;
        new_reloc->off = reloc->off;
        new_reloc->type = reloc->type;
        new_code->relocs = new_reloc;
    }
    return( new_code );
}

void AsmSysCopyCode( void )
/*************************/
{
    risc_byte_seq *code;

    code = CurrInfo->code;
    if( code != NULL && code == CurrAlias->code ) {
        CurrInfo->code = AuxCodeDup( code );
    }
}

⌨️ 快捷键说明

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