diff options
Diffstat (limited to 'src/cmd/gc/lex.c')
-rw-r--r-- | src/cmd/gc/lex.c | 105 |
1 files changed, 86 insertions, 19 deletions
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index b7f71d553..8c739391a 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -41,6 +41,19 @@ static struct { } exper[] = { // {"rune32", &rune32}, {"fieldtrack", &fieldtrack_enabled}, + {"precisestack", &precisestack_enabled}, + {nil, nil}, +}; + +// Debug arguments. +// These can be specified with the -d flag, as in "-d checknil" +// to set the debug_checknil variable. In general the list passed +// to -d can be comma-separated. +static struct { + char *name; + int *val; +} debugtab[] = { + {"nil", &debug_checknil}, {nil, nil}, }; @@ -238,12 +251,13 @@ main(int argc, char *argv[]) flagfn0("V", "print compiler version", doversion); flagcount("W", "debug parse tree after type checking", &debug['W']); flagcount("complete", "compiling complete package (no C or assembly)", &pure_go); - flagcount("d", "debug declarations", &debug['d']); + flagstr("d", "list: print debug information about items in list", &debugstr); flagcount("e", "no limit on number of errors reported", &debug['e']); flagcount("f", "debug stack frames", &debug['f']); flagcount("g", "debug code generation", &debug['g']); flagcount("h", "halt on error", &debug['h']); flagcount("i", "debug line number stack", &debug['i']); + flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix); flagcount("j", "debug runtime-initialized variables", &debug['j']); flagcount("l", "disable inlining", &debug['l']); flagcount("m", "print optimization decisions", &debug['m']); @@ -269,6 +283,24 @@ main(int argc, char *argv[]) racepkg = mkpkg(strlit("runtime/race")); racepkg->name = "race"; } + + // parse -d argument + if(debugstr) { + char *f[100]; + int i, j, nf; + + nf = getfields(debugstr, f, nelem(f), 1, ","); + for(i=0; i<nf; i++) { + for(j=0; debugtab[j].name != nil; j++) { + if(strcmp(debugtab[j].name, f[i]) == 0) { + *debugtab[j].val = 1; + break; + } + } + if(j == nelem(debugtab)) + fatal("unknown debug information -d '%s'\n", f[i]); + } + } // enable inlining. for now: // default: inlining on. (debug['l'] == 1) @@ -329,6 +361,8 @@ main(int argc, char *argv[]) curio.peekc = 0; curio.peekc1 = 0; curio.nlsemi = 0; + curio.eofnl = 0; + curio.last = 0; // Skip initial BOM if present. if(Bgetrune(curio.bin) != BOM) @@ -416,6 +450,10 @@ main(int argc, char *argv[]) // Phase 5: Escape analysis. if(!debug['N']) escapes(xtop); + + // Escape analysis moved escaped values off stack. + // Move large values off stack too. + movelarge(xtop); // Phase 6: Compile top level functions. for(l=xtop; l; l=l->next) @@ -540,7 +578,7 @@ static int findpkg(Strlit *name) { Idir *p; - char *q, *race; + char *q, *suffix, *suffixsep; if(islocalname(name)) { if(safemode) @@ -578,13 +616,19 @@ findpkg(Strlit *name) return 1; } if(goroot != nil) { - race = ""; - if(flag_race) - race = "_race"; - snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.a", goroot, goos, goarch, race, name); + suffix = ""; + suffixsep = ""; + if(flag_installsuffix != nil) { + suffixsep = "_"; + suffix = flag_installsuffix; + } else if(flag_race) { + suffixsep = "_"; + suffix = "race"; + } + snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.a", goroot, goos, goarch, suffixsep, suffix, name); if(access(namebuf, 0) >= 0) return 1; - snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s/%Z.%c", goroot, goos, goarch, race, name, thechar); + snprint(namebuf, sizeof(namebuf), "%s/pkg/%s_%s%s%s/%Z.%c", goroot, goos, goarch, suffixsep, suffix, name, thechar); if(access(namebuf, 0) >= 0) return 1; } @@ -1580,10 +1624,10 @@ getc(void) curio.cp++; } else { loop: - c = Bgetc(curio.bin); + c = BGETC(curio.bin); if(c == 0xef) { - c1 = Bgetc(curio.bin); - c2 = Bgetc(curio.bin); + c1 = BGETC(curio.bin); + c2 = BGETC(curio.bin); if(c1 == 0xbb && c2 == 0xbf) { yyerrorl(lexlineno, "Unicode (UTF-8) BOM in middle of file"); goto loop; @@ -1602,7 +1646,7 @@ check: } case EOF: // insert \n at EOF - if(curio.eofnl) + if(curio.eofnl || curio.last == '\n') return EOF; curio.eofnl = 1; c = '\n'; @@ -1611,6 +1655,7 @@ check: lexlineno++; break; } + curio.last = c; return c; } @@ -1971,27 +2016,27 @@ lexinit1(void) // error type s = lookup("error"); s->lexical = LNAME; - errortype = t; - errortype->sym = s; s1 = pkglookup("error", builtinpkg); + errortype = t; + errortype->sym = s1; s1->lexical = LNAME; s1->def = typenod(errortype); // byte alias s = lookup("byte"); s->lexical = LNAME; - bytetype = typ(TUINT8); - bytetype->sym = s; s1 = pkglookup("byte", builtinpkg); + bytetype = typ(TUINT8); + bytetype->sym = s1; s1->lexical = LNAME; s1->def = typenod(bytetype); // rune alias s = lookup("rune"); s->lexical = LNAME; - runetype = typ(TINT32); - runetype->sym = s; s1 = pkglookup("rune", builtinpkg); + runetype = typ(TINT32); + runetype->sym = s1; s1->lexical = LNAME; s1->def = typenod(runetype); } @@ -2242,6 +2287,28 @@ yytinit(void) } } +static void +pkgnotused(int lineno, Strlit *path, char *name) +{ + char *elem; + + // If the package was imported with a name other than the final + // import path element, show it explicitly in the error message. + // Note that this handles both renamed imports and imports of + // packages containing unconventional package declarations. + // Note that this uses / always, even on Windows, because Go import + // paths always use forward slashes. + elem = strrchr(path->s, '/'); + if(elem != nil) + elem++; + else + elem = path->s; + if(name == nil || strcmp(elem, name) == 0) + yyerrorl(lineno, "imported and not used: \"%Z\"", path); + else + yyerrorl(lineno, "imported and not used: \"%Z\" as %s", path, name); +} + void mkpackage(char* pkgname) { @@ -2267,7 +2334,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); + pkgnotused(s->def->lineno, s->def->pkg->path, s->name); s->def = N; continue; } @@ -2275,7 +2342,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); + pkgnotused(s->def->pack->lineno, s->def->pack->pkg->path, nil); s->def->pack->used = 1; } s->def = N; |