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

📄 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 页
字号:
                    labelList = 0 ;
                    gotoPos = block ;
                    scanforgoto(root,root,&labelList,(int)block->label) ;
                }
                break ;
            case st_label:
                if (id != -1 && id == (int)block->label) 
                {
                    int toerr = FALSE;
                    SNODE *s = 0;
                    DLIST *l = labelList, *g = gotoList;
                    while (l && l->fwd)
                        l = l->fwd ;
                    while (g && g->fwd)
                        g = g->fwd ;
                    while (l && g && l->data == g->data) 
                    {
                        l = l->back ;
                        g = g->back ;
                    }
                    if (!l && !g) 
                    { /* both in same block */
                        s = gotoPos;
                        while (s && s != block)
                        {
                            if (s->flags & ST_VARARRAY)
                                toerr = TRUE;
                            s = s->next;
                        }
                    }
                    else if (l)
                    { /* label in lower block, or two in disjoint blocks */
                        s = labelList->data;
                        while (s && s != block)
                        {
                            if (s->flags & ST_VARARRAY)
                                toerr = TRUE;
                            s = s->next;
                        }
                    }
                    else if (g)
                    { /* goto in lower block */
                        s = g->fwd->current;
                        while (s && s != block)
                        {
                            if (s->flags & ST_VARARRAY)
                                toerr = TRUE;
                            s = s->next;
                        }
                    }
                    if (s && toerr)
                        generror(ERR_VLAGOTO,0,0);
                    rv = FALSE ;
                }
                break ;
            case st_tryblock:
                break;
            case st_throw:
                break;
            case st_return:
            case st_expr:
                break;
            case st_while:
            case st_do:
                rv &= scanforgoto(block->s1,root,data,id);
                break;
            case st_for:
                rv &= scanforgoto(block->s1,root,data,id);
                break;
            case st_if:
                rv &= scanforgoto(block->s1,root,data,id);
                if (rv)
                    rv &= scanforgoto(block->s2,root,data,id);
                break;
            case st_switch:
                rv &= scanforgoto(block->s1,root,data,id);
                break;
            case st_case:
                rv &= scanforgoto(block->s1,root,data,id);
                break;
            case st_block:
                rv &= scanforgoto(block->exp,root,data,id);
                break;
            case st_asm:
                break;
        }
        block = block->next;
    }
    (*data) = (*data)->fwd ;
    if (*data)
        (*data)->back = 0 ;
    return rv ;
}

void block(SNODE *vlainit)
{
    SNODE *snp3;
    SNODE *funcsym = funcstmt; // in case they declare function ptrs
    int checkthunkret = mainfunc && (prm_cplusplus || prm_c99); 
        // && prm_cplusplus ; /* blockdecl resets mainfunc */
    int oldpragma = stdpragmas;
    block_rundown = 0;
    block_nesting = 1;
    arg_nesting = 0;
    lastst = 0;
    cbautoinithead = 0;
    gotoCount = 0 ;
    if (vlainit)
    {
        snp3 = vlainit;
        while (vlainit->next)
            vlainit = vlainit->next;
        vlainit->next = snp_line(TRUE);
    }
    else
        snp3 = snp_line(TRUE);
    lastst = begin;
    needpunc(begin, 0);
    if (prm_debug)
        debug_beginblock(lsyms);
    browse_blockstart(lineno);
    if (prm_cplusplus && (currentfunc->value.classdata.cppflags &PF_CONSTRUCTOR)
        )
    {
        SNODE *snp4 = xalloc(sizeof(SNODE));
        snp4->stype = st_expr;
        snp4->exp = 0;
        // thunk flags reset in decl.c before loading initializers
        thunkConstructors(snp4, currentfunc->parentclass, 0, FALSE);
        RefErrs(currentfunc->parentclass);
        if (snp3)
        {
            snp3->next = snp4;
        }
        else
            snp3 = snp4;
    }
    blockdecl();

    if (snp3)
    {
        SNODE *snp5 = snp3;
        while (snp5->next)
            snp5 = snp5->next;
        snp5->next = compound();
    }
    else
        snp3 = compound();

    /* Thunk in a return value of zero if this is the main func
     * and there was no return statement
     */
    if (checkthunkret)
    {
        SNODE *snp4 = snp3;
        while (snp4->next)
            snp4 = snp4->next;
        if (snp4->stype != st_return)
        {
            snp4->next = xalloc(sizeof(SNODE));
            snp4 = snp4->next;
            snp4->stype = st_return;
            snp4->exp = makeintnode(en_icon, 0);
        }
    }
    if (prm_c99 && gotoCount) {
        gotoList = 0 ;
        scanforgoto(snp3,snp3,&gotoList,-1) ;
    }
    parameter_rundown(&lsyms);
    /* create destructor call tree for end of function */
    if (prm_cplusplus && (currentfunc->value.classdata.cppflags &PF_DESTRUCTOR))
    {
        SNODE snp4;
        snp4.stype = st_expr;
        snp4.exp = 0;
        setthunkflags(currentfunc->parentclass, FALSE);
        thunkDestructors(&snp4, currentfunc->parentclass, 0, FALSE, TRUE);
        if (block_rundown)
            block_rundown = makenode(en_void, (void*)block_rundown, (void*)
                snp4.exp);
        else
            block_rundown = snp4.exp;
    }
    currentfunc->value.classdata.eofdest = block_rundown;
    block_rundown = 0;
    /*            addrundown(snp3); */
    addblocklist(lsyms.head, 0); // Add block level declarations
    if (!total_errors)
    {
        /* this unqualified the current function if it has structured
         * args or return value, or if it has nested declarations
         */
        if (currentfunc->value.classdata.cppflags &PF_INLINE)
        {
            if (isstructured(currentfunc->tp->btp))
                currentfunc->value.classdata.cppflags &= ~PF_INLINE;
            else
            {
                SYM *head = currentfunc->tp->lst.head;
                if (head != (SYM*) - 1)
                while (head)
                {
                    if (isstructured(head->tp))
                    {
                        currentfunc->value.classdata.cppflags &= ~PF_INLINE;
                        break;
                    }
                    head = head->next;
                }
                if (currentfunc->value.classdata.cppflags &PF_INLINE)
                {
                    if (arg_nesting)
                        currentfunc->value.classdata.cppflags &= ~PF_INLINE;
                }
            }
        }
        if (currentfunc->value.classdata.cppflags &PF_INLINE)
        {
            currentfunc->mainsym->value.classdata.inlinefunc = xalloc(sizeof
                (INLINEFUNC));
            currentfunc->mainsym->value.classdata.inlinefunc->stmt = snp3;
            currentfunc->mainsym->value.classdata.inlinefunc->syms =
                varlisthead;
            if (currentfunc->value.classdata.eofdest)
            {
                SNODE *snp4 = xalloc(sizeof(SNODE));
                snp4->stype = st_expr;
                snp4->exp = currentfunc->value.classdata.eofdest;
                while (snp3 && snp3->next)
                    snp3 = snp3->next;
                if (snp3)
                    snp3->next = snp4;
            }

            funcstmt = funcsym;
        }
        else
        {
            funcstmt = funcsym;
            genfunc(snp3);
        }
    }
        else
            currentfunc->value.classdata.cppflags &= ~PF_INLINE;
    if (prm_debug)
        debug_endblock(lsyms);
    browse_blockend(lineno);
    block_nesting = 0;
    block_rundown = 0;
    funcstmt = funcendstmt = 0;
    stdpragmas = oldpragma;
}

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

