summaryrefslogtreecommitdiff
path: root/src/cmd/gc/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/lex.c')
-rw-r--r--src/cmd/gc/lex.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 29b6d27ff..0290fb131 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define EXTERN
+#include <u.h>
+#include <libc.h>
#include "go.h"
#include "y.tab.h"
#include <ar.h>
@@ -64,7 +65,7 @@ yy_isalnum(int c)
#define isalpha use_yy_isalpha_instead_of_isalpha
#define isalnum use_yy_isalnum_instead_of_isalnum
-#define DBG if(!debug['x']);else print
+#define DBG if(!debug['x']){}else print
enum
{
EOF = -1,
@@ -77,22 +78,29 @@ usage(void)
print("flags:\n");
// -A is allow use of "any" type, for bootstrapping
print(" -I DIR search for packages in DIR\n");
+ print(" -L show full path in file:line prints\n");
+ print(" -N disable optimizer\n");
+ print(" -S print the assembly language\n");
+ print(" -V print the compiler version\n");
print(" -d print declarations\n");
print(" -e no limit on number of errors printed\n");
print(" -f print stack frame structure\n");
print(" -h panic on an error\n");
+ print(" -m print about moves to heap\n");
print(" -o file specify output file\n");
- print(" -S print the assembly language\n");
- print(" -V print the compiler version\n");
+ print(" -p assumed import path for this code\n");
+ print(" -s disable escape analysis\n");
print(" -u disable package unsafe\n");
print(" -w print the parse tree after typing\n");
print(" -x print lex tokens\n");
- exit(0);
+ exits(0);
}
void
fault(int s)
{
+ USED(s);
+
// If we've already complained about things
// in the program, don't bother complaining
// about the seg fault too; let the user clean up
@@ -108,9 +116,11 @@ main(int argc, char *argv[])
int i, c;
NodeList *l;
char *p;
-
+
+#ifdef SIGBUS
signal(SIGBUS, fault);
signal(SIGSEGV, fault);
+#endif
localpkg = mkpkg(strlit(""));
localpkg->prefix = "\"\"";
@@ -145,6 +155,10 @@ main(int argc, char *argv[])
case 'o':
outfile = EARGF(usage());
break;
+
+ case 'p':
+ myimportpath = EARGF(usage());
+ break;
case 'I':
addidir(EARGF(usage()));
@@ -156,7 +170,7 @@ main(int argc, char *argv[])
case 'V':
print("%cg version %s\n", thechar, getgoversion());
- exit(0);
+ exits(0);
} ARGEND
if(argc < 1)
@@ -236,24 +250,24 @@ main(int argc, char *argv[])
if(debug['f'])
frame(1);
- // Process top-level declarations in four phases.
+ // Process top-level declarations in phases.
// Phase 1: const, type, and names and types of funcs.
// This will gather all the information about types
// and methods but doesn't depend on any of it.
- // Phase 2: Variable assignments.
- // To check interface assignments, depends on phase 1.
- // Phase 3: Type check function bodies.
- // Phase 4: Compile function bodies.
defercheckwidth();
for(l=xtop; l; l=l->next)
if(l->n->op != ODCL && l->n->op != OAS)
typecheck(&l->n, Etop);
+
+ // Phase 2: Variable assignments.
+ // To check interface assignments, depends on phase 1.
for(l=xtop; l; l=l->next)
if(l->n->op == ODCL || l->n->op == OAS)
typecheck(&l->n, Etop);
resumetypecopy();
resumecheckwidth();
+ // Phase 3: Type check function bodies.
for(l=xtop; l; l=l->next) {
if(l->n->op == ODCLFUNC || l->n->op == OCLOSURE) {
curfn = l->n;
@@ -269,6 +283,11 @@ main(int argc, char *argv[])
if(nsavederrors+nerrors)
errorexit();
+ // Phase 3b: escape analysis.
+ if(!debug['s'])
+ escapes();
+
+ // Phase 4: Compile function bodies.
for(l=xtop; l; l=l->next)
if(l->n->op == ODCLFUNC)
funccompile(l->n, 0);
@@ -276,6 +295,7 @@ main(int argc, char *argv[])
if(nsavederrors+nerrors == 0)
fninit(xtop);
+ // Phase 4b: Compile all closures.
while(closures) {
l = closures;
closures = nil;
@@ -284,6 +304,7 @@ main(int argc, char *argv[])
}
}
+ // Phase 5: check external declarations.
for(l=externdcl; l; l=l->next)
if(l->n->op == ONAME)
typecheck(&l->n, Erv);
@@ -297,7 +318,7 @@ main(int argc, char *argv[])
errorexit();
flusherrors();
- exit(0);
+ exits(0);
return 0;
}
@@ -400,8 +421,8 @@ findpkg(Strlit *name)
}
// local imports should be canonicalized already.
- // don't want to see "container/../container/vector"
- // as different from "container/vector".
+ // don't want to see "encoding/../encoding/base64"
+ // as different from "encoding/base64".
q = mal(name->len+1);
memmove(q, name->s, name->len);
q[name->len] = '\0';
@@ -440,6 +461,8 @@ importfile(Val *f, int line)
Strlit *path;
char *cleanbuf;
+ USED(line);
+
// TODO(rsc): don't bother reloading imports more than once?
if(f->ctype != CTSTR) {
@@ -461,6 +484,11 @@ importfile(Val *f, int line)
errorexit();
}
+ if(myimportpath != nil && strcmp(f->u.sval->s, myimportpath) == 0) {
+ yyerror("import \"%Z\" while compiling that package (import cycle)", f->u.sval);
+ errorexit();
+ }
+
if(strcmp(f->u.sval->s, "unsafe") == 0) {
if(safemode) {
yyerror("cannot import package unsafe");
@@ -482,14 +510,14 @@ importfile(Val *f, int line)
}
if(!findpkg(path)) {
- yyerror("can't find import: %Z", f->u.sval);
+ yyerror("can't find import: \"%Z\"", f->u.sval);
errorexit();
}
importpkg = mkpkg(path);
imp = Bopen(namebuf, OREAD);
if(imp == nil) {
- yyerror("can't open import: %Z: %r", f->u.sval);
+ yyerror("can't open import: \"%Z\": %r", f->u.sval);
errorexit();
}
file = strdup(namebuf);
@@ -546,7 +574,7 @@ importfile(Val *f, int line)
continue;
return;
}
- yyerror("no import in: %Z", f->u.sval);
+ yyerror("no import in \"%Z\"", f->u.sval);
unimportfile();
}
@@ -665,7 +693,6 @@ l0:
ep = lexbuf+sizeof lexbuf;
*cp++ = c;
c = c1;
- c1 = 0;
goto casedot;
}
if(c1 == '.') {
@@ -1056,7 +1083,6 @@ talph:
return s->lexical;
tnum:
- c1 = 0;
cp = lexbuf;
ep = lexbuf+sizeof lexbuf;
if(c != '0') {
@@ -1740,7 +1766,6 @@ lexfini(void)
}
nodfp = nod(ONAME, N, N);
- nodfp->noescape = 1;
nodfp->type = types[TINT32];
nodfp->xoffset = 0;
nodfp->class = PPARAM;
@@ -1923,7 +1948,7 @@ mkpackage(char* pkgname)
// errors if a conflicting top-level name is
// introduced by a different file.
if(!s->def->used && !nsyntaxerrors)
- yyerrorl(s->def->lineno, "imported and not used: %Z", s->def->pkg->path);
+ yyerrorl(s->def->lineno, "imported and not used: \"%Z\"", s->def->pkg->path);
s->def = N;
continue;
}
@@ -1931,7 +1956,7 @@ mkpackage(char* pkgname)
// throw away top-level name left over
// from previous import . "x"
if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
- yyerrorl(s->def->pack->lineno, "imported and not used: %Z", s->def->pack->pkg->path);
+ yyerrorl(s->def->pack->lineno, "imported and not used: \"%Z\"", s->def->pack->pkg->path);
s->def->pack->used = 1;
}
s->def = N;