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

📄 einit.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      
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
 */
/*
 * handles initialization of module-scoped declarations
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "lists.h"
#include "diag.h"

extern int prm_c99;
extern int structlevel;
extern TYP *head,  **headptr;
extern struct template  *currentTemplate;
extern SNODE *funcstmt;
extern int stdaddrsize;
extern int stdldoublesize;
extern enum e_sym lastst;
extern char lastid[], laststr[];
extern int skm_declend[];
extern int nextlabel;
extern TYP stdmatch;
extern int skm_declclosepa[];
extern int skm_closebr[];
extern int prm_cplusplus, prm_debug;
extern SYM *currentfunc;
extern int prm_bss;
extern int laststrlen;
extern LIST *varlisthead,  *varlisttail;
extern int stdmemberptrsize;
extern SYM *typequal;
extern int total_errors;
extern char *cpp_funcname_tab[];
extern int conscount;
extern TRYBLOCK *try_block_list;
extern LIST *localfuncs;
extern SYM *parm_namespaces[20][100];
extern int parm_ns_counts[20];
extern int parm_ns_level;
extern int parsing_params;
extern int stdinttype, stdunstype, stdintsize, stdldoublesize, stdaddrsize, stdwchar_tsize;
extern int stdshortsize, stdlongsize, stdlonglongsize, stdfloatsize, stddoublesize, stdenumsize;

static ENODE *basenode;
static ENODE *returnval, **sptr;
static int baseoffset;
static SYM *locsp;
static int allocated;
static int startbit, bits;
static int begin_nesting;

static void initassign(ENODE *node, int offset, TYP *tp)
{
    ENODE *ep1 = makenode(en_add,makeintnode(en_icon,offset),basenode); 
    deref(&ep1,tp);
    if (bits != -1) {
        ep1 = makenode(en_bits,ep1,0) ;
        ep1->bits = bits;
        ep1->startbit = startbit;
    }
    ep1 = makenode(en_assign,ep1,node);
    *sptr = makenode(en_void,ep1,0);
    sptr = &(*sptr)->v.p[1];
    bits = -1;
}
//-------------------------------------------------------------------------

ENODE *doeinit(ENODE *node,TYP *tp)
/*
 * Handle static variable initialize
 */
{
    int nbytes;
    ENODE *ep = makenode(en_clearblock, node,0);
    begin_nesting = 0;
    bits = -1;
    allocated = FALSE;
    ep->size = tp->size;
    locsp=node->v.sp;
    basenode = node;
    baseoffset = 0;
    sptr = &returnval;
    *sptr = makenode(en_void,ep,0) ;
    sptr = &(*sptr)->v.p[1];
    nbytes = einittype(tp);
    endinit();
    return returnval;
}

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

int einittype(TYP *tp)
/*
 * Init for basic types
 */
{
    int nbytes;
    begin_nesting++;
    switch (tp->type)
    {

        case bt_float:
            nbytes = einitfloat();
            break;
        case bt_longdouble:
            nbytes = einitlongdouble();
            break;
        case bt_double:
            nbytes = einitdouble();
            break;
        case bt_fcomplex:
            nbytes = einitfcomplex();
            break;
        case bt_rcomplex:
            nbytes = einitrcomplex();
            break;
        case bt_lrcomplex:
            nbytes = einitlrcomplex();
            break;
        case bt_bool:
        case bt_char:
            nbytes = einitchar();
            break;
        case bt_unsignedchar:
            nbytes = einituchar();
            break;
        case bt_unsignedshort:
            nbytes = einitushort();
            break;
        case bt_short:
        case bt_segpointer:
            nbytes = einitshort();
            break;
        case bt_farpointer:
            nbytes = einitfarpointer();
            break;
        case bt_pointer:
            if (tp->btp->type == bt_func)
            {
                nbytes = einitpointerfunc();
                break;
            }
            else if (tp->val_flag)
            // VARARRY doesn't get this far
                nbytes = einitarray(tp);
            else
                nbytes = einitpointer();
            break;
            case bt_ref:
                nbytes = einitref(tp);
                break;
        case bt_unsignedlong:
            nbytes = einitulong();
            break;
        case bt_unsigned:
            nbytes = einituint();
            break;
        case bt_enum:
            nbytes = einitenum();
            break;
        case bt_long:
            nbytes = einitlong();
            break;
        case bt_int:
        case bt_matchall:
            nbytes = einitint();
            break;
        case bt_longlong:
            nbytes = einitlonglong();
            break;
        case bt_unsignedlonglong:
            nbytes = einitulonglong();
            break;
        case bt_struct:
            nbytes = einitstruct(tp);
            break;
        case bt_union:
            nbytes = einitunion(tp);
            break;
#ifdef XXXXX
            case bt_memberptr:
                nbytes = einitmemberptr(tp, tp->sp);
                break;
#endif
        default:
            gensymerror(ERR_NOINIT, locsp->name);
            nbytes = 0;
    }
    begin_nesting--;
    return nbytes;
}

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

