cpragma.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,622 行 · 第 1/3 页
C
1,622 行
int priority;
if( CurToken == T_LEFT_PAREN ) {
NextToken();
if( PragRecog( "compiler" ) ) {
priority = INIT_PRIORITY_LIBRARY - 1;
} else if( PragRecog( "lib" ) ) {
priority = INIT_PRIORITY_LIBRARY;
} else {
priority = INIT_PRIORITY_PROGRAM;
MustRecog( T_ID );
}
CompInfo.init_priority = priority;
MustRecog( T_RIGHT_PAREN );
}
}
// forms: #pragma extref symbol
// #pragma extref ( symbol, ..., symbol )
//
// causes a external reference to be emitted for the symbol
//
static void newPRAG_EXT_REF( SYMBOL sym )
{
PRAG_EXT_REF* entry = RingAlloc( &pragmaExtrefs, sizeof( PRAG_EXT_REF ) );
entry->extref = sym;
}
static int parseExtRef( // PARSE SYMBOL NAME
void )
{
int err; // TRUE ==> syntax error
if( PragIdCurToken() ) {
char* name = NameCreateLen( Buffer, TokenLen );
SEARCH_RESULT* result;
result = ScopeFindNaked( GetCurrScope()
, NameCreateLen( Buffer, TokenLen ) );
if( result == NULL ) {
CErr2p( ERR_PRAG_EXTREF_NONE, Buffer );
} else {
SYMBOL_NAME sname = result->sym_name;
SYMBOL sym = sname->name_syms;
ScopeFreeResult( result );
if( sym == NULL ) {
CErr2p( ERR_PRAG_EXTREF_BAD, Buffer );
} else if( SymIsFunction( sym ) ) {
if( IsOverloadedFunc( sym ) ) {
CErr2p( ERR_PRAG_EXTREF_OVERLOADED, sym );
sym = NULL;
}
} else if( SymIsData( sym ) ) {
// no checks now
} else {
CErr2p( ERR_PRAG_EXTREF_BAD, sym );
sym = NULL;
}
if( sym != NULL ) {
newPRAG_EXT_REF( sym );
}
}
NextToken();
err = 0;
} else {
err = 1;
}
return err;
}
static void pragExtRef( // #pragma extref ...
void )
{
int err; // - TRUE ==> error occurred
if( CurToken == T_LEFT_PAREN ) {
PPState = PPS_EOL;
NextToken();
for( ; ; ) {
err = parseExtRef();
if( err ) break;
if( CurToken != T_COMMA ) break;
NextToken();
}
PPState = PPS_EOL | PPS_NO_EXPAND;
if( ! err ) {
MustRecog( T_RIGHT_PAREN );
}
} else {
parseExtRef();
}
}
void PragmaExtrefsValidate // VALIDATE EXTREFS FOR PRAGMAS
( void )
{
PRAG_EXT_REF* entry; // - current entry
RingIterBeg( pragmaExtrefs, entry ) {
SYMBOL sym = entry->extref;
if( SymIsExtern( sym ) ) {
if( IsOverloadedFunc( sym ) ) {
CErr2p( ERR_PRAG_EXTREF_OVERLOADED, sym );
entry->extref = NULL;
}
} else {
CErr2p( ERR_PRAG_EXTREF_EXTERN, sym );
entry->extref = NULL;
}
} RingIterEnd( entry );
}
void PragmaExtrefsInject // INJECT EXTREFS FOR PRAGMAS
( void )
{
PRAG_EXT_REF* entry; // - current entry
RingIterBeg( pragmaExtrefs, entry ) {
SYMBOL sym = entry->extref;
if( NULL != sym ) {
CgInfoAddPragmaExtref( sym );
}
} RingIterEnd( entry );
}
static void pragIntrinsic( // SET FUNCTIONS TO BE (NOT TO BE) INTRINSIC
boolean intrinsic ) // - TRUE ==> function to be intrinsic
{
if( CurToken == T_LEFT_PAREN ) {
NextToken();
while( PragIdCurToken() ) {
ScopeIntrinsic( intrinsic );
NextToken();
if( CurToken != T_COMMA ) break;
NextToken();
}
MustRecog( T_RIGHT_PAREN );
}
}
static void pragDumpObjectModel( // DUMP OBJECT MODEL
void )
{
if( PragIdCurToken() ) {
SEARCH_RESULT* result = ScopeFindNaked( GetCurrScope()
, NameCreateLen( Buffer, TokenLen ) );
if( result == NULL ) {
CErr2p( ERR_DUMP_OBJ_MODEL, Buffer );
} else {
SYMBOL_NAME sname = result->sym_name;
ScopeFreeResult( result );
if( sname->name_syms == NULL ) {
TYPE type = sname->name_type->sym_type;
if( TypeDefined( type ) ) {
TYPE dump_type;
dump_type = StructType( type );
if( dump_type != NULL ) {
DumpObjectModelClass( dump_type );
} else {
dump_type = EnumType( type );
if( dump_type != NULL ) {
DumpObjectModelEnum( dump_type );
} else {
CErr2p( ERR_DUMP_OBJ_MODEL, Buffer );
}
}
} else {
CErr2p( ERR_DUMP_OBJ_MODEL, Buffer );
}
} else {
CErr2p( ERR_DUMP_OBJ_MODEL, Buffer );
}
}
NextToken();
}
}
static DT_METHOD parseDtorMethod( // PARSE A DESTRUCTOR METHOD
void )
{
DT_METHOD method; // - method specified
if( PragRecog( "direct" ) ) {
method = DTM_DIRECT;
} else if( PragRecog( "small" ) ) {
method = DTM_TABLE_SMALL;
} else if( PragRecog( "table" ) ) {
method = DTM_TABLE;
} else {
method = DTM_COUNT;
}
return method;
}
static void pragDestruct( // SPECIFY DESTRUCTION MECHANISM
void )
{
DT_METHOD method; // - method
DT_METHOD next; // - next method spec
if( CurToken == T_LEFT_PAREN ) {
NextToken();
method = DTM_COUNT;
for( ; ; ) {
if( CurToken == T_RIGHT_PAREN ) {
NextToken();
break;
}
next = parseDtorMethod();
switch( next ) {
default :
method = DTM_COUNT;
break;
case DTM_DIRECT :
switch( method ) {
case DTM_TABLE :
method = DTM_DIRECT_TABLE;
continue;
case DTM_TABLE_SMALL :
method = DTM_DIRECT_SMALL;
continue;
case DTM_COUNT :
method = next;
continue;
default :
continue;
}
case DTM_TABLE :
switch( method ) {
case DTM_DIRECT :
method = DTM_DIRECT_TABLE;
continue;
case DTM_COUNT :
method = next;
continue;
default :
continue;
}
case DTM_TABLE_SMALL :
switch( method ) {
case DTM_DIRECT :
method = DTM_DIRECT_SMALL;
continue;
case DTM_DIRECT_TABLE :
case DTM_TABLE :
method = DTM_TABLE_SMALL;
continue;
case DTM_COUNT :
method = next;
continue;
default :
continue;
}
}
break;
}
} else {
method = parseDtorMethod();
}
if( method != DTM_COUNT ) {
CompInfo.dt_method_speced = method;
CompFlags.dt_method_pragma = TRUE;
}
}
#ifndef NDEBUG
static void pragBreak()
{
__trap();
}
#endif
static boolean startPrag( char *id )
{
unsigned save;
// use this function when you want to immediately process macros
// after you recognize the pragma (PragRecog performs a NextToken
// so the pre-processing flag has to be set before PragRecog is called)
save = PPState;
PPState = PPS_EOL;
// NextToken inside of PragRecog will process macros on next token
if( PragRecog( id ) ) {
return( TRUE );
}
PPState = save;
return( FALSE );
}
// forms: (1) #pragma read_only_file
// (2) #pragma read_only_file "file"*
//
// (1) causes current file to be marked read-only
// (2) causes indicated file to be marked read-only
// - file must have started inclusion (may have completed)
//
static void pragReadOnlyFile
( void )
{
if( CurToken == T_STRING ) {
do {
SrcFileReadOnlyFile( Buffer );
NextToken();
if( CurToken == T_SEMI_COLON ) {
NextToken();
}
} while( CurToken == T_STRING );
} else {
SrcFileReadOnlyFile( NULL );
}
}
// form: #pragma read_only_directory "directory"*
//
// (1) causes all files within directory to be marked read-only
//
static void pragReadOnlyDir
( void )
{
while( CurToken == T_STRING ) {
SrcFileReadOnlyDir( Buffer );
NextToken();
if( CurToken == T_SEMI_COLON ) {
NextToken();
}
}
}
// form: #pragma once
//
// (1) current source file will never be #include'd again
static void pragOnce( void )
{
SrcFileOnceOnly();
}
static void pragLibs( // #PRAGMA library ( lib ... lib )
void )
{
if( CurToken == T_LEFT_PAREN ) {
NextToken();
while( PragIdCurToken() || CurToken == T_STRING ) {
CgInfoAddUserLib( Buffer );
NextToken();
}
MustRecog( T_RIGHT_PAREN );
} else {
CompFlags.pragma_library = 1;
}
}
// #pragma pack()
// #pragma pack( <number> )
// #pragma pack( pop )
// #pragma pack( push )
// #pragma pack( push, <number> )
static void pragPack( // #PRAGMA PACK
void )
{
if( CurToken == T_LEFT_PAREN ) {
PPState = PPS_EOL;
NextToken();
switch( CurToken ) {
case T_ID:
if( PragRecog( "pop" ) ) {
popPrag( &HeadPacks, &PackAmount );
MustRecog( T_RIGHT_PAREN );
} else if( PragRecog( "push" ) ) {
if( CurToken == T_RIGHT_PAREN ) {
pushPrag( &HeadPacks, PackAmount );
MustRecog( T_RIGHT_PAREN );
} else {
MustRecog( T_COMMA );
if( CurToken != T_CONSTANT ) {
MustRecog( T_CONSTANT );
} else {
pushPrag( &HeadPacks, PackAmount );
PackAmount = VerifyPackAmount( U32Fetch( Constant64 ) );
NextToken();
MustRecog( T_RIGHT_PAREN );
}
}
} else {
CErr( ERR_EXPECTING_BUT_FOUND, "pop", Buffer );
}
PPState = PPS_EOL | PPS_NO_EXPAND;
break;
case T_CONSTANT:
PackAmount = VerifyPackAmount( U32Fetch( Constant64 ) );
PPState = PPS_EOL | PPS_NO_EXPAND;
NextToken();
MustRecog( T_RIGHT_PAREN );
break;
case T_RIGHT_PAREN:
PPState = PPS_EOL | PPS_NO_EXPAND;
NextToken();
PackAmount = GblPackAmount;
break;
default:
PPState = PPS_EOL | PPS_NO_EXPAND;
MustRecog( T_RIGHT_PAREN );
}
}
}
void CPragma() // PROCESS A PRAGMA
{
boolean our_pragma; // - TRUE ==> one of ours
SrcFileGuardStateSig();
if( CompFlags.cpp_output ) {
if( ! CppPrinting() ) return;
fprintf( CppFile, "#pragma" );
PPState = PPS_EOL;
CompFlags.in_pragma = 1;
for(;;) {
GetNextToken();
if( CurToken == T_NULL ) break;
PrtToken();
}
CompFlags.in_pragma = 0;
} else {
our_pragma = FALSE;
NextToken();
for(;;) {
if( ! PragRecog( NULL ) ) break;
if( PragRecog( "on" ) ) {
pragFlag( 1 );
} else if( PragRecog( "off" ) ) {
pragFlag( 0 );
} else if( startPrag( "aux" ) || startPrag( "linkage" ) ) {
PragAux();
} else if( PragRecog( "library" ) ) {
pragLibs();
} else if( PragRecog( "once" ) ) {
pragOnce();
} else if( PragRecog( "extref" ) ) {
pragExtRef();
} else if( PragRecog( "comment" ) ) {
pragComment();
} else if( PragRecog( "pack" ) ) {
pragPack();
} else if( PragRecog( "warning" ) ) {
if( pragWarning() ) {
/* ignore #pragma warning */
break;
}
} else if( PragRecog( "code_seg" ) ) {
pragCodeSeg();
} else if( PragRecog( "data_seg" ) ) {
pragDataSeg();
} else if( PragRecog( "initialize" ) ) {
pragInitialize();
} else if( PragRecog( "init_seg" ) ) {
pragInitSeg();
} else if( PragRecog( "inline_depth" ) ) {
pragInlineDepth();
} else if( PragRecog( "template_depth" ) ) {
pragTemplateDepth();
} else if( PragRecog( "inline_recursion" ) ) {
pragInlineRecursion();
} else if( PragRecog( "intrinsic" ) ) {
pragIntrinsic( TRUE );
} else if( PragRecog( "function" ) ) {
pragIntrinsic( FALSE );
} else if( PragRecog( "destruct" ) ) {
pragDestruct();
} else if( PragRecog( "enum" ) ) {
pragEnum();
} else if( PragRecog( "dump_object_model" ) ) {
pragDumpObjectModel();
} else if( startPrag( "read_only_file" ) ) {
pragReadOnlyFile();
} else if( startPrag( "read_only_directory" ) ) {
pragReadOnlyDir();
} else if( PragRecog( "message" ) ) {
pragMessage();
} else if( PragRecog( "error" ) ) {
pragError();
#ifndef NDEBUG
} else if( PragRecog( "break" ) ) {
pragBreak();
#endif
} else {
break;
}
our_pragma = TRUE;
}
if( our_pragma ) {
endOfPragma();
}
}
}
void PragInit(
void )
{
WatcallInfo.use = 2;
CdeclInfo = WatcallInfo;
PascalInfo = WatcallInfo;
FortranInfo = WatcallInfo;
SyscallInfo = WatcallInfo;
OptlinkInfo = WatcallInfo;
StdcallInfo = WatcallInfo;
FastcallInfo = WatcallInfo;
CompInfo.init_priority = INIT_PRIORITY_PROGRAM;
}
typedef struct magic_word {
char *name;
struct aux_info *info;
} MAGIC_WORD;
#ifdef pick
#undef pick
#endif
#define pick( a, b, c ) { b , c },
static MAGIC_WORD magicWords[] = {
#include "auxinfo.h"
};
static int lookupMagicKeyword( // LOOKUP A MAGIC KEYWORD
char *name ) // - name to be looked up
{
int i;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?