⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecl2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    parms = NULL;
    if( CurToken != T_RIGHT_PAREN ) {
        parm_list = ParmList;
        ParmList = NULL;
        parms = FuncProtoType();
        if( parms == NULL  &&  ParmList != NULL ) {
            if( CurToken == T_SEMI_COLON || CurToken == T_COMMA ) {
                /* int f16(i,j); */
                CErr1( ERR_ID_LIST_SHOULD_BE_EMPTY );
            }
        }
        if( parm_list != NULL )  {
            FreeParmList();
            ParmList = parm_list;
        }
    } else {
        NextToken();    /* skip over ')' */
    }
    if( typ != NULL ) {                                 /* 09-apr-90 */
        TYPEPTR typ2;

        typ2 = typ;                                     /* 08-dec-93 */
        while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
        if( typ2->decl_type == TYPE_ARRAY ) {
            CErr1( ERR_FUNCTION_CANT_RETURN_AN_ARRAY );
        } else if( typ2->decl_type == TYPE_FUNCTION ) {
            CErr1( ERR_FUNCTION_CANT_RETURN_A_FUNCTION );
        }
    }
    typ = FuncNode( typ, mod, parms );
    return( typ );
}


static TYPEPTR DeclPart2( TYPEPTR typ, type_modifiers mod )
{
    if( CurToken == T_LEFT_PAREN ) {
        NextToken();
        typ = DeclPart3( typ, mod );
    }
    for(;;) {
        if( CurToken == T_LEFT_BRACKET ) {
            typ = ArrayDecl( typ );
        }
        if( CurToken != T_LEFT_PAREN ) break;
        NextToken();
        typ = DeclPart3( typ, mod );
    }
    return( typ );
}


local void CheckUniqueName( PARMPTR parm, char *name )  /* 13-apr-89 */
{
    if( name != NULL ) {                                /* 29-oct-91 */
        if( *name != '\0' ) {
            for( ; parm ; parm = parm->next_parm ) {
                if( parm->sym.name != NULL ) {          /* 16-oct-92 */
                    if( strcmp( parm->sym.name, name ) == 0 ) {
                        CErr2p( ERR_SYM_ALREADY_DEFINED, name );
                        parm->sym.flags |= SYM_REFERENCED;
                    }
                }
            }
        }
    }
}


struct parm_list *NewParm( TYPEPTR typ, struct parm_list *prev_parm )
{
    struct parm_list *parm;

    parm = (struct parm_list *)CMemAlloc( sizeof( struct parm_list ) );
    parm->parm_type = typ;
    parm->next_parm = prev_parm;
    return( parm );
}


void AdjParmType( SYMPTR sym )
{
    TYPEPTR     typ;

    typ = sym->sym_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    if( typ->decl_type == TYPE_FUNCTION ) {
        sym->sym_type = PtrNode( sym->sym_type, sym->attrib, SEG_CODE );
        sym->attrib = FLAG_NONE;
    } else if( typ->decl_type == TYPE_ARRAY ) {
        sym->sym_type = PtrNode( typ->object,
                        FLAG_WAS_ARRAY | sym->attrib,
                       SEG_DATA );
        sym->attrib = FLAG_NONE;
    }
}


