⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpragma.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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;

// local functions
local void EndOfPragma( void );
local void PragFlag( int value );
local void GetLibraryNames( void );
local void PragComment( void );
local void SetPackAmount( void );
local void PragPack( void );
local void PragAllocText( void );
local void PragEnableDisableMessage( int enable );
local void PragSTDCOption( void );
local void PragAddExtRef ( char * );
static void PragMessage( void );
static void PragEnum ( void );
static void PragLibs( void );
static void PragCodeSeg( void );
static void PragIntrinsic( int intrinsic );
static void PragDataSeg( void );
static void PragUnroll( void );
static void PragReadOnlyFile( void );
static void PragReadOnlyDir( void );
static void PragOnce( void );
static void PragSTDC( void );
static void PragExtRef( void );
local void CopyParms( void );
local void CopyLinkage( void );
local void CopyCode( void );
local void CopyObjName( void );


// 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;
    PragmaInit(); // call traget specific init
}

void CPragma( void )
{
    if( CompFlags.cpp_output ) {                    /* 29-sep-90 */
        if( ! CppPrinting() ) return;               /* 12-dec-89 */
        CppPrtf( "#pragma" );
        CompFlags.pre_processing = 1;               /* 28-feb-89 */
        CompFlags.in_pragma = 1;
        for(;;) {
            GetNextToken();
            if( CurToken == T_NULL ) break;
            PrtToken();
        }
        CompFlags.in_pragma = 0;
    } else {
        NextToken();
        if( PragRecog( "on" ) ) {
            PragFlag( 1 );
        } else if( PragRecog( "off" ) ) {
            PragFlag( 0 );
        } else if( PragRecog( "aux" ) || PragRecog( "linkage" ) ) {
            PragAux();
        } else if( PragRecog( "library" ) ) {
            PragLibs();
        } else if( PragRecog( "comment" ) ) {
            PragComment();
        } else if( PragRecog( "pack" ) ) {
            PragPack();
        } else if( PragRecog( "alloc_text" ) ) {    /* 26-oct-91 */
            PragAllocText();
        } else if( PragRecog( "code_seg" ) ) {      /* 22-oct-92 */
            PragCodeSeg();
        } else if( PragRecog( "data_seg" ) ) {      /* 22-oct-92 */
            PragDataSeg();
        } else if( PragRecog( "disable_message" ) ) {/* 18-jun-92 */
            PragEnableDisableMessage( 0 );
        } else if( PragRecog( "enable_message" ) ) {/* 18-jun-92 */
            PragEnableDisableMessage( 1 );
        } else if( PragRecog( "message" ) ) {   /* 13-oct-94 */
            PragMessage();
        } else if( PragRecog( "intrinsic" ) ) { /* 09-oct-92 */
            PragIntrinsic( 1 );
        } else if( PragRecog( "function" ) ) {
            PragIntrinsic( 0 );
        } else if( PragRecog( "enum" ) ) {
            PragEnum();
        } else if( PragRecog( "read_only_file" ) ) {
            PragReadOnlyFile();
        } else if( PragRecog( "read_only_directory" ) ) {
            PragReadOnlyDir();
        } else if( PragRecog( "once" ) ) {
            PragOnce();
        } else if( PragRecog( "unroll" ) ) {
            PragUnroll();
        } else if( PragRecog( "STDC" ) ) {
            PragSTDC();
        } else if( PragRecog( "extref" ) ) {
            PragExtRef();
        } else {
            return;                     /* don't recognize anything */
        }
        EndOfPragma();
    }
}


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



void PragInit( void )
{
    CdeclInfo   = DefaultInfo;
    PascalInfo  = DefaultInfo;
    FortranInfo = DefaultInfo;
    SyscallInfo = DefaultInfo;
    StdcallInfo = DefaultInfo;
    OptlinkInfo = DefaultInfo;
    DefaultInfo.use = 2;        /* so they don't get freed */
    CdeclInfo.use   = 2;
    PascalInfo.use  = 2;
    SyscallInfo.use = 2;
    OptlinkInfo.use = 2;
    FortranInfo.use = 2;
    PackInfo = NULL;
    EnumInfo = NULL;
}


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 );
}

struct magic_words {
        char *  name;
        int     index;
};

enum {
        M_UNKNOWN,
        M_DEFAULT,
        M_CDECL,
        M_PASCAL,
        M_FORTRAN,
        M_SYSTEM,
        M_STDCALL,
};

struct magic_words MagicWords[] = {                     /* 18-aug-90 */
        { "default",    M_DEFAULT },
        { "cdecl",      M_CDECL },
        { "pascal",     M_PASCAL },
        { "fortran",    M_FORTRAN },
        { "system",     M_SYSTEM },
        { "syscall",    M_SYSTEM },
        { "stdcall",    M_STDCALL },
        { "__cdecl",    M_CDECL },
        { "__pascal",   M_PASCAL },
        { "__fortran",  M_FORTRAN },
        { "__system",   M_SYSTEM },
        { "__syscall",  M_SYSTEM },
        { "__stdcall",  M_STDCALL },
        { NULL,         M_UNKNOWN }
};

local int MagicKeyword( void )
{
    int         i;

    for( i = 0; MagicWords[i].name; ++i ) {
        if( strcmp( Buffer, MagicWords[i].name ) == 0 ) break;
    }
    return( MagicWords[i].index );
}


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
    CurrInfo = (struct aux_info *)CMemAlloc( sizeof( struct aux_info ) );
}


void SetCurrInfo( void )
{
    switch( MagicKeyword() ) {
    case M_DEFAULT:
        CurrInfo = &DefaultInfo;
        break;
    case M_CDECL:
//      CompFlags.cdecl_defined = 1;
        CurrInfo = &CdeclInfo;
        break;
    case M_PASCAL:
//      CompFlags.pascal_defined = 1;
        CurrInfo = &PascalInfo;
        break;
    case M_FORTRAN:
//      CompFlags.fortran_defined = 1;
        CurrInfo = &FortranInfo;
        break;
    case M_SYSTEM:
        CurrInfo = &SyscallInfo;
        break;
    case M_STDCALL:
        CurrInfo = &StdcallInfo;
        break;
    default:
        CreateAux( Buffer );
    }
}


void PragCurrAlias()
{
    struct aux_entry *search;

    search = NULL;
    CurrAlias = &DefaultInfo;
    switch( MagicKeyword() ) {
    case M_CDECL:
        CurrAlias = &CdeclInfo;
        break;
    case M_PASCAL:
        CurrAlias = &PascalInfo;
        break;
    case M_FORTRAN:
        CurrAlias = &FortranInfo;
        break;
    case M_SYSTEM:
        CurrAlias = &SyscallInfo;
        break;
    case M_STDCALL:
        CurrAlias = &StdcallInfo;
        break;
    default:
        search = AuxLookup( Buffer );
        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;
}


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();
        CurrInfo->use = 1;
        CurrEntry->info = CurrInfo;
    }
    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;
    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 _MACHINE == _ALPHA || _MACHINE == _PPC
local void CopyCode( void )
{

⌨️ 快捷键说明

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