📄 template.c
字号:
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 + -