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

📄 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 页
字号:
    }
    infuncargs--;
}

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

void check_funcused(TABLE *oldlsym, TABLE *lsyms)
{
    /* oldlsym Must BE 0 at the end of a function */
    SYM *sym1;
    if (oldlsym && oldlsym->head == lsyms->head)
    {
        return ;
    }
    sym1 = lsyms->head;
    while (sym1 && (!oldlsym || sym1 != oldlsym->head))
    {
        if (sym1->tp->type != bt_func && sym1->tp->type != bt_ifunc && sym1
            ->storage_class != sc_type)
        {
            if (!(sym1->tp->uflags &UF_USED))
            {
                if (sym1->storage_class == sc_label)
                {
                    if (!oldlsym)
                        gensymerror(ERR_UNUSEDLABEL, sym1->name);
                }
                else
                    if (sym1->funcparm)
                        gensymerror(ERR_PARAMUNUSED, sym1->name);
                    else
                        gensymerror(ERR_SYMUNUSED, sym1->name);
            }
            if (sym1->tp->uflags &UF_ASSIGNED)
                gensymerror(ERR_SYMASSIGNED, sym1->name);
            if (!oldlsym && sym1->storage_class == sc_ulabel)
                gensymerror(ERR_UNDEFLABEL, sym1->name);
        }
        sym1 = sym1->next;
    }
}

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

void dump_instantiates(void)
{
    SYM *oldfunc = currentfunc;
    LIST *oldvar = varlisthead;
    while (instantiated_inlines)
    {
        currentfunc = instantiated_inlines->data;
        instantiated_inlines = instantiated_inlines->link;
        if (!currentfunc->value.classdata.inlinefunc) {
            char *nm = currentfunc->name;
            currentfunc = 0 ;
            gensymerror(ERR_INLINENOBODY,nm);
        } else {
            conscount = 0;
            varlisthead = currentfunc->value.classdata.inlinefunc->syms;
        
            genfunc(currentfunc->value.classdata.inlinefunc->stmt);
        }
        //		release_local() ;
    }
    varlisthead = oldvar;
    currentfunc = oldfunc;
}

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

void funcbody(SYM *sp)
/*
 */
{
    SYM *sp1,  *sp2;
    int xglob = global_flag;
    SNODE *vlaparminit = 0;
    funcnesting++;
    //				instantiated_inlines = 0 ;
    goodcode = 0;
    typequal = 0;
    conscount = 0;
    try_block_list = 0;
    /* 1 if inline, 0 if local define */
    global_flag = !!(sp->value.classdata.cppflags &PF_INLINE);
    /* Have to defer old style argument gathering until now
     * because of the pointer-to func syntax
     */
    if (sp->oldstyle)
    {
        SYM *spsave[50],  *sp1;
        int nparms, i;
        int poffset = stdretblocksize; /* size of return block */
        char **names;
        global_flag++;
        doargdecl(sc_member, 0, 0, &sp->tp->lst, FALSE); /* declare parameters
            */
        global_flag--;
        if (!ispascal && isstructured(sp->tp->btp))
        {
            poffset += stdaddrsize;
            sp->calleenearret = TRUE;
        }
        if (sp->farproc)
            poffset += stdintsize;
        nparms = (int)sp->oldstyle[0];
        names = &sp->oldstyle[1];
        for (i = 0; i < nparms; ++i)
        {
            if ((sp1 = search(names[i], &sp->tp->lst)) == 0)
                sp1 = makeint(litlate(names[i]), &sp->tp->lst);
            if (sp1->tp)
                sp1->tp->uflags |= UF_DEFINED;
            sp1->funcparm = TRUE;
            spsave[i] = sp1;
            sp1->storage_class = sc_auto;
        }
        /*
         * parameter allocation.  Have to do things backwards if this
         * function has the pascal declarator
         */
        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)
                    poffset += stdaddrsize;
                else
                {
                    poffset += sp1->tp->size;
                }
                if (poffset % stdintsize)
                    poffset += stdintsize - poffset % stdintsize;
            }
        }
        sp->paramsize = poffset;
    }
    else
    {
            if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
            if (!sp->pascaldefn && (sp->value.classdata.cppflags &PF_MEMBER) &&
                !(sp->value.classdata.cppflags &PF_STATIC))
            {
                SYM *s1 = sp->tp->lst.head;
                while (s1 && s1 != (SYM*) - 1)
                {
                    s1->value.i += stdaddrsize;
                    s1 = s1->next;
                }
            }
    }
    sp1 = sp->tp->lst.head;
    if (sp1 != (SYM*) - 1)
    {
        SNODE *vlaparmtail;
        while (sp1)
        {
            if (sp1->name[0] != '*' || sp1->tp->type == bt_ellipse)
            {
                TYP *tp;
                sp2 = copysym(sp1);
                insert(sp2, &lsyms);
                tp = sp2->tp;
                if (tp->type == bt_pointer && !(tp->val_flag &VARARRAY))
                    tp = tp->btp;
                if (tp->val_flag &VARARRAY)
                {
                    SNODE *snp = xalloc(sizeof(SNODE));
                    snp->next = 0;
                    snp->stype = st_expr;
                    snp->exp = createVarArray(sp2, tp, FALSE, FALSE);
                    snp->flags |= ST_VARARRAY ;
                    if (vlaparminit == 0)
                        vlaparminit = vlaparmtail = snp;
                    else
                    {
                        vlaparmtail->next = snp;
                        vlaparmtail = snp;
                    }
                }
                browse_variable(sp2, lineno);
            }
            else
                if (!prm_cplusplus)
                    generror(ERR_PARAMMISSINGNAME, 0, 0);

            sp1 = sp1->next;
        }
    }
    currentfunc = sp;
    firstlabel = nextlabel;
    goodcode &= ~GF_RETURN;
    block(vlaparminit);
    check_funcused(0, &lsyms);
    if (prm_listfile && varlisthead)
    {
        LIST *q = varlisthead;
        fprintf(listFile, "\n\n*** local symbol table ***\n\n");
        while (q)
        {
            SYM *sp = q->data;
            while (sp)
            {
                list_var(sp, 0);
                sp = sp->next;
            }
            q = q->link;
        }
        list_table(&ltags,0);
    }
    if (sp->tp->btp->type != bt_void && !(goodcode &(GF_RETURN | GF_UNREACH)))
        if (!prm_cplusplus || strcmp(currentfunc->name + prm_cmangle, "main"))
            generror(ERR_FUNCRETVAL, 0, 0);
    nl();

    local_using_list = 0;
    local_tag_using_list = 0;
    #ifdef ICODE
        dag_rundown();
    #endif 
    lsyms.head = 0;
    ltags.head = 0;
    oldlsym.head = oldlsym.tail = 0;
    lastfunc = currentfunc;

    //        dump_instantiates() ;
    while (lastst == semicolon)
        getsym();
    varlisthead = varlisttail = 0;
    if (!--funcnesting)
    {
        release_local(); /* release local symbols */
        release_opt();
        release_oc();
    }
    currentfunc = 0;
    global_flag = xglob;
}

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

