func (p *exporter) signature(sig *types.Signature) { // We need the receiver information (T vs *T) // for methods associated with named types. // We do not record interface receiver types in the // export data because 1) the importer can derive them // from the interface type and 2) they create cycles // in the type graph. if recv := sig.Recv(); recv != nil { if _, ok := recv.Type().Underlying().(*types.Interface); !ok { // 1-element tuple p.int(1) p.param(recv) } else { // 0-element tuple p.int(0) } } else { // 0-element tuple p.int(0) } p.tuple(sig.Params()) p.tuple(sig.Results()) if sig.Variadic() { p.int(1) } else { p.int(0) } }
func (d *DIBuilder) descriptorSignature(t *types.Signature, name string) llvm.Metadata { // If there's a receiver change the receiver to an // additional (first) parameter, and take the value of // the resulting signature instead. if recv := t.Recv(); recv != nil { params := t.Params() paramvars := make([]*types.Var, int(params.Len()+1)) paramvars[0] = recv for i := 0; i < int(params.Len()); i++ { paramvars[i+1] = params.At(i) } params = types.NewTuple(paramvars...) t := types.NewSignature(nil, nil, params, t.Results(), t.Variadic()) return d.typeDebugDescriptor(t, name) } if dt, ok := d.types.At(t).(llvm.Metadata); ok { return dt } var returnType llvm.Metadata results := t.Results() switch n := results.Len(); n { case 0: returnType = d.DIType(nil) // void case 1: returnType = d.DIType(results.At(0).Type()) default: fields := make([]*types.Var, results.Len()) for i := range fields { f := results.At(i) // Structs may not have multiple fields // with the same name, excepting "_". if f.Name() == "" { f = types.NewVar(f.Pos(), f.Pkg(), "_", f.Type()) } fields[i] = f } returnType = d.typeDebugDescriptor(types.NewStruct(fields, nil), "") } var paramTypes []llvm.Metadata params := t.Params() if params != nil && params.Len() > 0 { paramTypes = make([]llvm.Metadata, params.Len()+1) paramTypes[0] = returnType for i := range paramTypes[1:] { paramTypes[i+1] = d.DIType(params.At(i).Type()) } } else { paramTypes = []llvm.Metadata{returnType} } // TODO(axw) get position of type definition for File field return d.builder.CreateSubroutineType(llvm.DISubroutineType{ Parameters: paramTypes, }) }
// writeSignature writes to buf the signature sig in declaration syntax. func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature, params []*Parameter) { buf.WriteString("func ") if recv := sig.Recv(); recv != nil { buf.WriteString("(") if n := params[0].Name(); n != "" { buf.WriteString(n) buf.WriteString(" ") } types.WriteType(buf, from, params[0].Type()) buf.WriteString(") ") } buf.WriteString(name) types.WriteSignature(buf, from, sig) }
func (tm *llvmTypeMap) getSignatureInfo(sig *types.Signature) functionTypeInfo { var args, results []types.Type if sig.Recv() != nil { recvtype := sig.Recv().Type() if _, ok := recvtype.Underlying().(*types.Pointer); !ok && recvtype != types.Typ[types.UnsafePointer] { recvtype = types.NewPointer(recvtype) } args = []types.Type{recvtype} } for i := 0; i != sig.Params().Len(); i++ { args = append(args, sig.Params().At(i).Type()) } for i := 0; i != sig.Results().Len(); i++ { results = append(results, sig.Results().At(i).Type()) } return tm.getFunctionTypeInfo(args, results) }