]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/gc/main.go
[dev.typeparams] codereview.cfg: add config for dev.typeparams
[gostls13.git] / src / cmd / compile / internal / gc / main.go
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.
4
5 //go:generate go run mkbuiltin.go
6
7 package gc
8
9 import (
10         "bufio"
11         "bytes"
12         "cmd/compile/internal/base"
13         "cmd/compile/internal/ir"
14         "cmd/compile/internal/logopt"
15         "cmd/compile/internal/ssa"
16         "cmd/compile/internal/types"
17         "cmd/internal/bio"
18         "cmd/internal/dwarf"
19         "cmd/internal/goobj"
20         "cmd/internal/obj"
21         "cmd/internal/objabi"
22         "cmd/internal/src"
23         "flag"
24         "fmt"
25         "go/constant"
26         "internal/goversion"
27         "io"
28         "io/ioutil"
29         "log"
30         "os"
31         "path"
32         "regexp"
33         "runtime"
34         "sort"
35         "strconv"
36         "strings"
37 )
38
39 func hidePanic() {
40         if base.Debug.Panic == 0 && base.Errors() > 0 {
41                 // If we've already complained about things
42                 // in the program, don't bother complaining
43                 // about a panic too; let the user clean up
44                 // the code and try again.
45                 if err := recover(); err != nil {
46                         if err == "-h" {
47                                 panic(err)
48                         }
49                         base.ErrorExit()
50                 }
51         }
52 }
53
54 // Target is the package being compiled.
55 var Target *ir.Package
56
57 // timing data for compiler phases
58 var timings Timings
59
60 // Main parses flags and Go source files specified in the command-line
61 // arguments, type-checks the parsed Go package, compiles functions to machine
62 // code, and finally writes the compiled package definition to disk.
63 func Main(archInit func(*Arch)) {
64         timings.Start("fe", "init")
65
66         defer hidePanic()
67
68         archInit(&thearch)
69
70         base.Ctxt = obj.Linknew(thearch.LinkArch)
71         base.Ctxt.DiagFunc = base.Errorf
72         base.Ctxt.DiagFlush = base.FlushErrors
73         base.Ctxt.Bso = bufio.NewWriter(os.Stdout)
74
75         // UseBASEntries is preferred because it shaves about 2% off build time, but LLDB, dsymutil, and dwarfdump
76         // on Darwin don't support it properly, especially since macOS 10.14 (Mojave).  This is exposed as a flag
77         // to allow testing with LLVM tools on Linux, and to help with reporting this bug to the LLVM project.
78         // See bugs 31188 and 21945 (CLs 170638, 98075, 72371).
79         base.Ctxt.UseBASEntries = base.Ctxt.Headtype != objabi.Hdarwin
80
81         types.LocalPkg = types.NewPkg("", "")
82         types.LocalPkg.Prefix = "\"\""
83
84         // We won't know localpkg's height until after import
85         // processing. In the mean time, set to MaxPkgHeight to ensure
86         // height comparisons at least work until then.
87         types.LocalPkg.Height = types.MaxPkgHeight
88
89         // pseudo-package, for scoping
90         types.BuiltinPkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
91         types.BuiltinPkg.Prefix = "go.builtin"            // not go%2ebuiltin
92
93         // pseudo-package, accessed by import "unsafe"
94         unsafepkg = types.NewPkg("unsafe", "unsafe")
95
96         // Pseudo-package that contains the compiler's builtin
97         // declarations for package runtime. These are declared in a
98         // separate package to avoid conflicts with package runtime's
99         // actual declarations, which may differ intentionally but
100         // insignificantly.
101         Runtimepkg = types.NewPkg("go.runtime", "runtime")
102         Runtimepkg.Prefix = "runtime"
103
104         // pseudo-packages used in symbol tables
105         itabpkg = types.NewPkg("go.itab", "go.itab")
106         itabpkg.Prefix = "go.itab" // not go%2eitab
107
108         itablinkpkg = types.NewPkg("go.itablink", "go.itablink")
109         itablinkpkg.Prefix = "go.itablink" // not go%2eitablink
110
111         trackpkg = types.NewPkg("go.track", "go.track")
112         trackpkg.Prefix = "go.track" // not go%2etrack
113
114         // pseudo-package used for map zero values
115         mappkg = types.NewPkg("go.map", "go.map")
116         mappkg.Prefix = "go.map"
117
118         // pseudo-package used for methods with anonymous receivers
119         gopkg = types.NewPkg("go", "")
120
121         base.DebugSSA = ssa.PhaseOption
122         base.ParseFlags()
123
124         // Record flags that affect the build result. (And don't
125         // record flags that don't, since that would cause spurious
126         // changes in the binary.)
127         recordFlags("B", "N", "l", "msan", "race", "shared", "dynlink", "dwarflocationlists", "dwarfbasentries", "smallframes", "spectre")
128
129         if !enableTrace && base.Flag.LowerT {
130                 log.Fatalf("compiler not built with support for -t")
131         }
132
133         // Enable inlining (after recordFlags, to avoid recording the rewritten -l).  For now:
134         //      default: inlining on.  (Flag.LowerL == 1)
135         //      -l: inlining off  (Flag.LowerL == 0)
136         //      -l=2, -l=3: inlining on again, with extra debugging (Flag.LowerL > 1)
137         if base.Flag.LowerL <= 1 {
138                 base.Flag.LowerL = 1 - base.Flag.LowerL
139         }
140
141         if base.Flag.SmallFrames {
142                 maxStackVarSize = 128 * 1024
143                 maxImplicitStackVarSize = 16 * 1024
144         }
145
146         if base.Flag.Dwarf {
147                 base.Ctxt.DebugInfo = debuginfo
148                 base.Ctxt.GenAbstractFunc = genAbstractFunc
149                 base.Ctxt.DwFixups = obj.NewDwarfFixupTable(base.Ctxt)
150         } else {
151                 // turn off inline generation if no dwarf at all
152                 base.Flag.GenDwarfInl = 0
153                 base.Ctxt.Flag_locationlists = false
154         }
155         if base.Ctxt.Flag_locationlists && len(base.Ctxt.Arch.DWARFRegisters) == 0 {
156                 log.Fatalf("location lists requested but register mapping not available on %v", base.Ctxt.Arch.Name)
157         }
158
159         checkLang()
160
161         if base.Flag.SymABIs != "" {
162                 readSymABIs(base.Flag.SymABIs, base.Ctxt.Pkgpath)
163         }
164
165         if ispkgin(omit_pkgs) {
166                 base.Flag.Race = false
167                 base.Flag.MSan = false
168         }
169
170         thearch.LinkArch.Init(base.Ctxt)
171         startProfile()
172         if base.Flag.Race {
173                 racepkg = types.NewPkg("runtime/race", "")
174         }
175         if base.Flag.MSan {
176                 msanpkg = types.NewPkg("runtime/msan", "")
177         }
178         if base.Flag.Race || base.Flag.MSan {
179                 instrumenting = true
180         }
181         if base.Flag.Dwarf {
182                 dwarf.EnableLogging(base.Debug.DwarfInl != 0)
183         }
184         if base.Debug.SoftFloat != 0 {
185                 thearch.SoftFloat = true
186         }
187
188         if base.Flag.JSON != "" { // parse version,destination from json logging optimization.
189                 logopt.LogJsonOption(base.Flag.JSON)
190         }
191
192         IsIntrinsicCall = isIntrinsicCall
193         SSADumpInline = ssaDumpInline
194
195         ssaDump = os.Getenv("GOSSAFUNC")
196         ssaDir = os.Getenv("GOSSADIR")
197         if ssaDump != "" {
198                 if strings.HasSuffix(ssaDump, "+") {
199                         ssaDump = ssaDump[:len(ssaDump)-1]
200                         ssaDumpStdout = true
201                 }
202                 spl := strings.Split(ssaDump, ":")
203                 if len(spl) > 1 {
204                         ssaDump = spl[0]
205                         ssaDumpCFG = spl[1]
206                 }
207         }
208
209         Widthptr = thearch.LinkArch.PtrSize
210         Widthreg = thearch.LinkArch.RegSize
211
212         Target = new(ir.Package)
213
214         // initialize types package
215         // (we need to do this to break dependencies that otherwise
216         // would lead to import cycles)
217         initializeTypesPackage()
218
219         dclcontext = ir.PEXTERN
220
221         autogeneratedPos = makePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
222
223         timings.Start("fe", "loadsys")
224         loadsys()
225
226         timings.Start("fe", "parse")
227         lines := parseFiles(flag.Args())
228         cgoSymABIs()
229         timings.Stop()
230         timings.AddEvent(int64(lines), "lines")
231         if base.Flag.G != 0 && base.Flag.G < 3 {
232                 // can only parse generic code for now
233                 base.ExitIfErrors()
234                 return
235         }
236
237         finishUniverse()
238
239         recordPackageName()
240
241         typecheckok = true
242
243         // Process top-level declarations in phases.
244
245         // Phase 1: const, type, and names and types of funcs.
246         //   This will gather all the information about types
247         //   and methods but doesn't depend on any of it.
248         //
249         //   We also defer type alias declarations until phase 2
250         //   to avoid cycles like #18640.
251         //   TODO(gri) Remove this again once we have a fix for #25838.
252
253         // Don't use range--typecheck can add closures to Target.Decls.
254         timings.Start("fe", "typecheck", "top1")
255         for i := 0; i < len(Target.Decls); i++ {
256                 n := Target.Decls[i]
257                 if op := n.Op(); op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.(*ir.Decl).Left().Name().Alias()) {
258                         Target.Decls[i] = typecheck(n, ctxStmt)
259                 }
260         }
261
262         // Phase 2: Variable assignments.
263         //   To check interface assignments, depends on phase 1.
264
265         // Don't use range--typecheck can add closures to Target.Decls.
266         timings.Start("fe", "typecheck", "top2")
267         for i := 0; i < len(Target.Decls); i++ {
268                 n := Target.Decls[i]
269                 if op := n.Op(); op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.(*ir.Decl).Left().Name().Alias() {
270                         Target.Decls[i] = typecheck(n, ctxStmt)
271                 }
272         }
273
274         // Phase 3: Type check function bodies.
275         // Don't use range--typecheck can add closures to Target.Decls.
276         timings.Start("fe", "typecheck", "func")
277         var fcount int64
278         for i := 0; i < len(Target.Decls); i++ {
279                 n := Target.Decls[i]
280                 if n.Op() == ir.ODCLFUNC {
281                         Curfn = n.(*ir.Func)
282                         decldepth = 1
283                         errorsBefore := base.Errors()
284                         typecheckslice(Curfn.Body().Slice(), ctxStmt)
285                         checkreturn(Curfn)
286                         if base.Errors() > errorsBefore {
287                                 Curfn.PtrBody().Set(nil) // type errors; do not compile
288                         }
289                         // Now that we've checked whether n terminates,
290                         // we can eliminate some obviously dead code.
291                         deadcode(Curfn)
292                         fcount++
293                 }
294         }
295
296         // Phase 3.11: Check external declarations.
297         // TODO(mdempsky): This should be handled when type checking their
298         // corresponding ODCL nodes.
299         timings.Start("fe", "typecheck", "externdcls")
300         for i, n := range Target.Externs {
301                 if n.Op() == ir.ONAME {
302                         Target.Externs[i] = typecheck(Target.Externs[i], ctxExpr)
303                 }
304         }
305
306         // Phase 3.14: With all user code type-checked, it's now safe to verify map keys
307         // and unused dot imports.
308         checkMapKeys()
309         checkDotImports()
310         base.ExitIfErrors()
311
312         timings.AddEvent(fcount, "funcs")
313
314         if initTask := fninit(); initTask != nil {
315                 exportsym(initTask)
316         }
317
318         // Phase 4: Decide how to capture closed variables.
319         // This needs to run before escape analysis,
320         // because variables captured by value do not escape.
321         timings.Start("fe", "capturevars")
322         for _, n := range Target.Decls {
323                 if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil {
324                         Curfn = n.(*ir.Func)
325                         capturevars(Curfn)
326                 }
327         }
328         capturevarscomplete = true
329         Curfn = nil
330         base.ExitIfErrors()
331
332         // Phase 5: Inlining
333         timings.Start("fe", "inlining")
334         if base.Debug.TypecheckInl != 0 {
335                 // Typecheck imported function bodies if Debug.l > 1,
336                 // otherwise lazily when used or re-exported.
337                 for _, n := range importlist {
338                         if n.Inl != nil {
339                                 typecheckinl(n)
340                         }
341                 }
342                 base.ExitIfErrors()
343         }
344
345         if base.Flag.LowerL != 0 {
346                 // Find functions that can be inlined and clone them before walk expands them.
347                 visitBottomUp(Target.Decls, func(list []*ir.Func, recursive bool) {
348                         numfns := numNonClosures(list)
349                         for _, n := range list {
350                                 if !recursive || numfns > 1 {
351                                         // We allow inlining if there is no
352                                         // recursion, or the recursion cycle is
353                                         // across more than one function.
354                                         caninl(n)
355                                 } else {
356                                         if base.Flag.LowerM > 1 {
357                                                 fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Nname)
358                                         }
359                                 }
360                                 inlcalls(n)
361                         }
362                 })
363         }
364
365         for _, n := range Target.Decls {
366                 if n.Op() == ir.ODCLFUNC {
367                         devirtualize(n.(*ir.Func))
368                 }
369         }
370         Curfn = nil
371
372         // Phase 6: Escape analysis.
373         // Required for moving heap allocations onto stack,
374         // which in turn is required by the closure implementation,
375         // which stores the addresses of stack variables into the closure.
376         // If the closure does not escape, it needs to be on the stack
377         // or else the stack copier will not update it.
378         // Large values are also moved off stack in escape analysis;
379         // because large values may contain pointers, it must happen early.
380         timings.Start("fe", "escapes")
381         escapes(Target.Decls)
382
383         // Collect information for go:nowritebarrierrec
384         // checking. This must happen before transformclosure.
385         // We'll do the final check after write barriers are
386         // inserted.
387         if base.Flag.CompilingRuntime {
388                 EnableNoWriteBarrierRecCheck()
389         }
390
391         // Phase 7: Transform closure bodies to properly reference captured variables.
392         // This needs to happen before walk, because closures must be transformed
393         // before walk reaches a call of a closure.
394         timings.Start("fe", "xclosures")
395         for _, n := range Target.Decls {
396                 if n.Op() == ir.ODCLFUNC && n.Func().OClosure != nil {
397                         Curfn = n.(*ir.Func)
398                         transformclosure(Curfn)
399                 }
400         }
401
402         // Prepare for SSA compilation.
403         // This must be before peekitabs, because peekitabs
404         // can trigger function compilation.
405         initssaconfig()
406
407         // Just before compilation, compile itabs found on
408         // the right side of OCONVIFACE so that methods
409         // can be de-virtualized during compilation.
410         Curfn = nil
411         peekitabs()
412
413         // Phase 8: Compile top level functions.
414         // Don't use range--walk can add functions to Target.Decls.
415         timings.Start("be", "compilefuncs")
416         fcount = 0
417         for i := 0; i < len(Target.Decls); i++ {
418                 n := Target.Decls[i]
419                 if n.Op() == ir.ODCLFUNC {
420                         funccompile(n.(*ir.Func))
421                         fcount++
422                 }
423         }
424         timings.AddEvent(fcount, "funcs")
425
426         compileFunctions()
427
428         if base.Flag.CompilingRuntime {
429                 // Write barriers are now known. Check the call graph.
430                 NoWriteBarrierRecCheck()
431         }
432
433         // Finalize DWARF inline routine DIEs, then explicitly turn off
434         // DWARF inlining gen so as to avoid problems with generated
435         // method wrappers.
436         if base.Ctxt.DwFixups != nil {
437                 base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
438                 base.Ctxt.DwFixups = nil
439                 base.Flag.GenDwarfInl = 0
440         }
441
442         // Write object data to disk.
443         timings.Start("be", "dumpobj")
444         dumpdata()
445         base.Ctxt.NumberSyms()
446         dumpobj()
447         if base.Flag.AsmHdr != "" {
448                 dumpasmhdr()
449         }
450
451         // Check whether any of the functions we have compiled have gigantic stack frames.
452         sort.Slice(largeStackFrames, func(i, j int) bool {
453                 return largeStackFrames[i].pos.Before(largeStackFrames[j].pos)
454         })
455         for _, large := range largeStackFrames {
456                 if large.callee != 0 {
457                         base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args + %d MB callee", large.locals>>20, large.args>>20, large.callee>>20)
458                 } else {
459                         base.ErrorfAt(large.pos, "stack frame too large (>1GB): %d MB locals + %d MB args", large.locals>>20, large.args>>20)
460                 }
461         }
462
463         if len(funcStack) != 0 {
464                 base.Fatalf("funcStack is non-empty: %v", len(funcStack))
465         }
466         if len(compilequeue) != 0 {
467                 base.Fatalf("%d uncompiled functions", len(compilequeue))
468         }
469
470         logopt.FlushLoggedOpts(base.Ctxt, base.Ctxt.Pkgpath)
471         base.ExitIfErrors()
472
473         base.FlushErrors()
474         timings.Stop()
475
476         if base.Flag.Bench != "" {
477                 if err := writebench(base.Flag.Bench); err != nil {
478                         log.Fatalf("cannot write benchmark data: %v", err)
479                 }
480         }
481 }
482
483 func cgoSymABIs() {
484         // The linker expects an ABI0 wrapper for all cgo-exported
485         // functions.
486         for _, prag := range Target.CgoPragmas {
487                 switch prag[0] {
488                 case "cgo_export_static", "cgo_export_dynamic":
489                         if symabiRefs == nil {
490                                 symabiRefs = make(map[string]obj.ABI)
491                         }
492                         symabiRefs[prag[1]] = obj.ABI0
493                 }
494         }
495 }
496
497 // numNonClosures returns the number of functions in list which are not closures.
498 func numNonClosures(list []*ir.Func) int {
499         count := 0
500         for _, fn := range list {
501                 if fn.OClosure == nil {
502                         count++
503                 }
504         }
505         return count
506 }
507
508 func writebench(filename string) error {
509         f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
510         if err != nil {
511                 return err
512         }
513
514         var buf bytes.Buffer
515         fmt.Fprintln(&buf, "commit:", objabi.Version)
516         fmt.Fprintln(&buf, "goos:", runtime.GOOS)
517         fmt.Fprintln(&buf, "goarch:", runtime.GOARCH)
518         timings.Write(&buf, "BenchmarkCompile:"+base.Ctxt.Pkgpath+":")
519
520         n, err := f.Write(buf.Bytes())
521         if err != nil {
522                 return err
523         }
524         if n != buf.Len() {
525                 panic("bad writer")
526         }
527
528         return f.Close()
529 }
530
531 // symabiDefs and symabiRefs record the defined and referenced ABIs of
532 // symbols required by non-Go code. These are keyed by link symbol
533 // name, where the local package prefix is always `"".`
534 var symabiDefs, symabiRefs map[string]obj.ABI
535
536 // readSymABIs reads a symabis file that specifies definitions and
537 // references of text symbols by ABI.
538 //
539 // The symabis format is a set of lines, where each line is a sequence
540 // of whitespace-separated fields. The first field is a verb and is
541 // either "def" for defining a symbol ABI or "ref" for referencing a
542 // symbol using an ABI. For both "def" and "ref", the second field is
543 // the symbol name and the third field is the ABI name, as one of the
544 // named cmd/internal/obj.ABI constants.
545 func readSymABIs(file, myimportpath string) {
546         data, err := ioutil.ReadFile(file)
547         if err != nil {
548                 log.Fatalf("-symabis: %v", err)
549         }
550
551         symabiDefs = make(map[string]obj.ABI)
552         symabiRefs = make(map[string]obj.ABI)
553
554         localPrefix := ""
555         if myimportpath != "" {
556                 // Symbols in this package may be written either as
557                 // "".X or with the package's import path already in
558                 // the symbol.
559                 localPrefix = objabi.PathToPrefix(myimportpath) + "."
560         }
561
562         for lineNum, line := range strings.Split(string(data), "\n") {
563                 lineNum++ // 1-based
564                 line = strings.TrimSpace(line)
565                 if line == "" || strings.HasPrefix(line, "#") {
566                         continue
567                 }
568
569                 parts := strings.Fields(line)
570                 switch parts[0] {
571                 case "def", "ref":
572                         // Parse line.
573                         if len(parts) != 3 {
574                                 log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0])
575                         }
576                         sym, abistr := parts[1], parts[2]
577                         abi, valid := obj.ParseABI(abistr)
578                         if !valid {
579                                 log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abistr)
580                         }
581
582                         // If the symbol is already prefixed with
583                         // myimportpath, rewrite it to start with ""
584                         // so it matches the compiler's internal
585                         // symbol names.
586                         if localPrefix != "" && strings.HasPrefix(sym, localPrefix) {
587                                 sym = `"".` + sym[len(localPrefix):]
588                         }
589
590                         // Record for later.
591                         if parts[0] == "def" {
592                                 symabiDefs[sym] = abi
593                         } else {
594                                 symabiRefs[sym] = abi
595                         }
596                 default:
597                         log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0])
598                 }
599         }
600 }
601
602 func arsize(b *bufio.Reader, name string) int {
603         var buf [ArhdrSize]byte
604         if _, err := io.ReadFull(b, buf[:]); err != nil {
605                 return -1
606         }
607         aname := strings.Trim(string(buf[0:16]), " ")
608         if !strings.HasPrefix(aname, name) {
609                 return -1
610         }
611         asize := strings.Trim(string(buf[48:58]), " ")
612         i, _ := strconv.Atoi(asize)
613         return i
614 }
615
616 func isDriveLetter(b byte) bool {
617         return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
618 }
619
620 // is this path a local name? begins with ./ or ../ or /
621 func islocalname(name string) bool {
622         return strings.HasPrefix(name, "/") ||
623                 runtime.GOOS == "windows" && len(name) >= 3 && isDriveLetter(name[0]) && name[1] == ':' && name[2] == '/' ||
624                 strings.HasPrefix(name, "./") || name == "." ||
625                 strings.HasPrefix(name, "../") || name == ".."
626 }
627
628 func findpkg(name string) (file string, ok bool) {
629         if islocalname(name) {
630                 if base.Flag.NoLocalImports {
631                         return "", false
632                 }
633
634                 if base.Flag.Cfg.PackageFile != nil {
635                         file, ok = base.Flag.Cfg.PackageFile[name]
636                         return file, ok
637                 }
638
639                 // try .a before .6.  important for building libraries:
640                 // if there is an array.6 in the array.a library,
641                 // want to find all of array.a, not just array.6.
642                 file = fmt.Sprintf("%s.a", name)
643                 if _, err := os.Stat(file); err == nil {
644                         return file, true
645                 }
646                 file = fmt.Sprintf("%s.o", name)
647                 if _, err := os.Stat(file); err == nil {
648                         return file, true
649                 }
650                 return "", false
651         }
652
653         // local imports should be canonicalized already.
654         // don't want to see "encoding/../encoding/base64"
655         // as different from "encoding/base64".
656         if q := path.Clean(name); q != name {
657                 base.Errorf("non-canonical import path %q (should be %q)", name, q)
658                 return "", false
659         }
660
661         if base.Flag.Cfg.PackageFile != nil {
662                 file, ok = base.Flag.Cfg.PackageFile[name]
663                 return file, ok
664         }
665
666         for _, dir := range base.Flag.Cfg.ImportDirs {
667                 file = fmt.Sprintf("%s/%s.a", dir, name)
668                 if _, err := os.Stat(file); err == nil {
669                         return file, true
670                 }
671                 file = fmt.Sprintf("%s/%s.o", dir, name)
672                 if _, err := os.Stat(file); err == nil {
673                         return file, true
674                 }
675         }
676
677         if objabi.GOROOT != "" {
678                 suffix := ""
679                 suffixsep := ""
680                 if base.Flag.InstallSuffix != "" {
681                         suffixsep = "_"
682                         suffix = base.Flag.InstallSuffix
683                 } else if base.Flag.Race {
684                         suffixsep = "_"
685                         suffix = "race"
686                 } else if base.Flag.MSan {
687                         suffixsep = "_"
688                         suffix = "msan"
689                 }
690
691                 file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
692                 if _, err := os.Stat(file); err == nil {
693                         return file, true
694                 }
695                 file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.o", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
696                 if _, err := os.Stat(file); err == nil {
697                         return file, true
698                 }
699         }
700
701         return "", false
702 }
703
704 // loadsys loads the definitions for the low-level runtime functions,
705 // so that the compiler can generate calls to them,
706 // but does not make them visible to user code.
707 func loadsys() {
708         types.Block = 1
709
710         inimport = true
711         typecheckok = true
712
713         typs := runtimeTypes()
714         for _, d := range &runtimeDecls {
715                 sym := Runtimepkg.Lookup(d.name)
716                 typ := typs[d.typ]
717                 switch d.tag {
718                 case funcTag:
719                         importfunc(Runtimepkg, src.NoXPos, sym, typ)
720                 case varTag:
721                         importvar(Runtimepkg, src.NoXPos, sym, typ)
722                 default:
723                         base.Fatalf("unhandled declaration tag %v", d.tag)
724                 }
725         }
726
727         typecheckok = false
728         inimport = false
729 }
730
731 // myheight tracks the local package's height based on packages
732 // imported so far.
733 var myheight int
734
735 func importfile(f constant.Value) *types.Pkg {
736         if f.Kind() != constant.String {
737                 base.Errorf("import path must be a string")
738                 return nil
739         }
740
741         path_ := constant.StringVal(f)
742         if len(path_) == 0 {
743                 base.Errorf("import path is empty")
744                 return nil
745         }
746
747         if isbadimport(path_, false) {
748                 return nil
749         }
750
751         // The package name main is no longer reserved,
752         // but we reserve the import path "main" to identify
753         // the main package, just as we reserve the import
754         // path "math" to identify the standard math package.
755         if path_ == "main" {
756                 base.Errorf("cannot import \"main\"")
757                 base.ErrorExit()
758         }
759
760         if base.Ctxt.Pkgpath != "" && path_ == base.Ctxt.Pkgpath {
761                 base.Errorf("import %q while compiling that package (import cycle)", path_)
762                 base.ErrorExit()
763         }
764
765         if mapped, ok := base.Flag.Cfg.ImportMap[path_]; ok {
766                 path_ = mapped
767         }
768
769         if path_ == "unsafe" {
770                 return unsafepkg
771         }
772
773         if islocalname(path_) {
774                 if path_[0] == '/' {
775                         base.Errorf("import path cannot be absolute path")
776                         return nil
777                 }
778
779                 prefix := base.Ctxt.Pathname
780                 if base.Flag.D != "" {
781                         prefix = base.Flag.D
782                 }
783                 path_ = path.Join(prefix, path_)
784
785                 if isbadimport(path_, true) {
786                         return nil
787                 }
788         }
789
790         file, found := findpkg(path_)
791         if !found {
792                 base.Errorf("can't find import: %q", path_)
793                 base.ErrorExit()
794         }
795
796         importpkg := types.NewPkg(path_, "")
797         if importpkg.Imported {
798                 return importpkg
799         }
800
801         importpkg.Imported = true
802
803         imp, err := bio.Open(file)
804         if err != nil {
805                 base.Errorf("can't open import: %q: %v", path_, err)
806                 base.ErrorExit()
807         }
808         defer imp.Close()
809
810         // check object header
811         p, err := imp.ReadString('\n')
812         if err != nil {
813                 base.Errorf("import %s: reading input: %v", file, err)
814                 base.ErrorExit()
815         }
816
817         if p == "!<arch>\n" { // package archive
818                 // package export block should be first
819                 sz := arsize(imp.Reader, "__.PKGDEF")
820                 if sz <= 0 {
821                         base.Errorf("import %s: not a package file", file)
822                         base.ErrorExit()
823                 }
824                 p, err = imp.ReadString('\n')
825                 if err != nil {
826                         base.Errorf("import %s: reading input: %v", file, err)
827                         base.ErrorExit()
828                 }
829         }
830
831         if !strings.HasPrefix(p, "go object ") {
832                 base.Errorf("import %s: not a go object file: %s", file, p)
833                 base.ErrorExit()
834         }
835         q := fmt.Sprintf("%s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
836         if p[10:] != q {
837                 base.Errorf("import %s: object is [%s] expected [%s]", file, p[10:], q)
838                 base.ErrorExit()
839         }
840
841         // process header lines
842         for {
843                 p, err = imp.ReadString('\n')
844                 if err != nil {
845                         base.Errorf("import %s: reading input: %v", file, err)
846                         base.ErrorExit()
847                 }
848                 if p == "\n" {
849                         break // header ends with blank line
850                 }
851         }
852
853         // Expect $$B\n to signal binary import format.
854
855         // look for $$
856         var c byte
857         for {
858                 c, err = imp.ReadByte()
859                 if err != nil {
860                         break
861                 }
862                 if c == '$' {
863                         c, err = imp.ReadByte()
864                         if c == '$' || err != nil {
865                                 break
866                         }
867                 }
868         }
869
870         // get character after $$
871         if err == nil {
872                 c, _ = imp.ReadByte()
873         }
874
875         var fingerprint goobj.FingerprintType
876         switch c {
877         case '\n':
878                 base.Errorf("cannot import %s: old export format no longer supported (recompile library)", path_)
879                 return nil
880
881         case 'B':
882                 if base.Debug.Export != 0 {
883                         fmt.Printf("importing %s (%s)\n", path_, file)
884                 }
885                 imp.ReadByte() // skip \n after $$B
886
887                 c, err = imp.ReadByte()
888                 if err != nil {
889                         base.Errorf("import %s: reading input: %v", file, err)
890                         base.ErrorExit()
891                 }
892
893                 // Indexed format is distinguished by an 'i' byte,
894                 // whereas previous export formats started with 'c', 'd', or 'v'.
895                 if c != 'i' {
896                         base.Errorf("import %s: unexpected package format byte: %v", file, c)
897                         base.ErrorExit()
898                 }
899                 fingerprint = iimport(importpkg, imp)
900
901         default:
902                 base.Errorf("no import in %q", path_)
903                 base.ErrorExit()
904         }
905
906         // assume files move (get installed) so don't record the full path
907         if base.Flag.Cfg.PackageFile != nil {
908                 // If using a packageFile map, assume path_ can be recorded directly.
909                 base.Ctxt.AddImport(path_, fingerprint)
910         } else {
911                 // For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
912                 base.Ctxt.AddImport(file[len(file)-len(path_)-len(".a"):], fingerprint)
913         }
914
915         if importpkg.Height >= myheight {
916                 myheight = importpkg.Height + 1
917         }
918
919         return importpkg
920 }
921
922 func pkgnotused(lineno src.XPos, path string, name string) {
923         // If the package was imported with a name other than the final
924         // import path element, show it explicitly in the error message.
925         // Note that this handles both renamed imports and imports of
926         // packages containing unconventional package declarations.
927         // Note that this uses / always, even on Windows, because Go import
928         // paths always use forward slashes.
929         elem := path
930         if i := strings.LastIndex(elem, "/"); i >= 0 {
931                 elem = elem[i+1:]
932         }
933         if name == "" || elem == name {
934                 base.ErrorfAt(lineno, "imported and not used: %q", path)
935         } else {
936                 base.ErrorfAt(lineno, "imported and not used: %q as %s", path, name)
937         }
938 }
939
940 func mkpackage(pkgname string) {
941         if types.LocalPkg.Name == "" {
942                 if pkgname == "_" {
943                         base.Errorf("invalid package name _")
944                 }
945                 types.LocalPkg.Name = pkgname
946         } else {
947                 if pkgname != types.LocalPkg.Name {
948                         base.Errorf("package %s; expected %s", pkgname, types.LocalPkg.Name)
949                 }
950         }
951 }
952
953 func clearImports() {
954         type importedPkg struct {
955                 pos  src.XPos
956                 path string
957                 name string
958         }
959         var unused []importedPkg
960
961         for _, s := range types.LocalPkg.Syms {
962                 n := ir.AsNode(s.Def)
963                 if n == nil {
964                         continue
965                 }
966                 if n.Op() == ir.OPACK {
967                         // throw away top-level package name left over
968                         // from previous file.
969                         // leave s->block set to cause redeclaration
970                         // errors if a conflicting top-level name is
971                         // introduced by a different file.
972                         p := n.(*ir.PkgName)
973                         if !p.Used && base.SyntaxErrors() == 0 {
974                                 unused = append(unused, importedPkg{p.Pos(), p.Pkg.Path, s.Name})
975                         }
976                         s.Def = nil
977                         continue
978                 }
979                 if IsAlias(s) {
980                         // throw away top-level name left over
981                         // from previous import . "x"
982                         // We'll report errors after type checking in checkDotImports.
983                         s.Def = nil
984                         continue
985                 }
986         }
987
988         sort.Slice(unused, func(i, j int) bool { return unused[i].pos.Before(unused[j].pos) })
989         for _, pkg := range unused {
990                 pkgnotused(pkg.pos, pkg.path, pkg.name)
991         }
992 }
993
994 func IsAlias(sym *types.Sym) bool {
995         return sym.Def != nil && sym.Def.Sym() != sym
996 }
997
998 // recordFlags records the specified command-line flags to be placed
999 // in the DWARF info.
1000 func recordFlags(flags ...string) {
1001         if base.Ctxt.Pkgpath == "" {
1002                 // We can't record the flags if we don't know what the
1003                 // package name is.
1004                 return
1005         }
1006
1007         type BoolFlag interface {
1008                 IsBoolFlag() bool
1009         }
1010         type CountFlag interface {
1011                 IsCountFlag() bool
1012         }
1013         var cmd bytes.Buffer
1014         for _, name := range flags {
1015                 f := flag.Lookup(name)
1016                 if f == nil {
1017                         continue
1018                 }
1019                 getter := f.Value.(flag.Getter)
1020                 if getter.String() == f.DefValue {
1021                         // Flag has default value, so omit it.
1022                         continue
1023                 }
1024                 if bf, ok := f.Value.(BoolFlag); ok && bf.IsBoolFlag() {
1025                         val, ok := getter.Get().(bool)
1026                         if ok && val {
1027                                 fmt.Fprintf(&cmd, " -%s", f.Name)
1028                                 continue
1029                         }
1030                 }
1031                 if cf, ok := f.Value.(CountFlag); ok && cf.IsCountFlag() {
1032                         val, ok := getter.Get().(int)
1033                         if ok && val == 1 {
1034                                 fmt.Fprintf(&cmd, " -%s", f.Name)
1035                                 continue
1036                         }
1037                 }
1038                 fmt.Fprintf(&cmd, " -%s=%v", f.Name, getter.Get())
1039         }
1040
1041         if cmd.Len() == 0 {
1042                 return
1043         }
1044         s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "producer." + base.Ctxt.Pkgpath)
1045         s.Type = objabi.SDWARFCUINFO
1046         // Sometimes (for example when building tests) we can link
1047         // together two package main archives. So allow dups.
1048         s.Set(obj.AttrDuplicateOK, true)
1049         base.Ctxt.Data = append(base.Ctxt.Data, s)
1050         s.P = cmd.Bytes()[1:]
1051 }
1052
1053 // recordPackageName records the name of the package being
1054 // compiled, so that the linker can save it in the compile unit's DIE.
1055 func recordPackageName() {
1056         s := base.Ctxt.Lookup(dwarf.CUInfoPrefix + "packagename." + base.Ctxt.Pkgpath)
1057         s.Type = objabi.SDWARFCUINFO
1058         // Sometimes (for example when building tests) we can link
1059         // together two package main archives. So allow dups.
1060         s.Set(obj.AttrDuplicateOK, true)
1061         base.Ctxt.Data = append(base.Ctxt.Data, s)
1062         s.P = []byte(types.LocalPkg.Name)
1063 }
1064
1065 // currentLang returns the current language version.
1066 func currentLang() string {
1067         return fmt.Sprintf("go1.%d", goversion.Version)
1068 }
1069
1070 // goVersionRE is a regular expression that matches the valid
1071 // arguments to the -lang flag.
1072 var goVersionRE = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
1073
1074 // A lang is a language version broken into major and minor numbers.
1075 type lang struct {
1076         major, minor int
1077 }
1078
1079 // langWant is the desired language version set by the -lang flag.
1080 // If the -lang flag is not set, this is the zero value, meaning that
1081 // any language version is supported.
1082 var langWant lang
1083
1084 // langSupported reports whether language version major.minor is
1085 // supported in a particular package.
1086 func langSupported(major, minor int, pkg *types.Pkg) bool {
1087         if pkg == nil {
1088                 // TODO(mdempsky): Set Pkg for local types earlier.
1089                 pkg = types.LocalPkg
1090         }
1091         if pkg != types.LocalPkg {
1092                 // Assume imported packages passed type-checking.
1093                 return true
1094         }
1095
1096         if langWant.major == 0 && langWant.minor == 0 {
1097                 return true
1098         }
1099         return langWant.major > major || (langWant.major == major && langWant.minor >= minor)
1100 }
1101
1102 // checkLang verifies that the -lang flag holds a valid value, and
1103 // exits if not. It initializes data used by langSupported.
1104 func checkLang() {
1105         if base.Flag.Lang == "" {
1106                 return
1107         }
1108
1109         var err error
1110         langWant, err = parseLang(base.Flag.Lang)
1111         if err != nil {
1112                 log.Fatalf("invalid value %q for -lang: %v", base.Flag.Lang, err)
1113         }
1114
1115         if def := currentLang(); base.Flag.Lang != def {
1116                 defVers, err := parseLang(def)
1117                 if err != nil {
1118                         log.Fatalf("internal error parsing default lang %q: %v", def, err)
1119                 }
1120                 if langWant.major > defVers.major || (langWant.major == defVers.major && langWant.minor > defVers.minor) {
1121                         log.Fatalf("invalid value %q for -lang: max known version is %q", base.Flag.Lang, def)
1122                 }
1123         }
1124 }
1125
1126 // parseLang parses a -lang option into a langVer.
1127 func parseLang(s string) (lang, error) {
1128         matches := goVersionRE.FindStringSubmatch(s)
1129         if matches == nil {
1130                 return lang{}, fmt.Errorf(`should be something like "go1.12"`)
1131         }
1132         major, err := strconv.Atoi(matches[1])
1133         if err != nil {
1134                 return lang{}, err
1135         }
1136         minor, err := strconv.Atoi(matches[2])
1137         if err != nil {
1138                 return lang{}, err
1139         }
1140         return lang{major: major, minor: minor}, nil
1141 }
1142
1143 func initializeTypesPackage() {
1144         types.Widthptr = Widthptr
1145         types.Dowidth = dowidth
1146         types.TypeLinkSym = func(t *types.Type) *obj.LSym {
1147                 return typenamesym(t).Linksym()
1148         }
1149
1150         initUniverse()
1151 }