cdecl1.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 573 行 · 第 1/2 页

C
573
字号
        if( info.stg != SC_NULL  &&  info.stg != SC_REGISTER ) {
            CErr1( ERR_INVALID_STG_CLASS_FOR_PARM );
            info.stg = SC_NULL;
        }
        state = DECL_STATE_NONE;
        typ = info.typ;
        if( typ == NULL ) {
            state |= DECL_STATE_NOTYPE;
            typ = TypeDefault();
        }
        if( info.stg == SC_NULL )
            info.stg = SC_AUTO;

        for( ;; ) {
            if( CurToken == T_SEMI_COLON ) {
                Chk_Struct_Union_Enum( typ );
            } else {
                sym.name = NULL;                        /* 04-oct-91 */
                Declarator( &sym, info.mod, typ, state );
                if( sym.name == NULL  ||  sym.name[0] == '\0' ) {
                    InvDecl();
                } else {
                    for( parm = ParmList; parm; ) {
                        if( parm->sym.name != NULL ) {  /* 03-may-93 */
                            if( strcmp( parm->sym.name, sym.name ) == 0 ) {
                                break;
                            }
                        }
                        parm = parm->next_parm;
                    }
                    if( parm == NULL ) {
                        CErr2p( ERR_SYM_NOT_IN_PARM_LIST, sym.name );
                    } else if( parm->sym.sym_type != NULL ) {
                        CErr2p( ERR_PARM_ALREADY_DECLARED, sym.name );
                    } else {
                        ArgPromotion( &sym );
                        parm->sym.sym_type = sym.sym_type;
                        parm->sym.stg_class = info.stg;
                    }
                }
                CMemFree( sym.name );
            }

            if( CurToken == T_SEMI_COLON ) {
                NextToken();
                break;
            }
            if( CurToken == T_LEFT_BRACE ) {
                CErr1( ERR_MISSING_SEMICOLON );
                break;
            }
            if( CurToken == T_EOF )
                return;
            MustRecog( T_COMMA );
        }
    }
    ReverseParms();
    if( CurFunc->sym_type->u.fn.parms == NULL ) {
        CurFunc->flags |= SYM_OLD_STYLE_FUNC;   /* 13-sep-89 */
        AddParms();
    } else {
        ChkParms();
    }
    ParmList = NULL;
    if( VarParm( CurFunc ) ) {
        CurFunc->flags &= ~ SYM_OK_TO_RECURSE;  /* 25-sep-91 */
    }
}


local void ReverseParms( void )       /* reverse order of parms */
{
    PARMPTR     prev_parm, parm, next_parm;

    if( ParmsToBeReversed( CurFunc->attrib, NULL ) ) {
        prev_parm = NULL;
        parm = ParmList;
        while( parm != NULL ) {
            next_parm = parm->next_parm;
            parm->next_parm = prev_parm;
            prev_parm = parm;
            parm = next_parm;
        }
        ParmList = prev_parm;
    }
}


local void ChkProtoType( void )
{
    TYPEPTR     ret1;
    TYPEPTR     ret2;
    TYPEPTR     typ1;
    TYPEPTR     typ2;

    typ1 = CurFunc->sym_type;
    SKIP_TYPEDEFS( typ1 );
    ret1 = typ1->object;
    typ2 = PrevProtoType;
    SKIP_TYPEDEFS( typ2 );
    ret2 = typ2->object;
    typ1->object = NULL;
    typ2->object = NULL;
    VerifyType( CurFunc->sym_type, PrevProtoType, CurFunc );
    typ1->object = ret1;
    typ2->object = ret2;
}


