cpsubpgm.c

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

C
561
字号
                sym->ns.flags |= SY_USAGE | SY_SUBPROGRAM | SY_SENTRY |
                                     SY_SUBROUTINE | SY_REFERENCED;
            } else {
                sym->ns.flags |= SY_USAGE | SY_SUBPROGRAM | SY_SENTRY |
                                     SY_FUNCTION;
            }
            STFnShadow( sym );
            entry = AddEntryPt( sym );
            AdvanceITPtr();
            if( Options & OPT_TRACE ) {
                GSetSrcLine();
            }
            if( RecOpenParen() ) {
                ParmList( in_subr, entry );
                ReqCloseParen();
                ReqNOpn();
                AdvanceITPtr();
            }
            BIStartRBorEP( sym );
            ReqEOS();
        }
    }
    SgmtSw &= ~SG_PROLOG_DONE;       // indicate we need prologue
}


void    CpReturn(void) {
//==================

    if( !(ProgSw & PS_IN_SUBPROGRAM) ) {
        Extension( RE_IN_PROGRAM );
    }
    CkRemBlock();
    if( RecNOpn() && RecNextOpr( OPR_TRM ) ) {
        if( ( ( SubProgId->ns.flags & SY_CLASS ) == SY_SUBPROGRAM ) &&
            ( ( SubProgId->ns.flags & SY_SUBPROG_TYPE ) == SY_SUBROUTINE ) ) {
            GNullRetIdx();
        }
    } else {
        IntSubExpr();
        if( ( ( SubProgId->ns.flags & SY_CLASS ) == SY_SUBPROGRAM ) &&
            ( ( SubProgId->ns.flags & SY_SUBPROG_TYPE ) == SY_SUBROUTINE ) ) {
            GRetIdx();
        } else {
            Error( RE_ALT_IN_SUBROUTINE );
        }
    }
    AdvanceITPtr();
    ReqEOS();
    GGotoEpilog();
    Remember.transfer = TRUE;
    Remember.stop_or_return = TRUE;
}


static  void    CkRemBlock(void) {
//============================

    csnode      *csptr;

    csptr = CSHead;
    for(;;) {
        if( csptr->typ == CS_EMPTY_LIST ) return;
        if( csptr->typ == CS_REMOTEBLOCK ) break;
        csptr = csptr->link;
    }
    Error( SP_RET_IN_REMOTE );
}


static  void    CkSubEnd(void) {
//==========================

// Check if we had an END statement.

    if( ( SgmtSw & SG_STMT_PROCESSED ) && !Remember.endstmt ) {
        FiniSubProg();
        InitSubProg();
    }
    CkDefStmtNo();
}


static  parameter       *NameParm( entry_pt *entry ) {
//====================================================

// Process a symbolic dummy argument.

    parameter           *result;
    sym_id              sym;
    act_dim_list        *dim_ptr;
    unsigned_16         flags;
    unsigned_16         class;

    sym = LkSym();
    flags = sym->ns.flags;
    class = flags & SY_CLASS;
    if( class == SY_VARIABLE ) {
        if( InArgList( entry, sym ) ) {
            NameErr( AR_DUPLICATE_PARM, sym );
            return( NULL );
        } else if( flags & SY_SAVED ) {
            Error( SA_SAVED );
            return( NULL );
        } else if( flags & SY_IN_EC ) {
            IllName( sym );
            return( NULL );
        } else if( flags & SY_SUBSCRIPTED ) {
            dim_ptr = sym->ns.si.va.dim_ext;
            if( dim_ptr->dim_flags & DIM_PVD ) {
                dim_ptr->dim_flags |= DIM_ASSUMED;
                NameExt( SV_PVD, sym );
                if( dim_ptr->dim_flags & DIM_USED_IN_IO ) {
                    NameErr( SV_CANT_USE_ASSUMED, sym );
                    return( NULL );
                }
            }
        }
    } else if( class == SY_PARAMETER ) {
        IllName( sym );
        return( NULL );
    } else { // subroutine name
        class = flags & SY_SUBPROG_TYPE;
        if( ( class != SY_FUNCTION ) && ( class != SY_SUBROUTINE ) &&
            ( class != SY_FN_OR_SUB ) ) {
            IllName( sym );
            return( NULL );
        } else if( flags & ( SY_PS_ENTRY | SY_INTRINSIC ) ) {
            IllName( sym );
            return( NULL );
        }
    }
    result = FMemAlloc( sizeof( parameter ) );
    result->link = NULL;
    result->id = sym;
    result->flags = 0;
    if( sym->ns.flags & SY_SUB_PARM ) {
        result->flags |= ARG_DUPLICATE;
    }
    sym->ns.flags |= SY_SUB_PARM;
    return( result );
}


