Commit b88e532a authored by Hiroshi Ioka's avatar Hiroshi Ioka Committed by Ian Lance Taylor

cmd/cgo: use first error position instead of last one

Just like https://golang.org/cl/34783

Given cgo.go:
     1	package main
     2
     3	/*
     4	long double x = 0;
     5	*/
     6	import "C"
     7
     8	func main() {
     9		_ = C.x
    10		_ = C.x
    11	}

Before:
    ./cgo.go:10:6: unexpected: 16-byte float type - long double

After:
    ./cgo.go:9:6: unexpected: 16-byte float type - long double

The above test case is not portable. So it is tested on only amd64.

Change-Id: If0b84cf73d381a22e2ada71c8e9a6e6ec77ffd2e
Reviewed-on: https://go-review.googlesource.com/54950Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 5b43bbe6
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
/*
long double x = 0;
*/
import "C"
func main() {
_ = C.x // ERROR HERE
_ = C.x
}
...@@ -37,6 +37,9 @@ expect() { ...@@ -37,6 +37,9 @@ expect() {
check err1.go check err1.go
check err2.go check err2.go
check err3.go check err3.go
if [ $(go env GOARCH) == "amd64" ]; then # If we find a portable test case, we can remove this.
check err4.go
fi
check issue7757.go check issue7757.go
check issue8442.go check issue8442.go
check issue11097a.go check issue11097a.go
......
...@@ -63,6 +63,7 @@ func (f *File) ParseGo(name string, src []byte) { ...@@ -63,6 +63,7 @@ func (f *File) ParseGo(name string, src []byte) {
f.Package = ast1.Name.Name f.Package = ast1.Name.Name
f.Name = make(map[string]*Name) f.Name = make(map[string]*Name)
f.NamePos = make(map[*Name]token.Pos)
// In ast1, find the import "C" line and get any extra C preamble. // In ast1, find the import "C" line and get any extra C preamble.
sawC := false sawC := false
...@@ -212,6 +213,7 @@ func (f *File) saveRef(n *ast.Expr, context string) { ...@@ -212,6 +213,7 @@ func (f *File) saveRef(n *ast.Expr, context string) {
Go: goname, Go: goname,
} }
f.Name[goname] = name f.Name[goname] = name
f.NamePos[name] = sel.Pos()
} }
f.Ref = append(f.Ref, &Ref{ f.Ref = append(f.Ref, &Ref{
Name: name, Name: name,
......
...@@ -438,14 +438,7 @@ func (p *Package) guessKinds(f *File) []*Name { ...@@ -438,14 +438,7 @@ func (p *Package) guessKinds(f *File) []*Name {
for i, n := range names { for i, n := range names {
switch sniff[i] &^ notSignedIntConst { switch sniff[i] &^ notSignedIntConst {
default: default:
var tpos token.Pos error_(f.NamePos[n], "could not determine kind of name for C.%s", fixGo(n.Go))
for _, ref := range f.Ref {
if ref.Name == n {
tpos = ref.Pos()
break
}
}
error_(tpos, "could not determine kind of name for C.%s", fixGo(n.Go))
case notStrLiteral | notType: case notStrLiteral | notType:
if sniff[i]&notSignedIntConst != 0 { if sniff[i]&notSignedIntConst != 0 {
n.Kind = "uconst" n.Kind = "uconst"
...@@ -543,10 +536,6 @@ func (p *Package) loadDWARF(f *File, names []*Name) { ...@@ -543,10 +536,6 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
// Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i. // Scan DWARF info for top-level TagVariable entries with AttrName __cgo__i.
types := make([]dwarf.Type, len(names)) types := make([]dwarf.Type, len(names))
nameToRef := make(map[*Name]*Ref)
for _, ref := range f.Ref {
nameToRef[ref.Name] = ref
}
r := d.Reader() r := d.Reader()
for { for {
e, err := r.Next() e, err := r.Next()
...@@ -597,10 +586,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) { ...@@ -597,10 +586,7 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
if types[i] == nil { if types[i] == nil {
continue continue
} }
pos := token.NoPos pos := f.NamePos[n]
if ref, ok := nameToRef[n]; ok {
pos = ref.Pos()
}
f, fok := types[i].(*dwarf.FuncType) f, fok := types[i].(*dwarf.FuncType)
if n.Kind != "type" && fok { if n.Kind != "type" && fok {
n.Kind = "func" n.Kind = "func"
......
...@@ -54,6 +54,7 @@ type File struct { ...@@ -54,6 +54,7 @@ type File struct {
Calls []*Call // all calls to C.xxx in AST Calls []*Call // all calls to C.xxx in AST
ExpFunc []*ExpFunc // exported functions for this file ExpFunc []*ExpFunc // exported functions for this file
Name map[string]*Name // map from Go name to Name Name map[string]*Name // map from Go name to Name
NamePos map[*Name]token.Pos // map from Name to position of the first reference
} }
func nameKeys(m map[string]*Name) []string { func nameKeys(m map[string]*Name) []string {
......
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