aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/main.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2020-12-23 00:52:53 -0500
committerRuss Cox <rsc@golang.org>2020-12-23 06:39:06 +0000
commitfbc82f03b104ba9bde67ad202e9cb00a13842dca (patch)
tree95caee1bcac4c02fc9feff7692ef46ec1c2ee64c /src/cmd/compile/internal/gc/main.go
parentde454eef5f47212dc8a9d9c2c8b598fa343d2c2b (diff)
downloadgo-fbc82f03b104ba9bde67ad202e9cb00a13842dca.tar.gz
go-fbc82f03b104ba9bde67ad202e9cb00a13842dca.zip
[dev.regabi] cmd/compile: split out package noder [generated]
[git-generate] cd src/cmd/compile/internal/gc rf ' mv ArhdrSize HeaderSize mv arsize ReadHeader mv formathdr FormatHeader mv HeaderSize ReadHeader FormatHeader archive.go mv archive.go cmd/internal/archive mv makePos main.go mv checkDotImports CheckDotImports mv parseFiles ParseFiles mv Pragma pragmas mv PragmaEmbed pragmaEmbed mv PragmaPos pragmaPos mv FuncPragmas funcPragmas mv TypePragmas typePragmas mv fakeRecv noder.funcLit renameinitgen renameinit oldname varEmbed noder.go mv isDriveLetter islocalname findpkg myheight importfile \ reservedimports isbadimport \ pkgnotused \ mkpackage clearImports \ CheckDotImports dotImports importDot \ importName \ import.go mv noder _noder mv import.go lex.go lex_test.go noder.go cmd/compile/internal/noder ' cd ../noder rf ' mv _noder noder ' Change-Id: Iac2b856f7b86143c666d818e4b7c5b261cf387d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/279473 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/gc/main.go')
-rw-r--r--src/cmd/compile/internal/gc/main.go380
1 files changed, 7 insertions, 373 deletions
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index cda00fb9ae..7b540d8675 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -14,26 +14,21 @@ import (
"cmd/compile/internal/inline"
"cmd/compile/internal/ir"
"cmd/compile/internal/logopt"
+ "cmd/compile/internal/noder"
"cmd/compile/internal/ssa"
"cmd/compile/internal/typecheck"
"cmd/compile/internal/types"
- "cmd/internal/bio"
"cmd/internal/dwarf"
- "cmd/internal/goobj"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
"flag"
"fmt"
- "go/constant"
- "io"
"io/ioutil"
"log"
"os"
- "path"
"runtime"
"sort"
- "strconv"
"strings"
)
@@ -212,7 +207,7 @@ func Main(archInit func(*Arch)) {
// Parse input.
base.Timer.Start("fe", "parse")
- lines := parseFiles(flag.Args())
+ lines := noder.ParseFiles(flag.Args())
cgoSymABIs()
base.Timer.Stop()
base.Timer.AddEvent(int64(lines), "lines")
@@ -222,7 +217,7 @@ func Main(archInit func(*Arch)) {
typecheck.Package()
// With all user code typechecked, it's now safe to verify unused dot imports.
- checkDotImports()
+ noder.CheckDotImports()
base.ExitIfErrors()
// Build init task.
@@ -468,371 +463,6 @@ func readSymABIs(file, myimportpath string) {
}
}
-func arsize(b *bufio.Reader, name string) int {
- var buf [ArhdrSize]byte
- if _, err := io.ReadFull(b, buf[:]); err != nil {
- return -1
- }
- aname := strings.Trim(string(buf[0:16]), " ")
- if !strings.HasPrefix(aname, name) {
- return -1
- }
- asize := strings.Trim(string(buf[48:58]), " ")
- i, _ := strconv.Atoi(asize)
- return i
-}
-
-func isDriveLetter(b byte) bool {
- return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
-}
-
-// is this path a local name? begins with ./ or ../ or /
-func islocalname(name string) bool {
- return strings.HasPrefix(name, "/") ||
- runtime.GOOS == "windows" && len(name) >= 3 && isDriveLetter(name[0]) && name[1] == ':' && name[2] == '/' ||
- strings.HasPrefix(name, "./") || name == "." ||
- strings.HasPrefix(name, "../") || name == ".."
-}
-
-func findpkg(name string) (file string, ok bool) {
- if islocalname(name) {
- if base.Flag.NoLocalImports {
- return "", false
- }
-
- if base.Flag.Cfg.PackageFile != nil {
- file, ok = base.Flag.Cfg.PackageFile[name]
- return file, ok
- }
-
- // try .a before .6. important for building libraries:
- // if there is an array.6 in the array.a library,
- // want to find all of array.a, not just array.6.
- file = fmt.Sprintf("%s.a", name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- file = fmt.Sprintf("%s.o", name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- return "", false
- }
-
- // local imports should be canonicalized already.
- // don't want to see "encoding/../encoding/base64"
- // as different from "encoding/base64".
- if q := path.Clean(name); q != name {
- base.Errorf("non-canonical import path %q (should be %q)", name, q)
- return "", false
- }
-
- if base.Flag.Cfg.PackageFile != nil {
- file, ok = base.Flag.Cfg.PackageFile[name]
- return file, ok
- }
-
- for _, dir := range base.Flag.Cfg.ImportDirs {
- file = fmt.Sprintf("%s/%s.a", dir, name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- file = fmt.Sprintf("%s/%s.o", dir, name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- }
-
- if objabi.GOROOT != "" {
- suffix := ""
- suffixsep := ""
- if base.Flag.InstallSuffix != "" {
- suffixsep = "_"
- suffix = base.Flag.InstallSuffix
- } else if base.Flag.Race {
- suffixsep = "_"
- suffix = "race"
- } else if base.Flag.MSan {
- suffixsep = "_"
- suffix = "msan"
- }
-
- file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.a", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- file = fmt.Sprintf("%s/pkg/%s_%s%s%s/%s.o", objabi.GOROOT, objabi.GOOS, objabi.GOARCH, suffixsep, suffix, name)
- if _, err := os.Stat(file); err == nil {
- return file, true
- }
- }
-
- return "", false
-}
-
-// myheight tracks the local package's height based on packages
-// imported so far.
-var myheight int
-
-func importfile(f constant.Value) *types.Pkg {
- if f.Kind() != constant.String {
- base.Errorf("import path must be a string")
- return nil
- }
-
- path_ := constant.StringVal(f)
- if len(path_) == 0 {
- base.Errorf("import path is empty")
- return nil
- }
-
- if isbadimport(path_, false) {
- return nil
- }
-
- // The package name main is no longer reserved,
- // but we reserve the import path "main" to identify
- // the main package, just as we reserve the import
- // path "math" to identify the standard math package.
- if path_ == "main" {
- base.Errorf("cannot import \"main\"")
- base.ErrorExit()
- }
-
- if base.Ctxt.Pkgpath != "" && path_ == base.Ctxt.Pkgpath {
- base.Errorf("import %q while compiling that package (import cycle)", path_)
- base.ErrorExit()
- }
-
- if mapped, ok := base.Flag.Cfg.ImportMap[path_]; ok {
- path_ = mapped
- }
-
- if path_ == "unsafe" {
- return ir.Pkgs.Unsafe
- }
-
- if islocalname(path_) {
- if path_[0] == '/' {
- base.Errorf("import path cannot be absolute path")
- return nil
- }
-
- prefix := base.Ctxt.Pathname
- if base.Flag.D != "" {
- prefix = base.Flag.D
- }
- path_ = path.Join(prefix, path_)
-
- if isbadimport(path_, true) {
- return nil
- }
- }
-
- file, found := findpkg(path_)
- if !found {
- base.Errorf("can't find import: %q", path_)
- base.ErrorExit()
- }
-
- importpkg := types.NewPkg(path_, "")
- if importpkg.Imported {
- return importpkg
- }
-
- importpkg.Imported = true
-
- imp, err := bio.Open(file)
- if err != nil {
- base.Errorf("can't open import: %q: %v", path_, err)
- base.ErrorExit()
- }
- defer imp.Close()
-
- // check object header
- p, err := imp.ReadString('\n')
- if err != nil {
- base.Errorf("import %s: reading input: %v", file, err)
- base.ErrorExit()
- }
-
- if p == "!<arch>\n" { // package archive
- // package export block should be first
- sz := arsize(imp.Reader, "__.PKGDEF")
- if sz <= 0 {
- base.Errorf("import %s: not a package file", file)
- base.ErrorExit()
- }
- p, err = imp.ReadString('\n')
- if err != nil {
- base.Errorf("import %s: reading input: %v", file, err)
- base.ErrorExit()
- }
- }
-
- if !strings.HasPrefix(p, "go object ") {
- base.Errorf("import %s: not a go object file: %s", file, p)
- base.ErrorExit()
- }
- q := fmt.Sprintf("%s %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version, objabi.Expstring())
- if p[10:] != q {
- base.Errorf("import %s: object is [%s] expected [%s]", file, p[10:], q)
- base.ErrorExit()
- }
-
- // process header lines
- for {
- p, err = imp.ReadString('\n')
- if err != nil {
- base.Errorf("import %s: reading input: %v", file, err)
- base.ErrorExit()
- }
- if p == "\n" {
- break // header ends with blank line
- }
- }
-
- // Expect $$B\n to signal binary import format.
-
- // look for $$
- var c byte
- for {
- c, err = imp.ReadByte()
- if err != nil {
- break
- }
- if c == '$' {
- c, err = imp.ReadByte()
- if c == '$' || err != nil {
- break
- }
- }
- }
-
- // get character after $$
- if err == nil {
- c, _ = imp.ReadByte()
- }
-
- var fingerprint goobj.FingerprintType
- switch c {
- case '\n':
- base.Errorf("cannot import %s: old export format no longer supported (recompile library)", path_)
- return nil
-
- case 'B':
- if base.Debug.Export != 0 {
- fmt.Printf("importing %s (%s)\n", path_, file)
- }
- imp.ReadByte() // skip \n after $$B
-
- c, err = imp.ReadByte()
- if err != nil {
- base.Errorf("import %s: reading input: %v", file, err)
- base.ErrorExit()
- }
-
- // Indexed format is distinguished by an 'i' byte,
- // whereas previous export formats started with 'c', 'd', or 'v'.
- if c != 'i' {
- base.Errorf("import %s: unexpected package format byte: %v", file, c)
- base.ErrorExit()
- }
- fingerprint = typecheck.ReadImports(importpkg, imp)
-
- default:
- base.Errorf("no import in %q", path_)
- base.ErrorExit()
- }
-
- // assume files move (get installed) so don't record the full path
- if base.Flag.Cfg.PackageFile != nil {
- // If using a packageFile map, assume path_ can be recorded directly.
- base.Ctxt.AddImport(path_, fingerprint)
- } else {
- // For file "/Users/foo/go/pkg/darwin_amd64/math.a" record "math.a".
- base.Ctxt.AddImport(file[len(file)-len(path_)-len(".a"):], fingerprint)
- }
-
- if importpkg.Height >= myheight {
- myheight = importpkg.Height + 1
- }
-
- return importpkg
-}
-
-func pkgnotused(lineno src.XPos, path string, name string) {
- // 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 := path
- if i := strings.LastIndex(elem, "/"); i >= 0 {
- elem = elem[i+1:]
- }
- if name == "" || elem == name {
- base.ErrorfAt(lineno, "imported and not used: %q", path)
- } else {
- base.ErrorfAt(lineno, "imported and not used: %q as %s", path, name)
- }
-}
-
-func mkpackage(pkgname string) {
- if types.LocalPkg.Name == "" {
- if pkgname == "_" {
- base.Errorf("invalid package name _")
- }
- types.LocalPkg.Name = pkgname
- } else {
- if pkgname != types.LocalPkg.Name {
- base.Errorf("package %s; expected %s", pkgname, types.LocalPkg.Name)
- }
- }
-}
-
-func clearImports() {
- type importedPkg struct {
- pos src.XPos
- path string
- name string
- }
- var unused []importedPkg
-
- for _, s := range types.LocalPkg.Syms {
- n := ir.AsNode(s.Def)
- if n == nil {
- continue
- }
- if n.Op() == ir.OPACK {
- // throw away top-level package name left over
- // from previous file.
- // leave s->block set to cause redeclaration
- // errors if a conflicting top-level name is
- // introduced by a different file.
- p := n.(*ir.PkgName)
- if !p.Used && base.SyntaxErrors() == 0 {
- unused = append(unused, importedPkg{p.Pos(), p.Pkg.Path, s.Name})
- }
- s.Def = nil
- continue
- }
- if types.IsDotAlias(s) {
- // throw away top-level name left over
- // from previous import . "x"
- // We'll report errors after type checking in checkDotImports.
- s.Def = nil
- continue
- }
- }
-
- sort.Slice(unused, func(i, j int) bool { return unused[i].pos.Before(unused[j].pos) })
- for _, pkg := range unused {
- pkgnotused(pkg.pos, pkg.path, pkg.name)
- }
-}
-
// recordFlags records the specified command-line flags to be placed
// in the DWARF info.
func recordFlags(flags ...string) {
@@ -922,3 +552,7 @@ func useABIWrapGen(f *ir.Func) bool {
return true
}
+
+func makePos(b *src.PosBase, line, col uint) src.XPos {
+ return base.Ctxt.PosTable.XPos(src.MakePos(b, line, col))
+}