cpragma.c

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

C
998
字号
/****************************************************************************
*
*                            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:  Generic (target independent) pragma processing.
*
****************************************************************************/


#include "cvars.h"
#include "cgswitch.h"
#include "pragdefn.h"
#include "pdefn2.h"

struct  pack_info {
    struct pack_info *next;
    int         pack_amount;
} *PackInfo;

struct enums_info {
    struct enums_info *next;
    int    make_enums;
} *EnumInfo;

extern struct aux_info *GetLangInfo( type_modifiers flags );

// local variables
static struct toggle ToggleNames[] = {
    #define TOGDEF( a, b ) {  #a, b },
    #include "togdef.h"
    #undef TOGDEF
        { NULL, 0 }
    };

void CPragmaInit( void ) {
//********************************//
// Init any general pragma things //
//********************************//
    TextSegList = NULL;
    
/* Pragma Pack init */
    PackInfo = NULL;

/* Pragma Enum init */
    EnumInfo = NULL;

/* Pragma Aux init */
    WatcallInfo.use = 2;        /* so they don't get freed */

    CdeclInfo   = WatcallInfo;
    PascalInfo  = WatcallInfo;
    SyscallInfo = WatcallInfo;
    StdcallInfo = WatcallInfo;
    OptlinkInfo = WatcallInfo;
    FortranInfo = WatcallInfo;
    FastcallInfo= WatcallInfo;

#if _INTEL_CPU
    PragmaAuxInit();
#endif

    SetAuxDefaultInfo();

/* call target specific init */
    PragmaInit();
}

local void EndOfPragma( void )
/*****************************/
{
    if( CurToken == T_SEMI_COLON ) NextToken();
    if( CurToken != T_NULL ) ExpectEndOfLine();
    while( CurToken != T_NULL && CurToken != T_EOF ) NextToken();
}


extern int SetToggleFlag( char const *name, int const value )
/**************************************************************/
{
    int     i;
    char   *pnt;
    int     ret;

    ret = FALSE;
    for( i=0; ( pnt = ToggleNames[ i ].name ) != NULL; ++i ) {
        if( strcmp( pnt, name ) == 0 ) {
            if( value == 0 ){
                Toggles &= ~ToggleNames[ i ].flag;
            }else{
                Toggles |= ToggleNames[ i ].flag;
            }
            ret = TRUE;
            break;
        }
    }
    return( ret );
}

local void PragFlag( int value )
/******************************/
{

    if( CurToken != T_LEFT_PAREN ) return;
    NextToken();
    while( CurToken == T_ID ) {
        SetToggleFlag( Buffer, value );
        NextToken();
    }
    MustRecog( T_RIGHT_PAREN );
}

local void GetLibraryNames( void )
/********************************/
{
    struct library_list **owner;
    struct library_list *new;

    for( owner = &HeadLibs; *owner != NULL; owner = &(*owner)->next )
            ; /* nothing to do */
    while( CurToken == T_ID  ||  CurToken == T_STRING ) {
        new = (void *)CMemAlloc( sizeof( struct library_list ) + TokenLen );
        new->next = NULL;
        new->prio = USER_LIB_PRIO;
        strcpy( new->name, Buffer );
        *owner = new;
        owner  = &new->next;
        NextToken();
    }
    MustRecog( T_RIGHT_PAREN );
}

static void PragLibs( void )
/**************************/
{
    if( CurToken == T_LEFT_PAREN ) {
        NextToken();
        GetLibraryNames();
    }
}

local void PragComment( void )
/****************************/
{
    if( CurToken == T_LEFT_PAREN ) {
        NextToken();
        if( PragRecog( "lib" ) ) {
            MustRecog( T_COMMA );
            GetLibraryNames();
        }
    }
}

local void SetPackAmount( void )
/******************************/
{
    PackAmount = Constant;
    switch( PackAmount ) {
    case 1:
    case 2:
    case 4:
    case 8:
    case 16:                                    /* 09-oct-92 */
        break;
    default:
        PackAmount = 1;
    }
}

