1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:generate go run mkbuiltin.go
11 "cmd/compile/internal/ssa"
25 var imported_unsafe bool
42 // These can be specified with the -d flag, as in "-d nil"
43 // to set the debug_checknil variable. In general the list passed
44 // to -d can be comma-separated.
45 var debugtab = []struct {
49 {"append", &Debug_append}, // print information about append compilation
50 {"disablenil", &Disable_checknil}, // disable nil checks
51 {"gcprog", &Debug_gcprog}, // print dump of GC programs
52 {"nil", &Debug_checknil}, // print information about nil checks
53 {"panic", &Debug_panic}, // do not hide any compiler panic
54 {"slice", &Debug_slice}, // print information about slice compilation
55 {"typeassert", &Debug_typeassert}, // print information about type assertion inlining
56 {"wb", &Debug_wb}, // print information about write barriers
57 {"export", &Debug_export}, // print export data
65 fmt.Printf("usage: compile [options] file.go...\n")
71 if Debug_panic == 0 && nsavederrors+nerrors > 0 {
72 // If we've already complained about things
73 // in the program, don't bother complaining
74 // about a panic too; let the user clean up
75 // the code and try again.
76 if err := recover(); err != nil {
91 fmt.Printf("compile version %s%s%s\n", obj.Getgoversion(), sep, p)
98 // Allow GOARCH=thearch.thestring or GOARCH=thearch.thestringsuffix,
99 // but not other values.
102 if !strings.HasPrefix(p, Thearch.Thestring) {
103 log.Fatalf("cannot use %cg with GOARCH=%s", Thearch.Thechar, p)
107 Thearch.Linkarchinit()
108 Ctxt = obj.Linknew(Thearch.Thelinkarch)
109 Ctxt.DiagFunc = Yyerror
111 bstdout = *obj.Binitw(os.Stdout)
114 localpkg.Prefix = "\"\""
116 // pseudo-package, for scoping
117 builtinpkg = mkpkg("go.builtin")
119 builtinpkg.Prefix = "go.builtin" // not go%2ebuiltin
121 // pseudo-package, accessed by import "unsafe"
122 unsafepkg = mkpkg("unsafe")
124 unsafepkg.Name = "unsafe"
126 // real package, referred to by generated runtime calls
127 Runtimepkg = mkpkg("runtime")
129 Runtimepkg.Name = "runtime"
131 // pseudo-packages used in symbol tables
132 gostringpkg = mkpkg("go.string")
134 gostringpkg.Name = "go.string"
135 gostringpkg.Prefix = "go.string" // not go%2estring
137 itabpkg = mkpkg("go.itab")
139 itabpkg.Name = "go.itab"
140 itabpkg.Prefix = "go.itab" // not go%2eitab
142 weaktypepkg = mkpkg("go.weak.type")
144 weaktypepkg.Name = "go.weak.type"
145 weaktypepkg.Prefix = "go.weak.type" // not go%2eweak%2etype
147 typelinkpkg = mkpkg("go.typelink")
148 typelinkpkg.Name = "go.typelink"
149 typelinkpkg.Prefix = "go.typelink" // not go%2etypelink
151 trackpkg = mkpkg("go.track")
153 trackpkg.Name = "go.track"
154 trackpkg.Prefix = "go.track" // not go%2etrack
156 typepkg = mkpkg("type")
158 typepkg.Name = "type"
160 goroot = obj.Getgoroot()
163 Nacl = goos == "nacl"
169 obj.Flagcount("+", "compiling runtime", &compiling_runtime)
170 obj.Flagcount("%", "debug non-static initializers", &Debug['%'])
171 obj.Flagcount("A", "for bootstrapping, allow 'any' type", &Debug['A'])
172 obj.Flagcount("B", "disable bounds checking", &Debug['B'])
173 obj.Flagstr("D", "set relative `path` for local imports", &localimport)
174 obj.Flagcount("E", "debug symbol export", &Debug['E'])
175 obj.Flagfn1("I", "add `directory` to import search path", addidir)
176 obj.Flagcount("K", "debug missing line numbers", &Debug['K'])
177 obj.Flagcount("L", "use full (long) path in error messages", &Debug['L'])
178 obj.Flagcount("M", "debug move generation", &Debug['M'])
179 obj.Flagcount("N", "disable optimizations", &Debug['N'])
180 obj.Flagcount("P", "debug peephole optimizer", &Debug['P'])
181 obj.Flagcount("R", "debug register optimizer", &Debug['R'])
182 obj.Flagcount("S", "print assembly listing", &Debug['S'])
183 obj.Flagfn0("V", "print compiler version", doversion)
184 obj.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
185 obj.Flagstr("asmhdr", "write assembly header to `file`", &asmhdr)
186 obj.Flagstr("buildid", "record `id` as the build id in the export metadata", &buildid)
187 obj.Flagcount("complete", "compiling complete package (no C or assembly)", &pure_go)
188 obj.Flagstr("d", "print debug information about items in `list`", &debugstr)
189 obj.Flagcount("e", "no limit on number of errors reported", &Debug['e'])
190 obj.Flagcount("f", "debug stack frames", &Debug['f'])
191 obj.Flagcount("g", "debug code generation", &Debug['g'])
192 obj.Flagcount("h", "halt on error", &Debug['h'])
193 obj.Flagcount("i", "debug line number stack", &Debug['i'])
194 obj.Flagfn1("importmap", "add `definition` of the form source=actual to import map", addImportMap)
195 obj.Flagstr("installsuffix", "set pkg directory `suffix`", &flag_installsuffix)
196 obj.Flagcount("j", "debug runtime-initialized variables", &Debug['j'])
197 obj.Flagcount("l", "disable inlining", &Debug['l'])
198 obj.Flagcount("live", "debug liveness analysis", &debuglive)
199 obj.Flagcount("m", "print optimization decisions", &Debug['m'])
200 obj.Flagcount("msan", "build code compatible with C/C++ memory sanitizer", &flag_msan)
201 obj.Flagcount("newexport", "use new export format", &newexport) // TODO(gri) remove eventually (issue 13241)
202 obj.Flagcount("nolocalimports", "reject local (relative) imports", &nolocalimports)
203 obj.Flagstr("o", "write output to `file`", &outfile)
204 obj.Flagstr("p", "set expected package import `path`", &myimportpath)
205 obj.Flagcount("pack", "write package file instead of object file", &writearchive)
206 obj.Flagcount("r", "debug generated wrappers", &Debug['r'])
207 obj.Flagcount("race", "enable race detector", &flag_race)
208 obj.Flagcount("s", "warn about composite literals that can be simplified", &Debug['s'])
209 obj.Flagstr("trimpath", "remove `prefix` from recorded source file paths", &Ctxt.LineHist.TrimPathPrefix)
210 obj.Flagcount("u", "reject unsafe code", &safemode)
211 obj.Flagcount("v", "increase debug verbosity", &Debug['v'])
212 obj.Flagcount("w", "debug type checking", &Debug['w'])
214 obj.Flagcount("wb", "enable write barrier", &use_writebarrier)
215 obj.Flagcount("x", "debug lexer", &Debug['x'])
216 obj.Flagcount("y", "debug declarations in canned imports (with -d)", &Debug['y'])
218 var flag_dynlink bool
219 switch Thearch.Thechar {
220 case '5', '6', '7', '8', '9':
221 obj.Flagcount("shared", "generate code that can be linked into a shared library", &flag_shared)
223 if Thearch.Thechar == '6' {
224 obj.Flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel)
226 switch Thearch.Thechar {
227 case '5', '6', '7', '8', '9':
228 flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
230 obj.Flagstr("cpuprofile", "write cpu profile to `file`", &cpuprofile)
231 obj.Flagstr("memprofile", "write memory profile to `file`", &memprofile)
232 obj.Flagint64("memprofilerate", "set runtime.MemProfileRate to `rate`", &memprofilerate)
238 Ctxt.Flag_shared = int32(flag_shared)
239 Ctxt.Flag_dynlink = flag_dynlink
241 Ctxt.Debugasm = int32(Debug['S'])
242 Ctxt.Debugvlog = int32(Debug['v'])
251 racepkg = mkpkg("runtime/race")
252 racepkg.Name = "race"
255 msanpkg = mkpkg("runtime/msan")
256 msanpkg.Name = "msan"
258 if flag_race != 0 && flag_msan != 0 {
259 log.Fatal("cannot use both -race and -msan")
260 } else if flag_race != 0 || flag_msan != 0 {
267 for _, name := range strings.Split(debugstr, ",") {
272 if i := strings.Index(name, "="); i >= 0 {
274 val, err = strconv.Atoi(name[i+1:])
276 log.Fatalf("invalid debug value %v", name)
280 for _, t := range debugtab {
288 // special case for ssa for now
289 if strings.HasPrefix(name, "ssa/") {
290 // expect form ssa/phase/flag
291 // e.g. -d=ssa/generic_cse/time
292 // _ in phase name also matches space
294 flag := "debug" // default flag is debug
295 if i := strings.Index(phase, "/"); i >= 0 {
299 err := ssa.PhaseOption(phase, flag, val)
305 log.Fatalf("unknown debug key -d %s\n", name)
309 // enable inlining. for now:
310 // default: inlining on. (debug['l'] == 1)
311 // -l: inlining off (debug['l'] == 0)
312 // -ll, -lll: inlining on again, with extra debugging (debug['l'] > 1)
314 Debug['l'] = 1 - Debug['l']
319 Fatalf("betypeinit failed")
334 for _, infile = range flag.Args() {
335 if trace && Debug['x'] != 0 {
336 fmt.Printf("--- %s ---\n", infile)
341 bin, err := obj.Bopenr(infile)
343 fmt.Printf("open %s: %v\n", infile, err)
347 // Skip initial BOM if present.
348 if obj.Bgetrune(bin) != BOM {
355 imported_unsafe = false
358 if nsyntaxerrors != 0 {
362 // Instead of converting EOF into '\n' in getc and count it as an extra line
363 // for the line history to work, and which then has to be corrected elsewhere,
364 // just add a line here.
372 mkpackage(localpkg.Name) // final import not used checks
380 // Process top-level declarations in phases.
382 // Phase 1: const, type, and names and types of funcs.
383 // This will gather all the information about types
384 // and methods but doesn't depend on any of it.
387 for l := xtop; l != nil; l = l.Next {
388 if l.N.Op != ODCL && l.N.Op != OAS && l.N.Op != OAS2 {
389 typecheck(&l.N, Etop)
393 // Phase 2: Variable assignments.
394 // To check interface assignments, depends on phase 1.
395 for l := xtop; l != nil; l = l.Next {
396 if l.N.Op == ODCL || l.N.Op == OAS || l.N.Op == OAS2 {
397 typecheck(&l.N, Etop)
402 // Phase 3: Type check function bodies.
403 for l := xtop; l != nil; l = l.Next {
404 if l.N.Op == ODCLFUNC || l.N.Op == OCLOSURE {
408 typechecklist(l.N.Nbody, Etop)
411 l.N.Nbody = nil // type errors; do not compile
416 // Phase 4: Decide how to capture closed variables.
417 // This needs to run before escape analysis,
418 // because variables captured by value do not escape.
419 for l := xtop; l != nil; l = l.Next {
420 if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil {
428 if nsavederrors+nerrors != 0 {
434 // Typecheck imported function bodies if debug['l'] > 1,
435 // otherwise lazily when used or re-exported.
436 for _, n := range importlist {
437 if n.Func.Inl != nil {
443 if nsavederrors+nerrors != 0 {
449 // Find functions that can be inlined and clone them before walk expands them.
450 visitBottomUp(xtop, func(list []*Node, recursive bool) {
451 // TODO: use a range statement here if the order does not matter
452 for i := len(list) - 1; i >= 0; i-- {
454 if n.Op == ODCLFUNC {
462 // Phase 6: Escape analysis.
463 // Required for moving heap allocations onto stack,
464 // which in turn is required by the closure implementation,
465 // which stores the addresses of stack variables into the closure.
466 // If the closure does not escape, it needs to be on the stack
467 // or else the stack copier will not update it.
468 // Large values are also moved off stack in escape analysis;
469 // because large values may contain pointers, it must happen early.
472 // Phase 7: Transform closure bodies to properly reference captured variables.
473 // This needs to happen before walk, because closures must be transformed
474 // before walk reaches a call of a closure.
475 for l := xtop; l != nil; l = l.Next {
476 if l.N.Op == ODCLFUNC && l.N.Func.Closure != nil {
478 transformclosure(l.N)
484 // Phase 8: Compile top level functions.
485 for l := xtop; l != nil; l = l.Next {
486 if l.N.Op == ODCLFUNC {
491 if nsavederrors+nerrors == 0 {
495 if compiling_runtime != 0 {
496 checknowritebarrierrec()
499 // Phase 9: Check external declarations.
500 for i, n := range externdcl {
502 typecheck(&externdcl[i], Erv)
506 if nerrors+nsavederrors != 0 {
516 if nerrors+nsavederrors != 0 {
523 var importMap = map[string]string{}
525 func addImportMap(s string) {
526 if strings.Count(s, "=") != 1 {
527 log.Fatal("-importmap argument must be of the form source=actual")
529 i := strings.Index(s, "=")
530 source, actual := s[:i], s[i+1:]
531 if source == "" || actual == "" {
532 log.Fatal("-importmap argument must be of the form source=actual; source and actual must be non-empty")
534 importMap[source] = actual
538 nsavederrors += nerrors
542 func arsize(b *obj.Biobuf, name string) int {
543 var buf [ArhdrSize]byte
544 if _, err := io.ReadFull(b, buf[:]); err != nil {
547 aname := strings.Trim(string(buf[0:16]), " ")
548 if !strings.HasPrefix(aname, name) {
551 asize := strings.Trim(string(buf[48:58]), " ")
552 i, _ := strconv.Atoi(asize)
556 func skiptopkgdef(b *obj.Biobuf) bool {
558 p := obj.Brdline(b, '\n')
562 if obj.Blinelen(b) != 8 {
565 if p != "!<arch>\n" {
569 // symbol table may be first; skip it
570 sz := arsize(b, "__.GOSYMDEF")
573 obj.Bseek(b, int64(sz), 1)
578 // package export block is next
579 sz = arsize(b, "__.PKGDEF")
589 func addidir(dir string) {
591 idirs = append(idirs, dir)
595 // is this path a local name? begins with ./ or ../ or /
596 func islocalname(name string) bool {
597 return strings.HasPrefix(name, "/") ||
598 Ctxt.Windows != 0 && len(name) >= 3 && isAlpha(int(name[0])) && name[1] == ':' && name[2] == '/' ||
599 strings.HasPrefix(name, "./") || name == "." ||
600 strings.HasPrefix(name, "../") || name == ".."
603 func findpkg(name string) (file string, ok bool) {
604 if islocalname(name) {
605 if safemode != 0 || nolocalimports != 0 {
609 // try .a before .6. important for building libraries:
610 // if there is an array.6 in the array.a library,
611 // want to find all of array.a, not just array.6.
612 file = fmt.Sprintf("%s.a", name)
613 if _, err := os.Stat(file); err == nil {
616 file = fmt.Sprintf("%s.o", name)
617 if _, err := os.Stat(file); err == nil {
623 // local imports should be canonicalized already.
624 // don't want to see "encoding/../encoding/base64"
625 // as different from "encoding/base64".
626 if q := path.Clean(name); q != name {
627 Yyerror("non-canonical import path %q (should be %q)", name, q)
631 for _, dir := range idirs {
632 file = fmt.Sprintf("%s/%s.a", dir, name)
633 if _, err := os.Stat(file); err == nil {
636 file = fmt.Sprintf("%s/%s.o", dir, name)
637 if _, err := os.Stat(file); err == nil {
645 if flag_installsuffix != "" {
647 suffix = flag_installsuffix
648 } else if flag_race != 0 {
651 } else if flag_msan != 0 {
656 file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", goroot, goos, goarch, suffixsep, suffix, name)
657 if _, err := os.Stat(file); err == nil {
660 file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.o", goroot, goos, goarch, suffixsep, suffix, name)
661 if _, err := os.Stat(file); err == nil {
669 // loadsys loads the definitions for the low-level runtime and unsafe functions,
670 // so that the compiler can generate calls to them,
671 // but does not make the names "runtime" or "unsafe" visible as packages.
681 importpkg = Runtimepkg
682 parse_import(obj.Binitr(strings.NewReader(runtimeimport)), nil)
684 importpkg = unsafepkg
685 parse_import(obj.Binitr(strings.NewReader(unsafeimport)), nil)
691 func importfile(f *Val, indent []byte) {
692 if importpkg != nil {
693 Fatalf("importpkg not nil")
696 path_, ok := f.U.(string)
698 Yyerror("import statement not a string")
703 Yyerror("import path is empty")
707 if isbadimport(path_) {
711 // The package name main is no longer reserved,
712 // but we reserve the import path "main" to identify
713 // the main package, just as we reserve the import
714 // path "math" to identify the standard math package.
716 Yyerror("cannot import \"main\"")
720 if myimportpath != "" && path_ == myimportpath {
721 Yyerror("import %q while compiling that package (import cycle)", path_)
725 if mapped, ok := importMap[path_]; ok {
729 if path_ == "unsafe" {
731 Yyerror("cannot import package unsafe")
735 importpkg = unsafepkg
736 imported_unsafe = true
740 if islocalname(path_) {
742 Yyerror("import path cannot be absolute path")
746 prefix := Ctxt.Pathname
747 if localimport != "" {
750 path_ = path.Join(prefix, path_)
752 if isbadimport(path_) {
757 file, found := findpkg(path_)
759 Yyerror("can't find import: %q", path_)
763 importpkg = mkpkg(path_)
765 if importpkg.Imported {
769 importpkg.Imported = true
771 imp, err := obj.Bopenr(file)
773 Yyerror("can't open import: %q: %v", path_, err)
778 if strings.HasSuffix(file, ".a") {
779 if !skiptopkgdef(imp) {
780 Yyerror("import %s: not a package file", file)
785 // check object header
786 p := obj.Brdstr(imp, '\n', 1)
788 if p != "empty archive" {
789 if !strings.HasPrefix(p, "go object ") {
790 Yyerror("import %s: not a go object file", file)
794 q := fmt.Sprintf("%s %s %s %s", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring())
796 Yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q)
801 // assume files move (get installed)
802 // so don't record the full path.
803 linehistpragma(file[len(file)-len(path_)-2:]) // acts as #pragma lib
805 // In the importfile, if we find:
806 // $$\n (old format): position the input right after $$\n and return
807 // $$B\n (new format): import directly, then feed the lexer a dummy statement
818 if c == '$' || c < 0 {
824 // get character after $$
832 parse_import(imp, indent)
836 obj.Bgetc(imp) // skip \n after $$B
840 Yyerror("no import in %q", path_)
844 if safemode != 0 && !importpkg.Safe {
845 Yyerror("cannot import unsafe package %q", importpkg.Path)
849 func isSpace(c int) bool {
850 return c == ' ' || c == '\t' || c == '\n' || c == '\r'
853 func isAlpha(c int) bool {
854 return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
857 func isDigit(c int) bool {
858 return '0' <= c && c <= '9'
860 func isAlnum(c int) bool {
861 return isAlpha(c) || isDigit(c)
864 func plan9quote(s string) string {
868 for _, c := range s {
869 if c <= ' ' || c == '\'' {
870 return "'" + strings.Replace(s, "'", "''", -1) + "'"
876 func isfrog(c int) bool {
877 // complain about possibly invisible control characters
879 return !isSpace(c) // exclude good white space
882 if 0x7f <= c && c <= 0xa0 { // DEL, unicode block including unbreakable space.
892 peekc1 int // second peekc for ...
894 nlsemi bool // if set, '\n' and EOF translate to ';'
898 sym_ *Sym // valid if tok == LNAME
899 val Val // valid if tok == LLITERAL
900 op Op // valid if tok == LASOP
904 LLITERAL = 57346 + iota
951 func (l *lexer) next() {
969 if c == '\n' && nlsemi {
972 fmt.Printf("lex: implicit semi\n")
983 if c >= utf8.RuneSelf {
984 // all multibyte runes are alpha
1001 cp.WriteByte(byte(c))
1009 if c == 'e' || c == 'E' || c == 'p' || c == 'P' {
1019 cp.WriteByte(byte(c))
1021 if c == 'x' || c == 'X' {
1023 cp.WriteByte(byte(c))
1028 if c >= 'a' && c <= 'f' {
1031 if c >= 'A' && c <= 'F' {
1034 if lexbuf.Len() == 2 {
1035 Yyerror("malformed hex constant")
1044 if c == 'p' { // 0p begins floating point zero
1053 if c < '0' || c > '7' {
1056 cp.WriteByte(byte(c))
1063 if c == 'e' || c == 'E' {
1070 Yyerror("malformed octal constant")
1079 // Treat EOF as "end of line" for the purposes
1080 // of inserting a semicolon.
1082 if Debug['x'] != 0 {
1083 fmt.Printf("lex: implicit semi\n")
1101 cp.WriteByte(byte(c))
1120 lexbuf.WriteString(`"<string>"`)
1126 if l.escchar('"', &escflag, &v) {
1129 if v < utf8.RuneSelf || escflag != 0 {
1130 cp.WriteByte(byte(v))
1132 cp.WriteRune(rune(v))
1141 lexbuf.WriteString("`<string>`")
1152 Yyerror("eof in string")
1159 cp.WriteRune(rune(c))
1166 if l.escchar('\'', &escflag, &v) {
1167 Yyerror("empty character literal or unescaped ' in character literal")
1171 if !l.escchar('\'', &escflag, &v) {
1172 Yyerror("missing '")
1180 if Debug['x'] != 0 {
1181 fmt.Printf("lex: codepoint literal\n")
1183 litbuf = "string literal"
1212 Yyerror("eof in comment")
1219 c = l.getlinepragma()
1221 if c == '\n' || c == EOF {
1394 if Debug['x'] != 0 {
1396 fmt.Printf("%v lex: TOKEN %s\n", Ctxt.Line(int(lexlineno)), lexname(c))
1398 fmt.Printf("%v lex: TOKEN '%c'\n", Ctxt.Line(int(lexlineno)), c)
1402 Yyerror("illegal character 0x%x", uint(c))
1406 if importpkg == nil && (c == '#' || c == '$' || c == '?' || c == '@' || c == '\\') {
1407 Yyerror("%s: unexpected %c", "syntax error", c)
1416 if Debug['x'] != 0 {
1417 fmt.Printf("lex: TOKEN ASOP %s=\n", goopnames[op])
1422 // cp is set to lexbuf and some
1423 // prefix has been stored
1426 if c >= utf8.RuneSelf {
1430 // 0xb7 · is used for internal names
1431 if !unicode.IsLetter(r) && !unicode.IsDigit(r) && (importpkg == nil || r != 0xb7) {
1432 Yyerror("invalid identifier character U+%04x", r)
1434 if cp.Len() == 0 && unicode.IsDigit(r) {
1435 Yyerror("identifier cannot begin with digit U+%04x", r)
1438 } else if !isAlnum(c) && c != '_' {
1441 cp.WriteByte(byte(c))
1449 s = LookupBytes(lexbuf.Bytes())
1450 if s.Lexical == LIGNORE {
1454 if Debug['x'] != 0 {
1455 fmt.Printf("lex: %s %s\n", s, lexname(int(s.Lexical)))
1459 case LNAME, LRETURN, LBREAK, LCONTINUE, LFALL:
1462 l.tok = int32(s.Lexical)
1469 str = lexbuf.String()
1470 l.val.U = new(Mpint)
1471 mpatofix(l.val.U.(*Mpint), str)
1472 if l.val.U.(*Mpint).Ovf {
1473 Yyerror("overflow in constant")
1474 Mpmovecfix(l.val.U.(*Mpint), 0)
1477 if Debug['x'] != 0 {
1478 fmt.Printf("lex: integer literal\n")
1480 litbuf = "literal " + str
1487 cp.WriteByte(byte(c))
1497 if c != 'e' && c != 'E' {
1502 if importpkg == nil && (c == 'p' || c == 'P') {
1503 // <mantissa>p<base-2-exponent> is allowed in .a/.o imports,
1504 // but not in .go sources. See #9036.
1505 Yyerror("malformed floating point constant")
1507 cp.WriteByte(byte(c))
1509 if c == '+' || c == '-' {
1510 cp.WriteByte(byte(c))
1515 Yyerror("malformed floating point constant exponent")
1518 cp.WriteByte(byte(c))
1527 // imaginary constant
1531 str = lexbuf.String()
1532 l.val.U = new(Mpcplx)
1533 Mpmovecflt(&l.val.U.(*Mpcplx).Real, 0.0)
1534 mpatoflt(&l.val.U.(*Mpcplx).Imag, str)
1535 if l.val.U.(*Mpcplx).Imag.Val.IsInf() {
1536 Yyerror("overflow in imaginary constant")
1537 Mpmovecflt(&l.val.U.(*Mpcplx).Imag, 0.0)
1540 if Debug['x'] != 0 {
1541 fmt.Printf("lex: imaginary literal\n")
1543 litbuf = "literal " + str
1552 str = lexbuf.String()
1553 l.val.U = newMpflt()
1554 mpatoflt(l.val.U.(*Mpflt), str)
1555 if l.val.U.(*Mpflt).Val.IsInf() {
1556 Yyerror("overflow in float constant")
1557 Mpmovecflt(l.val.U.(*Mpflt), 0.0)
1560 if Debug['x'] != 0 {
1561 fmt.Printf("lex: floating literal\n")
1563 litbuf = "literal " + str
1569 l.val.U = internString(cp.Bytes())
1570 if Debug['x'] != 0 {
1571 fmt.Printf("lex: string literal\n")
1573 litbuf = "string literal"
1578 var internedStrings = map[string]string{}
1580 func internString(b []byte) string {
1581 s, ok := internedStrings[string(b)] // string(b) here doesn't allocate
1584 internedStrings[s] = s
1589 func more(pp *string) bool {
1591 for p != "" && isSpace(int(p[0])) {
1598 // read and interpret syntax that looks like
1599 // //line parse.y:15
1600 // as a discontinuity in sequential line numbers.
1601 // the next line of input comes from parse.y:15
1602 func (l *lexer) getlinepragma() int {
1603 var cmd, verb, name string
1609 cp.WriteByte('g') // already read
1612 if c == EOF || c >= utf8.RuneSelf {
1618 cp.WriteByte(byte(c))
1622 text := strings.TrimSuffix(lexbuf.String(), "\r")
1624 if strings.HasPrefix(text, "go:cgo_") {
1630 if i := strings.Index(verb, " "); i >= 0 {
1634 if verb == "go:linkname" {
1635 if !imported_unsafe {
1636 Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
1638 f := strings.Fields(cmd)
1640 Yyerror("usage: //go:linkname localname linkname")
1644 Lookup(f[1]).Linkname = f[2]
1648 if verb == "go:nointerface" && obj.Fieldtrack_enabled != 0 {
1653 if verb == "go:noescape" {
1658 if verb == "go:norace" {
1663 if verb == "go:nosplit" {
1668 if verb == "go:noinline" {
1673 if verb == "go:systemstack" {
1674 if compiling_runtime == 0 {
1675 Yyerror("//go:systemstack only allowed in runtime")
1681 if verb == "go:nowritebarrier" {
1682 if compiling_runtime == 0 {
1683 Yyerror("//go:nowritebarrier only allowed in runtime")
1685 nowritebarrier = true
1689 if verb == "go:nowritebarrierrec" {
1690 if compiling_runtime == 0 {
1691 Yyerror("//go:nowritebarrierrec only allowed in runtime")
1693 nowritebarrierrec = true
1694 nowritebarrier = true // Implies nowritebarrier
1702 for i := 1; i < 5; i++ {
1704 if c != int("line "[i]) {
1724 linep = cp.Len() + 1
1726 cp.WriteByte(byte(c))
1734 text := strings.TrimSuffix(lexbuf.String(), "\r")
1736 for _, c := range text[linep:] {
1737 if c < '0' || c > '9' {
1740 n = n*10 + int(c) - '0'
1742 Yyerror("line number out of range")
1751 name = text[:linep-1]
1752 linehistupdate(name, n)
1759 func getimpsym(pp *string) string {
1760 more(pp) // skip spaces
1762 if p == "" || p[0] == '"' {
1766 for i < len(p) && !isSpace(int(p[i])) && p[i] != '"' {
1774 func getquoted(pp *string) (string, bool) {
1775 more(pp) // skip spaces
1777 if p == "" || p[0] != '"' {
1781 i := strings.Index(p, `"`)
1789 // Copied nearly verbatim from the C compiler's #pragma parser.
1790 // TODO: Rewrite more cleanly once the compiler is written in Go.
1791 func pragcgo(text string) {
1794 if i := strings.Index(text, " "); i >= 0 {
1795 text, q = text[:i], text[i:]
1798 verb := text[3:] // skip "go:"
1800 if verb == "cgo_dynamic_linker" || verb == "dynlinker" {
1801 p, ok := getquoted(&q)
1803 Yyerror("usage: //go:cgo_dynamic_linker \"path\"")
1806 pragcgobuf += fmt.Sprintf("cgo_dynamic_linker %v\n", plan9quote(p))
1811 if verb == "dynexport" {
1812 verb = "cgo_export_dynamic"
1814 if verb == "cgo_export_static" || verb == "cgo_export_dynamic" {
1815 local := getimpsym(&q)
1821 pragcgobuf += fmt.Sprintf("%s %v\n", verb, plan9quote(local))
1825 remote = getimpsym(&q)
1829 pragcgobuf += fmt.Sprintf("%s %v %v\n", verb, plan9quote(local), plan9quote(remote))
1833 Yyerror("usage: //go:%s local [remote]", verb)
1837 if verb == "cgo_import_dynamic" || verb == "dynimport" {
1839 local := getimpsym(&q)
1846 pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v\n", plan9quote(local))
1850 remote = getimpsym(&q)
1855 pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v\n", plan9quote(local), plan9quote(remote))
1859 p, ok = getquoted(&q)
1863 pragcgobuf += fmt.Sprintf("cgo_import_dynamic %v %v %v\n", plan9quote(local), plan9quote(remote), plan9quote(p))
1867 Yyerror("usage: //go:cgo_import_dynamic local [remote [\"library\"]]")
1871 if verb == "cgo_import_static" {
1872 local := getimpsym(&q)
1873 if local == "" || more(&q) {
1874 Yyerror("usage: //go:cgo_import_static local")
1877 pragcgobuf += fmt.Sprintf("cgo_import_static %v\n", plan9quote(local))
1882 if verb == "cgo_ldflag" {
1883 p, ok := getquoted(&q)
1885 Yyerror("usage: //go:cgo_ldflag \"arg\"")
1888 pragcgobuf += fmt.Sprintf("cgo_ldflag %v\n", plan9quote(p))
1894 func (l *lexer) getc() int {
1903 c = obj.Bgetc(l.bin)
1904 // recognize BOM (U+FEFF): UTF-8 encoding is 0xef 0xbb 0xbf
1906 buf, err := l.bin.Peek(2)
1908 yyerrorl(int(lexlineno), "illegal UTF-8 sequence ef % x followed by read error (%v)", string(buf), err)
1911 if buf[0] == 0xbb && buf[1] == 0xbf {
1912 yyerrorl(int(lexlineno), "Unicode (UTF-8) BOM in middle of file")
1914 // consume BOM bytes
1923 Yyerror("illegal NUL byte")
1926 if c == '\n' && importpkg == nil {
1932 func (l *lexer) ungetc(c int) {
1935 if c == '\n' && importpkg == nil {
1940 func (l *lexer) getr() int32 {
1941 var buf [utf8.UTFMax]byte
1945 if i == 0 && c < utf8.RuneSelf {
1949 if i+1 == len(buf) || utf8.FullRune(buf[:i+1]) {
1950 r, w := utf8.DecodeRune(buf[:i+1])
1951 if r == utf8.RuneError && w == 1 {
1953 // The string conversion here makes a copy for passing
1954 // to fmt.Printf, so that buf itself does not escape and can
1955 // be allocated on the stack.
1956 Yyerror("illegal UTF-8 sequence % x", string(buf[:i+1]))
1963 func (l *lexer) escchar(e int, escflg *int, val *int64) bool {
1969 Yyerror("eof in string")
1973 Yyerror("newline in string")
1992 *escflg = 1 // it's a byte
2014 *escflg = 1 // it's a byte
2016 for i := 2; i > 0; i-- {
2018 if c >= '0' && c <= '7' {
2019 x = x*8 + int64(c) - '0'
2023 Yyerror("non-octal character in escape sequence: %c", c)
2028 Yyerror("octal escape value > 255: %d", x)
2053 Yyerror("unknown escape sequence: %c", c)
2064 if c >= '0' && c <= '9' {
2065 x = x*16 + int64(c) - '0'
2069 if c >= 'a' && c <= 'f' {
2070 x = x*16 + int64(c) - 'a' + 10
2074 if c >= 'A' && c <= 'F' {
2075 x = x*16 + int64(c) - 'A' + 10
2079 Yyerror("non-hex character in escape sequence: %c", c)
2084 if u != 0 && (x > utf8.MaxRune || (0xd800 <= x && x < 0xe000)) {
2085 Yyerror("invalid Unicode code point in escape sequence: %#x", x)
2093 var syms = []struct {
2100 {"int8", LNAME, TINT8, OXXX},
2101 {"int16", LNAME, TINT16, OXXX},
2102 {"int32", LNAME, TINT32, OXXX},
2103 {"int64", LNAME, TINT64, OXXX},
2104 {"uint8", LNAME, TUINT8, OXXX},
2105 {"uint16", LNAME, TUINT16, OXXX},
2106 {"uint32", LNAME, TUINT32, OXXX},
2107 {"uint64", LNAME, TUINT64, OXXX},
2108 {"float32", LNAME, TFLOAT32, OXXX},
2109 {"float64", LNAME, TFLOAT64, OXXX},
2110 {"complex64", LNAME, TCOMPLEX64, OXXX},
2111 {"complex128", LNAME, TCOMPLEX128, OXXX},
2112 {"bool", LNAME, TBOOL, OXXX},
2113 {"string", LNAME, TSTRING, OXXX},
2114 {"any", LNAME, TANY, OXXX},
2115 {"break", LBREAK, Txxx, OXXX},
2116 {"case", LCASE, Txxx, OXXX},
2117 {"chan", LCHAN, Txxx, OXXX},
2118 {"const", LCONST, Txxx, OXXX},
2119 {"continue", LCONTINUE, Txxx, OXXX},
2120 {"default", LDEFAULT, Txxx, OXXX},
2121 {"else", LELSE, Txxx, OXXX},
2122 {"defer", LDEFER, Txxx, OXXX},
2123 {"fallthrough", LFALL, Txxx, OXXX},
2124 {"for", LFOR, Txxx, OXXX},
2125 {"func", LFUNC, Txxx, OXXX},
2126 {"go", LGO, Txxx, OXXX},
2127 {"goto", LGOTO, Txxx, OXXX},
2128 {"if", LIF, Txxx, OXXX},
2129 {"import", LIMPORT, Txxx, OXXX},
2130 {"interface", LINTERFACE, Txxx, OXXX},
2131 {"map", LMAP, Txxx, OXXX},
2132 {"package", LPACKAGE, Txxx, OXXX},
2133 {"range", LRANGE, Txxx, OXXX},
2134 {"return", LRETURN, Txxx, OXXX},
2135 {"select", LSELECT, Txxx, OXXX},
2136 {"struct", LSTRUCT, Txxx, OXXX},
2137 {"switch", LSWITCH, Txxx, OXXX},
2138 {"type", LTYPE, Txxx, OXXX},
2139 {"var", LVAR, Txxx, OXXX},
2140 {"append", LNAME, Txxx, OAPPEND},
2141 {"cap", LNAME, Txxx, OCAP},
2142 {"close", LNAME, Txxx, OCLOSE},
2143 {"complex", LNAME, Txxx, OCOMPLEX},
2144 {"copy", LNAME, Txxx, OCOPY},
2145 {"delete", LNAME, Txxx, ODELETE},
2146 {"imag", LNAME, Txxx, OIMAG},
2147 {"len", LNAME, Txxx, OLEN},
2148 {"make", LNAME, Txxx, OMAKE},
2149 {"new", LNAME, Txxx, ONEW},
2150 {"panic", LNAME, Txxx, OPANIC},
2151 {"print", LNAME, Txxx, OPRINT},
2152 {"println", LNAME, Txxx, OPRINTN},
2153 {"real", LNAME, Txxx, OREAL},
2154 {"recover", LNAME, Txxx, ORECOVER},
2155 {"notwithstanding", LIGNORE, Txxx, OXXX},
2156 {"thetruthofthematter", LIGNORE, Txxx, OXXX},
2157 {"despiteallobjections", LIGNORE, Txxx, OXXX},
2158 {"whereas", LIGNORE, Txxx, OXXX},
2159 {"insofaras", LIGNORE, Txxx, OXXX},
2162 // lexinit initializes known symbols and the basic types.
2164 for _, s := range syms {
2166 s1 := Lookup(s.name)
2167 s1.Lexical = uint16(lex)
2169 if etype := s.etype; etype != Txxx {
2170 if int(etype) >= len(Types) {
2171 Fatalf("lexinit: %s bad etype", s.name)
2173 s2 := Pkglookup(s.name, builtinpkg)
2179 if etype != TANY && etype != TSTRING {
2187 s2.Def.Name = new(Name)
2191 // TODO(marvin): Fix Node.EType type union.
2192 if etype := s.op; etype != OXXX {
2193 s2 := Pkglookup(s.name, builtinpkg)
2195 s2.Def = Nod(ONAME, nil, nil)
2197 s2.Def.Etype = EType(etype)
2201 // logically, the type of a string literal.
2202 // types[TSTRING] is the named type string
2203 // (the type of x in var x string or var x = "hello").
2204 // this is the ideal form
2205 // (the type of x in const x = "hello").
2206 idealstring = typ(TSTRING)
2208 idealbool = typ(TBOOL)
2210 s := Pkglookup("true", builtinpkg)
2211 s.Def = Nodbool(true)
2212 s.Def.Sym = Lookup("true")
2213 s.Def.Name = new(Name)
2214 s.Def.Type = idealbool
2216 s = Pkglookup("false", builtinpkg)
2217 s.Def = Nodbool(false)
2218 s.Def.Sym = Lookup("false")
2219 s.Def.Name = new(Name)
2220 s.Def.Type = idealbool
2224 s.Def = Nod(ONAME, nil, nil)
2226 Types[TBLANK] = typ(TBLANK)
2227 s.Def.Type = Types[TBLANK]
2230 s = Pkglookup("_", builtinpkg)
2232 s.Def = Nod(ONAME, nil, nil)
2234 Types[TBLANK] = typ(TBLANK)
2235 s.Def.Type = Types[TBLANK]
2237 Types[TNIL] = typ(TNIL)
2238 s = Pkglookup("nil", builtinpkg)
2243 s.Def.Name = new(Name)
2247 // t = interface { Error() string }
2248 rcvr := typ(TSTRUCT)
2250 rcvr.Type = typ(TFIELD)
2251 rcvr.Type.Type = Ptrto(typ(TSTRUCT))
2256 out.Type = typ(TFIELD)
2257 out.Type.Type = Types[TSTRING]
2268 t.Type = typ(TFIELD)
2269 t.Type.Sym = Lookup("Error")
2273 s := Lookup("error")
2276 s1 := Pkglookup("error", builtinpkg)
2280 s1.Def = typenod(errortype)
2286 s1 = Pkglookup("byte", builtinpkg)
2287 bytetype = typ(TUINT8)
2290 s1.Def = typenod(bytetype)
2291 s1.Def.Name = new(Name)
2297 s1 = Pkglookup("rune", builtinpkg)
2298 runetype = typ(TINT32)
2301 s1.Def = typenod(runetype)
2302 s1.Def.Name = new(Name)
2306 for i := range syms {
2307 lex := syms[i].lexical
2311 s := Lookup(syms[i].name)
2312 s.Lexical = uint16(lex)
2314 etype := syms[i].etype
2315 if etype != Txxx && (etype != TANY || Debug['A'] != 0) && s.Def == nil {
2316 s.Def = typenod(Types[etype])
2317 s.Def.Name = new(Name)
2318 s.Origpkg = builtinpkg
2321 // TODO(marvin): Fix Node.EType type union.
2322 etype = EType(syms[i].op)
2323 if etype != EType(OXXX) && s.Def == nil {
2324 s.Def = Nod(ONAME, nil, nil)
2327 s.Origpkg = builtinpkg
2331 // backend-specific builtin types (e.g. int).
2332 for i := range Thearch.Typedefs {
2333 s := Lookup(Thearch.Typedefs[i].Name)
2335 s.Def = typenod(Types[Thearch.Typedefs[i].Etype])
2336 s.Def.Name = new(Name)
2337 s.Origpkg = builtinpkg
2341 // there's only so much table-driven we can handle.
2342 // these are special cases.
2343 if s := Lookup("byte"); s.Def == nil {
2344 s.Def = typenod(bytetype)
2345 s.Def.Name = new(Name)
2346 s.Origpkg = builtinpkg
2349 if s := Lookup("error"); s.Def == nil {
2350 s.Def = typenod(errortype)
2351 s.Def.Name = new(Name)
2352 s.Origpkg = builtinpkg
2355 if s := Lookup("rune"); s.Def == nil {
2356 s.Def = typenod(runetype)
2357 s.Def.Name = new(Name)
2358 s.Origpkg = builtinpkg
2361 if s := Lookup("nil"); s.Def == nil {
2366 s.Def.Name = new(Name)
2367 s.Origpkg = builtinpkg
2370 if s := Lookup("iota"); s.Def == nil {
2371 s.Def = Nod(OIOTA, nil, nil)
2373 s.Origpkg = builtinpkg
2376 if s := Lookup("true"); s.Def == nil {
2377 s.Def = Nodbool(true)
2379 s.Def.Name = new(Name)
2380 s.Origpkg = builtinpkg
2383 if s := Lookup("false"); s.Def == nil {
2384 s.Def = Nodbool(false)
2386 s.Def.Name = new(Name)
2387 s.Origpkg = builtinpkg
2390 nodfp = Nod(ONAME, nil, nil)
2391 nodfp.Type = Types[TINT32]
2393 nodfp.Class = PPARAM
2394 nodfp.Sym = Lookup(".fp")
2397 var lexn = map[int]string{
2407 LCONTINUE: "CONTINUE",
2410 LDEFAULT: "DEFAULT",
2424 LINTERFACE: "INTERFACE",
2426 LLITERAL: "LITERAL",
2433 LPACKAGE: "PACKAGE",
2444 func lexname(lex int) string {
2445 if s, ok := lexn[lex]; ok {
2448 return fmt.Sprintf("LEX-%d", lex)
2451 func pkgnotused(lineno int, path string, name string) {
2452 // If the package was imported with a name other than the final
2453 // import path element, show it explicitly in the error message.
2454 // Note that this handles both renamed imports and imports of
2455 // packages containing unconventional package declarations.
2456 // Note that this uses / always, even on Windows, because Go import
2457 // paths always use forward slashes.
2459 if i := strings.LastIndex(elem, "/"); i >= 0 {
2462 if name == "" || elem == name {
2463 yyerrorl(int(lineno), "imported and not used: %q", path)
2465 yyerrorl(int(lineno), "imported and not used: %q as %s", path, name)
2469 func mkpackage(pkgname string) {
2470 if localpkg.Name == "" {
2472 Yyerror("invalid package name _")
2474 localpkg.Name = pkgname
2476 if pkgname != localpkg.Name {
2477 Yyerror("package %s; expected %s", pkgname, localpkg.Name)
2479 for _, s := range localpkg.Syms {
2483 if s.Def.Op == OPACK {
2484 // throw away top-level package name leftover
2485 // from previous file.
2486 // leave s->block set to cause redeclaration
2487 // errors if a conflicting top-level name is
2488 // introduced by a different file.
2489 if !s.Def.Used && nsyntaxerrors == 0 {
2490 pkgnotused(int(s.Def.Lineno), s.Def.Name.Pkg.Path, s.Name)
2497 // throw away top-level name left over
2498 // from previous import . "x"
2499 if s.Def.Name != nil && s.Def.Name.Pack != nil && !s.Def.Name.Pack.Used && nsyntaxerrors == 0 {
2500 pkgnotused(int(s.Def.Name.Pack.Lineno), s.Def.Name.Pack.Name.Pkg.Path, "")
2501 s.Def.Name.Pack.Used = true
2512 if i := strings.LastIndex(p, "/"); i >= 0 {
2515 if Ctxt.Windows != 0 {
2516 if i := strings.LastIndex(p, `\`); i >= 0 {
2520 if i := strings.LastIndex(p, "."); i >= 0 {
2524 if writearchive > 0 {
2527 outfile = p + suffix