Commit af951994 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/cgo: split name rewriting out of rewriteRef

This is in preparation for later changes.

Change-Id: I2b9b77a782cf65a2fcec5e700ec6bb8b1476f6b5
Reviewed-on: https://go-review.googlesource.com/c/142882
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 19b264e7
...@@ -1166,6 +1166,60 @@ func (p *Package) rewriteRef(f *File) { ...@@ -1166,6 +1166,60 @@ func (p *Package) rewriteRef(f *File) {
if r.Name.IsConst() && r.Name.Const == "" { if r.Name.IsConst() && r.Name.Const == "" {
error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go)) error_(r.Pos(), "unable to find value of constant C.%s", fixGo(r.Name.Go))
} }
if r.Name.Kind == "func" {
switch r.Context {
case ctxCall, ctxCall2:
functions[r.Name.Go] = true
}
}
expr := p.rewriteName(f, r)
if *godefs {
// Substitute definition for mangled type name.
if id, ok := expr.(*ast.Ident); ok {
if t := typedef[id.Name]; t != nil {
expr = t.Go
}
if id.Name == r.Name.Mangle && r.Name.Const != "" {
expr = ast.NewIdent(r.Name.Const)
}
}
}
// Copy position information from old expr into new expr,
// in case expression being replaced is first on line.
// See golang.org/issue/6563.
pos := (*r.Expr).Pos()
if x, ok := expr.(*ast.Ident); ok {
expr = &ast.Ident{NamePos: pos, Name: x.Name}
}
// Change AST, because some later processing depends on it,
// and also because -godefs mode still prints the AST.
old := *r.Expr
*r.Expr = expr
// Record source-level edit for cgo output.
repl := gofmt(expr)
if r.Name.Kind != "type" {
repl = "(" + repl + ")"
}
f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
}
// Remove functions only used as expressions, so their respective
// bridge functions are not generated.
for name, used := range functions {
if !used {
delete(f.Name, name)
}
}
}
// rewriteName returns the expression used to rewrite a reference.
func (p *Package) rewriteName(f *File, r *Ref) ast.Expr {
var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default var expr ast.Expr = ast.NewIdent(r.Name.Mangle) // default
switch r.Context { switch r.Context {
case ctxCall, ctxCall2: case ctxCall, ctxCall2:
...@@ -1182,7 +1236,6 @@ func (p *Package) rewriteRef(f *File) { ...@@ -1182,7 +1236,6 @@ func (p *Package) rewriteRef(f *File) {
error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go)) error_(r.Pos(), "call of non-function C.%s", fixGo(r.Name.Go))
break break
} }
functions[r.Name.Go] = true
if r.Context == ctxCall2 { if r.Context == ctxCall2 {
if r.Name.Go == "_CMalloc" { if r.Name.Go == "_CMalloc" {
error_(r.Pos(), "no two-result form for C.malloc") error_(r.Pos(), "no two-result form for C.malloc")
...@@ -1263,47 +1316,7 @@ func (p *Package) rewriteRef(f *File) { ...@@ -1263,47 +1316,7 @@ func (p *Package) rewriteRef(f *File) {
error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go)) error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
} }
} }
return expr
if *godefs {
// Substitute definition for mangled type name.
if id, ok := expr.(*ast.Ident); ok {
if t := typedef[id.Name]; t != nil {
expr = t.Go
}
if id.Name == r.Name.Mangle && r.Name.Const != "" {
expr = ast.NewIdent(r.Name.Const)
}
}
}
// Copy position information from old expr into new expr,
// in case expression being replaced is first on line.
// See golang.org/issue/6563.
pos := (*r.Expr).Pos()
if x, ok := expr.(*ast.Ident); ok {
expr = &ast.Ident{NamePos: pos, Name: x.Name}
}
// Change AST, because some later processing depends on it,
// and also because -godefs mode still prints the AST.
old := *r.Expr
*r.Expr = expr
// Record source-level edit for cgo output.
repl := gofmt(expr)
if r.Name.Kind != "type" {
repl = "(" + repl + ")"
}
f.Edit.Replace(f.offset(old.Pos()), f.offset(old.End()), repl)
}
// Remove functions only used as expressions, so their respective
// bridge functions are not generated.
for name, used := range functions {
if !used {
delete(f.Name, name)
}
}
} }
// gccBaseCmd returns the start of the compiler command line. // gccBaseCmd returns the start of the compiler command line.
......
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