Commit f71f32e5 authored by Alexander Menzhinsky's avatar Alexander Menzhinsky Committed by Ian Lance Taylor

cmd/cgo: read source files once

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/40939Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent 2e45310c
...@@ -17,8 +17,8 @@ import ( ...@@ -17,8 +17,8 @@ import (
"strings" "strings"
) )
func parse(name string, flags parser.Mode) *ast.File { func parse(name string, src []byte, flags parser.Mode) *ast.File {
ast1, err := parser.ParseFile(fset, name, nil, flags) ast1, err := parser.ParseFile(fset, name, src, flags)
if err != nil { if err != nil {
if list, ok := err.(scanner.ErrorList); ok { if list, ok := err.(scanner.ErrorList); ok {
// If err is a scanner.ErrorList, its String will print just // If err is a scanner.ErrorList, its String will print just
...@@ -39,12 +39,12 @@ func sourceLine(n ast.Node) int { ...@@ -39,12 +39,12 @@ func sourceLine(n ast.Node) int {
return fset.Position(n.Pos()).Line return fset.Position(n.Pos()).Line
} }
// ReadGo populates f with information learned from reading the // ParseGo populates f with information learned from the Go source code
// Go source file with the given file name. It gathers the C preamble // 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, // 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 // a list of exported functions, and the actual AST, to be rewritten and
// printed. // 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 // Create absolute path for file, so that it will be used in error
// messages and recorded in debug line number information. // messages and recorded in debug line number information.
// This matches the rest of the toolchain. See golang.org/issue/5122. // This matches the rest of the toolchain. See golang.org/issue/5122.
...@@ -58,8 +58,8 @@ func (f *File) ReadGo(name string) { ...@@ -58,8 +58,8 @@ func (f *File) ReadGo(name string) {
// so we use ast1 to look for the doc comments on import "C" // so we use ast1 to look for the doc comments on import "C"
// and on exported functions, and we use ast2 for translating // and on exported functions, and we use ast2 for translating
// and reprinting. // and reprinting.
ast1 := parse(name, parser.ParseComments) ast1 := parse(name, src, parser.ParseComments)
ast2 := parse(name, 0) ast2 := parse(name, src, 0)
f.Package = ast1.Name.Name f.Package = ast1.Name.Name
f.Name = make(map[string]*Name) f.Name = make(map[string]*Name)
......
...@@ -17,7 +17,7 @@ import ( ...@@ -17,7 +17,7 @@ import (
"go/ast" "go/ast"
"go/printer" "go/printer"
"go/token" "go/token"
"io" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
...@@ -265,30 +265,28 @@ func main() { ...@@ -265,30 +265,28 @@ func main() {
// concern is other cgo wrappers for the same functions. // concern is other cgo wrappers for the same functions.
// Use the beginning of the md5 of the input to disambiguate. // Use the beginning of the md5 of the input to disambiguate.
h := md5.New() h := md5.New()
for _, input := range goFiles { fs := make([]*File, len(goFiles))
for i, input := range goFiles {
if *srcDir != "" { if *srcDir != "" {
input = filepath.Join(*srcDir, input) input = filepath.Join(*srcDir, input)
} }
f, err := os.Open(input)
b, err := ioutil.ReadFile(input)
if err != nil { if err != nil {
fatalf("%s", err) fatalf("%s", err)
} }
io.Copy(h, f) if _, err = h.Write(b); err != nil {
f.Close() fatalf("%s", err)
}
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)
} }
f := new(File) f := new(File)
f.ReadGo(input) f.ParseGo(input, b)
f.DiscardCgoDirectives() f.DiscardCgoDirectives()
fs[i] = f fs[i] = f
} }
cPrefix = fmt.Sprintf("_%x", h.Sum(nil)[0:6])
if *objDir == "" { if *objDir == "" {
// make sure that _obj directory exists, so that we can write // make sure that _obj directory exists, so that we can write
// all the output files there. // all the output files there.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment