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

📄 template.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
                        break;
                    sx = sx->next;
                } if (!sx)
                {
                    if (tp->type == bt_templateplaceholder)
                        *ps = copysym(tp->lst.head);
                    else
                        *ps = copysym(tp->sp);
                }
                else
                {
                    (*ps) = copysym(sx);
                }
                (*ps)->next = 0;
                ps = &(*ps)->next;
                s2 = s2->next;
                tn = tn->link;
            }
            global_flag--;
            currentTemplate->classes.head = s1;
        }
    #endif 
    return tnorig;
}

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

void tsname(char *unmang, char *name)
{
    char *p = unmang,  *q;
    unmangle(unmang, name);
    while (*p &&  *p != '<')
        p++;
    q = p;
    while (*p &&  *p != '>')
    {
        if (*p == '(')
        {
            p++;
            do
            {
                q--;
            }
            while (*q != '<' &&  *q != ',');
            q++;
            while (*p &&  *p != ')')
                *q++ =  *p++;
            if (*p)
                p++;
        }
        else
            *q++ =  *p++;
    }

    while (*p)
        *q++ =  *p++;
    *q =  *p;
}

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

static int spcomp(TYP **lst, int *count, int *partials, struct template  *tm,
    LIST *fi, LIST *ti)
{
    while (ti && fi)
    {
        TYP *t = ti->data,  *f = fi->data;
        if (t->type == bt_class)
        {
            int index = tlookup(t, tm);
            if (index !=  - 1)
            {
                if (index >=  *count)
                    *count = index + 1;
                else if (lst[index] && !exactype(lst[index], f, FALSE))
                    return FALSE;
                lst[index] = f;
            } 
            else
            {
                return FALSE;
            }
        }
        else if (t->type == bt_templateplaceholder)
        {
            if (f->type != bt_templateplaceholder)
                return FALSE;
            if (strcmp(t->lst.head->name, f->lst.head->name))
                return FALSE;
            if (!spcomp(lst, count, partials, tm, (LIST*)f->lst.tail, t
                ->lst.tail))
                return FALSE;
        }
        else
        {
            if (!exactype(fi, ti, FALSE))
                return FALSE;
        }
        (*partials)++;
        ti = ti->link;
        fi = fi->link;
    }
    return !(fi || ti);
}

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

static SYM *specialize(SYM *sp, TYP **tn)
{
    SYM *spx = search("$$DETEMP", &sp->tp->lst.head);
    int maxpartials = 0;
    SYM *hold;
    TYP *maxtyplst[100];
    int maxcount = 0;
    int i;
    if (spx)
    {
        spx = spx->tp->lst.head;
        while (spx)
        {
            TYP *typlst[100];
            int typcount = 0;
            int partials = 0;
            struct template  *tm = spx->value.classdata.templatedata;
            memset(typlst, 0, sizeof(typlst));
            if (spcomp(typlst, &typcount, &partials, tm,  *tn, spx
                ->value.classdata.templateargs))
            {
                SYM *t = tm->classes.head;
                for (i = 0; i<typcount || t; i++, t = t ? t->next: 0)
                if (!typlst[i])
                {
                    if (t && t->defalt)
                    {
                        typlst[i] = t->defalt;
                        if (i >= typcount)
                            typcount++;
                    } break;
                }
                if (i >= typcount)
                {
                    if (partials && partials == maxpartials)
                        gensymerror(ERR_AMBIGTEMPLATE, sp->name);
                    if (partials > maxpartials)
                    {
                        maxpartials = partials;
                        maxcount = typcount;
                        memcpy(maxtyplst, typlst, typcount *sizeof(int));
                        hold = spx;
                    }
                }
            }
            spx = spx->next;
        }
    }
    if (maxpartials)
    {
        LIST **x = tn;
        for (i = 0; i < maxcount; i++)
        {
            *x = xalloc(sizeof(LIST));
            (*x)->data = maxtyplst[i];
            x = &(*x)->link;
        }
        return hold;
    }
    return sp;
}

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