local TYPEPTR *GetProtoType( decl_info *first )
{
    PARMPTR     parm;
    PARMPTR     prev_parm = NULL;
    PARMPTR     parm_namelist;
    int         parm_count;
    struct parm_list *parmlist;
    decl_state        state;
    declspec_class   declspec;
    stg_classes      stg_class;
    type_modifiers    mod;
    TYPEPTR          typ;
    decl_info        info;

    parm_count = 0;
    parmlist = NULL;
    parm_namelist = NULL;
    info = *first;
    for(;;) {
        SYMPTR           sym; // parm sym

        stg_class = info.stg;
        declspec  = info.decl;
        typ = info.typ;
        mod = info.mod;
        if( stg_class != SC_NULL  &&  stg_class != SC_REGISTER ) {
            CErr1( ERR_INVALID_STG_CLASS_FOR_PARM_PROTO );
        }
        state = DECL_STATE_ISPARM;
        if( typ == NULL ) {
            state |= DECL_STATE_NOTYPE;
            if( stg_class == SC_NULL ) {                /* 30-nov-94 */
                CErr1( ERR_TYPE_REQUIRED_IN_PARM_LIST );
            }
            typ = TypeDefault();
        }
        parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
        parm->next_parm = NULL;
        sym = &parm->sym;
        memset( sym, 0, sizeof( SYM_ENTRY ) );              /* 02-apr-91 */
        sym->name = "";
        Declarator( sym, mod, typ, state );
        typ = sym->sym_type;
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_VOID ) {
            char buffer[20];
            char *name;
            if( sym->name[0] == '\0' ) {
                sprintf( buffer, "Parm %d", parm_count );
                name = buffer;
            }else{
                name = sym->name;
            }
            CErr2p( ERR_VAR_CANT_BE_VOID, name );
            sym->sym_type = TypeDefault();
        }
        if( stg_class == SC_NULL ) {
            stg_class = SCSpecifier();                  /* 17-mar-91 */
            if( stg_class == SC_NULL )  stg_class = SC_AUTO;
        }
        sym->stg_class = stg_class;
        AdjParmType( sym );
        parmlist = NewParm( sym->sym_type, parmlist );
        if( parm_count == 0 ) {
            parm_namelist = parm;
        } else {
            CheckUniqueName( parm_namelist, sym->name );
            prev_parm->next_parm = parm;
        }
        if( (Toggles & TOGGLE_UNREFERENCED) == 0 ) {
            sym->flags |= SYM_REFERENCED;
        }
        ++parm_count;
        if( CurToken == T_RIGHT_PAREN ) break;
        if( CurToken == T_EOF  ||  CurToken == T_LEFT_BRACE )  break;
        MustRecog( T_COMMA );
        if( CurToken == T_DOT_DOT_DOT ) {
            typ = GetType( TYPE_DOT_DOT_DOT );
            parmlist = NewParm( typ, parmlist );
            NextToken();
            break;
        }
        prev_parm = parm;
        FullDeclSpecifier( &info );
    }
    ParmList = parm_namelist;
        /* if void is specified as a parm, it is the only parm allowed */
    return( MakeParmList( parmlist, parm_count, 0 ) );
}


TYPEPTR *MakeParmList( struct parm_list *parm, int parm_count, int reversed )
{
    TYPEPTR     *type_list;
    struct parm_list *next_parm, *prev_parm;
    TYPEPTR     typ;
    int         index;

    type_list = NULL;
    if( parm != NULL ) {
        if( ! reversed ) {
            prev_parm = NULL;
            for(;;) {
                next_parm = parm->next_parm;
                parm->next_parm = prev_parm;
                if( next_parm == NULL ) break;
                prev_parm = parm;
                parm = next_parm;
            }
        }
        parm_count = 0;
        next_parm = parm;
        while( next_parm != NULL ) {
            ++parm_count;
            next_parm = next_parm->next_parm;
        }

        /* try to find an existing parm list that matches, 29-dec-88 */

        index = parm_count;
        if( index > MAX_PARM_LIST_HASH_SIZE ) {
            index = MAX_PARM_LIST_HASH_SIZE;
        }
        for( typ = FuncTypeHead[ index ]; typ; typ = typ->next_type ) {
            type_list = typ->u.parms;
            next_parm = parm;
            for(;;) {
                if( next_parm == NULL ) {
                    if( *type_list != NULL ) break;
                    while( parm != NULL ) {
                        next_parm = parm->next_parm;
                        CMemFree( parm );
                        parm = next_parm;
                    }
                    return( typ->u.parms );
                }
                if( next_parm->parm_type != *type_list ) break;
                next_parm = next_parm->next_parm;
                ++type_list;
            }
        }

        type_list = (TYPEPTR *)CPermAlloc( (parm_count+1)*sizeof(TYPEPTR));
        if( type_list != NULL ) {
            type_list[ parm_count ] = NULL;
            parm_count = 0;
            while( parm != NULL ) {
                type_list[ parm_count ] = parm->parm_type;
                next_parm = parm->next_parm;
                CMemFree( parm );
                parm = next_parm;
                ++parm_count;
            }
        }
    }
    return( type_list );
}

local int VoidType( TYPEPTR typ )                       /* 03-oct-91 */
{
    if( typ != NULL ) {
        while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
        if( typ->decl_type == TYPE_VOID )  return( 1 );
    }
    return( 0 );
}

