cpsubpgm.c

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

C
561
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  compile SUBROUTINE, (type)FUNCTION, and related statements
*
****************************************************************************/


//      Note : "type{*n} FUNCTION" statement handled by PR_type

#include "ftnstd.h"
#include "segsw.h"
#include "errcod.h"
#include "progsw.h"
#include "opr.h"
#include "namecod.h"
#include "global.h"
#include "cpopt.h"
#include "fmemmgr.h"
#include "recog.h"
#include "types.h"
#include "ferror.h"
#include "insert.h"
#include "utility.h"

extern  TYPE            MapTypes(TYPE,int);
extern  TYPE            ImplType(char);
extern  bool            EmptyCSList(void);
extern  sym_id          LkSym(void);
extern  sym_id          LkProgram(void);
extern  sym_id          LkBlkData(void);
extern  void            FreeLabel(label_id);
extern  void            FiniSubProg(void);
extern  void            InitSubProg(void);
extern  void            GSegLabel(void);
extern  void            GPgmLabel(void);
extern  void            GBranch(label_id);
extern  void            GLabel(label_id);
extern  void            GWarp(sym_id);
extern  void            GEpilog(void);
extern  void            GGotoEpilog(void);
extern  void            GSPProlog(void);
extern  void            GEPProlog(void);
extern  void            GRetIdx(void);
extern  void            GNullRetIdx(void);
extern  void            GBlockLabel(void);
extern  bool            LenSpec(TYPE,uint *);
extern  label_id        NextLabel(void);
extern  void            CkDefStmtNo(void);
extern  bool            InArgList(entry_pt *,sym_id);
extern  sym_id          STFnShadow(sym_id);
extern  void            BIStartRBorEP( sym_id );
extern  void            BIStartBlockData( sym_id );
extern  void            BIStartSubroutine( void );
extern  void            GSetSrcLine(void);


void    CpProgram(void) {
//===================

    CkSubEnd();
    if( ReqName( NAME_PROGRAM ) ) {
        SubProgId = LkProgram();    // use default name
    } else {
        SubProgId = LkProgram();        // use default name
    }
    StartProg();
    AdvanceITPtr();
    ReqEOS();
}


void    DefProg(void) {
//=================

// Define the program unit since no PROGRAM, SUBROUTINE, FUNCTION or
// BLOCK DATA statements were specified.

    SubProgId = LkProgram();
    StartProg();
}


static  void    StartProg(void) {
//===========================

    ProgSw &= ~PS_IN_SUBPROGRAM;
    if( ProgSw & PS_PROGRAM_DONE ) {
        Error( SR_TWO_PROGRAMS );
    }
    ProgSw |= PS_PROGRAM_DONE;
    GPgmLabel();
    BIStartSubroutine();
}


static  entry_pt        *AddEntryPt( sym_id sym_ptr ) {
//=====================================================

    entry_pt    *ptr;

    if( Entries == NULL ) {
        ArgList = FMemAlloc( sizeof( entry_pt ) );
        Entries = ArgList;
        ptr     = Entries;
    } else {
        ptr = Entries;
        while( ptr->link != NULL ) {
            ptr = ptr->link;
        }
        ptr->link = FMemAlloc( sizeof( entry_pt ) );
        ptr = ptr->link;
        if( ArgList == NULL ) {
            ArgList = ptr;
        }
    }
    ptr->link = NULL;
    ptr->id = sym_ptr;
    ptr->parms = NULL;
    return( ptr );
}