SYM *lookupTemplateType(SYM *tempsym, int cppflags)
{
    SYM *sp,  *rv;
    TYP *ohead = head,  *otail = tail,  **oheadptr = headptr;
    int odlft = defaulttype;
    struct template  *tm;
    char name[256], unmangname[512],  *p,  *nm = tempsym->name;
    LIST *tn = 0,  **tnail = &tn;
    int len, max;
    char *buf;
    LIST *to = 0,  **ton = &to;
    SYM *sp1,  *s1;
    tm = tempsym->value.classdata.templatedata;
    getsym();
    if (recordingTemplate || matching)
    {
        // need to make a template placeholder type
        rv = tm->classes.head;
        global_flag++;
        matchandmangle(name, nm, tnail, tm->classes.head);
        tempsym = specialize(tempsym, &tn);
        rv = copysym(tempsym);
        rv->tp = maketype(bt_templateplaceholder, 0);
        rv->tp->lst.head = tempsym; /* so we can declclass it */
        rv->tp->lst.tail = tn; /* for type matching later if we need it */
        global_flag--;
    } 
    else
    {
        // else are instantiating a template
        TYP *thead = head,  **theadptr = headptr,  *ttail = tail;
        TYP *tcq = typequal;
        typequal = 0;
        matchandmangle(name, nm, tnail, tm->classes.head);
        tempsym = specialize(tempsym, &tn);
        tm = tempsym->value.classdata.templatedata;
        tsname(unmangname, name);
        head = thead;
        tail = ttail;
        headptr = theadptr;
        rv = search(name, tagtable);
        typequal = tcq;
        if (!rv)
        {
            LIST *t = tn;
            s1 = tm->classes.head;
            while (t && s1)
            {
                if (s1->tp->type != bt_class)
                {
                    if (!((TYP*)t->data)->sp || ((TYP*)t->data)->sp
                        ->storage_class != sc_tconst)
                        break;
                }
                else if (((TYP*)t->data)->sp && ((TYP*)t->data)->sp
                    ->storage_class == sc_tconst)
                    break;
                t = t->link;
                s1 = s1->next;
            }
            if (t || s1)
            {
                gensymerror(ERR_AMBIGTEMPLATE, nm);
                return 0;
            }
            sp1 = tm->classes.head;
            while (sp1)
            {
                *ton = xalloc(sizeof(LIST));
                (*ton)->data = sp1->tp;
                ton = &(*ton)->link;
                sp1 = sp1->next;
            }
            buf = xalloc(tm->linemax *sizeof(short));
            memcpy(buf, tm->lines, tm->linemax *sizeof(short));
            len = tm->linelen;
            max = tm->linemax;
            savecontext();
            statictemplate |= cppflags & PF_STATIC;
            interjectptr = llreplace2(buf, &max, &len, tempsym->name,
                unmangname);
            interjectptr = replace2(interjectptr, &max, &len, to, tn);
            setunaltered();
            infile = errfile = tm->filename;
            lineno = errlineno = tm->lineno;
            global_flag++;
            getch();
            getsym();
            dodecl(sc_global);
            restorecontext();
            rv = search(name, tagtable);
            //		 if (rv) {
            //			 rv->value.classdata.templateparent = tempsym ;
            //			 rv->value.classdata.templateargs = tn ;
            //		 }
            instantiateTemplateFuncs(tempsym, rv, tn, TRUE);
            global_flag--;
        } 
//        else
//            rv->tp->size = rv->mainsym->tp->size;
        defaulttype = odlft;
    }
    head = ohead;
    tail = otail;
    headptr = oheadptr;
    return rv;

}

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

void replaceTemplateFunctionClasses(SYM *sp, SYM *typequal)
{
    SYM *s,  *t;
    if (!templateLookup || !typequal || !typequal->istemplate)
        return ;
    sp = sp->tp->lst.head;
    while (sp)
    {
        if (sp->tp->type == bt_class)
        {
            s = currentTemplate->classes.head;
            t = typequal->value.classdata.templatedata->classes.head;
            while (s && t)
            {
                if (!strcmp(s->name, sp->tp->sp->name))
                {
                    sp->tp = t->tp;
                    break;
                }
                s = s->next;
                t = t->next;
            }
        }
        sp = sp->next;
    }
}

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

void templateMatchCheck(SYM *tq, struct template  *p)
{
    SYM *s,  *t;
    if (!tq || !p || !tq->istemplate|| !tq->value.classdata.templatedata)
        return ;
    s = p->classes.head;
    t = tq->value.classdata.templatedata->classes.head;
    while (s && t)
    {
        s = s->next;
        t = t->next;
    } if (s || t)
        generror(ERR_TEMPLATEFUNCMATCHCLASS, 0, 0);
}

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

void replaceSize(TYP *candidate)
{
    // this still be buggy for nested classes that return structs corresponding to their parents...
    while (candidate->type == bt_pointer || candidate->type == bt_ref ||
        candidate->type == bt_farpointer || candidate->type == bt_segpointer)
        candidate = candidate->btp;
    if (isstructured(candidate) && !candidate->size)
        candidate->size = candidate->sp->mainsym->tp->size;
}

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

void parseClassFuncs(ILIST *l)
{
    while (l)
    {
        SYM *sp1 = (SYM*)l->sp;
        if (sp1->value.classdata.templatedata)
        {
            savecontext();
            sp1->parentclass = declclass = l->dc;
            infile = errfile = sp1->value.classdata.templatedata->filename;
            lineno = errlineno = sp1->value.classdata.templatedata->lineno;
            interjectptr = sp1->value.classdata.templatedata->lines;
            setunaltered();
            getch();
            if (lastch == ':')
            {
                lastst = colon;
                getch();
                classbaseasn(declclass, sp1);
                if (lastst != begin)
                    generror(ERR_NEEDCHAR, '{', 0);
            }
            else
            {
                lastst = begin;
                getch();
            }
            funcbody(sp1);
            interjectptr = 0;
            restorecontext();
            sp1->value.classdata.templatedata = 0;
        }
        l = l->next;
    }
}

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

void checkTemplateSpecialization(SYM *sp, char *name)
{
    struct template  *tpl = sp->value.classdata.templatedata;
    char nm[256];
    SYM *sp1 = tpl->classes.head;
    tpl->partials = tpl->argcount = 0;
    while (sp1 && sp1 != (SYM*) - 1)
    {
        if (tlookup(sp1->tp, tpl) ==  - 1 && sp1->tp->sp->storage_class ==
            sc_const)
            tpl->partials++;
        tpl->argcount++;
        sp1 = sp1->next;
    } if (tpl->partials)
    {
        matchandmangle(nm, name, 0, tpl->classes.head);
        if (sp == specialize(sp, nm))
        {
            gensymerror(ERR_SPECIALIZATION, sp->name);
        }
    }
}

⌨️ 快捷键说明

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