type.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,314 行 · 第 1/5 页
C
2,314 行
parms = dinfo->parms;
cantHaveDefaultArgGaps( parms );
if( cantHaveDefaultArgs( err_msg, parms )){
removeDefaultArgs( parms );
}
}
void FreeArgsDefaultsOK( DECL_INFO * dinfo)
{
checkForMissingDefaultArgs( dinfo );
freeDeclList( &dinfo );
}
void FreeArgs( DECL_INFO *dinfo )
{
cantHaveDefaultArgGaps( dinfo );
cantHaveDefaultArgs( ERR_DEFAULT_ARGS_IN_A_TYPE, dinfo );
freeDeclList( &dinfo );
}
static boolean isVoid( TYPE type )
{
type = TypedefRemove( type );
if( type->id == TYP_VOID ) {
return( TRUE );
}
return( FALSE );
}
static TYPE *makeExceptionList( PTREE tree )
{
TYPE any_exception;
TYPE *vector;
TYPE *curr_type;
PTREE curr;
unsigned count;
any_exception = GetBasicType( TYP_DOT_DOT_DOT );
count = 0;
for( curr = tree; curr != NULL; curr = curr->u.type.next ) {
if( curr->type == any_exception ) {
return( NULL );
}
++count;
}
vector = CPermAlloc( ( count + 1 ) * sizeof( TYPE ) );
curr_type = vector;
for( curr = tree; curr != NULL; curr = curr->u.type.next ) {
*curr_type = curr->type;
++curr_type;
}
*curr_type = NULL;
return( vector );
}
static void abstractDiagnose( unsigned msg, TYPE type )
{
type = ArrayBaseType( type );
CErr2p( msg, type );
ScopeNotePureFunctions( type );
}
TYPE MakeFnType( DECL_INFO **arg_decls, specifier_t cv, PTREE exception_spec )
/****************************************************************************/
{
unsigned num_args;
unsigned void_args;
TYPE type;
TYPE fntype;
TYPE *currarg;
DECL_INFO *curr;
arg_list *args;
PTREE next;
num_args = 0;
void_args = 0;
RingIterBeg( *arg_decls, curr ) {
type = curr->type;
if( isVoid( type ) ) {
++void_args;
} else if( TypeAbstract( type ) ) {
abstractDiagnose( ERR_ARG_ABSTRACT_TYPE, type );
}
num_args++;
} RingIterEnd( curr )
if( num_args > 0 ) {
if( void_args > 0 ) {
if( num_args > 1 || void_args > 1 ) {
CErr1( ERR_NO_VOID_PARMS );
}
freeDeclList( arg_decls );
num_args = 0;
}
}
args = AllocArgListPerm( num_args );
// if cv includes more than const or volatile, fix default op= qualifiers
args->qualifier = convertCVSpec( cv );
args->except_spec = makeExceptionList( exception_spec );
for( ; exception_spec != NULL; exception_spec = next ) {
next = exception_spec->u.type.next;
PTreeFreeSubtrees( exception_spec );
}
currarg = args->type_list;
RingIterBeg( *arg_decls, curr ) {
*currarg = curr->type;
TypeStripTdMod( ( *currarg ) );
currarg++;
} RingIterEnd( curr )
fntype = MakeType( TYP_FUNCTION );
fntype->u.f.args = args;
return( fntype );
}
static TYPE buildFnType( TYPE ret_type, va_list count_args, va_list use_args )
{
TYPE arg_type;
TYPE fn_type;
TYPE *curr_arg;
arg_list *args;
unsigned arg_count;
arg_count = 0;
for(;;) {
arg_type = va_arg( count_args, TYPE );
if( arg_type == NULL ) break;
++arg_count;
}
va_end( count_args );
args = AllocArgListPerm( arg_count );
curr_arg = args->type_list;
for(;;) {
arg_type = va_arg( use_args, TYPE );
if( arg_type == NULL ) break;
*curr_arg = arg_type;
++curr_arg;
}
va_end( use_args );
fn_type = MakeType( TYP_FUNCTION );
fn_type->of = ret_type;
fn_type->flag |= TF1_PLUSPLUS;
fn_type->u.f.args = args;
return( fn_type );
}
TYPE MakeSimpleFunction( TYPE return_type, ... )
/**********************************************/
{
TYPE fn_type;
va_list args1;
va_list args2;
va_start( args1, return_type );
va_start( args2, return_type );
fn_type = buildFnType( return_type, args1, args2 );
return( CheckDupType( fn_type ) );
}
TYPE MakeModifiableFunction( TYPE return_type, ... )
/**************************************************/
{
TYPE fn_type;
va_list args1;
va_list args2;
va_start( args1, return_type );
va_start( args2, return_type );
fn_type = buildFnType( return_type, args1, args2 );
return( fn_type );
}
TYPE MakeTypeOf( // MAKE UNIQUE TYPE OF
TYPE new_type, // - a new type
TYPE of_type ) // - the (already unique) "of" type
{
new_type->of = of_type;
return( CheckDupType( new_type ) );
}
#ifndef NDEBUG
typedef struct {
unsigned long sum;
unsigned long max;
unsigned long chains;
} DUMP_STATS;
static void dumpStatsZero( // ZERO DUMP STATISTICS
DUMP_STATS *stats )
{
stats->sum = 0;
stats->max = 0;
stats->chains = 0;
}
static void dumpStats( // PRINT STATISTICS
DUMP_STATS *stats )
{
printf( "total types: %6u\n", stats->sum );
printf( "longest chain: %6u\n", stats->max );
printf( "average chain: %6u\n", stats->sum / stats->chains );
putchar( '\n' );
}
static TYPE* dumpTypeRing( // DUMP A TYPE RING
TYPE* ring,
DUMP_STATS *stats )
{
long length = 0;
TYPE curr;
++ stats->chains;
RingIterBeg( *ring, curr ) {
DumpType( curr );
++length;
} RingIterEnd( curr )
stats->sum += length;
if( length > stats->max ) {
stats->max = length;
}
putchar( '\n' );
return ring + 1;
}
static TYPE* dumpTypeVector( // DUMP VECTOR OF TYPE RINGS
TYPE* vector,
DUMP_STATS *stats,
const char* fmt )
{
int j;
for( j = 0; j < TYPE_HASH_MODULUS; ++j ) {
printf( fmt, j );
vector = dumpTypeRing( vector, stats );
putchar( '\n' );
}
return vector;
}
void dumpTypeTables( void )
{
DUMP_STATS stats;
int i;
TYPE *head;
dumpStatsZero( &stats );
head = &typeTable[0];
for( i = 0; i < TYP_MAX; ++i ) {
switch( i ) {
case TYP_POINTER :
dumpTypeVector( pointerHashTable
, &stats
, "pointer types %3d\n" );
break;
case TYP_BITFIELD :
dumpTypeVector( bitfieldHashTable
, &stats
, "bitfield types %3d\n" );
break;
case TYP_ARRAY :
dumpTypeVector( arrayHashTable
, &stats
, "array types %3d\n" );
break;
case TYP_MODIFIER :
dumpTypeVector( modifierHashTable
, &stats
, "modifier types %3d\n" );
break;
default :
printf( "type id %3d:\n", i );
head = dumpTypeRing( head, &stats );
break;
}
}
dumpStats( &stats );
dumpStatsZero( &stats );
head = &fnHashTable[0][0];
for( i = 0; i < ARGS_HASH; ++i ) {
char buf[32];
sprintf( buf, "args %3d %%3d:\n", i );
head = dumpTypeVector( head, &stats, buf );
}
head = &fnTable[0];
for( i = ARGS_HASH; i < ARGS_MAX; ++i ) {
printf( "args %3d:\n", i );
head = dumpTypeRing( head, &stats );
}
dumpStatsZero( &stats );
}
#endif
TYPE PTypeListOfTypes( type_id id )
/*********************************/
{
/* won't work for optimized search types (i.e., TYP_FUNCTION) */
return( typeTable[id] );
}
void PTypeSignedChar( void )
/**************************/
{
basicTypes[ TYP_CHAR ]->of = basicTypes[ TYP_SCHAR ];
}
static void initCacheAfterOptions( void )
{
TYPE void_type;
TYPE void_handler_fun_of_void;
void_type = GetBasicType( TYP_VOID );
void_handler_fun_of_void = MakeModifiableFunction( void_type, NULL );
void_handler_fun_of_void->u.f.pragma = GetTargetHandlerPragma();
void_handler_fun_of_void = CheckDupType( void_handler_fun_of_void );
TypeSetCache( TYPC_VOID_HANDLER_FUN_OF_VOID, void_handler_fun_of_void );
}
void PTypeCheckInit( void )
/*************************/
{
TYPE basic_type;
unsigned index;
// code that must execute after the command line options have been parsed
for( index = TYP_MIN; index < TYP_MAX; index++ ) {
basic_type = basicTypes[ index ];
if( basic_type != NULL ) {
basicTypes[ index ] = CheckDupType( basic_type );
}
}
initCacheAfterOptions();
if( IsBigCode() ) {
defaultFunctionMemFlag = TF1_FAR;
} else {
defaultFunctionMemFlag = TF1_NEAR;
}
if( IsHugeData() ) {
defaultDataMemFlag = TF1_HUGE;
} else if( IsBigData() ) {
defaultDataMemFlag = TF1_FAR;
} else {
defaultDataMemFlag = TF1_NEAR;
}
}
static type_id findTypeId( scalar_t scalar )
/******************************************/
{
switch( scalar ) {
case STM_BOOL:
return( TYP_BOOL );
case STM_CHAR:
return( TYP_CHAR );
case STM_CHAR | STM_SIGNED:
return( TYP_SCHAR );
case STM_CHAR | STM_UNSIGNED:
return( TYP_UCHAR );
case STM_SHORT:
return( TYP_SSHORT );
case STM_SHORT | STM_INT:
return( TYP_SSHORT );
case STM_SHORT | STM_SIGNED:
return( TYP_SSHORT );
case STM_SHORT | STM_SIGNED | STM_INT:
return( TYP_SSHORT );
case STM_SHORT | STM_UNSIGNED:
return( TYP_USHORT );
case STM_SHORT | STM_UNSIGNED | STM_INT:
return( TYP_USHORT );
case STM_SIGNED:
return( TYP_SINT );
case STM_INT:
return( TYP_SINT );
case STM_INT | STM_SIGNED:
return( TYP_SINT );
case STM_INT | STM_UNSIGNED:
return( TYP_UINT );
case STM_UNSIGNED:
return( TYP_UINT );
case STM_LONG:
return( TYP_SLONG );
case STM_LONG | STM_SIGNED:
return( TYP_SLONG );
case STM_LONG | STM_UNSIGNED:
return( TYP_ULONG );
case STM_LONG | STM_INT:
return( TYP_SLONG );
case STM_LONG | STM_INT | STM_SIGNED:
return( TYP_SLONG );
case STM_LONG | STM_INT | STM_UNSIGNED:
return( TYP_ULONG );
case STM_INT64:
return( TYP_SLONG64 );
case STM_INT64 | STM_SIGNED:
return( TYP_SLONG64 );
case STM_INT64 | STM_UNSIGNED:
return( TYP_ULONG64 );
case STM_INT64 | STM_INT:
return( TYP_SLONG64 );
case STM_INT64 | STM_INT | STM_SIGNED:
return( TYP_SLONG64 );
case STM_INT64 | STM_INT | STM_UNSIGNED:
return( TYP_ULONG64 );
case STM_FLOAT:
return( TYP_FLOAT );
case STM_DOUBLE:
return( TYP_DOUBLE );
case STM_VOID:
return( TYP_VOID );
case STM_LONG | STM_DOUBLE:
return( TYP_LONG_DOUBLE );
case STM_LONG | STM_CHAR:
return( TYP_WCHAR );
case STM_SEGMENT:
return( TYP_USHORT );
default:
return( TYP_MAX );
}
}
static TYPE findScalarType( DECL_SPEC *dspec )
{
scalar_t scalar;
TYPE type;
if( dspec->is_default ) {
type = TypeGetCache( TYPC_DEFAULT_INT );
} else {
scalar = dspec->scalar;
switch( scalar ) {
case STM_NULL:
type = TypeGetCache( TYPC_DEFAULT_INT );
break;
case STM_INT:
type = TypeGetCache( TYPC_CLEAN_INT );
break;
case STM_SEGMENT:
type = TypeGetCache( TYPC_SEGMENT_SHORT );
break;
default:
type = GetBasicType( findTypeId( scalar ) );
}
}
return( type );
}
static void figureOutStgClass( DECL_SPEC *dspec )
{
if( dspec->linkage != NULL && dspec->stg_class == STG_NULL ) {
dspec->stg_class = STG_EXTERN;
}
}
static void figureOutDSpec( DECL_SPEC *dspec )
{
specifier_t specs;
type_flag cv_flags;
if( dspec->decl_checked ) return;
figureOutStgClass( dspec );
if( dspec->partial == NULL ) {
dspec->partial = findScalarType( dspec );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?