local TYPEPTR *FuncProtoType()
{
    TYPEPTR             *type_list;
    TAGPTR              old_taghead;
    decl_info           info;

    if( !CompFlags.extensions_enabled ) ++SymLevel; /* 03-may-89 */
    old_taghead = TagHead;
    FullDeclSpecifier( &info );
    if( info.stg == SC_NULL  &&  info.typ == NULL ) {
        GetFuncParmList();
        if( CurToken == T_RIGHT_PAREN ) {
            NextToken();
        } else {
            Expecting( ")" );                               /* 24-mar-91 */
        }
        type_list = NULL;
    } else {    /* function prototype present */
        if( VoidType( info.typ )  &&  /*27-dec-88*/
            info.stg== SC_NULL  &&  CurToken == T_RIGHT_PAREN ) {
            type_list = VoidParmList;
        } else {
            type_list = GetProtoType(  &info );
        }
        if( CurToken == T_RIGHT_PAREN ) {
            NextToken();
        } else {
            Expecting( ")" );                       /* 24-mar-91 */
        }
        if( CurToken != T_LEFT_BRACE ) {                /* 18-jan-89 */
            if( SymLevel > 1  ||                        /* 03-dec-90 */
            ! CompFlags.extensions_enabled ) {  /* 25-jul-91 */
            /* get rid of any new tags regardless of SymLevel;  23-jul-90 */
                TagHead = old_taghead;  /* get rid of new tags from proto */
                FreeEnums();                    /* 03-may-89 */
            }
        }
    }
    if( !CompFlags.extensions_enabled ) --SymLevel; /* 03-may-89 */
    return( type_list );
}


local void GetFuncParmList( void )
{
    PARMPTR     parm = NULL;
    PARMPTR     newparm;
    PARMPTR     parm_namelist;

    parm_namelist = NULL;
    while( CurToken == T_ID ) { /* scan off func parm list */
        if( parm_namelist == NULL ) {
            parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
            SymCreate( &parm->sym, Buffer );
            parm_namelist = parm;
        } else {
            newparm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
            SymCreate( &newparm->sym, Buffer );
            CheckUniqueName( parm_namelist, Buffer );
            parm->next_parm = newparm;
            parm = newparm;
        }
        parm->sym.info.hash_value = HashValue;
        if( (Toggles & TOGGLE_UNREFERENCED) == 0 ) {
            parm->sym.flags |= SYM_REFERENCED;
        }
        NextToken();
        if( CurToken == T_RIGHT_PAREN ) break;
        if( CurToken == T_EOF ) break;
        if( CurToken != T_COMMA ) {     /* 04-jan-89 */
            MustRecog( T_COMMA );               /* forces error msg */
            for(;;) {   /* skip until ')' to avoid cascading errors */
                if( CurToken == T_RIGHT_PAREN ) break;
                if( CurToken == T_EOF ) break;
                NextToken();
            }
            break;
        }
        MustRecog( T_COMMA );
        if( CurToken == T_DOT_DOT_DOT ) {
            parm->next_parm = (PARMPTR) CMemAlloc( sizeof( PARM_ENTRY ) );
            parm = parm->next_parm;
            SymCreate( &parm->sym, "" );
            /* set flags so we don't give funny error messages */
            parm->sym.flags |= SYM_TEMP | SYM_ASSIGNED | SYM_REFERENCED;
            NextToken();
            break;
        }
    }
    ParmList = parm_namelist;
}


local void FreeParmList( void )
{
    PARMPTR     parm;

    for( ; (parm = ParmList); ) {
        ParmList = parm->next_parm;
        CMemFree( parm->sym.name );
        CMemFree( parm );
    }
}

#if _CPU == 370
local bool IsIntComp( TYPEPTR ret1 )
    /*
     * what's target compatible between default int as ret type
     * and a later declaration
     */
{
    bool        ret;

    while( ret1->decl_type == TYPE_TYPEDEF ) ret1 = ret1->object;
    switch( ret1->decl_type ) {
    case TYPE_CHAR:
    case TYPE_UCHAR:
    case TYPE_SHORT:
    case TYPE_USHORT:
    case TYPE_INT:
    case  TYPE_LONG:
        ret = TRUE;
        break;
    default:
       ret = FALSE;
    }
    return( ret );
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -