]> Cypherpunks repositories - gostls13.git/commitdiff
unnamed substructures - not complete
authorKen Thompson <ken@golang.org>
Mon, 20 Oct 2008 03:13:37 +0000 (20:13 -0700)
committerKen Thompson <ken@golang.org>
Mon, 20 Oct 2008 03:13:37 +0000 (20:13 -0700)
R=r
OCL=17437
CL=17437

src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/walk.c

index b65d8c0bb6a762889d555565907e19cd9c7e4aae..95f4e020cb7c66311bc62011b90a673bd3050eb7 100644 (file)
@@ -471,6 +471,7 @@ loop:
 
        if(n->left != N && n->left->op == ONAME) {
                f->nname = n->left;
+               f->embedded = n->embedded;
        } else {
                vargen++;
                snprint(buf, sizeof(buf), "_e%s_%.3ld", filename, vargen);
index 42b068c8d0dd21d717a1eaa4b86f39a8704274b6..c72dbb8c6713508ad4820760226bdda57e0f131f 100644 (file)
@@ -124,6 +124,7 @@ struct      Type
        uchar   trecur;         // to detect loops
        uchar   methptr;        // 1=direct 2=pointer
        uchar   printed;
+       uchar   embedded;       // TFIELD embedded type
 
        // TFUNCT
        uchar   thistuple;
@@ -161,6 +162,7 @@ struct      Node
        uchar   class;          // PPARAM, PAUTO, PEXTERN, PSTATIC
        uchar   method;         // OCALLMETH name
        uchar   iota;           // OLITERAL made from iota
+       uchar   embedded;       // ODCLFIELD embedded type
 
        // most nodes
        Node*   left;
index 4afc1c6e841b30dc27198aa1c196338d58d2516c..3e1c073bc82f33a92af2879102204c4b43547263 100644 (file)
@@ -1378,15 +1378,19 @@ structdcl:
                $$ = nod(ODCLFIELD, $1, N);
                $$->type = $2;
        }
-|      new_name
+|      LATYPE
        {
-               // must be  latype
-               $$ = nod(ODCLFIELD, N, N);
-               $$->type = $1->sym->otype;
-               if($1->sym->lexical != LATYPE) {
-                       yyerror("unnamed structure field must be a type");
-                       $$->type = types[TINT32];
-               };
+               $$ = nod(ODCLFIELD, newname($1), N);
+               $$->type = oldtype($1);
+               $$->embedded = 1;
+       }
+|      lpack '.' LATYPE
+       {
+               $$ = newname(lookup($3->name));
+               $$ = nod(ODCLFIELD, $$, N);
+               $$->type = oldtype($3);
+               $$->embedded = 1;
+               context = nil;
        }
 
 interfacedcl:
index 610051a50b36983350654e3e22b457a6140722d6..1acbd90c69215812711caa9d5c51ffb45a84bd0d 100644 (file)
@@ -1390,38 +1390,57 @@ walkselect(Node *sel)
        lineno = lno;
 }
 
-/*
- * allowable type combinations for
- * normal binary operations.
- */
 Type*
-lookdot(Node *n, Type *f)
+lookdot(Node *n, Type *f, int d)
 {
-       Type *r;
-       Sym *s;
+       Type *r, *r1;
+       Sym *s, *sf;
 
        r = T;
        s = n->sym;
 
        for(; f!=T; f=f->down) {
-               if(f->sym == S)
+               sf = f->sym;
+               if(sf == S)
                        continue;
-       //      if(strcmp(f->sym->name, s->name) != 0)
-               if(f->sym != s)
-                       continue;
-               if(r != T) {
-                       yyerror("ambiguous DOT reference %S", s);
-                       break;
+
+               // depth=0 -- look directly in structure
+               if(d == 0) {
+                       if(sf != s)
+                               continue;
+                       if(r != T)
+                               goto ambig;
+                       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;
                }
-               r = f;
        }
        return r;
+
+ambig:
+       yyerror("ambiguous DOT reference %S", s);
+       return r;
 }
 
 void
 walkdot(Node *n)
 {
        Type *t, *f;
+       int d;
 
        if(n->left == N || n->right == N)
                return;
@@ -1447,14 +1466,16 @@ walkdot(Node *n)
        }
 
        if(t->etype == TSTRUCT || t->etype == TINTER) {
-               f = lookdot(n->right, t->type);
-               if(f != T) {
-                       n->xoffset = f->width;
-                       n->right = f->nname;            // substitute real name
-                       n->type = f->type;
-                       if(t->etype == TINTER)
-                               n->op = ODOTINTER;
-                       return;
+               for(d=0; d<=5; d++) {
+                       f = lookdot(n->right, t->type, d);
+                       if(f != T) {
+                               n->xoffset = n->right->xoffset;
+                               n->right = f->nname;            // substitute real name
+                               n->type = f->type;
+                               if(t->etype == TINTER)
+                                       n->op = ODOTINTER;
+                               return;
+                       }
                }
        }
 
@@ -1462,7 +1483,7 @@ walkdot(Node *n)
        f = T;
        t = ismethod(n->left->type);
        if(t != T)
-               f = lookdot(n->right, t->method);
+               f = lookdot(n->right, t->method, 0);
        if(f == T) {
                yyerror("undefined DOT %S on %T", n->right->sym, n->left->type);
                return;