From 4978065c9c42e78669848c5a749f4d230ffcc465 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 28 Apr 2019 14:11:48 +0200 Subject: [PATCH] cgo: avoid file/lineno hack for error locations --- loader/libclang.go | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/loader/libclang.go b/loader/libclang.go index 1d6a9ee8..469b0ebb 100644 --- a/loader/libclang.go +++ b/loader/libclang.go @@ -4,6 +4,7 @@ package loader // modification. It does not touch the AST itself. import ( + "fmt" "go/ast" "go/scanner" "go/token" @@ -68,9 +69,13 @@ func (info *fileInfo) parseFragment(fragment string, cflags []string, posFilenam index := C.clang_createIndex(0, 0) defer C.clang_disposeIndex(index) + // pretend to be a .c file filenameC := C.CString(posFilename + "!cgo.c") defer C.free(unsafe.Pointer(filenameC)) + // fix up error locations + fragment = fmt.Sprintf("# %d %#v\n", posLine+1, posFilename) + fragment + fragmentC := C.CString(fragment) 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)) severity := diagnosticSeverity[C.clang_getDiagnosticSeverity(diagnostic)] location := C.clang_getDiagnosticLocation(diagnostic) - var file C.CXFile + var libclangFilename C.CXString var line C.unsigned var column C.unsigned - var offset C.unsigned - C.clang_getExpansionLocation(location, &file, &line, &column, &offset) - filename := getString(C.clang_getFileName(file)) - 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) { + C.clang_getPresumedLocation(location, &libclangFilename, &line, &column) + filename := getString(libclangFilename) + if filepath.IsAbs(filename) { // Relative paths for readability, like other Go parser errors. relpath, err := filepath.Rel(info.Program.Dir, filename) if err == nil { @@ -132,7 +129,7 @@ func (info *fileInfo) parseFragment(fragment string, cflags []string, posFilenam errs = append(errs, &scanner.Error{ Pos: token.Position{ Filename: filename, - Offset: int(offset), + Offset: 0, // not provided by clang_getPresumedLocation Line: int(line), Column: int(column), },