1
0
mirror of https://github.com/golang/go synced 2024-11-26 08:38:01 -07:00

unnamed substructures - not complete

R=r
OCL=17437
CL=17437
This commit is contained in:
Ken Thompson 2008-10-19 20:13:37 -07:00
parent 52e9080d56
commit 61361af9e8
4 changed files with 60 additions and 32 deletions

View File

@ -471,6 +471,7 @@ loop:
if(n->left != N && n->left->op == ONAME) { if(n->left != N && n->left->op == ONAME) {
f->nname = n->left; f->nname = n->left;
f->embedded = n->embedded;
} else { } else {
vargen++; vargen++;
snprint(buf, sizeof(buf), "_e%s_%.3ld", filename, vargen); snprint(buf, sizeof(buf), "_e%s_%.3ld", filename, vargen);

View File

@ -124,6 +124,7 @@ struct Type
uchar trecur; // to detect loops uchar trecur; // to detect loops
uchar methptr; // 1=direct 2=pointer uchar methptr; // 1=direct 2=pointer
uchar printed; uchar printed;
uchar embedded; // TFIELD embedded type
// TFUNCT // TFUNCT
uchar thistuple; uchar thistuple;
@ -161,6 +162,7 @@ struct Node
uchar class; // PPARAM, PAUTO, PEXTERN, PSTATIC uchar class; // PPARAM, PAUTO, PEXTERN, PSTATIC
uchar method; // OCALLMETH name uchar method; // OCALLMETH name
uchar iota; // OLITERAL made from iota uchar iota; // OLITERAL made from iota
uchar embedded; // ODCLFIELD embedded type
// most nodes // most nodes
Node* left; Node* left;

View File

@ -1378,15 +1378,19 @@ structdcl:
$$ = nod(ODCLFIELD, $1, N); $$ = nod(ODCLFIELD, $1, N);
$$->type = $2; $$->type = $2;
} }
| new_name | LATYPE
{ {
// must be latype $$ = nod(ODCLFIELD, newname($1), N);
$$ = nod(ODCLFIELD, N, N); $$->type = oldtype($1);
$$->type = $1->sym->otype; $$->embedded = 1;
if($1->sym->lexical != LATYPE) { }
yyerror("unnamed structure field must be a type"); | lpack '.' LATYPE
$$->type = types[TINT32]; {
}; $$ = newname(lookup($3->name));
$$ = nod(ODCLFIELD, $$, N);
$$->type = oldtype($3);
$$->embedded = 1;
context = nil;
} }
interfacedcl: interfacedcl:

View File

@ -1390,31 +1390,49 @@ walkselect(Node *sel)
lineno = lno; lineno = lno;
} }
/*
* allowable type combinations for
* normal binary operations.
*/
Type* Type*
lookdot(Node *n, Type *f) lookdot(Node *n, Type *f, int d)
{ {
Type *r; Type *r, *r1;
Sym *s; Sym *s, *sf;
r = T; r = T;
s = n->sym; s = n->sym;
for(; f!=T; f=f->down) { for(; f!=T; f=f->down) {
if(f->sym == S) sf = f->sym;
if(sf == S)
continue; continue;
// if(strcmp(f->sym->name, s->name) != 0)
if(f->sym != s) // depth=0 -- look directly in structure
if(d == 0) {
if(sf != s)
continue; continue;
if(r != T) { if(r != T)
yyerror("ambiguous DOT reference %S", s); goto ambig;
break;
}
r = f; r = f;
n->xoffset = f->width;
} }
// depth>0 -- look into unnamed substructures
if(d > 0 && f->embedded) {
if(f->type == T)
continue;
if(f->type->etype != TSTRUCT && f->type->etype != TINTER)
continue;
r1 = lookdot(n, f->type->type, d-1);
if(r1 == T)
continue;
if(r != T)
goto ambig;
r = r1;
n->xoffset += f->width;
}
}
return r;
ambig:
yyerror("ambiguous DOT reference %S", s);
return r; return r;
} }
@ -1422,6 +1440,7 @@ void
walkdot(Node *n) walkdot(Node *n)
{ {
Type *t, *f; Type *t, *f;
int d;
if(n->left == N || n->right == N) if(n->left == N || n->right == N)
return; return;
@ -1447,9 +1466,10 @@ walkdot(Node *n)
} }
if(t->etype == TSTRUCT || t->etype == TINTER) { if(t->etype == TSTRUCT || t->etype == TINTER) {
f = lookdot(n->right, t->type); for(d=0; d<=5; d++) {
f = lookdot(n->right, t->type, d);
if(f != T) { if(f != T) {
n->xoffset = f->width; n->xoffset = n->right->xoffset;
n->right = f->nname; // substitute real name n->right = f->nname; // substitute real name
n->type = f->type; n->type = f->type;
if(t->etype == TINTER) if(t->etype == TINTER)
@ -1457,12 +1477,13 @@ walkdot(Node *n)
return; return;
} }
} }
}
// as a method // as a method
f = T; f = T;
t = ismethod(n->left->type); t = ismethod(n->left->type);
if(t != T) if(t != T)
f = lookdot(n->right, t->method); f = lookdot(n->right, t->method, 0);
if(f == T) { if(f == T) {
yyerror("undefined DOT %S on %T", n->right->sym, n->left->type); yyerror("undefined DOT %S on %T", n->right->sym, n->left->type);
return; return;