void gather_labels(TABLE *oldlsym, TABLE *lsyms)
{
    TABLE sym;
    sym.head = 0;
    if (oldlsym->head == lsyms->head)
    {
        return ;
    }
    else
    {
        SYM *sp = lsyms->head,  *r = oldlsym->head;
        lsyms->head = 0;
        while (sp && sp != r)
        {
            SYM *q = sp->next;
            sp->next = 0;
            if (sp->storage_class == sc_label || sp->storage_class == sc_ulabel)
            {
                if (!oldlsym->head)
                {
                    oldlsym->head = oldlsym->tail = sp;
                }
                else
                {
                    oldlsym->tail->next = sp;
                    oldlsym->tail = sp;
                }
            }
            else
                if (!lsyms->head)
                    lsyms->head = lsyms->tail = sp;
                else
                    lsyms->tail = lsyms->tail->next = sp;
            sp = q;
        }
        if (oldlsym->head)
            oldlsym->tail->next = 0;
    }
}

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

SNODE *compoundblock(void)
{
    SNODE *snp;
    TABLE oldoldlsym, oldoldltag;
    SYM *q;
    LIST *nsusing = local_using_list;
    LIST *nstusing = local_tag_using_list;
    LASTDEST rundown;
    int oldpragma = stdpragmas;
    rundown.chain = rundown.last = lastDestPointer;
    rundown.block = block_rundown;
    lastDestPointer = &rundown;
    block_rundown = 0;
    block_nesting++;
    oldoldltag = oldltag;
    oldltag = ltags;
    oldoldlsym = oldlsym;
    oldlsym = lsyms;
    if (prm_debug)
        debug_beginblock(lsyms);
    browse_blockstart(lineno);
    cbautoinithead = 0;
    blockdecl();
    snp = compound();
    addrundown(snp);
    check_funcused(&oldlsym, &lsyms);
    q = lsyms.head;
    gather_labels(&oldlsym, &lsyms);
    while (q && q->next != oldlsym.head)
        q = q->next;
    if (q)
        q->next = 0;
    addblocklist(lsyms.head, oldlsym.head);
    if (oldlsym.head != lsyms.head)
        arg_nesting++;
    if (prm_debug)
        debug_endblock(lsyms);
    browse_blockend(lineno);
    stdpragmas = oldpragma;
    lsyms = oldlsym;
    oldlsym.head = oldoldlsym.head;
    ltags = oldltag;
    oldltag.head = oldoldltag.head;
    local_using_list = nsusing;
    local_tag_using_list = nstusing;
    block_nesting--;
    block_rundown = rundown.block;
    lastDestPointer = rundown.last;
    return (snp);
}

⌨️ 快捷键说明

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