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

📄 func.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"

extern int prm_c99;
extern int stdpragmas;
extern LIST *local_using_list,  *local_tag_using_list;
extern char *templatePrefix;
extern int mainfunc;
extern int lineno;
extern SNODE *cbautoinithead,  *cbautoinittail;
extern int ispascal, isstdcall;
extern FILE *listFile;
extern enum e_sym lastst;
extern long firstlabel, nextlabel;
extern char lastid[];
extern TABLE *gsyms, lsyms, ltags;
extern int global_flag;
extern int stdaddrsize, stdretblocksize;
extern int stackadd, stackmod;
extern TYP *head,  *tail,  **headptr;
extern char declid[100];
extern int prm_listfile;
extern int prm_cplusplus, prm_debug;
extern int stdintsize;
extern int goodcode;
extern int prm_linkreg;
extern TABLE lsyms;
extern int total_errors;
extern int cppflags;
extern SYM *declclass,  *typequal;
extern int prm_cmangle;
extern LASTDEST *lastDestPointer;
extern int conscount;
extern int prm_xcept;
extern TRYBLOCK *try_block_list;

typedef struct _dlist {
    struct _dlist *fwd, *back ;
    void *data, *current ;
} DLIST ;

DLIST *gotoList ;

int gotoCount;
int block_nesting, arg_nesting;
int infuncargs, infunclineno;
int funcnesting;
ENODE *block_rundown; /* maintains destructors for block, WILL maintain global
 * scope when no funcs in progress but we don't use that
 * now
 */
TABLE oldlsym, oldltag;
LIST *varlisthead,  *varlisttail;
LIST *instantiated_inlines;
SNODE *funcstmt,  *funcendstmt;

static int skm_func[] = 
{
    closepa, begin, semicolon, 0
};

SYM *currentfunc = 0,  *lastfunc;

/*      function compilation routines           */
void funcini(void)
{
    currentfunc = lastfunc = 0;
    infuncargs = 0;
    funcnesting = 0;
    instantiated_inlines = 0;
}

//-------------------------------------------------------------------------

