]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: read source files once
authorAlexander Menzhinsky <amenzhinsky@gmail.com>
Tue, 18 Apr 2017 03:06:46 +0000 (22:06 -0500)
committerIan Lance Taylor <iant@golang.org>
Tue, 18 Apr 2017 22:59:42 +0000 (22:59 +0000)
Now cgo reads source files twice: for c prefix generation and parsing
go code to an ast node. It can be narrowed down to single loop.

Change-Id: Ie05452a3a12106aaab863244727390037e69e8e6
Reviewed-on: https://go-review.googlesource.com/40939
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>

src/cmd/cgo/ast.go
src/cmd/cgo/main.go

index 8ce824196d9a6cfd2e20f3bc149a835559813649..7122a9dbbebae6f841b84248b9dc30cba8cfb00a 100644 (file)
@@ -17,8 +17,8 @@ import (
        "strings"
 )
 
-func parse(name string, flags parser.Mode) *ast.File {
-       ast1, err := parser.ParseFile(fset, name, nil, flags)
+func parse(name string, src []byte, flags parser.Mode) *ast.File {
+       ast1, err := parser.ParseFile(fset, name, src, flags)
        if err != nil {
                if list, ok := err.(scanner.ErrorList); ok {
                        // If err is a scanner.ErrorList, its String will print just
@@ -39,12 +39,12 @@ func sourceLine(n ast.Node) int {
        return fset.Position(n.Pos()).Line
 }
 
-// ReadGo populates f with information learned from reading the
-// Go source file with the given file name. It gathers the C preamble
+// ParseGo populates f with information learned from the Go source code
+// which was read from the named file. It gathers the C preamble
 // attached to the import "C" comment, a list of references to C.xxx,
 // a list of exported functions, and the actual AST, to be rewritten and
 // printed.
-func (f *File) ReadGo(name string) {
+func (f *File) ParseGo(name string, src []byte) {
        // Create absolute path for file, so that it will be used in error
        // messages and recorded in debug line number information.
        // This matches the rest of the toolchain. See golang.org/issue/5122.
@@ -58,8 +58,8 @@ func (f *File) ReadGo(name string) {
        // so we use ast1 to look for the doc comments on import "C"
        // and on exported functions, and we use ast2 for translating
        // and reprinting.
-       ast1 := parse(name, parser.ParseComments)
-       ast2 := parse(name, 0)
+       ast1 := parse(name, src, parser.ParseComments)
+       ast2 := parse(name, src, 0)
 
        f.Package = ast1.Name.Name
        f.Name = make(map[string]*Name)
index 505d25551d31e3f85452fe5ad1d7abda15c8f464..4a60ac5f6e0de95cd8403632610c52e4297ae9b4 100644 (file)
@@ -17,7 +17,7 @@ import (
        "go/ast"
        "go/printer"
        "go/token"
-       "io"
+       "io/ioutil"
        "os"
        "path/filepath"
        "reflect"
@@ -265,30 +265,28 @@ func main() {
        // concern is other cgo wrappers for the same functions.
        // Use the beginning of the md5 of the input to disambiguate.
        h := md5.New()
-       for _, input := range goFiles {
+       fs := make([]*File, len(goFiles))
+       for i, input := range goFiles {
                if *srcDir != "" {
                        input = filepath.Join(*srcDir, input)
                }
-               f, err := os.Open(input)
+
+               b, err := ioutil.ReadFile(input)
                if err != nil {
                        fatalf("%s", err)
                }
-               io.Copy(h, f)
-               f.Close()
-       }
-       cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
-
-       fs := make([]*File, len(goFiles))
-       for i, input := range goFiles {
-               if *srcDir != "" {
-                       input = filepath.Join(*srcDir, input)
+               if _, err = h.Write(b); err != nil {
+                       fatalf("%s", err)
                }
+
                f := new(File)
-               f.ReadGo(input)
+               f.ParseGo(input, b)
                f.DiscardCgoDirectives()
                fs[i] = f
        }
 
+       cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
+
        if *objDir == "" {
                // make sure that _obj directory exists, so that we can write
                // all the output files there.