mirror of https://github.com/golang/go.git
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/40939 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
2e45310caf
commit
f71f32e5e1
|
|
@ -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 {
|
||||||
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) {
|
||||||
// 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 (
|
||||||
"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() {
|
||||||
// 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 {
|
|
||||||
if *srcDir != "" {
|
|
||||||
input = filepath.Join(*srcDir, input)
|
|
||||||
}
|
|
||||||
f, err := os.Open(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))
|
fs := make([]*File, len(goFiles))
|
||||||
for i, input := range goFiles {
|
for i, input := range goFiles {
|
||||||
if *srcDir != "" {
|
if *srcDir != "" {
|
||||||
input = filepath.Join(*srcDir, input)
|
input = filepath.Join(*srcDir, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b, err := ioutil.ReadFile(input)
|
||||||
|
if err != nil {
|
||||||
|
fatalf("%s", err)
|
||||||
|
}
|
||||||
|
if _, err = h.Write(b); err != nil {
|
||||||
|
fatalf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue