cgo: avoid file/lineno hack for error locations

Этот коммит содержится в:
Ayke van Laethem 2019-04-28 14:11:48 +02:00 коммит произвёл Ron Evans
родитель 78a26fec13
коммит 4978065c9c

Просмотреть файл

@ -4,6 +4,7 @@ package loader
// modification. It does not touch the AST itself. // modification. It does not touch the AST itself.
import ( import (
"fmt"
"go/ast" "go/ast"
"go/scanner" "go/scanner"
"go/token" "go/token"
@ -68,9 +69,13 @@ func (info *fileInfo) parseFragment(fragment string, cflags []string, posFilenam
index := C.clang_createIndex(0, 0) index := C.clang_createIndex(0, 0)
defer C.clang_disposeIndex(index) defer C.clang_disposeIndex(index)
// pretend to be a .c file
filenameC := C.CString(posFilename + "!cgo.c") filenameC := C.CString(posFilename + "!cgo.c")
defer C.free(unsafe.Pointer(filenameC)) defer C.free(unsafe.Pointer(filenameC))
// fix up error locations
fragment = fmt.Sprintf("# %d %#v\n", posLine+1, posFilename) + fragment
fragmentC := C.CString(fragment) fragmentC := C.CString(fragment)
defer C.free(unsafe.Pointer(fragmentC)) defer C.free(unsafe.Pointer(fragmentC))
@ -109,20 +114,12 @@ func (info *fileInfo) parseFragment(fragment string, cflags []string, posFilenam
spelling := getString(C.clang_getDiagnosticSpelling(diagnostic)) spelling := getString(C.clang_getDiagnosticSpelling(diagnostic))
severity := diagnosticSeverity[C.clang_getDiagnosticSeverity(diagnostic)] severity := diagnosticSeverity[C.clang_getDiagnosticSeverity(diagnostic)]
location := C.clang_getDiagnosticLocation(diagnostic) location := C.clang_getDiagnosticLocation(diagnostic)
var file C.CXFile var libclangFilename C.CXString
var line C.unsigned var line C.unsigned
var column C.unsigned var column C.unsigned
var offset C.unsigned C.clang_getPresumedLocation(location, &libclangFilename, &line, &column)
C.clang_getExpansionLocation(location, &file, &line, &column, &offset) filename := getString(libclangFilename)
filename := getString(C.clang_getFileName(file)) if filepath.IsAbs(filename) {
if filename == posFilename+"!cgo.c" {
// Adjust errors from the `import "C"` snippet.
// Note: doesn't adjust filenames inside the error message
// itself.
filename = posFilename
line += C.uint(posLine)
offset = 0 // hard to calculate
} else if filepath.IsAbs(filename) {
// Relative paths for readability, like other Go parser errors. // Relative paths for readability, like other Go parser errors.
relpath, err := filepath.Rel(info.Program.Dir, filename) relpath, err := filepath.Rel(info.Program.Dir, filename)
if err == nil { if err == nil {
@ -132,7 +129,7 @@ func (info *fileInfo) parseFragment(fragment string, cflags []string, posFilenam
errs = append(errs, &scanner.Error{ errs = append(errs, &scanner.Error{
Pos: token.Position{ Pos: token.Position{
Filename: filename, Filename: filename,
Offset: int(offset), Offset: 0, // not provided by clang_getPresumedLocation
Line: int(line), Line: int(line),
Column: int(column), Column: int(column),
}, },