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