Commit 74427c63 authored by Ken Thompson's avatar Ken Thompson

DOTDOTDOT

R=r
OCL=18317
CL=18317
parent 6fff0efd
......@@ -119,6 +119,9 @@ dowidth(Type *t)
case TFLOAT80:
w = 10;
break;
case TDDD:
w = 2*wptr;
break;
case TINTER: // implemented as 2 pointers
case TFORWINTER:
offmod(t);
......
......@@ -1557,6 +1557,7 @@ isfat(Type *t)
case TSTRUCT:
case TARRAY:
case TINTER: // maybe remove later
case TDDD: // maybe remove later
return 1;
}
return 0;
......
......@@ -597,6 +597,7 @@ int isptrarray(Type*);
int isptrdarray(Type*);
int isinter(Type*);
int isnilinter(Type*);
int isddd(Type*);
Sym* globalsig(Type*);
Type* ismethod(Type*);
Type* methtype(Type*);
......
......@@ -818,6 +818,7 @@ etnames[] =
[TBOOL] = "BOOL",
[TPTR32] = "PTR32",
[TPTR64] = "PTR64",
[TDDD] = "DDD",
[TFUNC] = "FUNC",
[TARRAY] = "ARRAY",
// [TDARRAY] = "DARRAY",
......@@ -1453,8 +1454,12 @@ isselect(Node *n)
int
isinter(Type *t)
{
if(t != T && t->etype == TINTER)
return 1;
if(t != T) {
if(t->etype == TINTER)
return 1;
if(t->etype == TDDD)
return 1;
}
return 0;
}
......@@ -1468,6 +1473,14 @@ isnilinter(Type *t)
return 1;
}
int
isddd(Type *t)
{
if(t != T && t->etype == TDDD)
return 1;
return 0;
}
Type*
ismethod(Type *t)
{
......@@ -1604,6 +1617,7 @@ globalsig(Type *t)
return S;
case TINTER:
case TDDD:
if(isnilinter(t)) {
snprint(buf, sizeof(buf), "%s_%s", "sigi", "inter");
goto out;
......@@ -1670,6 +1684,10 @@ signame(Type *t, int block)
if(t == T)
goto bad;
ss = globalsig(t);
if(ss != S)
return ss;
s = t->sym;
if(s == S) {
if(isptr[t->etype]) {
......@@ -1682,10 +1700,6 @@ signame(Type *t, int block)
goto bad;
}
ss = globalsig(t);
if(ss != S)
return ss;
e = "sigt";
if(t->etype == TINTER)
e = "sigi";
......
......@@ -1555,10 +1555,7 @@ loop:
a = nod(OAS, l, r);
a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn);
nn = list(a, nn);
l = listnext(&savel);
r = listnext(&saver);
......@@ -1595,10 +1592,7 @@ loop:
a = nod(OAS, l, nodarg(r, fp));
a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn);
nn = list(a, nn);
l = listnext(&savel);
r = structnext(&saver);
......@@ -1606,6 +1600,109 @@ loop:
goto loop;
}
/*
* make a tsig for the structure
* carrying the ... arguments
*/
Type*
sigtype(Type *st)
{
Dcl *x;
Sym *s;
Type *t;
static int sigdddgen;
dowidth(st);
sigdddgen++;
snprint(namebuf, sizeof(namebuf), "dsigddd_%d", sigdddgen);
s = lookup(namebuf);
t = newtype(s);
t = dodcltype(t);
updatetype(t, st);
// record internal type for signature generation
x = mal(sizeof(*x));
x->op = OTYPE;
x->dsym = s;
x->dtype = s->otype;
x->forw = signatlist;
x->block = block;
signatlist = x;
return s->otype;
}
/*
* package all the arguments that
* match a ... parameter into an
* automatic structure.
* then call the ... arg (interface)
* with a pointer to the structure
*/
Node*
mkdotargs(Node *r, Iter *saver, Node *nn, Type *l, int fp)
{
Type *t, *st, *ft;
Node *a, *n, *var;
Iter saven;
n = N; // list of assignments
st = typ(TSTRUCT); // generated structure
ft = T; // last field
while(r != N) {
defaultlit(r);
// generate the next structure field
t = typ(TFIELD);
t->type = r->type;
if(ft == T)
st->type = t;
else
ft->down = t;
ft = t;
a = nod(OAS, N, r);
n = list(n, a);
r = listnext(saver);
}
// make a named type for the struct
st = sigtype(st);
// now we have the size, make the struct
var = nod(OXXX, N, N);
tempname(var, st);
// assign the fields to the struct
n = rev(n);
r = listfirst(&saven, &n);
t = st->type;
while(r != N) {
r->left = nod(OXXX, N, N);
*r->left = *var;
r->left->type = r->right->type;
r->left->xoffset += t->width;
nn = list(r, nn);
r = listnext(&saven);
t = t->down;
}
// last thing is to put assignment
// of a pointer to the structure to
// the DDD parameter
a = nod(OADDR, var, N);
a->type = ptrto(st);
a = nod(OAS, nodarg(l, fp), a);
a = convas(a);
nn = list(a, nn);
return nn;
}
Node*
ascompatte(int op, Type **nl, Node **nr, int fp)
{
......@@ -1622,7 +1719,21 @@ ascompatte(int op, Type **nl, Node **nr, int fp)
l = structfirst(&savel, nl);
r = listfirst(&saver, nr);
nn = N;
loop:
if(l != T && isddd(l->type)) {
if(r != T && isddd(r->type)) {
goto more;
}
nn = mkdotargs(r, &saver, nn, l, fp);
l = structnext(&savel);
if(l != T)
yyerror("... must be last argument");
return rev(nn);
}
if(l == T || r == N) {
if(l != T || r != N)
yyerror("error in shape across %O", op);
......@@ -1634,12 +1745,10 @@ loop:
return N;
}
more:
a = nod(OAS, nodarg(l, fp), r);
a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn);
nn = list(a, nn);
l = structnext(&savel);
r = listnext(&saver);
......@@ -2518,6 +2627,8 @@ isandss(Type *lt, Node *r)
rt = r->type;
if(isinter(lt)) {
if(isinter(rt)) {
if(isnilinter(lt) && isnilinter(rt))
return Inone;
if(!eqtype(rt, lt, 0))
return I2I;
return Inone;
......@@ -2649,6 +2760,9 @@ convas(Node *n)
if(n->op != OAS)
fatal("convas: not OAS %O", n->op);
lt = T;
rt = T;
l = n->left;
r = n->right;
if(l == N || r == N)
......@@ -2747,10 +2861,7 @@ colas(Node *nl, Node *nr)
walktype(r, Erv);
defaultlit(r);
a = old2new(l, r->type);
if(n == N)
n = a;
else
n = list(n, a);
n = list(n, a);
l = listnext(&savel);
r = listnext(&saver);
......@@ -2785,10 +2896,7 @@ multi:
t = structfirst(&saver, getoutarg(t));
while(l != N) {
a = old2new(l, t->type);
if(n == N)
n = a;
else
n = list(n, a);
n = list(n, a);
l = listnext(&savel);
t = structnext(&saver);
}
......@@ -2877,16 +2985,12 @@ loop2:
if(l == N) {
r = rev(r);
g = rev(g);
if(g != N)
f = list(g, f);
f = list(g, f);
r = list(f, r);
return r;
}
if(l->ullman < UINF) {
if(r == N)
r = l;
else
r = list(l, r);
r = list(l, r);
goto more;
}
if(f == N) {
......@@ -2898,19 +3002,12 @@ loop2:
a = nod(OXXX, N, N);
tempname(a, l->right->type);
a = nod(OAS, a, l->right);
if(g == N)
g = a;
else
g = list(a, g);
g = list(a, g);
// put normal arg assignment on list
// with fncall replaced by tempname
l->right = a->left;
if(r == N)
r = l;
else
r = list(l, r);
r = list(l, r);
more:
l = listnext(&save);
......@@ -3040,20 +3137,14 @@ reorder3(Node *n)
q = N;
l1 = listfirst(&save1, &n);
while(l1 != N) {
if(q == N)
q = l1;
else
q = list(q, l1);
q = list(q, l1);
l1 = listnext(&save1);
}
r = rev(r);
l1 = listfirst(&save1, &r);
while(l1 != N) {
if(q == N)
q = l1;
else
q = list(q, l1);
q = list(q, l1);
l1 = listnext(&save1);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment