diff --git a/src/go/internal/srcimporter/srcimporter.go b/src/go/internal/srcimporter/srcimporter.go index daef27c8b9dc86..2a6c274424d15b 100644 --- a/src/go/internal/srcimporter/srcimporter.go +++ b/src/go/internal/srcimporter/srcimporter.go @@ -14,11 +14,8 @@ import ( "go/token" "go/types" "io" - "io/ioutil" "os" - "os/exec" "path/filepath" - "strings" "sync" ) @@ -118,6 +115,7 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type var firstHardErr error conf := types.Config{ IgnoreFuncBodies: true, + FakeImportC: true, // continue type-checking after the first error Error: func(err error) { if firstHardErr == nil && !err.(types.Error).Soft { @@ -127,21 +125,6 @@ func (p *Importer) ImportFrom(path, srcDir string, mode types.ImportMode) (*type Importer: p, Sizes: p.sizes, } - if len(bp.CgoFiles) > 0 { - if p.ctxt.OpenFile != nil { - // cgo, gcc, pkg-config, etc. do not support - // build.Context's VFS. - conf.FakeImportC = true - } else { - conf.UsesCgo = true - file, err := p.cgo(bp) - if err != nil { - return nil, err - } - files = append(files, file) - } - } - pkg, err = conf.Check(bp.ImportPath, p.fset, files, nil) if err != nil { // If there was a hard error it is possibly unsafe @@ -198,47 +181,6 @@ func (p *Importer) parseFiles(dir string, filenames []string) ([]*ast.File, erro return files, nil } -func (p *Importer) cgo(bp *build.Package) (*ast.File, error) { - tmpdir, err := ioutil.TempDir("", "srcimporter") - if err != nil { - return nil, err - } - defer os.RemoveAll(tmpdir) - - args := []string{"go", "tool", "cgo", "-objdir", tmpdir} - if bp.Goroot { - switch bp.ImportPath { - case "runtime/cgo": - args = append(args, "-import_runtime_cgo=false", "-import_syscall=false") - case "runtime/race": - args = append(args, "-import_syscall=false") - } - } - args = append(args, "--") - args = append(args, strings.Fields(os.Getenv("CGO_CPPFLAGS"))...) - args = append(args, bp.CgoCPPFLAGS...) - if len(bp.CgoPkgConfig) > 0 { - cmd := exec.Command("pkg-config", append([]string{"--cflags"}, bp.CgoPkgConfig...)...) - out, err := cmd.CombinedOutput() - if err != nil { - return nil, err - } - args = append(args, strings.Fields(string(out))...) - } - args = append(args, "-I", tmpdir) - args = append(args, strings.Fields(os.Getenv("CGO_CFLAGS"))...) - args = append(args, bp.CgoCFLAGS...) - args = append(args, bp.CgoFiles...) - - cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = bp.Dir - if err := cmd.Run(); err != nil { - return nil, err - } - - return parser.ParseFile(p.fset, filepath.Join(tmpdir, "_cgo_gotypes.go"), nil, 0) -} - // context-controlled file system operations func (p *Importer) absPath(path string) (string, error) { diff --git a/src/go/internal/srcimporter/srcimporter_test.go b/src/go/internal/srcimporter/srcimporter_test.go index c456b8e26a7823..56549434d14d3e 100644 --- a/src/go/internal/srcimporter/srcimporter_test.go +++ b/src/go/internal/srcimporter/srcimporter_test.go @@ -232,14 +232,3 @@ func TestIssue23092(t *testing.T) { func TestIssue24392(t *testing.T) { testImportPath(t, "go/internal/srcimporter/testdata/issue24392") } - -func TestCgo(t *testing.T) { - testenv.MustHaveGoBuild(t) - testenv.MustHaveCGO(t) - - importer := New(&build.Default, token.NewFileSet(), make(map[string]*types.Package)) - _, err := importer.ImportFrom("./misc/cgo/test", runtime.GOROOT(), 0) - if err != nil { - t.Fatalf("Import failed: %v", err) - } -} diff --git a/src/go/types/api.go b/src/go/types/api.go index 7787b88906e358..2a21ad0c53f2e3 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -105,15 +105,6 @@ type Config struct { // Do not use casually! FakeImportC bool - // If UsesCgo is set, the type checker expects the - // _cgo_gotypes.go file generated by running cmd/cgo to be - // provided as a package source file. Qualified identifiers - // referring to package C will be resolved to cgo-provided - // declarations within _cgo_gotypes.go. - // - // It is an error to set both FakeImportC and UsesCgo. - UsesCgo bool - // If Error != nil, it is called with each error found // during type checking; err has dynamic type Error. // Secondary errors (for instance, to enumerate all types @@ -290,7 +281,7 @@ func (tv TypeAndValue) IsBuiltin() bool { // nil Value. func (tv TypeAndValue) IsValue() bool { switch tv.mode { - case constant_, variable, mapindex, value, commaok, commaerr: + case constant_, variable, mapindex, value, commaok: return true } return false diff --git a/src/go/types/assignments.go b/src/go/types/assignments.go index 34a9d7843d9438..efa0cbba50270a 100644 --- a/src/go/types/assignments.go +++ b/src/go/types/assignments.go @@ -22,7 +22,7 @@ func (check *Checker) assignment(x *operand, T Type, context string) { switch x.mode { case invalid: return // error reported before - case constant_, variable, mapindex, value, commaok, commaerr: + case constant_, variable, mapindex, value, commaok: // ok default: unreachable() diff --git a/src/go/types/call.go b/src/go/types/call.go index 1ef9a4057e82f1..689ef8744c446e 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -9,7 +9,6 @@ package types import ( "go/ast" "go/token" - "strings" ) func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { @@ -55,8 +54,6 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { default: // function/method call - cgocall := x.mode == cgofunc - sig, _ := x.typ.Underlying().(*Signature) if sig == nil { check.invalidOp(x.pos(), "cannot call non-function %s", x) @@ -77,11 +74,7 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind { case 0: x.mode = novalue case 1: - if cgocall { - x.mode = commaerr - } else { - x.mode = value - } + x.mode = value x.typ = sig.results.vars[0].typ // unpack tuple default: x.mode = value @@ -199,13 +192,10 @@ func unpack(get getter, n int, allowCommaOk bool) (getter, int, bool) { }, t.Len(), false } - if x0.mode == mapindex || x0.mode == commaok || x0.mode == commaerr { + if x0.mode == mapindex || x0.mode == commaok { // comma-ok value if allowCommaOk { a := [2]Type{x0.typ, Typ[UntypedBool]} - if x0.mode == commaerr { - a[1] = universeError - } return func(x *operand, i int) { x.mode = value x.expr = x0.expr @@ -312,17 +302,6 @@ func (check *Checker) argument(sig *Signature, i int, x *operand, ellipsis token check.assignment(x, typ, context) } -var cgoPrefixes = [...]string{ - "_Ciconst_", - "_Cfconst_", - "_Csconst_", - "_Ctype_", - "_Cvar_", // actually a pointer to the var - "_Cfpvar_fp_", - "_Cfunc_", - "_Cmacro_", // function to evaluate the expanded expression -} - func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { // these must be declared before the "goto Error" statements var ( @@ -343,43 +322,16 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { check.recordUse(ident, pname) pname.used = true pkg := pname.imported - - var exp Object - funcMode := value - if pkg.cgo { - // cgo special cases C.malloc: it's - // rewritten to _CMalloc and does not - // support two-result calls. - if sel == "malloc" { - sel = "_CMalloc" - } else { - funcMode = cgofunc - } - for _, prefix := range cgoPrefixes { - // cgo objects are part of the current package (in file - // _cgo_gotypes.go). Use regular lookup. - _, exp = check.scope.LookupParent(prefix+sel, check.pos) - if exp != nil { - break - } - } - if exp == nil { - check.errorf(e.Sel.Pos(), "%s not declared by package C", sel) - goto Error - } - check.objDecl(exp, nil) - } else { - exp = pkg.scope.Lookup(sel) - if exp == nil { - if !pkg.fake { - check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) - } - goto Error - } - if !exp.Exported() { - check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) - // ok to continue + exp := pkg.scope.Lookup(sel) + if exp == nil { + if !pkg.fake { + check.errorf(e.Sel.Pos(), "%s not declared by package %s", sel, pkg.name) } + goto Error + } + if !exp.Exported() { + check.errorf(e.Sel.Pos(), "%s not exported by package %s", sel, pkg.name) + // ok to continue } check.recordUse(e.Sel, exp) @@ -397,16 +349,9 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) { case *Var: x.mode = variable x.typ = exp.typ - if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") { - x.typ = x.typ.(*Pointer).base - } case *Func: - x.mode = funcMode + x.mode = value x.typ = exp.typ - if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") { - x.mode = value - x.typ = x.typ.(*Signature).results.vars[0].typ - } case *Builtin: x.mode = builtin x.typ = exp.typ diff --git a/src/go/types/check.go b/src/go/types/check.go index a94770ffef3ed6..71d49ad83d583d 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -7,7 +7,6 @@ package types import ( - "errors" "go/ast" "go/constant" "go/token" @@ -248,13 +247,7 @@ func (check *Checker) handleBailout(err *error) { // Files checks the provided files as part of the checker's package. func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) } -var errBadCgo = errors.New("cannot use FakeImportC and UsesCgo together") - func (check *Checker) checkFiles(files []*ast.File) (err error) { - if check.conf.FakeImportC && check.conf.UsesCgo { - return errBadCgo - } - defer check.handleBailout(&err) check.initFiles(files) @@ -355,7 +348,7 @@ func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) { if a[0] == nil || a[1] == nil { return } - assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError)) + assert(isTyped(a[0]) && isTyped(a[1]) && isBoolean(a[1])) if m := check.Types; m != nil { for { tv := m[x] diff --git a/src/go/types/operand.go b/src/go/types/operand.go index 80d11e2f215301..43b7385ad86dea 100644 --- a/src/go/types/operand.go +++ b/src/go/types/operand.go @@ -27,8 +27,6 @@ const ( mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment) value // operand is a computed value commaok // like value, but operand may be used in a comma,ok expression - commaerr // like commaok, but second value is error, not boolean - cgofunc // operand is a cgo function ) var operandModeString = [...]string{ @@ -41,8 +39,6 @@ var operandModeString = [...]string{ mapindex: "map index expression", value: "value", commaok: "comma, ok expression", - commaerr: "comma, error expression", - cgofunc: "cgo function", } // An operand represents an intermediate value during type checking. @@ -98,12 +94,6 @@ func (x *operand) pos() token.Pos { // commaok ( ) // commaok ( of type ) // -// commaerr ( ) -// commaerr ( of type ) -// -// cgofunc ( ) -// cgofunc ( of type ) -// func operandString(x *operand, qf Qualifier) string { var buf bytes.Buffer diff --git a/src/go/types/package.go b/src/go/types/package.go index 7b89def1b5d513..cd202a0ed9f789 100644 --- a/src/go/types/package.go +++ b/src/go/types/package.go @@ -17,7 +17,6 @@ type Package struct { complete bool imports []*Package fake bool // scope lookup errors are silently dropped if package is fake (internal use only) - cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go } // NewPackage returns a new Package for the given package path and name. diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index f80b4ec7841f17..839d076e361447 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -141,10 +141,9 @@ func (check *Checker) importPackage(pos token.Pos, path, dir string) *Package { } // no package yet => import it - if path == "C" && (check.conf.FakeImportC || check.conf.UsesCgo) { + if path == "C" && check.conf.FakeImportC { imp = NewPackage("C", "C") - imp.fake = true // package scope is not populated - imp.cgo = check.conf.UsesCgo + imp.fake = true } else { // ordinary import var err error diff --git a/src/go/types/universe.go b/src/go/types/universe.go index ff5b89118ad9ef..7af6dab320edd1 100644 --- a/src/go/types/universe.go +++ b/src/go/types/universe.go @@ -21,10 +21,9 @@ var Universe *Scope var Unsafe *Package var ( - universeIota *Const - universeByte *Basic // uint8 alias, but has name "byte" - universeRune *Basic // int32 alias, but has name "rune" - universeError *Named + universeIota *Const + universeByte *Basic // uint8 alias, but has name "byte" + universeRune *Basic // int32 alias, but has name "rune" ) // Typ contains the predeclared *Basic types indexed by their @@ -201,7 +200,6 @@ func init() { universeIota = Universe.Lookup("iota").(*Const) universeByte = Universe.Lookup("byte").(*TypeName).typ.(*Basic) universeRune = Universe.Lookup("rune").(*TypeName).typ.(*Basic) - universeError = Universe.Lookup("error").(*TypeName).typ.(*Named) } // Objects with names containing blanks are internal and not entered into