]> Cypherpunks repositories - gostls13.git/commitdiff
output args declared
authorKen Thompson <ken@golang.org>
Sat, 5 Jul 2008 19:49:25 +0000 (12:49 -0700)
committerKen Thompson <ken@golang.org>
Sat, 5 Jul 2008 19:49:25 +0000 (12:49 -0700)
arguments in first block for diagnostics
thomo return
better syntax error recovery

SVN=126045

src/cmd/6g/gen.c
src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/lex.c
src/cmd/gc/walk.c

index 6b4dfde80ce240c2d1571f84247d61b3bd453874..8072b6126233c54361bcc29b842f9702214edb06 100644 (file)
@@ -106,6 +106,26 @@ allocparams(void)
                t = funcnext(&list);
        }
 
+       t = structfirst(&list, getoutarg(curfn->type));
+       while(t != T) {
+               if(t->nname != N && t->nname->sym->name[0] != '_') {
+                       if(d == D)
+                               fatal("allocparams: this nil");
+                       if(d->op != ONAME) {
+                               d = d->forw;
+                               continue;
+                       }
+
+                       n = d->dnode;
+                       if(n->class != PPARAM)
+                               fatal("allocparams: this class");
+
+                       n->xoffset = t->width;
+                       d = d->forw;
+               }
+               t = structnext(&list);
+       }
+
        /*
         * allocate (set xoffset) the stack
         * slots for all automatics.
index 65563f3b7c78762b20a4555462e50cef3b683119..0bb35806912aff4beb73b127257c311dce0e0f36 100644 (file)
@@ -353,7 +353,7 @@ funchdr(Node *n)
                fatal("funchdr: dclcontext");
 
        dclcontext = PAUTO;
-       markdcl("func");
+       markdcl();
        funcargs(n->type);
 
        if(n->type->thistuple > 0) {
@@ -368,8 +368,9 @@ funcargs(Type *t)
 {
        Type *n1;
        Iter save;
+       int all;
 
-       // declare the this argument
+       // declare the this/in arguments
        n1 = funcfirst(&save, t);
        while(n1 != T) {
                if(n1->nname != N)
@@ -378,13 +379,22 @@ funcargs(Type *t)
        }
 
        // declare the outgoing arguments
-//     n1 = structfirst(&save, getoutarg(t));
-//     while(n1 != T) {
-//             n1->left = newname(n1->sym);
-//             if(n1->nname != N)
-//                     addvar(n1->nname, n1->type, PPARAM);
-//             n1 = structnext(&save);
-//     }
+       all = 0;
+       n1 = structfirst(&save, getoutarg(t));
+       while(n1 != T) {
+               if(n1->nname != N && n1->nname->sym->name[0] != '_') {
+                       addvar(n1->nname, n1->type, PPARAM);
+                       all |= 1;
+               } else
+                       all |= 2;
+               n1 = structnext(&save);
+       }
+       if(all == 3)
+               yyerror("output parameters are all named or not named");
+
+       t->outnamed = 0;
+       if(all == 1)
+               t->outnamed = 1;
 }
 
 /*
@@ -401,7 +411,7 @@ funcbody(Node *n)
        // change the declaration context from auto to extern
        if(dclcontext != PAUTO)
                fatal("funcbody: dclcontext");
-       popdcl("func");
+       popdcl();
        dclcontext = PEXTERN;
 }
 
@@ -515,7 +525,7 @@ pushdcl(Sym *s)
 }
 
 void
-popdcl(char *why)
+popdcl(void)
 {
        Sym *d, *s;
 
@@ -532,8 +542,6 @@ popdcl(char *why)
        }
        if(d == S)
                fatal("popdcl: no mark");
-       if(strcmp(why, d->package) != 0)
-               fatal("popdcl: pushed as %s popped as %s", d->package, why);
        dclstack = d->link;
        block = d->vblock;
 }
@@ -556,17 +564,17 @@ poptodcl(void)
 }
 
 void
-markdcl(char *why)
+markdcl(void)
 {
        Sym *d;
 
        d = push();
        d->name = nil;          // used as a mark in fifo
-       d->package = why;       // diagnostic for unmatched
        d->vblock = block;
 
        blockgen++;
        block = blockgen;
+
 //     if(dflag())
 //             print("markdcl\n");
 }
@@ -576,7 +584,7 @@ markdclstack(void)
 {
        Sym *d, *s;
 
-       markdcl("fnlit");
+       markdcl();
 
        // copy the entire pop of the stack
        // all the way back to block0.
@@ -639,8 +647,14 @@ addvar(Node *n, Type *t, int ctxt)
                gen = 0;
        }
 
-       if(s->vblock == block)
-               yyerror("var %S redeclared in this block %d", s, block);
+       if(s->vblock == block) {
+               if(s->oname != N) {
+                       yyerror("var %S redeclared in this block"
+                               "\n     previous declaration at %L",
+                               s, s->oname->lineno);
+               } else
+                       yyerror("var %S redeclared in this block", s);
+       }
                
        if(ctxt != PEXTERN)
                pushdcl(s);
index 828ebbb7126c32b8579de22e1f1861a14a2bc2b3..7f5b3829de00a2ee05ba0934f1dd4d00efa8c95d 100644 (file)
@@ -80,6 +80,7 @@ struct        Type
        uchar   thistuple;
        uchar   outtuple;
        uchar   intuple;
+       uchar   outnamed;
 
        Sym*    sym;
        long    vargen;         // unique name for OTYPE/ONAME
@@ -144,7 +145,7 @@ struct      Node
        Sym*    psym;           // import
        Sym*    sym;            // various
        long    vargen;         // unique name for OTYPE/ONAME
-       ulong   lineno;
+       long    lineno;
        vlong   xoffset;
 };
 #define        N       ((Node*)0)
@@ -525,8 +526,8 @@ void        funcbody(Node*);
 Type*  dostruct(Node*, int);
 Type** stotype(Node*, Type**);
 Type*  sortinter(Type*);
-void   markdcl(char*);
-void   popdcl(char*);
+void   markdcl(void);
+void   popdcl(void);
 void   poptodcl(void);
 void   markdclstack(void);
 void   testdclstack(void);
@@ -566,6 +567,7 @@ void        doimport7(Node*, Node*);
  */
 void   walk(Node*);
 void   walktype(Node*, int);