static  parameter       *StarParm(void) {
//===================================

// Process an asterisk dummy argument.

    parameter   *result;

    result = FMemAlloc( sizeof( parameter ) );
    result->link = NULL;
    result->flags |= ARG_STMTNO;
    return( result );
}


static  void    ParmList( bool star_ok, entry_pt *entry ) {
//=========================================================

// Process the formal parameter list of a FUNCTION/SUBROUTINE.

    parameter   **args;
    parameter   *new_arg;

    args = &entry->parms;
    if( RecNOpn() && RecNextOpr( OPR_RBR ) ) {
        // consider name()
        AdvanceITPtr();
    } else {
        for(;;) {       // process parm list
            if( star_ok && RecNOpn() ) {
                AdvanceITPtr();
                if( ReqMul() && ReqNOpn() ) {
                    *args = StarParm();
                    args = &(*args)->link;
                }
            } else if( ReqName( NAME_ARGUMENT ) ) {
                new_arg = NameParm( entry );
                if( new_arg != NULL ) {
                    *args = new_arg;
                    args = &(*args)->link;
                }
            }
            AdvanceITPtr();
            if( !RecComma() ) break;
        }
    }
}



void    Prologue(void) {
//==================

// Generate a FUNCTION/SUBROUTINE/ENTRY prologue starting with ArgList.

    label_id    skip_label;

    SgmtSw |= SG_PROLOG_DONE;
    if( ( ArgList != NULL ) && ( ArgList->id == SubProgId ) ) {
        GSPProlog();
        InitParms();
        ArgList = ArgList->link;
    }
    while( ArgList != NULL ) {
        skip_label = NextLabel();
        GBranch( skip_label );
        GEPProlog();
        InitParms();
        GLabel( skip_label );
        FreeLabel( skip_label );
        ArgList = ArgList->link;
    }
}


static  void    InitParms(void) {
//===========================

    DoWarps();
}


static  void    DoWarps(void) {
//=========================

// Generate calls to warp code.

    parameter   *parm;
    sym_id      sym;

    for( parm = ArgList->parms; parm != NULL; parm = parm->link ) {
        if( parm->flags & ARG_STMTNO ) continue;
        sym = parm->id;
        if( ( sym->ns.flags & SY_CLASS ) != SY_VARIABLE ) continue;
        if( ( sym->ns.flags & SY_SUBSCRIPTED ) == 0 ) continue;
        if( _AdvRequired( sym->ns.si.va.dim_ext ) == 0 ) continue;
        GWarp( sym );
    }
}


void    Epilogue(void) {
//==================

// Generate an epilogue.

    if( ( SgmtSw & SG_PROLOG_DONE ) == 0 ) {
        Prologue();
    }
    if( SubProgId != NULL ) {
        GEpilog();
    }
}


void    CpBlockData(void) {
//=====================

    sym_id  sym_ptr;

    CkSubEnd();
    ProgSw |= PS_IN_SUBPROGRAM | PS_BLOCK_DATA;
    if( RecName() ) {
        sym_ptr = LkSym();
        sym_ptr->ns.flags = SY_USAGE | SY_SUBPROGRAM | SY_BLOCK_DATA |
                            SY_PENTRY | SY_REFERENCED;
    } else {
        ReqNOpn();
        sym_ptr = LkBlkData();
    }
    SubProgId = sym_ptr;
    GBlockLabel();
    AdvanceITPtr();
    ReqEOS();
    BIStartBlockData( SubProgId );
}

⌨️ 快捷键说明

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