// from the gc compiler's object files; no code will be available.
//
func (b *Builder) createPackageImpl(typkg *types.Package, importPath string, files []*ast.File) *Package {
- // TODO(gri): make this an invariant and eliminate importPath
- // param and Package field.
- // if importPath != p.Types.Path {
- // panic(importPath + " != " + p.Types.Path)
- // }
+ // The typechecker sets types.Package.Path only for GcImported
+ // packages, since it doesn't know import path until after typechecking is done.
+ // Here we ensure it is always set, since we know the correct path.
+ // TODO(adonovan): eliminate redundant ssa.Package.ImportPath field.
+ if typkg.Path == "" {
+ typkg.Path = importPath
+ }
p := &Package{
Prog: b.Prog,
}
}
}
+
optimizeBlocks(f)
// Build immediate-use (referrers) graph.
// FullName returns the full name of this function, qualified by
// package name, receiver type, etc.
//
+// The specific formatting rules are not guaranteed and may change.
+//
// Examples:
// "math.IsNaN" // a package-level function
+// "IsNaN" // intra-package reference to same
// "(*sync.WaitGroup).Add" // a declared method
// "(*exp/ssa.Ret).Block" // a bridge method
// "(ssa.Instruction).Block" // an interface method thunk
} else {
recvType = f.Params[0].Type() // interface method thunk
}
- // TODO(adonovan): print type package-qualified, if NamedType.
return fmt.Sprintf("(%s).%s", recvType, f.Name_)
}
- // "pkg." prefix for cross-package references only.
- var pkgQual string
- if from != f.Pkg {
- pkgQual = f.Pkg.ImportPath + "."
- }
-
// Declared method?
if recv != nil {
- star := ""
- if isPointer(recv.Type) {
- star = "*"
- }
- return fmt.Sprintf("(%s%s%s).%s", star, pkgQual, deref(recv.Type), f.Name_)
+ return fmt.Sprintf("(%s).%s", recv.Type, f.Name_)
}
// Package-level function.
- return pkgQual + f.Name_
+ // Prefix with package name for cross-package references only.
+ if from != f.Pkg {
+ return fmt.Sprintf("%s.%s", f.Pkg.ImportPath, f.Name_)
+ }
+ return f.Name_
}
// DumpTo prints to w a human readable "disassembly" of the SSA code of
func (f *Function) DumpTo(w io.Writer) {
fmt.Fprintf(w, "# Name: %s\n", f.FullName())
fmt.Fprintf(w, "# Declared at %s\n", f.Prog.Files.Position(f.Pos))
- fmt.Fprintf(w, "# Type: %s\n", f.Signature)
if f.Enclosing != nil {
fmt.Fprintf(w, "# Parent: %s\n", f.Enclosing.Name())
}
}
+ // Function Signature in declaration syntax; derived from types.Signature.String().
io.WriteString(w, "func ")
params := f.Params
if f.Signature.Recv != nil {
}
io.WriteString(w, v.Name())
io.WriteString(w, " ")
+ if f.Signature.IsVariadic && i == len(params)-1 {
+ io.WriteString(w, "...")
+ }
io.WriteString(w, v.Type().String())
}
- io.WriteString(w, "):\n")
+ io.WriteString(w, ")")
+ if res := f.Signature.Results; res != nil {
+ io.WriteString(w, " ")
+ var t types.Type
+ if len(res) == 1 && res[0].Name == "" {
+ t = res[0].Type
+ } else {
+ t = &types.Result{Values: res}
+ }
+ io.WriteString(w, t.String())
+ }
+ io.WriteString(w, ":\n")
for _, b := range f.Blocks {
if b == nil {