+void   walkbool(Node*);
 Type*  walkswitch(Node*, Type*(*)(Node*, Type*));
 int    casebody(Node*);
 int    whatis(Node*);
index e3fe87a3bcf0e9690317883297a2f2a505a85bd7..67345054d348719b5c79c05596838a5004ea62eb 100644 (file)
@@ -47,8 +47,7 @@
 %type  <node>          export_list_r export
 %type  <node>          hidden_importsym_list_r ohidden_importsym_list hidden_importsym isym
 %type  <node>          hidden_importfield_list_r ohidden_importfield_list hidden_importfield
-%type  <node>          fnbody
-%type  <node>          fnres Afnres Bfnres fnliteral xfndcl fndcl
+%type  <node>          fnres Afnres Bfnres fnliteral xfndcl fndcl fnbody
 %type  <node>          keyval_list_r keyval
 %type  <node>          typedcl Atypedcl Btypedcl
 
@@ -148,13 +147,9 @@ xdcl:
        {
                $$ = N;
        }
-|      error '}'
+|      error xdcl
        {
-               $$ = N;
-       }
-|      error ';'
-       {
-               $$ = N;
+               $$ = $2;
        }
 
 common_dcl:
@@ -330,13 +325,12 @@ inc_stmt:
 complex_stmt:
        LFOR for_stmt
        {
-               /* FOR and WHILE are the same keyword */
-               popdcl("for/while");
+               popdcl();
                $$ = $2;
        }
 |      LSWITCH if_stmt
        {
-               popdcl("if/switch");
+               popdcl();
                if(!casebody($2->nbody))
                        yyerror("switch statement must have case labels");
                $$ = $2;
@@ -346,14 +340,14 @@ complex_stmt:
        }
 |      LIF if_stmt
        {
-               popdcl("if/switch");
+               popdcl();
                $$ = $2;
                //if($$->ninit != N && $$->ntest == N)
                //      yyerror("if conditional should not be missing");
        }
 |      LIF if_stmt LELSE else_stmt1
        {
-               popdcl("if/switch");
+               popdcl();
                $$ = $2;
                $$->nelse = $4;
                //if($$->ninit != N && $$->ntest == N)
@@ -361,7 +355,7 @@ complex_stmt:
        }
 |      LRANGE range_stmt
        {
-               popdcl("range");
+               popdcl();
                $$ = $2;
        }
 |      LCASE expr_list ':'