void declfuncarg(int isint, int isfar, SYM *sp)
{
    char *names[50]; /* 50 parameters maximum */
    int nparms, poffset, i, isinline;
    SYM *sp1,  *sp2,  *spsave[50],  *oldargs = 0,  *typesp = typequal;
    TYP *temp,  *temp1,  *todo,  *oheadptr;
    char oldeclare[100];
    char *nm;
    sp->hasproto = TRUE;
    if (!infuncargs)
    {
        if (lineno != infunclineno)
            funcstmt = snp_line(FALSE);
        // only want the first one
        infunclineno = lineno;
    }
    infuncargs++;
    if (prm_linkreg && !isint)
    {
        poffset = stdretblocksize; /* size of return block */
        if (isfar)
            poffset += stdintsize;
    }
    else
        poffset = 0;
     /* size of return block */
    nparms = 0;
    temp = head;
    temp1 = tail;
    oheadptr = headptr;
    todo = sp->tp;
    if (!prm_cplusplus)
    {
        sp2 = gsearch(declid);
        if (sp2)
        {
            oldargs = sp2->tp->lst.head;
        }
    }
    todo->lst.head = todo->lst.tail = 0;
    if (lastst == kw_void)
    {
        getsym();
        if (lastst != closepa)
        {
            backup(lastst);
            lastst = kw_void;
        }
        else
        {
            todo->lst.head = (SYM*) - 1;
            getsym();
            goto verify;
        }
    }
    else
    if (lastst == closepa)
    {
        if (prm_cplusplus)
            todo->lst.head = (SYM*) - 1;
        getsym();
        goto verify;
    } else
        if (lastst == id) 
        {
            if ((typesp = typesearch(lastid)) && (typesp->storage_class ==
                sc_type))
                if (typesp->tp->type == bt_void) 
                {
                    getsym();
                    if (lastst != closepa)
                    {
                        backup(lastst);
                        lastst = id;
                    }
                    else
                    {
                        todo->lst.head = (SYM*) - 1;
                        getsym();
                        goto verify;
                    }
                }
        }
    strcpy(oldeclare, declid);
    if (!prm_cplusplus && lastst == id && ((sp1 = search(lastid, gsyms)) == 0 
        || sp1->storage_class != sc_type) && ((sp1 = search(lastid, &lsyms)) ==
        0 || sp1->storage_class != sc_type))
    {
        int xglob = global_flag;
        /* declare parameters */
        global_flag = 0;
        while (lastst == id)
        {
            names[nparms++] = litlate(lastid);
            getsym();
            if (lastst == comma)
                getsym();
            else
                break;
        }
        needpunc(closepa, skm_func);
        sp->oldstyle = xalloc((nparms + 1) *sizeof(char*));
        sp->oldstyle[0] = nparms;
        memcpy(&sp->oldstyle[1], names, nparms *sizeof(char*));
        global_flag = xglob;
        if (prm_debug)
            debug_outfunc(sp);
        infuncargs--;
        return ;
    }
    else
    {
        SYM *tq = typequal;
        doargdecl(sc_member, names, &nparms, &todo->lst, isinline = TRUE);
        needpunc(closepa, skm_func);
        replaceTemplateFunctionClasses(sp, tq);
    }
    strcpy(declid, oldeclare);
    if (!ispascal && isstructured(todo->btp))
    {
        poffset += stdaddrsize;
        sp->calleenearret = TRUE;
    }
    typequal = 0;
    for (i = 0; i < nparms; ++i)
    {
        if ((sp1 = search(names[i], &todo->lst)) == 0)
            sp1 = makeint(litlate(names[i]), &todo->lst);
        if (sp1->tp)
            sp1->tp->uflags |= UF_DEFINED;
        sp1->funcparm = TRUE;
        spsave[i] = sp1;
        sp1->storage_class = sc_auto;
    }
    typequal = typesp;
    /*
     * parameter allocation.  Have to do things backwards if this
     * function has the pascal declarator
     */
    if (!ispascal)
    for (i = 0; i < nparms; ++i)
    {
        sp1 = spsave[i];
        if (sp1->tp->type != bt_pointer && sp1->tp->type != bt_farpointer &&
            sp1->tp->type != bt_segpointer && sp1->tp->size < stdintsize)
        {
            sp1->value.i = poffset + funcvaluesize(sp1->tp->size);
            poffset += stdintsize;
        }
        else
        {
            sp1->value.i = poffset;
            if (sp1->tp->type == bt_pointer)
            {
                TYP *tp = sp1->tp;
                if (!(tp->val_flag &VARARRAY))
                    tp = tp->btp;
                if (tp->type != bt_pointer || !(tp->val_flag &VARARRAY))
                    poffset += stdaddrsize;
                else
                {
                    poffset += tp->size;
                }
            }
            else
                poffset += sp1->tp->size;
            if (poffset % stdintsize)
                poffset += stdintsize - poffset % stdintsize;
        }
    }
    else
    for (i = nparms - 1; i >= 0; --i)
    {
        sp1 = spsave[i];
        if (sp1->tp->type != bt_pointer && sp1->tp->type != bt_farpointer &&
            sp1->tp->type != bt_segpointer && sp1->tp->size < stdintsize)
        {
            sp1->value.i = poffset + funcvaluesize(sp1->tp->size);
            poffset += stdintsize;
        }
        else
        {
            sp1->value.i = poffset;
            if (sp1->tp->type == bt_pointer)
            {
                TYP *tp = sp1->tp;
                if (!(tp->val_flag &VARARRAY))
                    tp = tp->btp;
                if (tp->type != bt_pointer || !(tp->val_flag &VARARRAY))
                    poffset += stdaddrsize;
                else
                {
                    poffset += tp->size;
                }
            }
            else
                poffset += sp1->tp->size;
            if (poffset % stdintsize)
                poffset += stdintsize - poffset % stdintsize;
        }
    }
    sp->paramsize = poffset;
    if (!isinline)
    {
        todo->lst.head = todo->lst.tail = 0;
        for (i = 0; i < nparms; i++)
            insert(spsave[i], &todo->lst);
    }

    sp->recalculateParameters = TRUE;
        if (prm_cplusplus && todo->lst.head == 0)
            todo->lst.head = (SYM*) - 1;
         /* () is equiv to (void) in cpp */
    verify: head = temp;
    tail = temp1;
    headptr = oheadptr;
    if (prm_debug)
        debug_outfunc(sp);

        if (prm_cplusplus)
        {
            infuncargs--;
            return ;
        }

    if (oldargs && head->lst.head)
    {
        SYM *newargs = head->lst.head;
        while (oldargs && newargs)
        {
            if (oldargs == (SYM*) - 1 || newargs == (SYM*) - 1)
                break;
            if (!exactype(oldargs->tp, newargs->tp, FALSE))
                gensymerror(ERR_DECLMISMATCH, sp2->name);
            oldargs = oldargs->next;
            newargs = newargs->next;
        }
        if (oldargs && oldargs != (SYM*) - 1)
            gensymerror(ERR_ARGLENSHORT, sp->name);
        if (newargs && newargs != (SYM*) - 1)
            gensymerror(ERR_ARGLENLONG, sp->name);

⌨️ 快捷键说明

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