SYM *makeint(char *name, TABLE *table)
{
    SYM *sp;
    TYP *tp;
    global_flag++;
    sp = makesym(sc_auto);
    tp = xalloc(sizeof(TYP));
    global_flag--;
    tp->type = bt_int;
    tp->size = stdintsize;
    tp->btp = tp->lst.head = 0;
    tp->sp = 0;
    sp->name = name;
    tp->bits = tp->startbit =  - 1;
    sp->tp = tp;
    insert(sp, table);
    return sp;
}

/* a little ditty to add C++ destructors on the tail of a block
 */
void addrundown(SNODE *snp)
{
    if (block_rundown && snp)
    {
        SNODE *snp2;
        snp2 = xalloc(sizeof(SNODE));
        snp2->next = 0;
        snp2->stype = st_expr;
        snp2->exp = block_rundown;
        block_rundown = 0;
        while (snp->next)
            snp = snp->next;
        snp->next = snp2;
    }
}

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

void addblocklist(SYM *sp, SYM *old)
{
    LIST *l;
    if (!sp)
        return ;
    if (!currentfunc)
        return ;
    if (varlisthead && sp == varlisttail->data)
        return ;
    if (sp == old)
        return ;
    if (currentfunc->value.classdata.cppflags &PF_INLINE)
    {
        global_flag++;
        l = xalloc(sizeof(LIST));
        global_flag--;
    }
    else
        l = xalloc(sizeof(LIST));
    l->link = 0;
    l->data = sp;
    if (varlisthead)
        varlisttail = varlisttail->link = l;
    else
        varlisthead = varlisttail = l;
    if (old)
    while (sp)
    {
        if (sp->next == old)
        {
            sp->next = 0;
            break;
        }
        sp = sp->next;
    }
}

//-------------------------------------------------------------------------
int scanforgoto(SNODE *block, SNODE *root, DLIST **data, int id)
/*
 *  scan a statement tree for gotos.  We are going to put out an error if
 *  a goto tries to bypass a VLA initialization
 */
{
    static DLIST *labelList;
    static SNODE *gotoPos ;
    int rv = TRUE ;
    DLIST *m = xalloc(sizeof(DLIST)) ;
    m->fwd = *data ;
    m->back = 0 ;
    if (*data)
        (*data)->back = m ;
    *data = m ;
    m->data = block ;
    while (block != 0 && rv)
    {
        m->current = block ;
        switch (block->stype)
        {
            case st_goto:
                if (id == -1) 
                {

⌨️ 快捷键说明

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