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

📄 declass.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"

#define VTABVALTHRESH (1024 * 1024)

extern ENODE *expr_runup[50];
extern ENODE *expr_rundown[50];
extern int expr_updowncount;

extern int prm_xcept;
extern int global_flag;
extern int typequal;
extern int skm_closepa[], skm_declbegin[];
extern LIST *instantiated_inlines;
extern int prm_cplusplus;
extern ENODE *thisenode;
extern char *cpp_funcname_tab[];
extern int lastst;
extern int skm_declcomma[];
extern int skm_declclosepa[];
extern int stdaddrsize;
extern ENODE *block_rundown;
extern SYM *declclass;
extern char lastid[];
extern TYP stdmatch;
extern TABLE lsyms;
extern SYM undef;
extern long nextlabel;
extern TYP stdvoidfunc;
extern SYM *currentfunc;

TABLE *baseasnsymtbl;

int classhead;
int vtabhead;
static TABLE vmptab;
static TYP functovoidtype = 
{
    bt_func, 0, 0,  - 1,  - 1, 4
};
static TYP vtyp;

void defclassini(void)
{
    vtyp.type = bt_func;
    vtyp.lst.head = vtyp.lst.tail =  - 1;
    vtyp.cflags = 0;
    vtabhead = stdaddrsize * 3;
    classhead = stdaddrsize;
    vmptab.head = 0;
    functovoidtype.lst.head =  - 1;
    functovoidtype.btp = maketype(bt_void, 0);
}

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

void SetExtFlag(SYM *sp, int state)
{
    sp->mainsym->extflag = state;
    if (state && (sp->value.classdata.cppflags &PF_INLINE) && !(sp
        ->value.classdata.cppflags &PF_INSTANTIATED))
    {
        LIST *l;
        global_flag++;
        l = xalloc(sizeof(LIST));
        global_flag--;
        l->data = sp;
        l->link = instantiated_inlines;
        instantiated_inlines = l;
        sp->value.classdata.cppflags |= PF_INSTANTIATED;
        sp->value.classdata.cppflags &= ~PF_INLINE;
    }
}

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