int einitarray(TYP *tp)
/*
 * Init for arrays
 */
{
    struct decldata **osptr = sptr, **sizearray;
    int nbytes, maxsize = -1;
    int index=0,size;
    int canpad = FALSE;
    char *p;
    int has_begin = TRUE ;
    nbytes = 0;
    if ((tp->btp->type == bt_char || tp->btp->type == bt_unsignedchar) &&
            lastst == sconst 
            || (tp->btp->type == bt_short || tp->btp->type == bt_unsignedshort) &&
            lastst == lsconst)
    {
        if (lastst == begin)
            getsym() ;
        else
            has_begin = FALSE;
        allocated = TRUE;
        nbytes = 0;
        if ((tp->btp->type == bt_char || tp->btp->type == bt_unsignedchar) &&
            lastst == sconst)
        {
            int label;
            ENODE *ep1,*ep2;
            char buf[MAX_STRLEN],*p = buf;
            buf[0] = 0;
            canpad = TRUE;
            nbytes = 1 ;
            while (lastst == sconst || lastst == lsconst)
            {
                if (lastst == sconst) {
                    memcpy(p,laststr,laststrlen);
                    p += laststrlen;
                    nbytes += laststrlen;
                } else {
                    p = laststr;
                    while (laststrlen--)
                    {
                        nbytes++;
                        agflush(1,  *((short *)p)++);
                    }
                }
                getsym();
            }
            *p = 0;
            if (has_begin)
                needpunc(end, skm_declend);
            tp->size = basenode->v.sp->tp->size = nbytes;
            label = stringlit(buf,FALSE,strlen(buf)+1);
            ep1 = makenode(en_add,copynode(basenode),makeintnode(en_icon,baseoffset));
            ep2 = makenode(en_moveblock,ep1,makenode(en_labcon,(void *)label,0)) ;
            ep2->size = strlen(buf)+1 < tp->size ? strlen(buf)+1 : tp->size ;
            (*sptr) = makenode(en_void,ep2,0) ;
            sptr = &(*sptr)->v.p[1];
        }
        else if ((tp->btp->type == bt_short || tp->btp->type ==
            bt_unsignedshort) && lastst == lsconst)
        {
            int label;
            ENODE *ep1, *ep2;
            short buf[MAX_STRLEN], *p = buf;
            buf[0] = 0;
            nbytes = 2;
            while (lastst == lsconst || lastst == sconst)
            {
                if (lastst == lsconst) {
                    memcpy(p,laststr, laststrlen * 2) ;
                    p += pstrlen(p) ;
                } else {
                    int i;
                    for (i=0; i < laststrlen; i++)
                        *p++ = laststr[i];
                }
                nbytes += laststrlen * 2;
                getsym();
            }
            *p = 0;
            if (has_begin)
                needpunc(end, skm_declend);
            tp->size = basenode->v.sp->tp->size = nbytes;
            label = stringlit(buf,TRUE,pstrlen(buf)*2+2);
            ep1 = makenode(en_add,copynode(basenode),makeintnode(en_icon,baseoffset));
            ep2 = makenode(en_moveblock,ep1,makenode(en_labcon,(void *)label,0)) ;
            ep2->size = pstrlen(buf)*2+2 < tp->size ? pstrlen(buf)*2+2 : tp->size ;
            (*sptr) = makenode(en_void,ep2,0) ;
            sptr = &(*sptr)->v.p[1];
        }
        else
            generror(ERR_PUNCT, semicolon, 0);
    }
    else
    {            
        if (begin_nesting == 1)
            needpunc(begin,0) ;
        else
            if (lastst == begin)
                getsym() ;
            else
                has_begin = FALSE;
        size = tp->size/tp->btp->size ;
        if (size ==0)
            maxsize = 50;
        sizearray = xalloc(sizeof(struct decldata *) * (size == 0 ? maxsize : size));
        while (lastst != end && lastst != eof)
        {
            if (prm_cplusplus && isstructured(tp->btp) && search
                (cpp_funcname_tab[CI_CONSTRUCTOR], &tp->btp->lst))
            {
                if (!strcmp(lastid, tp->btp->sp->name))
                {
                    TYP *tp1;
                    ENODE *qn;
                    getsym();
                    if (lastst == openpa)
                    {
                        getsym();
                        tp1 = gatherparms(&qn, FALSE);
                        headptr = &head;
                        head = tp->btp;
                        conspair(locsp, sc_global,  - 1, tp1, qn, FALSE, nbytes,
                            FALSE);
                        parm_ns_level--;
                        nbytes += tp->btp->size;
                    }
                    else
                    {
                        backup(id);
                        goto join;
                    }
                }
                else
                {
                    ENODE *qn;
                    TYP *tp2;
                    join: tp2 = exprnc(&qn);
                    if (tp2)
                    {
                        SYM *sm;
                        TYP *tp1 = maketype(bt_func, 0);
                        qn = makenode(en_void, qn, 0);
                        sm = makesym(0);
                        tp1->lst.head = tp1->lst.tail = sm;
                        sm->tp = tp2;
                        headptr = &head;
                        head = tp->btp;
                        conspair(locsp, sc_global,  - 1, tp1, qn, FALSE, nbytes,
                            TRUE);
                        nbytes += tp->btp->size;
                    }
                    else
                        generror(ERR_ILLINIT, 0, 0);
                }
            }
            else {
                int ofs = baseoffset ;
                if (prm_c99 && lastst == openbr) 
                {
                    int l;
                    getsym() ;
                    l = intexpr(0);
                    index = l;
                    needpunc(closebr,0);
                    needpunc(assign,0);
                }
                    if (index >= size) 
                    {
                        if (maxsize == -1) 
                        {
                            index = 0;
                            generror(ERR_INITSIZE, 0, 0);
                        } 
                        else
                        {
                            size = index + 1 ;
                            if (size > maxsize)
                            {
                                struct decldata *newarray ;
                                int oldsize = maxsize;
                                maxsize = size + 50 ;
                                
                                newarray = xalloc(sizeof(struct decldata *) * maxsize);
                                memcpy(newarray,sizearray,sizeof(struct decldata *) * oldsize) ;
                                sizearray = newarray;
                            }  
                        }
                    }
                sptr = &sizearray[index];
                *sptr = 0;
                baseoffset += index * tp->btp->size;
                einittype(tp->btp);
                index++;
                baseoffset = ofs ;
            }
            if (maxsize == -1 && !has_begin && index >= size)
                break;
            if (lastst == comma)
                getsym();
            else if (lastst != end)
            {
                expecttoken(end, 0);
                break;
            }
        }
        if (has_begin)
            needpunc(end,0);
        
        sptr = osptr;
        nbytes = 0 ;
        for (index=0;index < size;index++) 
        {
            *sptr = sizearray[index];
            while (*sptr)
                sptr = &(*sptr)->v.p[1];
        }
        nbytes = size * tp->btp->size;
        if (maxsize != -1)
            basenode->v.sp->tp->size = nbytes;
    }
    return tp->size;
}

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