local void PragPack( void )
/*************************/
{
    struct pack_info    *pi;

    if( CurToken != T_LEFT_PAREN ) return;
    CompFlags.pre_processing = 1;           /* enable macros */
    NextToken();
    CompFlags.pre_processing = 2;
    if( CurToken == T_RIGHT_PAREN ) {
        NextToken();
        if( CurToken == T_SEMI_COLON ) NextToken();
        PackAmount = GblPackAmount;
        return;
    }
    /* check to make sure it is a numeric token */
    if( CurToken == T_CONSTANT ) {                  /* 24-may-89 */
        SetPackAmount();
        NextToken();
    } else if( PragRecog( "push" ) ) {                  /* 29-sep-94 */
        pi = (struct pack_info *)CMemAlloc( sizeof(struct pack_info) );
        pi->next = PackInfo;
        pi->pack_amount = PackAmount;
        PackInfo = pi;
        if( CurToken == T_COMMA ) {
            NextToken();
            if( CurToken == T_CONSTANT ) {
                SetPackAmount();
            } else {
                CErr1( ERR_NOT_A_CONSTANT_EXPR );
            }
            NextToken();
        }
    } else if( PragRecog( "pop" ) ) {
        pi = PackInfo;
        if( pi != NULL ) {
            PackAmount = pi->pack_amount;
            PackInfo = pi->next;
            CMemFree( pi );
        }
    } else {
        CErr1( ERR_NOT_A_CONSTANT_EXPR );
        NextToken();
    }
    MustRecog( T_RIGHT_PAREN );
}

#ifdef pick
#undef pick
#endif

#define pick(a,b,c) { b, c },
struct magic_words {
    char            *name;
    struct aux_info *info;
} MagicWords[] = {
#include "auxinfo.h"
};

struct aux_info *MagicKeyword( char *name )
{
    int         i;

    if( *name == '_' ) {
        ++name;
        if( *name == '_' ) {
            ++name;
        }
    }
    for( i = 0; MagicWords[i].name; ++i ) {
        if( strcmp( name, MagicWords[i].name ) == 0 ) {
            break;
        }
    }
    return( MagicWords[i].info );
}


void CreateAux( char *id )
/************************/
{
    CurrEntry = (struct aux_entry *)
            CMemAlloc( sizeof(struct aux_entry) + strlen( id ) );
    strcpy( CurrEntry->name, id );
#if _CPU == 370
    CurrEntry->offset = -1;
#endif
}


void SetCurrInfo( char *name )
/****************************/
{
    SYM_HANDLE      sym_handle;
    SYM_ENTRY       sym;
    type_modifiers  sym_attrib = FLAG_NONE;
    
    CurrInfo = MagicKeyword( name );
    if( CurrInfo == NULL ) {
        if( CurrAlias == NULL ) {
            sym_handle = SymLook( HashValue, name );
            if( sym_handle != 0 ) {
                SymGet( &sym, sym_handle );
                sym_attrib = sym.attrib;
            }
            CurrAlias = GetLangInfo( sym_attrib );
        }
        CreateAux( name );
    } else if( CurrAlias == NULL ) {
        CurrAlias = CurrInfo;
    }
}


void PragCurrAlias( char *name )
/******************************/
{
    struct aux_entry *search;
    
    search = NULL;
    CurrAlias = MagicKeyword( name );
    if( CurrAlias == NULL ) {
        search = AuxLookup( name );
        if( search != NULL ) {
            CurrAlias = search->info;
        }
    }
}


void XferPragInfo( char *from, char *to )
/***************************************/
{
    struct aux_entry *ent;

    if( AuxLookup( to ) != NULL )
        return;
    ent = AuxLookup( from );
    if( ent == NULL )
        return;
    CreateAux( to );
    CurrEntry->info = ent->info;
    ent->info->use++;
    CurrEntry->next = AuxList;
    AuxList = CurrEntry;
}


local void CopyLinkage( void )
/****************************/
{
#if _CPU == 370
    linkage_regs *regs;

    if( CurrInfo->linkage == &DefaultLinkage ) return;
    if( CurrInfo->linkage == &OSLinkage ) return;
    if( CurrInfo->linkage != CurrAlias->linkage ) return;
    regs = (linkage_regs *)CMemAlloc( sizeof( linkage_regs ) );
    memcpy( regs, CurrInfo->linkage, sizeof( linkage_regs ) );
    CurrInfo->linkage = regs;
#endif
}


