📄 cpragma.c
字号:
/****************************************************************************
*
* 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 + -