static  entry_pt        *SubProgName( TYPE typ, unsigned_16 flags,
                                      uint def_size, bool len_spec ) {
//====================================================================

// Process the symbolic name of a SUBROUTINE or FUNCTION.

    entry_pt    *entry;
    itnode      *name_node;
    itnode      *next_node;
    sym_id      sym_ptr;
    uint        size;
    sym_ptr = LkSym();
    SubProgId = sym_ptr;
    GSegLabel();    // must be before DumpStatement() so that ISN code for
    if( Options & OPT_TRACE ) {
        GSetSrcLine();
    }
    name_node = CITNode;
    sym_ptr->ns.flags = flags;
    name_node->flags = flags;
    size = def_size;
    next_node = CITNode->link;
    if( !len_spec ) {
        AdvanceITPtr();
        if( !LenSpec( typ, &size ) ) {
            size = StorageSize( typ );
        }
        next_node = CITNode;
    }
    sym_ptr->ns.xt.size = size;
    name_node->size = size;
    typ = MapTypes( typ, size );
    sym_ptr->ns.typ = typ;
    name_node->typ = typ;
    CITNode = name_node;
    entry = AddEntryPt( sym_ptr );
    CITNode = next_node;
    return( entry );
}


void    CpSubroutine(void) {
//======================

    entry_pt    *entry;

    CkSubEnd();
    ProgSw |= PS_IN_SUBPROGRAM;
    if( ReqName( NAME_SUBROUTINE ) ) {
        entry = SubProgName( TY_NO_TYPE, SY_USAGE | SY_SUBPROGRAM | SY_PENTRY |
                              SY_SUBROUTINE | SY_REFERENCED, 0, TRUE );
        if( RecOpenParen() ) {
            ParmList( TRUE, entry );
            ReqCloseParen();
            ReqNOpn();
            AdvanceITPtr();
        }
        ReqEOS();
    } else {
        // We still want to start a subprogram even though there is no name.
        SubProgId = LkProgram();        // use default name
        GSegLabel();
    }
    BIStartSubroutine();
}


void    Function( TYPE typ, uint size, bool len_spec ) {
//=====================================================

// Compile [type] [*len] FUNCTION NAME[*len] ([d,d,...])
//            \                /
//             Already scanned
//

    unsigned_16 flags;
    entry_pt    *entry;

    flags = SY_USAGE | SY_SUBPROGRAM | SY_PENTRY | SY_FUNCTION;
    if( typ == TY_NO_TYPE ) {
        typ = ImplType( *(CITNode->opnd) );
    } else {
        flags |= SY_TYPE;
    }
    CkSubEnd();
    ProgSw |= PS_IN_SUBPROGRAM;
    if( ReqName( NAME_FUNCTION ) ) {
        entry = SubProgName( typ, flags, size, len_spec );
        STFnShadow( SubProgId );
        if( ReqOpenParen() ) {
            ParmList( FALSE, entry );
        }
        ReqCloseParen();
        ReqNOpn();
        AdvanceITPtr();
        ReqEOS();
    } else {
        // We still want to start a subprogram even though there is no name.
        SubProgId = LkProgram();        // use default name
        GSegLabel();
    }
    BIStartSubroutine();
}


void    CpFunction(void) {
//====================

    Function( TY_NO_TYPE, -1, FALSE );
}


void    CpEntry(void) {
//=================

    entry_pt    *entry;
    bool        in_subr;
    sym_id      sym;

    if( ( ProgSw & PS_IN_SUBPROGRAM ) == 0 ) {
        StmtErr( SR_ILL_IN_PROG );
    }
    if( !EmptyCSList() ) {
        Error( EY_NOT_IN_CS );
    }
    if( ReqName( NAME_FUNCTION ) ) {
        in_subr = (SubProgId->ns.flags & SY_SUBPROG_TYPE) == SY_SUBROUTINE;
        sym = LkSym();
        if( ( sym->ns.flags & (SY_USAGE|SY_SUB_PARM|SY_IN_EC|SY_SAVED) ) ||
            ( in_subr && (sym->ns.flags & SY_TYPE) ) ) {
            IllName( sym );
        } else {
            sym->ns.typ = CITNode->typ;
            sym->ns.flags &= SY_TYPE;
            if( in_subr ) {

⌨️ 快捷键说明

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