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 + -
显示快捷键?