local void CopyParms( void )
/**************************/
{
    int         i;
    hw_reg_set  *regs;

    if( CurrInfo->parms != CurrAlias->parms ) return;
    if( IsAuxParmsBuiltIn( CurrInfo->parms ) ) return;
    for( i = 1, regs = CurrInfo->parms;
         !HW_CEqual( *regs, HW_EMPTY ); ++i, ++regs )
        ;
    i *= sizeof( hw_reg_set );
    regs = (hw_reg_set *)CMemAlloc( i );
    memcpy( regs, CurrInfo->parms, i );
    CurrInfo->parms = regs;
}

#if _RISC_CPU
#define BYTE_SEQ    risc_byte_seq
#else
#define BYTE_SEQ    byte_seq
#endif

local void CopyCode( void )
/*************************/
{
    BYTE_SEQ    *code;
    int         size;
//TODO deal with reloc list
    if( CurrInfo->code == NULL ) return;
    if( CurrInfo->code != CurrAlias->code ) return;
    size = sizeof( BYTE_SEQ ) + CurrInfo->code->length;
    code = (BYTE_SEQ *)CMemAlloc( size );
    memcpy( code, CurrInfo->code, size );
    CurrInfo->code = code;
}

local void CopyObjName( void )
/****************************/
{
    if( CurrInfo->objname == NULL )
        return;
    if( CurrInfo->objname != CurrAlias->objname )
        return;
    CurrInfo->objname = CStrSave( CurrInfo->objname );
}

#if _CPU == _AXP
local void CopyExceptRtn( void )
/******************************/
{
    if( CurrInfo->except_rtn == NULL )
        return;
    if( CurrInfo->except_rtn != CurrAlias->except_rtn )
        return;
    CurrInfo->except_rtn = CStrSave( CurrInfo->except_rtn );
}
#endif

void PragEnding( void )
/*********************/
{
    if( CurrEntry == NULL )
        return;
    CurrInfo->use = CurrAlias->use; /* for compare */
    if( memcmp( CurrAlias, CurrInfo,
                sizeof( struct aux_info ) ) == 0 ) {
        CurrEntry->info = CurrAlias;
        CurrAlias->use++;
        CMemFree( CurrInfo );
    } else {
        CopyParms();
        CopyLinkage();
        CopyCode();
        CopyObjName();
#if _CPU == _AXP
        CopyExceptRtn();
#endif
        CurrInfo->use = 1;
        CurrEntry->info = CurrInfo;
    }
    CurrEntry->next = AuxList;
    AuxList = CurrEntry;
}


int PragRecog( char *what )
/*************************/
{
    char        *p;

    if( !(CurToken == T_ID
      || (CurToken >= FIRST_KEYWORD && CurToken < T_MACRO_PARM)) ) {
        return( 0 );
    }
    p = Buffer;
    if( *p == '_' ) ++p;
    if( *p == '_' ) ++p;
    if( stricmp( what, p ) == 0 ) {
        NextToken();
        return( 1 );
    }
    return( 0 );
}


void PragObjNameInfo( char **objname )
/************************************/
{
    if( CurToken == T_STRING ) {
        *objname = CStrSave( Buffer );
        NextToken();
    }
}

TOKEN PragRegSet( void )
/**********************/
{
    if( CurToken == T_LEFT_BRACKET )
        return( T_RIGHT_BRACKET );
    if( CurToken == T_LEFT_BRACE )
        return( T_RIGHT_BRACE );
    return( T_NULL );
}


hw_reg_set PragRegList( void )
/****************************/
{
    hw_reg_set  res, reg;
    TOKEN       close;
    char        buf[80];

    HW_CAsgn( res, HW_EMPTY );
    HW_CAsgn( reg, HW_EMPTY );
    close = PragRegSet();
    if( close != T_NULL ) {
        CompFlags.pre_processing = 1;       /* enable macros */
        NextToken();
        *buf = '\0';
        for( ; CurToken != close; ) {
            strcat( buf, Buffer );
            if( CurToken != T_BAD_CHAR ) {
                reg = PragRegName( buf );
                HW_TurnOn( res, reg );

⌨️ 快捷键说明

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