local void CIfDef( void ) { MEPTR mentry; PPNextToken(); if( CurToken != T_ID ) { ExpectIdentifier(); IncLevel( 0 ); return; } mentry = MacroLookup( Buffer ); if( mentry != NULL ) { mentry->macro_flags |= MFLAG_REFERENCED; IncLevel( 1 ); } else { IncLevel( 0 ); } PPNextToken(); ChkEOL(); }
TYPEPTR EnumDecl( int flags ) { TYPEPTR typ; TAGPTR tag; flags = flags; NextToken(); if( CurToken == T_ID ) { /* could be: (1) "enum" <id> ";" (2) "enum" <id> <variable_name> ";" (3) "enum" <id> "{" <enum_const_decl> ... "}" */ tag = TagLookup(); NextToken(); if( CurToken != T_LEFT_BRACE ) { typ = tag->sym_type; if( typ == NULL ) { CErr1( ERR_INCOMPLETE_ENUM_DECL ); typ = TypeDefault(); } else { if( typ->decl_type != TYPE_ENUM ) { /* 18-jan-89 */ CErr2p( ERR_DUPLICATE_TAG, tag->name ); } typ->u.tag = tag; } return( typ ); } tag = VfyNewTag( tag, TYPE_ENUM ); } else { tag = NullTag(); } typ = TypeNode( TYPE_ENUM, GetType( TYPE_INT ) ); typ->u.tag = tag; tag->sym_type = typ; tag->size = TARGET_INT; tag->u.enum_list = NULL; if( CurToken == T_LEFT_BRACE ) { const_val val; enum enum_rng index; enum enum_rng const_index; enum enum_rng start_index; enum enum_rng step; enum enum_rng error; uint64 n; uint64 Inc; bool minus; bool has_sign; ENUMPTR *prev_lnk; ENUMPTR esym; source_loc error_loc; char buff[50]; if( CompFlags.make_enums_an_int ) { start_index = ENUM_INT; } else { start_index = ENUM_S8; } const_index = ENUM_UNDEF; NextToken(); if( CurToken == T_RIGHT_BRACE ) { CErr1( ERR_EMPTY_ENUM_LIST ); } U32ToU64( 1, &Inc ); U64Clear( n ); minus = FALSE; has_sign = FALSE; step = 1; prev_lnk = &esym; esym = NULL; while( CurToken == T_ID ) { esym = EnumLkAdd( tag ); *prev_lnk = esym; prev_lnk = &esym->thread; error_loc = TokenLoc; NextToken(); if( CurToken == T_EQUAL ) { NextToken(); error_loc = TokenLoc; ConstExprAndType( &val ); switch( val.type ){ case TYPE_ULONG: case TYPE_UINT: case TYPE_ULONG64: minus = FALSE; break; default: if( val.value.u.sign.v ) { minus = TRUE; step = 2; } else { minus = FALSE; } break; } n = val.value; } else if( has_sign ) { if( n.u.sign.v ) { minus = TRUE; } else { minus = FALSE; } } for( index = start_index; index < ENUM_SIZE; index += step ) { if( minus ) { if( I64Cmp( &n, &( RangeTable[ index ][LOW] ) ) >= 0 ) break; } else { if( U64Cmp( &n, &( RangeTable[ index ][HIGH]) ) <= 0 ) break; } } error = ENUM_UNDEF; if( !CompFlags.extensions_enabled && ( index > ENUM_INT )) { error = ENUM_INT; } if( index >= ENUM_SIZE ) { // overflow signed maximum range if( error == ENUM_UNDEF ) { error = const_index; } } else if(( const_index == ENUM_SIZE - 1 ) && minus ) { // overflow unsigned maximum range by any negative signed value if( error == ENUM_UNDEF ) error = const_index; step = 1; } else { if( !has_sign && minus) { has_sign = TRUE; if( index < const_index ) { // round up to signed index = ( const_index + 1 ) & ~1; } } if( index > const_index ) { const_index = index; typ->object = GetType( ItypeTable[const_index].decl_type ); tag->size = ItypeTable[const_index].size; } } if( error != ENUM_UNDEF ) { SetErrLoc( &error_loc ); get_msg_range( buff, error ); CErr2p( ERR_ENUM_CONSTANT_OUT_OF_RANGE, buff ); InitErrLoc(); } esym->value = n; EnumTable[ esym->hash ] = esym; /* 08-nov-94 */ if( CurToken == T_RIGHT_BRACE ) break; U64Add( &n, &Inc, &n ); MustRecog( T_COMMA ); if( !CompFlags.extensions_enabled && !CompFlags.c99_extensions && ( CurToken == T_RIGHT_BRACE )) { ExpectIdentifier(); /* 13-may-91 */ } } MustRecog( T_RIGHT_BRACE ); } return( typ ); }
local void CDefine( void ) { struct macro_parm *mp, *prev_mp, *formal_parms; int parm_cnt, parm_end = 0; int ppscan_mode; char *token_buf; source_loc macro_loc; PPNextToken(); if( CurToken != T_ID ) { ExpectIdentifier(); return; } if( strcmp( Buffer, "defined" ) == 0 ) { CErr1( ERR_CANT_DEFINE_DEFINED ); return; } token_buf = CStrSave( Buffer ); formal_parms = NULL; macro_loc = SrcFileLoc; parm_cnt = -1; /* -1 ==> no () following */ if( CurrChar == '(' ) { /* parms present */ PPNextToken(); /* grab the '(' */ PPNextToken(); parm_cnt = 0; /* 0 ==> () following */ parm_end = 0; prev_mp = NULL; for( ;; ) { if( CurToken == T_RIGHT_PAREN ) break; if( parm_end ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } ++parm_cnt; if( CurToken == T_DOT_DOT_DOT ) { parm_end = 1; /* can have no more parms after this. */ } mp = (struct macro_parm *)CMemAlloc( sizeof( struct macro_parm ) ); if( formal_parms == NULL ) { formal_parms = mp; } else { if( FormalParm( formal_parms ) ) { CErr2p( ERR_DUPLICATE_MACRO_PARM, Buffer ); } prev_mp->next_macro_parm = mp; } if( CurToken == T_DOT_DOT_DOT ) mp->parm = CStrSave( "__VA_ARGS__" ); else mp->parm = CStrSave( Buffer ); prev_mp = mp; PPNextToken(); if( CurToken == T_RIGHT_PAREN ) break; if( CurToken == T_NULL ) { CErr1( ERR_INVALID_MACRO_DEFN ); break; } if( parm_end ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } MustRecog( T_COMMA ); if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } } } /* grab replacement tokens */ ppscan_mode = InitPPScan(); // enable T_PPNUMBER tokens GrabTokens( parm_end ? -(parm_cnt + 1) : (parm_cnt + 1), formal_parms, token_buf, ¯o_loc ); FiniPPScan( ppscan_mode ); // disable T_PPNUMBER tokens for( ; (mp = formal_parms) != NULL; ) { formal_parms = mp->next_macro_parm; CMemFree( mp->parm ); CMemFree( mp ); } CMemFree( token_buf ); }
static void CDefine( void ) { MPPTR mp; MPPTR prev_mp; MPPTR formal_parms; mac_parm_count parm_count; macro_flags mflags; bool ppscan_mode; char *token_buf; source_loc macro_loc; PPNextToken(); if( CurToken != T_ID ) { ExpectIdentifier(); return; } if( CMPLIT( Buffer, "defined" ) == 0 ) { CErr1( ERR_CANT_DEFINE_DEFINED ); return; } token_buf = CStrSave( Buffer ); formal_parms = NULL; macro_loc = SrcFileLoc; parm_count = 0; /* 0 ==> no () following */ mflags = MFLAG_USER_DEFINED; if( CurrChar == '(' ) { /* parms present */ PPNextToken(); /* grab the '(' */ PPNextToken(); parm_count = 1; /* 1 ==> () following */ prev_mp = NULL; for( ; CurToken != T_RIGHT_PAREN; ) { if( mflags & MFLAG_VAR_ARGS ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } ++parm_count; if( CurToken == T_DOT_DOT_DOT ) { mflags |= MFLAG_VAR_ARGS; /* can have no more parms after this. */ } mp = (MPPTR)CMemAlloc( sizeof( MPDEFN ) ); if( formal_parms == NULL ) { formal_parms = mp; } else { if( FormalParm( formal_parms ) ) { CErr2p( ERR_DUPLICATE_MACRO_PARM, Buffer ); } prev_mp->next = mp; } if( CurToken == T_DOT_DOT_DOT ) { mp->parm = CStrSave( "__VA_ARGS__" ); } else { mp->parm = CStrSave( Buffer ); } prev_mp = mp; PPNextToken(); if( CurToken == T_RIGHT_PAREN ) break; if( CurToken == T_NULL ) { CErr1( ERR_INVALID_MACRO_DEFN ); break; } if( mflags & MFLAG_VAR_ARGS ) { ExpectingAfter( T_RIGHT_PAREN, T_DOT_DOT_DOT ); return; } MustRecog( T_COMMA ); if( CurToken != T_DOT_DOT_DOT && !ExpectingToken( T_ID ) ) { return; } } } /* grab replacement tokens */ ppscan_mode = InitPPScan(); // enable T_PPNUMBER tokens GrabTokens( parm_count, mflags, formal_parms, token_buf, ¯o_loc ); FiniPPScan( ppscan_mode ); // disable T_PPNUMBER tokens for( ; (mp = formal_parms) != NULL; ) { formal_parms = mp->next; CMemFree( mp->parm ); CMemFree( mp ); } CMemFree( token_buf ); }