int einitunion(TYP *tp)
{
    int nbytes=0, has_begin = TRUE;
    struct decldata **osptr = sptr;
    int ooffset;
    SYM *sp = tp->lst.head;
    if (begin_nesting == 1)
    {
        if (!needpunc(begin,skm_declend))
            return tp->size;       
    }
    else
        if (lastst == begin)
            getsym() ;
        else
            has_begin = FALSE;
    ooffset = baseoffset;
    if (prm_c99 && lastst == dot) 
    {
        getsym() ;
        if (lastst == id) 
        {
            SYM *sp1 = tp->lst.head ;
            while (sp1) {
                if (!strcmp(sp1->name,lastid)) 
                    break ;
                sp1 = sp1->next;
            }
            if (!sp1)
                gensymerror(ERR_UNDEFINED,lastid) ;
            else
                sp = sp1;
            getsym();
            needpunc(assign,0);
        }
        else
            gensymerror(ERR_UNDEFINED,lastid) ;
    } 
    sptr = &sp->init;
    sp->init = 0;
    baseoffset += sp->value.i;
    inittype(sp->tp);
    baseoffset = ooffset;
    sp = tp->lst.head; /* start at top of symbol table */
    sptr = osptr;
    while (sp) 
    {
        *sptr = sp->init;
        while (*sptr)
            sptr = &(*sptr)->v.p[1];
        if (sp->init) 
        {
            sp->init = 0;
            break;
        }
        sp = sp->next;
    }
    if (has_begin)
        needpunc(end, 0);
    if (nbytes < tp->size)
        makestorage(tp->size - nbytes);
    return tp->size;
}

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

int einitstruct(TYP *tp)
/*
 * Init for structures
 */
{
    SYM *sp;
    struct decldata *osptr = sptr;
    int nbytes;
    int has_begin = TRUE;
    if (prm_cplusplus && lastst == id)
    {
        if (lastst != id)
            generror(ERR_IDEXPECT, 0, skm_declend);
        else
        {
            ENODE *ep1,  *ep2;
            TYP *tp2;
            ep1 = makenode(en_nacon, (void*)locsp, 0);
            if (tp->val_flag == 0)
                tp = deref(&ep1, tp);
            tp2 = exprnc(&ep2);
            if (!exactype(tp, tp2, FALSE))
                cppcast(tp2, tp, &ep2, FALSE);
            if (ep2->nodetype == en_callblock)

⌨️ 快捷键说明

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