SYM *copysym(SYM *sp)
{
    SYM *rv = xalloc(sizeof(SYM));
    *rv =  *sp;
    rv->next = 0;
    return rv;
}

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

    static int copydata(SYM *sym, SYM *from, int mode)
    {
        int size = sym->value.classdata.size;

        TABLE *dest = &sym->tp->lst;

        if (from)
        {
            SYM *head = from->tp->lst.head;
            while (head)
            {
                SYM *sp;
                if (head->storage_class == sc_friendlist)
                {
                    TABLE *t;
                    SYM *sp1;
                    if (!(sp = basesearch(head->name, dest, FALSE)))
                    {
                        sp = copysym(head);
                        sp->tp = cponetype(sp->tp);
                        sp->tp->sp = sp;
                        sp->tp->lst.head = sp->tp->lst.tail = 0;
                    }
                    t = &sp->tp->lst;
                    sp1 = head->tp->lst.head;
                    while (sp1)
                    {
                        SYM *sp2 = copysym(sp1);
                        if (!t->head)
                            t->head = t->tail = sp2;
                        else
                            t->tail = t->tail->next = sp2;
                        sp1 = sp1->next;
                    }
                    if (!dest->head)
                        dest->head = dest->tail = sp;
                    else
                        dest->tail = dest->tail->next = sp;
                    head = head->next;
                    continue;
                }
                sp = copysym(head);
                if (!sp->mainsym)
                    sp->mainsym = head;
                sp->next = 0;
                sp->parentclass = sym;
                sp->value.classdata.cppflags |= PF_INHERITED;
                if (sp->value.classdata.cppflags &PF_VIRTUAL)
                    sp->value.classdata.cppflags |= PF_NODEF;
                if (sp->value.classdata.cppflags &PF_PRIVATE)
                    sp->value.classdata.cppflags |= PF_UNREACHABLE;

                if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
                    sp->value.classdata.vtaboffs += size;
                else if (sp->tp->type == bt_defunc)
                {
                    SYM *head2 = dest->head;
                    SYM *head3 = sp->tp->lst.head;
                    int retagged = 0;
                    while (head2)
                    {
                        if (!strcmp(head2->name, sp->name) && head2->tp->type 
                            == bt_defunc)
                        {
                            sp = head2;
                            retagged = TRUE;
                            break;
                        }
                        head2 = head2->next;
                    }
                    if (!retagged)
                    {
                        sp->tp = cponetype(sp->tp);
                        sp->tp->sp = sp;
                        sp->tp->lst.head = sp->tp->lst.tail = 0;
                    }
                    head2 = head3;
                    while (head2)
                    {
                        if (!(head2->value.classdata.cppflags &(PF_CONSTRUCTOR 
                            | PF_DESTRUCTOR)))
                        {
                            SYM *s = copysym(head2);
                            s->value.classdata.cppflags |= PF_INHERITED;
                            if (!s->mainsym)
                                s->mainsym = head2;
                            if (s->value.classdata.cppflags &PF_VIRTUAL)
                                s->tp = copytype(s->tp, 0);
                            s->value.classdata.vtaboffs += size;
                            if (sp->tp->lst.head)
                                sp->tp->lst.tail = sp->tp->lst.tail->next = s;
                            else
                                sp->tp->lst.head = sp->tp->lst.tail = s;
                            s->next = 0;
                        }
                        head2 = head2->next;
                    }
                    if (retagged || sp->tp->lst.head == 0)
                    {
                        head = head->next;
                        continue;
                    }
                }
                else
                    sp->value.i += size;

                if (mode == BM_PRIVATE)
                {
                    sp->value.classdata.cppflags &= ~(PF_PUBLIC | PF_PROTECTED);
                    sp->value.classdata.cppflags |= PF_PRIVATE;
                }
                else
                {
                    if (mode == BM_PROTECTED && (sp->value.classdata.cppflags
                        &PF_PUBLIC))
                    {
                        sp->value.classdata.cppflags &= ~PF_PUBLIC;
                        sp->value.classdata.cppflags |= PF_PROTECTED;
                    }
                }
                if (!dest->head)
                    dest->head = dest->tail = sp;
                else
                    dest->tail = dest->tail->next = sp;
                head = head->next;
            }
        }
        return size;
    }
    int loadclassdata(SYM *sp, SYM *spc, int mode, int virtual)
    {
        CLASSLIST *l = spc->value.classdata.baseclass,  *lo = sp
            ->value.classdata.baseclass,  **lp = &lo;
        CLASSLIST *x = lo->link;
        int rv = copydata(sp, spc, mode);
        int first = 2, primary = 1, firstrun;
        int ofs = lo->vtabsize - 12;
        while (*lp)
        {
            first--;
            if (!first)
                break;
            lp = &(*lp)->link;
        }
        {
            LIST **vlist = &lo->vtablist,  *slst = l->vtablist;
            int voffs = lo->vtabsize - 12;
            int offs = sp->value.classdata.size;
            while (*vlist)
                vlist =  *vlist;
            if (!first)
            {
                *vlist = xalloc(sizeof(LIST));
                (*vlist)->data = rv;
                vlist = &(*vlist)->link;
                *vlist = xalloc(sizeof(LIST));
                (*vlist)->data = lo->vtabsize - 12+8;
                vlist = &(*vlist)->link;
                lo->vtabsize += 2 * stdaddrsize;
                ofs += 2 * stdaddrsize;
                voffs += 2 * stdaddrsize;
            }
            while (slst)
            {
                if ((int)slst->data < VTABVALTHRESH)
                {
                    *vlist = xalloc(sizeof(LIST));
                    (*vlist)->data = (void*)((int)slst->data + offs);
                    vlist = &(*vlist)->link;
                    slst = slst->link;
                    *vlist = xalloc(sizeof(LIST));
                    (*vlist)->data = (void*)((int)slst->data + voffs);
                    vlist = &(*vlist)->link;
                    slst = slst->link;
                }
                else
                {
                    *vlist = xalloc(sizeof(LIST));
                    (*vlist)->data = slst->data;
                    vlist = &(*vlist)->link;
                    slst = slst->link;
                }
            }
        }
        firstrun = first;
        lp = &lo->link;
        while (l)
        {
            LIST *vlst = 0,  **vlstp = &vlst,  *slst;
            *lp = xalloc(sizeof(CLASSLIST));
            (*lp)->data = l->data;
            (*lp)->offset = l->offset + rv;
            (*lp)->vtabsize = l->vtabsize;
            if (primary)
                lo->vtabsize += l->vtabsize - vtabhead;
            if (l->flags &CL_VTAB)
            {
                (*lp)->flags |= CL_VTAB;
                lo->flags |= CL_VTAB;
            }
            (*lp)->vtaboffs = l->vtaboffs + ofs;
            (*lp)->vtabsp = l->vtabsp;
            if (primary)
                (*lp)->flags |= CL_PRIMARY;
            if (firstrun && l->offset + rv == 0)
                (*lp)->flags |= CL_TOPCLASS;
            if (l->mode == BM_PRIVATE || mode == BM_PRIVATE)
                (*lp)->mode = BM_PRIVATE;
            else if (l->mode == BM_PROTECTED || mode == BM_PROTECTED)
                (*lp)->mode = BM_PROTECTED;
            else
                (*lp)->mode = BM_PUBLIC;
            (*lp)->vtablist = vlst;
            (*lp)->link = x;
            lp = &(*lp)->link;
            first = FALSE;
            primary = FALSE;
            l = l->link;
        }
        sp->value.classdata.size = rv + spc->value.classdata.size;
        return sp->value.classdata.size;
    }
	int insertVirtualData(SYM *sp)
	{
		return 0 ;
	}
    static char *findname(char *buf)
    {
        char *buf1 = buf;
        while (TRUE)
        {
            buf1 = strchr(buf1 + 1, '$');
            if (!buf1)
                return FALSE;

            if (*(buf1 - 1) != '@')
            {
                while (*(buf1 - 1) != '@' && buf1 != buf)
                    buf1--;
                return buf1;
            }
        }
    }
    static int vtabmatch(SYM *candidate, SYM *current)
    {
        char *cbuf = candidate->name;
        char *ubuf = current->name;
        if (!exactype(candidate->tp, current->tp, FALSE))
            return FALSE;
        cbuf = findname(cbuf);
        ubuf = findname(ubuf);
        if (!cbuf || !ubuf)
            return FALSE;
        return (!strcmp(cbuf, ubuf));
    }
    void addvtabentry(SYM *cl, SYM *sp)
    {
        CLASSLIST *l = cl->value.classdata.baseclass;
        LIST **lst;
        SetExtFlag(sp, TRUE);
        if (sp->tp->type == bt_func)
            sp->storage_class = sc_externalfunc;
        if (l->flags &CL_VTAB)
        {
            LIST *lst = l->vtablist;
            while (lst)
            {
                SYM *sp1 = lst->data;
                if (sp1 > VTABVALTHRESH)
                {
                    if (vtabmatch(sp, sp1))
                    {
                        CLASSLIST *l1 = l;
                        while (l1 && l1->data->mainsym != sp1->parentclass
                            ->mainsym)
                            l1 = l1->link;
                        if (l1 && l1->offset)
                        {
                            SYM *sp2 = gen_vsn_virtual_thunk(sp, l1->offset);

⌨️ 快捷键说明

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