local void AddParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle = 0;
    SYM_HANDLE          new_sym_handle;
    TYPEPTR             typ = NULL;
    int                 parm_count;
    int                 hash;
    struct parm_list    *parmlist;
    SYM_ENTRY           new_sym;

    CurFunc->u.func.locals = 0;
    CurFunc->u.func.parms = 0;
    parm = ParmList;
    parmlist = NULL;
    parm_count = 0;
    prev_parm = NULL;
    while( parm != NULL ) {
        new_sym_handle = 0;
        parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
        parm->sym.is_parm = TRUE;
        hash = parm->sym.info.hash_value;
        if( parm->sym.name[0] == '\0' ) {
            /* no name ==> ... */
            parm->sym.sym_type = GetType( TYPE_DOT_DOT_DOT );
            parm->sym.stg_class = SC_AUTO;
        } else if( parm->sym.sym_type == NULL ) {
            parm->sym.sym_type = TypeDefault();
            parm->sym.stg_class = SC_AUTO;
        } else {
/*
        go through ParmList again, looking for FLOAT parms
        change the name to ".P" and duplicate the symbol with type
        float and generate an assignment statement.
*/
            typ = parm->sym.sym_type;
            SKIP_TYPEDEFS( typ );

            switch( typ->decl_type ) {
            case TYPE_CHAR:
            case TYPE_UCHAR:
            case TYPE_SHORT:
                if( CompFlags.strict_ANSI ) {
                    parm->sym.sym_type = GetType( TYPE_INT );
                }
                break;

            case TYPE_USHORT:
                if( CompFlags.strict_ANSI ) {
#if TARGET_SHORT == TARGET_INT
                    parm->sym.sym_type = GetType( TYPE_UINT );
#else
                    parm->sym.sym_type = GetType( TYPE_INT );
#endif
                }
                break;

            case TYPE_FLOAT:
                memcpy( &new_sym, &parm->sym, sizeof(SYM_ENTRY) );
                new_sym.handle = CurFunc->u.func.locals;
                new_sym_handle = SymAdd( hash, &new_sym );
                CurFunc->u.func.locals = new_sym_handle;
                SymReplace( &new_sym, new_sym_handle );
                parm->sym.name = ".P";
                parm->sym.flags |= SYM_REFERENCED;      /* 24-nov-89 */
                parm->sym.sym_type = GetType( TYPE_DOUBLE );
                break;

            default:
                break;
            }
        }
        sym_handle = SymAdd( hash, &parm->sym );
        if( new_sym_handle != 0 ) {
            TREEPTR         tree;

            tree = ExprNode( VarLeaf( &new_sym, new_sym_handle ),
                 OPR_EQUALS, RValue( VarLeaf(&parm->sym, sym_handle) ) );
            tree->op.result_type = typ;
            tree->expr_type = typ;
            AddStmt( tree );
        }

        if( prev_parm == NULL ) {
            CurFunc->u.func.parms = sym_handle;
        } else {
            prev_parm->sym.handle = sym_handle;
            SymReplace( &prev_parm->sym, prev_sym_handle );
            CMemFree( prev_parm );
        }
        prev_parm = parm;
        prev_sym_handle = sym_handle;
        ++parm_count;
        parmlist = NewParm( parm->sym.sym_type, parmlist );
        parm = parm->next_parm;
    }
    if( prev_parm != NULL ) {
        prev_parm->sym.handle = 0;
        SymReplace( &prev_parm->sym, prev_sym_handle );
        CMemFree( prev_parm );
    }
    typ = CurFunc->sym_type;
    // TODO not following my scheme
    CurFunc->sym_type = FuncNode( typ->object, FLAG_NONE,
        MakeParmList( parmlist, parm_count,
        ParmsToBeReversed( CurFunc->attrib, NULL ) ) );

    if( PrevProtoType != NULL ) {                       /* 12-may-91 */
        ChkProtoType();
    }
}


local void ChkParms( void )
{
    PARMPTR             parm;
    PARMPTR             prev_parm;
    SYM_HANDLE          sym_handle;
    SYM_HANDLE          prev_sym_handle = 0;
    TYPEPTR             typ;

    CurFunc->u.func.locals = 0;
    CurFunc->u.func.parms  = 0;
    parm = ParmList;
    prev_parm = NULL;
    typ = *(CurFunc->sym_type->u.fn.parms);
    SKIP_TYPEDEFS( typ );
    if( typ->decl_type != TYPE_VOID ) {
        while( parm != NULL ) {
            if( parm->sym.name == NULL ) {              /* 03-may-93 */
                parm->sym.name = ".J";
                parm->sym.flags |= SYM_REFERENCED;
            }
            if( parm->sym.name[0] == '\0' ) {
                parm->sym.name = ".I";
                InvDecl();
            }
            if( parm->sym.sym_type == NULL ) {
                parm->sym.sym_type = TypeDefault();
            }
            /* make sure name not already defined in this SymLevel */
            sym_handle = SymAdd( parm->sym.info.hash_value, &parm->sym );
            if( prev_parm == NULL ) {
                CurFunc->u.func.parms = sym_handle;
            } else {
                prev_parm->sym.handle = sym_handle;
                SymReplace( &prev_parm->sym, prev_sym_handle );
                CMemFree( prev_parm );
            }
            prev_parm = parm;
            prev_sym_handle = sym_handle;
            parm->sym.flags |= SYM_DEFINED | SYM_ASSIGNED;
            parm->sym.is_parm = TRUE;
            parm = parm->next_parm;
        }
        if( prev_parm != NULL ) {
#if _CPU == 370                     /* 24-oct-91 */
            {
                SYM_ENTRY   var_parm;

                if( VarParm( CurFunc ) ) {
                    typ = ArrayNode( GetType( TYPE_CHAR ) );
                    typ->u.array->dimension = 160;
                    sym_handle = GetNewSym( &var_parm, 'V', typ, SC_AUTO );
                    SymReplace( &var_parm, sym_handle );
                    prev_parm->sym.handle = sym_handle;
                }
            }
#endif
            SymReplace( &prev_parm->sym, prev_sym_handle );
            CMemFree( prev_parm );
        }
    }
}

⌨️ 快捷键说明

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