// Write _cgoCheckPointer calls to sbCheck.
var sbCheck bytes.Buffer
for i, param := range params {
+ origArg := args[i]
arg, nu := p.mangle(f, &args[i])
if nu {
needsUnsafe = true
}
if !p.needsPointerCheck(f, param.Go, args[i]) {
- fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtLine(arg))
+ fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
continue
}
continue
}
- fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtLine(arg))
+ fmt.Fprintf(&sb, "_cgo%d := %s; ", i, gofmtPos(arg, origArg.Pos()))
fmt.Fprintf(&sbCheck, "_cgoCheckPointer(_cgo%d); ", i)
}
return false
}
- fmt.Fprintf(sb, "_cgoIndex%d := %s; ", i, gofmtLine(index.X))
+ fmt.Fprintf(sb, "_cgoIndex%d := %s; ", i, gofmtPos(index.X, index.X.Pos()))
origX := index.X
index.X = ast.NewIdent(fmt.Sprintf("_cgoIndex%d", i))
- fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtLine(arg))
+ fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
index.X = origX
fmt.Fprintf(sbCheck, "_cgoCheckPointer(_cgo%d, _cgoIndex%d); ", i, i)
return false
}
- fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtLine(*px))
+ fmt.Fprintf(sb, "_cgoBase%d := %s; ", i, gofmtPos(*px, (*px).Pos()))
origX := *px
*px = ast.NewIdent(fmt.Sprintf("_cgoBase%d", i))
- fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtLine(arg))
+ fmt.Fprintf(sb, "_cgo%d := %s; ", i, gofmtPos(arg, arg.Pos()))
*px = origX
// Use "0 == 0" to do the right thing in the unlikely event
// Record source-level edit for cgo output.
if !r.Done {
- repl := gofmt(expr)
+ repl := gofmtPos(expr, old.Pos())
+ end := fset.Position(old.End())
+ // Subtract 1 from the column if we are going to
+ // append a close parenthesis. That will set the
+ // correct column for the following characters.
+ sub := 0
+ if r.Name.Kind != "type" {
+ sub = 1
+ }
+ if end.Column > sub {
+ repl = fmt.Sprintf("%s/*line :%d:%d*/", repl, end.Line, end.Column-sub)
+ }
if r.Name.Kind != "type" {
repl = "(" + repl + ")"
}
return expr
}
+// gofmtPos returns the gofmt-formatted string for an AST node,
+// with a comment setting the position before the node.
+func gofmtPos(n ast.Expr, pos token.Pos) string {
+ s := gofmtLine(n)
+ p := fset.Position(pos)
+ if p.Column == 0 {
+ return s
+ }
+ return fmt.Sprintf("/*line :%d:%d*/%s", p.Line, p.Column, s)
+}
+
// gccBaseCmd returns the start of the compiler command line.
// It uses $CC if set, or else $GCC, or else the compiler recorded
// during the initial build as defaultCC.