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) ...@@ -119,6 +119,9 @@ dowidth(Type *t)
case TFLOAT80: case TFLOAT80:
w = 10; w = 10;
break; break;
case TDDD:
w = 2*wptr;
break;
case TINTER: // implemented as 2 pointers case TINTER: // implemented as 2 pointers
case TFORWINTER: case TFORWINTER:
offmod(t); offmod(t);
......
...@@ -1557,6 +1557,7 @@ isfat(Type *t) ...@@ -1557,6 +1557,7 @@ isfat(Type *t)
case TSTRUCT: case TSTRUCT:
case TARRAY: case TARRAY:
case TINTER: // maybe remove later case TINTER: // maybe remove later
case TDDD: // maybe remove later
return 1; return 1;
} }
return 0; return 0;
......
...@@ -597,6 +597,7 @@ int isptrarray(Type*); ...@@ -597,6 +597,7 @@ int isptrarray(Type*);
int isptrdarray(Type*); int isptrdarray(Type*);
int isinter(Type*); int isinter(Type*);
int isnilinter(Type*); int isnilinter(Type*);
int isddd(Type*);
Sym* globalsig(Type*); Sym* globalsig(Type*);
Type* ismethod(Type*); Type* ismethod(Type*);
Type* methtype(Type*); Type* methtype(Type*);
......
...@@ -818,6 +818,7 @@ etnames[] = ...@@ -818,6 +818,7 @@ etnames[] =
[TBOOL] = "BOOL", [TBOOL] = "BOOL",
[TPTR32] = "PTR32", [TPTR32] = "PTR32",
[TPTR64] = "PTR64", [TPTR64] = "PTR64",
[TDDD] = "DDD",
[TFUNC] = "FUNC", [TFUNC] = "FUNC",
[TARRAY] = "ARRAY", [TARRAY] = "ARRAY",
// [TDARRAY] = "DARRAY", // [TDARRAY] = "DARRAY",
...@@ -1453,8 +1454,12 @@ isselect(Node *n) ...@@ -1453,8 +1454,12 @@ isselect(Node *n)
int int
isinter(Type *t) isinter(Type *t)
{ {
if(t != T && t->etype == TINTER) if(t != T) {
if(t->etype == TINTER)
return 1;
if(t->etype == TDDD)
return 1; return 1;
}
return 0; return 0;
} }
...@@ -1468,6 +1473,14 @@ isnilinter(Type *t) ...@@ -1468,6 +1473,14 @@ isnilinter(Type *t)
return 1; return 1;
} }
int
isddd(Type *t)
{
if(t != T && t->etype == TDDD)
return 1;
return 0;
}
Type* Type*
ismethod(Type *t) ismethod(Type *t)
{ {
...@@ -1604,6 +1617,7 @@ globalsig(Type *t) ...@@ -1604,6 +1617,7 @@ globalsig(Type *t)
return S; return S;
case TINTER: case TINTER:
case TDDD:
if(isnilinter(t)) { if(isnilinter(t)) {
snprint(buf, sizeof(buf), "%s_%s", "sigi", "inter"); snprint(buf, sizeof(buf), "%s_%s", "sigi", "inter");
goto out; goto out;
...@@ -1670,6 +1684,10 @@ signame(Type *t, int block) ...@@ -1670,6 +1684,10 @@ signame(Type *t, int block)
if(t == T) if(t == T)
goto bad; goto bad;
ss = globalsig(t);
if(ss != S)
return ss;
s = t->sym; s = t->sym;
if(s == S) { if(s == S) {
if(isptr[t->etype]) { if(isptr[t->etype]) {
...@@ -1682,10 +1700,6 @@ signame(Type *t, int block) ...@@ -1682,10 +1700,6 @@ signame(Type *t, int block)
goto bad; goto bad;
} }
ss = globalsig(t);
if(ss != S)
return ss;
e = "sigt"; e = "sigt";
if(t->etype == TINTER) if(t->etype == TINTER)
e = "sigi"; e = "sigi";
......
...@@ -1555,9 +1555,6 @@ loop: ...@@ -1555,9 +1555,6 @@ loop:
a = nod(OAS, l, r); a = nod(OAS, l, r);
a = convas(a); a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn); nn = list(a, nn);
l = listnext(&savel); l = listnext(&savel);
...@@ -1595,9 +1592,6 @@ loop: ...@@ -1595,9 +1592,6 @@ loop:
a = nod(OAS, l, nodarg(r, fp)); a = nod(OAS, l, nodarg(r, fp));
a = convas(a); a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn); nn = list(a, nn);
l = listnext(&savel); l = listnext(&savel);
...@@ -1606,6 +1600,109 @@ loop: ...@@ -1606,6 +1600,109 @@ loop:
goto 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* Node*
ascompatte(int op, Type **nl, Node **nr, int fp) ascompatte(int op, Type **nl, Node **nr, int fp)
{ {
...@@ -1622,7 +1719,21 @@ 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); l = structfirst(&savel, nl);
r = listfirst(&saver, nr); r = listfirst(&saver, nr);
nn = N; nn = N;
loop: 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) {
if(l != T || r != N) if(l != T || r != N)
yyerror("error in shape across %O", op); yyerror("error in shape across %O", op);
...@@ -1634,11 +1745,9 @@ loop: ...@@ -1634,11 +1745,9 @@ loop:
return N; return N;
} }
more:
a = nod(OAS, nodarg(l, fp), r); a = nod(OAS, nodarg(l, fp), r);
a = convas(a); a = convas(a);
if(nn == N)
nn = a;
else
nn = list(a, nn); nn = list(a, nn);
l = structnext(&savel); l = structnext(&savel);
...@@ -2518,6 +2627,8 @@ isandss(Type *lt, Node *r) ...@@ -2518,6 +2627,8 @@ isandss(Type *lt, Node *r)
rt = r->type; rt = r->type;
if(isinter(lt)) { if(isinter(lt)) {
if(isinter(rt)) { if(isinter(rt)) {
if(isnilinter(lt) && isnilinter(rt))
return Inone;
if(!eqtype(rt, lt, 0)) if(!eqtype(rt, lt, 0))
return I2I; return I2I;
return Inone; return Inone;
...@@ -2649,6 +2760,9 @@ convas(Node *n) ...@@ -2649,6 +2760,9 @@ convas(Node *n)
if(n->op != OAS) if(n->op != OAS)
fatal("convas: not OAS %O", n->op); fatal("convas: not OAS %O", n->op);
lt = T;
rt = T;
l = n->left; l = n->left;
r = n->right; r = n->right;
if(l == N || r == N) if(l == N || r == N)
...@@ -2747,9 +2861,6 @@ colas(Node *nl, Node *nr) ...@@ -2747,9 +2861,6 @@ colas(Node *nl, Node *nr)
walktype(r, Erv); walktype(r, Erv);
defaultlit(r); defaultlit(r);
a = old2new(l, r->type); a = old2new(l, r->type);
if(n == N)
n = a;
else
n = list(n, a); n = list(n, a);
l = listnext(&savel); l = listnext(&savel);
...@@ -2785,9 +2896,6 @@ multi: ...@@ -2785,9 +2896,6 @@ multi:
t = structfirst(&saver, getoutarg(t)); t = structfirst(&saver, getoutarg(t));
while(l != N) { while(l != N) {
a = old2new(l, t->type); a = old2new(l, t->type);
if(n == N)
n = a;
else
n = list(n, a); n = list(n, a);
l = listnext(&savel); l = listnext(&savel);
t = structnext(&saver); t = structnext(&saver);
...@@ -2877,15 +2985,11 @@ loop2: ...@@ -2877,15 +2985,11 @@ loop2:
if(l == N) { if(l == N) {
r = rev(r); r = rev(r);
g = rev(g); g = rev(g);
if(g != N)
f = list(g, f); f = list(g, f);
r = list(f, r); r = list(f, r);
return r; return r;
} }
if(l->ullman < UINF) { if(l->ullman < UINF) {
if(r == N)
r = l;
else
r = list(l, r); r = list(l, r);
goto more; goto more;
} }
...@@ -2898,18 +3002,11 @@ loop2: ...@@ -2898,18 +3002,11 @@ loop2:
a = nod(OXXX, N, N); a = nod(OXXX, N, N);
tempname(a, l->right->type); tempname(a, l->right->type);
a = nod(OAS, a, l->right); 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 // put normal arg assignment on list
// with fncall replaced by tempname // with fncall replaced by tempname
l->right = a->left; l->right = a->left;
if(r == N)
r = l;
else
r = list(l, r); r = list(l, r);
more: more:
...@@ -3040,9 +3137,6 @@ reorder3(Node *n) ...@@ -3040,9 +3137,6 @@ reorder3(Node *n)
q = N; q = N;
l1 = listfirst(&save1, &n); l1 = listfirst(&save1, &n);
while(l1 != N) { while(l1 != N) {
if(q == N)
q = l1;
else
q = list(q, l1); q = list(q, l1);
l1 = listnext(&save1); l1 = listnext(&save1);
} }
...@@ -3050,9 +3144,6 @@ reorder3(Node *n) ...@@ -3050,9 +3144,6 @@ reorder3(Node *n)
r = rev(r); r = rev(r);
l1 = listfirst(&save1, &r); l1 = listfirst(&save1, &r);
while(l1 != N) { while(l1 != N) {
if(q == N)
q = l1;
else
q = list(q, l1); q = list(q, l1);
l1 = listnext(&save1); 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