@@ -414,7 +408,7 @@ semi_stmt:
        }
 |      LIF if_stmt LELSE else_stmt2
        {
-               popdcl("if/switch");
+               popdcl();
                $$ = $2;
                $$->nelse = $4;
                //if($$->ninit != N && $$->ntest == N)
@@ -424,13 +418,13 @@ semi_stmt:
 compound_stmt:
        '{'
        {
-               markdcl("compound");
+               markdcl();
        } ostmt_list '}'
        {
                $$ = $3;
                if($$ == N)
                        $$ = nod(OEMPTY, N, N);
-               popdcl("compound");
+               popdcl();
        }
 
 for_header:
@@ -460,7 +454,7 @@ for_body:
 
 for_stmt:
        {
-               markdcl("for/while");
+               markdcl();
        } for_body
        {
                $$ = $2;
@@ -491,7 +485,7 @@ if_body:
 
 if_stmt:
        {
-               markdcl("if/switch");
+               markdcl();
        } if_body
        {
                $$ = $2;
@@ -521,7 +515,7 @@ range_body:
 
 range_stmt:
        {
-               markdcl("range");
+               markdcl();
        } range_body
        {
                $$ = $2;
@@ -1012,7 +1006,7 @@ fnlitdcl:
 fnliteral:
        fnlitdcl '{' ostmt_list '}'
        {
-               popdcl("fnlit");
+               popdcl();
 
                vargen++;
                snprint(namebuf, sizeof(namebuf), "_f%.3ld", vargen);
@@ -1036,16 +1030,17 @@ fnliteral:
        }
 
 fnbody:
-       compound_stmt
+       '{' ostmt_list '}'
        {
-               $$ = $1;
-               if($$->op == OEMPTY)
+               $$ = $2;
+               if($$ == N)
                        $$ = nod(ORETURN, N, N);
        }
 |      ';'
        {
                $$ = N;
        }
+
 fnres:
        Afnres
 |      Bfnres
@@ -1202,11 +1197,7 @@ Astmt:
        {
                $$ = N;
        }
-|      error ';'
-       {
-               $$ = N;
-       }
-|      error '}'
+|      error Astmt
        {
                $$ = N;
        }
@@ -1218,6 +1209,10 @@ Astmt:
 Bstmt:
        semi_stmt
 |      Bcommon_dcl
+|      error Bstmt
+       {
+               $$ = N;
+       }
 
 /*
  * need semi in front YES
index 5aa12c328e9ace7df2037c839cf20f4a3eba1a27..2642bc88e403eade0cbc89d152a4cc07565db5f0 100644 (file)
@@ -550,7 +550,7 @@ tnum:
        }
        *cp++ = c;
        c = getc();
-       if(c == 'x' || c == 'X')
+       if(c == 'x' || c == 'X') {
                for(;;) {
                        *cp++ = c;
                        c = getc();
@@ -564,16 +564,24 @@ tnum:
                                yyerror("malformed hex constant");
                        goto ncu;
                }
-       if(c < '0' || c > '7')
-               goto dc;
+       }
+
+       c1 = 0;
        for(;;) {
-               if(c >= '0' && c <= '7') {
-                       *cp++ = c;
-                       c = getc();
-                       continue;
-               }
-               goto ncu;
+               if(!isdigit(c))
+                       break;
+               if(c < '0' || c > '7')
+                       c1 = 1;         // not octal
+               *cp++ = c;
+               c = getc();
        }
+       if(c == '.')
+               goto casedot;
+       if(c == 'e' || c == 'E')
+               goto casee;
+       if(c1)
+               yyerror("malformed octal constant");
+       goto ncu;
 
 dc:
        if(c == '.')
index 0110fe407317d46365d4657fbef47b9209ee2b50..f8c10c3ec9aae7b1f34a01bf7940f16a6c51a061 100644 (file)
@@ -112,7 +112,7 @@ loop:
                if(top != Etop)
                        goto nottop;
                walktype(n->ninit, Etop);
-               walktype(n->ntest, Erv);
+               walkbool(n->ntest);
                walktype(n->nincr, Etop);
                n = n->nbody;
                goto loop;
@@ -151,7 +151,7 @@ loop:
                if(top != Etop)
                        goto nottop;
                walktype(n->ninit, Etop);
-               walktype(n->ntest, Erv);
+               walkbool(n->ntest);
                walktype(n->nelse, Etop);
                n = n->nbody;
                goto loop;
@@ -377,6 +377,10 @@ loop:
                if(top != Etop)
                        goto nottop;
                walktype(n->left, Erv);
+               if(curfn->type->outnamed && n->left == N) {
+                       // print("special return\n");
+                       goto ret;
+               }
                l = ascompatte(n->op, getoutarg(curfn->type), &n->left, 1);
                if(l != N)
                        n->left = reorder4(l);
@@ -722,6 +726,15 @@ ret:
        lineno = lno;
 }
 
+void
+walkbool(Node *n)
+{
+       walktype(n, Erv);
+       if(n != N && n->type != T)
+               if(!eqtype(n->type, types[TBOOL], 0))
+                       yyerror("IF and FOR require a boolean type");
+}
+
 /*
  * return the first type
  */