本文整理汇总了Golang中code/google/com/p/go/tools/go/ssa.Value.Type方法的典型用法代码示例。如果您正苦于以下问题:Golang Value.Type方法的具体用法?Golang Value.Type怎么用?Golang Value.Type使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类code/google/com/p/go/tools/go/ssa.Value
的用法示例。
在下文中一共展示了Value.Type方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: valueOffsetNode
// valueOffsetNode ascertains the node for tuple/struct value v,
// then returns the node for its subfield #index.
//
func (a *analysis) valueOffsetNode(v ssa.Value, index int) nodeid {
id := a.valueNode(v)
if id == 0 {
panic(fmt.Sprintf("cannot offset within n0: %s = %s", v.Name(), v))
}
return id + nodeid(a.offsetOf(v.Type(), index))
}
示例2: DeclareTempVar
func (l langType) DeclareTempVar(v ssa.Value) string {
typ := l.LangType(v.Type().Underlying(), false, "temp var declaration")
if typ == "" {
return ""
}
return "var _" + v.Name() + ":" + typ + ";"
}
示例3: AddIndirectQuery
// AddQuery adds v to Config.IndirectQueries.
// Precondition: CanPoint(v.Type().Underlying().(*types.Pointer).Elem()).
func (c *Config) AddIndirectQuery(v ssa.Value) {
if c.IndirectQueries == nil {
c.IndirectQueries = make(map[ssa.Value]struct{})
}
if !CanPoint(mustDeref(v.Type())) {
panic(fmt.Sprintf("%s is not the address of a pointer-like value: %s", v, v.Type()))
}
c.IndirectQueries[v] = struct{}{}
}
示例4: AddQuery
// AddQuery adds v to Config.Queries.
// Precondition: CanPoint(v.Type()).
// TODO(adonovan): consider returning a new Pointer for this query,
// which will be initialized during analysis. That avoids the needs
// for the corresponding ssa.Value-keyed maps in Config and Result.
func (c *Config) AddQuery(v ssa.Value) {
if !CanPoint(v.Type()) {
panic(fmt.Sprintf("%s is not a pointer-like value: %s", v, v.Type()))
}
if c.Queries == nil {
c.Queries = make(map[ssa.Value]struct{})
}
c.Queries[v] = struct{}{}
}
示例5: genOffsetAddr
// genOffsetAddr generates constraints for a 'v=ptr.field' (FieldAddr)
// or 'v=ptr[*]' (IndexAddr) instruction v.
func (a *analysis) genOffsetAddr(cgn *cgnode, v ssa.Value, ptr nodeid, offset uint32) {
dst := a.valueNode(v)
if obj := a.objectNode(cgn, v); obj != 0 {
// Pre-apply offsetAddrConstraint.solve().
a.addressOf(v.Type(), dst, obj)
} else {
a.offsetAddr(v.Type(), dst, ptr, offset)
}
}
示例6: declare
// declare creates an llvm.dbg.declare call for the specified function
// parameter or local variable.
func (d *debugInfo) declare(b llvm.Builder, v ssa.Value, llv llvm.Value, paramIndex int) {
tag := tagAutoVariable
if paramIndex >= 0 {
tag = tagArgVariable
}
ld := debug.NewLocalVariableDescriptor(tag)
ld.Argument = uint32(paramIndex + 1)
ld.Name = llv.Name()
if file := d.Fset.File(v.Pos()); file != nil {
ld.Line = uint32(file.Position(v.Pos()).Line)
ld.File = &d.getCompileUnit(file).Path
}
ld.Type = d.TypeDebugDescriptor(deref(v.Type()))
ld.Context = d.context()
b.InsertDeclare(d.module, llvm.MDNode([]llvm.Value{llv}), d.MDNode(ld))
}
示例7: valueNode
// valueNode returns the id of the value node for v, creating it (and
// the association) as needed. It may return zero for uninteresting
// values containing no pointers.
//
func (a *analysis) valueNode(v ssa.Value) nodeid {
// Value nodes for locals are created en masse by genFunc.
if id, ok := a.localval[v]; ok {
return id
}
// Value nodes for globals are created on demand.
id, ok := a.globalval[v]
if !ok {
var comment string
if a.log != nil {
comment = v.String()
}
id = a.addNodes(v.Type(), comment)
if obj := a.objectNode(nil, v); obj != 0 {
a.addressOf(v.Type(), id, obj)
}
a.setValueNode(v, id, nil)
}
return id
}
示例8: runPTA
// runPTA runs the pointer analysis of the selected SSA value or address.
func runPTA(o *Oracle, v ssa.Value, isAddr bool) (ptrs []pointerResult, err error) {
buildSSA(o)
if isAddr {
o.ptaConfig.AddIndirectQuery(v)
} else {
o.ptaConfig.AddQuery(v)
}
ptares := ptrAnalysis(o)
var ptr pointer.Pointer
if isAddr {
ptr = ptares.IndirectQueries[v]
} else {
ptr = ptares.Queries[v]
}
if ptr == (pointer.Pointer{}) {
return nil, fmt.Errorf("pointer analysis did not find expression (dead code?)")
}
pts := ptr.PointsTo()
if pointer.CanHaveDynamicTypes(v.Type()) {
// Show concrete types for interface/reflect.Value expression.
if concs := pts.DynamicTypes(); concs.Len() > 0 {
concs.Iterate(func(conc types.Type, pta interface{}) {
labels := pta.(pointer.PointsToSet).Labels()
sort.Sort(byPosAndString(labels)) // to ensure determinism
ptrs = append(ptrs, pointerResult{conc, labels})
})
}
} else {
// Show labels for other expressions.
labels := pts.Labels()
sort.Sort(byPosAndString(labels)) // to ensure determinism
ptrs = append(ptrs, pointerResult{v.Type(), labels})
}
sort.Sort(byTypeString(ptrs)) // to ensure determinism
return ptrs, nil
}
示例9: setValueNode
// setValueNode associates node id with the value v.
// cgn identifies the context iff v is a local variable.
//
func (a *analysis) setValueNode(v ssa.Value, id nodeid, cgn *cgnode) {
if cgn != nil {
a.localval[v] = id
} else {
a.globalval[v] = id
}
if a.log != nil {
fmt.Fprintf(a.log, "\tval[%s] = n%d (%T)\n", v.Name(), id, v)
}
// Due to context-sensitivity, we may encounter the same Value
// in many contexts. We merge them to a canonical node, since
// that's what all clients want.
// Record the (v, id) relation if the client has queried pts(v).
if _, ok := a.config.Queries[v]; ok {
t := v.Type()
ptr, ok := a.result.Queries[v]
if !ok {
// First time? Create the canonical query node.
ptr = Pointer{a, a.addNodes(t, "query")}
a.result.Queries[v] = ptr
}
a.result.Queries[v] = ptr
a.copy(ptr.n, id, a.sizeof(t))
}
// Record the (*v, id) relation if the client has queried pts(*v).
if _, ok := a.config.IndirectQueries[v]; ok {
t := v.Type()
ptr, ok := a.result.IndirectQueries[v]
if !ok {
// First time? Create the canonical indirect query node.
ptr = Pointer{a, a.addNodes(v.Type(), "query.indirect")}
a.result.IndirectQueries[v] = ptr
}
a.genLoad(cgn, ptr.n, v, 0, a.sizeof(t))
}
}
示例10: getErrorInfo
func (ctxt *context) getErrorInfo(v ssa.Value, member int, enclosingPos token.Pos, seen map[ssa.Value]bool) (result *errorInfo) {
if !enclosingPos.IsValid() {
panicf("getErrorInfo with invalid pos; %T %s", v, v)
}
// log.Printf("getErrorInfo[%d] %T %v {", member, v, v)
// defer func() {
// log.Printf("} -> %+v", result)
// }()
if seen[v] {
return &errorInfo{}
}
seen[v] = true
defer delete(seen, v)
if pos := v.Pos(); pos.IsValid() {
enclosingPos = pos
}
terminate := func() []errorTermination {
return []errorTermination{{
val: v,
pos: enclosingPos,
}}
}
switch v := v.(type) {
case *ssa.Call:
if member > 0 && member != v.Type().(*types.Tuple).Len()-1 {
log.Printf("error from non-final member of function")
return &errorInfo{unknown: terminate()}
}
return &errorInfo{nested: []*ssa.Call{v}}
case *ssa.ChangeInterface:
return ctxt.getErrorInfo(v.X, 0, enclosingPos, seen)
case *ssa.Extract:
return ctxt.getErrorInfo(v.Tuple, v.Index, enclosingPos, seen)
case *ssa.Field:
return &errorInfo{unknown: terminate()}
case *ssa.Index:
return &errorInfo{unknown: terminate()}
case *ssa.Lookup:
return &errorInfo{unknown: terminate()}
case *ssa.Const:
if v.Value != nil {
panicf("non-nil constant cannot make error, surely?")
}
return &errorInfo{}
case *ssa.MakeInterface:
// TODO look into components of v.X
return &errorInfo{nonNil: terminate()}
case *ssa.Next:
return &errorInfo{unknown: terminate()}
case *ssa.Parameter:
return &errorInfo{unknown: terminate()}
case *ssa.Phi:
var info errorInfo
for _, edge := range v.Edges {
info.add(ctxt.getErrorInfo(edge, member, enclosingPos, seen))
}
return &info
case *ssa.Select:
return &errorInfo{unknown: terminate()}
case *ssa.TypeAssert:
if v.CommaOk {
return &errorInfo{unknown: terminate()}
}
return ctxt.getErrorInfo(v.X, 0, enclosingPos, seen)
case *ssa.UnOp:
switch v.Op {
case token.ARROW:
return &errorInfo{unknown: terminate()}
case token.MUL:
if _, isGlobal := v.X.(*ssa.Global); isGlobal {
// Assume that if we're returning a global variable, it's a
// global non-nil error, such as os.ErrInvalid.
return &errorInfo{nonNil: terminate()}
}
return &errorInfo{unknown: terminate()}
default:
panicf("unexpected unary operator %s at %s", v, ctxt.lprog.Fset.Position(enclosingPos))
}
}
panicf("unexpected value found for error: %T; %v", v, v)
panic("not reached")
}
示例11: value
func (fr *frame) value(v ssa.Value) (result *LLVMValue) {
switch v := v.(type) {
case nil:
return nil
case *ssa.Function:
result, ok := fr.funcvals[v]
if ok {
return result
}
// fr.globals[v] has the function in raw pointer form;
// we must convert it to <f,ctx> form. If the function
// does not have a receiver, then create a wrapper
// function that has an additional "context" parameter.
f := fr.resolveFunction(v)
if v.Signature.Recv() == nil && len(v.FreeVars) == 0 {
f = contextFunction(fr.compiler, f)
}
pair := llvm.ConstNull(fr.llvmtypes.ToLLVM(f.Type()))
fnptr := llvm.ConstBitCast(f.LLVMValue(), pair.Type().StructElementTypes()[0])
pair = llvm.ConstInsertValue(pair, fnptr, []uint32{0})
result = fr.NewValue(pair, f.Type())
fr.funcvals[v] = result
return result
case *ssa.Const:
return fr.NewConstValue(v.Value, v.Type())
case *ssa.Global:
if g, ok := fr.globals[v]; ok {
return g
}
// Create an external global. Globals for this package are defined
// on entry to translatePackage, and have initialisers.
llelemtyp := fr.llvmtypes.ToLLVM(deref(v.Type()))
llglobal := llvm.AddGlobal(fr.module.Module, llelemtyp, v.String())
global := fr.NewValue(llglobal, v.Type())
fr.globals[v] = global
return global
}
if value, ok := fr.env[v]; ok {
return value
}
// Instructions are not necessarily visited before they are used (e.g. Phi
// edges) so we must "backpatch": create a value with the resultant type,
// and then replace it when we visit the instruction.
if b, ok := fr.backpatch[v]; ok {
return b
}
if fr.backpatch == nil {
fr.backpatch = make(map[ssa.Value]*LLVMValue)
}
// Note: we must not create a constant here (e.g. Undef/ConstNull), as
// it is not permissible to replace a constant with a non-constant.
// We must create the value in its own standalone basic block, so we can
// dispose of it after replacing.
currBlock := fr.builder.GetInsertBlock()
fr.builder.SetInsertPointAtEnd(llvm.AddBasicBlock(currBlock.Parent(), ""))
placeholder := fr.compiler.builder.CreatePHI(fr.llvmtypes.ToLLVM(v.Type()), "")
fr.builder.SetInsertPointAtEnd(currBlock)
value := fr.NewValue(placeholder, v.Type())
fr.backpatch[v] = value
return value
}
示例12: objectNode
// objectNode returns the object to which v points, if known.
// In other words, if the points-to set of v is a singleton, it
// returns the sole label, zero otherwise.
//
// We exploit this information to make the generated constraints less
// dynamic. For example, a complex load constraint can be replaced by
// a simple copy constraint when the sole destination is known a priori.
//
// Some SSA instructions always have singletons points-to sets:
// Alloc, Function, Global, MakeChan, MakeClosure, MakeInterface, MakeMap, MakeSlice.
// Others may be singletons depending on their operands:
// FreeVar, Const, Convert, FieldAddr, IndexAddr, Slice.
//
// Idempotent. Objects are created as needed, possibly via recursion
// down the SSA value graph, e.g IndexAddr(FieldAddr(Alloc))).
//
func (a *analysis) objectNode(cgn *cgnode, v ssa.Value) nodeid {
switch v.(type) {
case *ssa.Global, *ssa.Function, *ssa.Const, *ssa.FreeVar:
// Global object.
obj, ok := a.globalobj[v]
if !ok {
switch v := v.(type) {
case *ssa.Global:
obj = a.nextNode()
a.addNodes(mustDeref(v.Type()), "global")
a.endObject(obj, nil, v)
case *ssa.Function:
obj = a.makeFunctionObject(v, nil)
case *ssa.Const:
// not addressable
case *ssa.FreeVar:
// not addressable
}
if a.log != nil {
fmt.Fprintf(a.log, "\tglobalobj[%s] = n%d\n", v, obj)
}
a.globalobj[v] = obj
}
return obj
}
// Local object.
obj, ok := a.localobj[v]
if !ok {
switch v := v.(type) {
case *ssa.Alloc:
obj = a.nextNode()
a.addNodes(mustDeref(v.Type()), "alloc")
a.endObject(obj, cgn, v)
case *ssa.MakeSlice:
obj = a.nextNode()
a.addNodes(sliceToArray(v.Type()), "makeslice")
a.endObject(obj, cgn, v)
case *ssa.MakeChan:
obj = a.nextNode()
a.addNodes(v.Type().Underlying().(*types.Chan).Elem(), "makechan")
a.endObject(obj, cgn, v)
case *ssa.MakeMap:
obj = a.nextNode()
tmap := v.Type().Underlying().(*types.Map)
a.addNodes(tmap.Key(), "makemap.key")
elem := a.addNodes(tmap.Elem(), "makemap.value")
// To update the value field, MapUpdate
// generates store-with-offset constraints which
// the presolver can't model, so we must mark
// those nodes indirect.
for id, end := elem, elem+nodeid(a.sizeof(tmap.Elem())); id < end; id++ {
a.mapValues = append(a.mapValues, id)
}
a.endObject(obj, cgn, v)
case *ssa.MakeInterface:
tConc := v.X.Type()
obj = a.makeTagged(tConc, cgn, v)
// Copy the value into it, if nontrivial.
if x := a.valueNode(v.X); x != 0 {
a.copy(obj+1, x, a.sizeof(tConc))
}
case *ssa.FieldAddr:
if xobj := a.objectNode(cgn, v.X); xobj != 0 {
obj = xobj + nodeid(a.offsetOf(mustDeref(v.X.Type()), v.Field))
}
case *ssa.IndexAddr:
if xobj := a.objectNode(cgn, v.X); xobj != 0 {
obj = xobj + 1
}
case *ssa.Slice:
//.........这里部分代码省略.........
示例13: objectNode
// objectNode returns the object to which v points, if known.
// In other words, if the points-to set of v is a singleton, it
// returns the sole label, zero otherwise.
//
// We exploit this information to make the generated constraints less
// dynamic. For example, a complex load constraint can be replaced by
// a simple copy constraint when the sole destination is known a priori.
//
// Some SSA instructions always have singletons points-to sets:
// Alloc, Function, Global, MakeChan, MakeClosure, MakeInterface, MakeMap, MakeSlice.
// Others may be singletons depending on their operands:
// Capture, Const, Convert, FieldAddr, IndexAddr, Slice.
//
// Idempotent. Objects are created as needed, possibly via recursion
// down the SSA value graph, e.g IndexAddr(FieldAddr(Alloc))).
//
func (a *analysis) objectNode(cgn *cgnode, v ssa.Value) nodeid {
if cgn == nil {
// Global object.
obj, ok := a.globalobj[v]
if !ok {
switch v := v.(type) {
case *ssa.Global:
obj = a.nextNode()
a.addNodes(mustDeref(v.Type()), "global")
a.endObject(obj, nil, v)
case *ssa.Function:
obj = a.makeFunctionObject(v, nil)
case *ssa.Const:
// The only pointer-like Consts are nil.
case *ssa.Capture:
// For now, Captures have the same cardinality as globals.
// TODO(adonovan): treat captures context-sensitively.
}
if a.log != nil {
fmt.Fprintf(a.log, "\tglobalobj[%s] = n%d\n", v, obj)
}
a.globalobj[v] = obj
}
return obj
}
// Local object.
obj, ok := a.localobj[v]
if !ok {
switch v := v.(type) {
case *ssa.Alloc:
obj = a.nextNode()
a.addNodes(mustDeref(v.Type()), "alloc")
a.endObject(obj, cgn, v)
case *ssa.MakeSlice:
obj = a.nextNode()
a.addNodes(sliceToArray(v.Type()), "makeslice")
a.endObject(obj, cgn, v)
case *ssa.MakeChan:
obj = a.nextNode()
a.addNodes(v.Type().Underlying().(*types.Chan).Elem(), "makechan")
a.endObject(obj, cgn, v)
case *ssa.MakeMap:
obj = a.nextNode()
tmap := v.Type().Underlying().(*types.Map)
a.addNodes(tmap.Key(), "makemap.key")
a.addNodes(tmap.Elem(), "makemap.value")
a.endObject(obj, cgn, v)
case *ssa.MakeInterface:
tConc := v.X.Type()
obj = a.makeTagged(tConc, cgn, v)
// Copy the value into it, if nontrivial.
if x := a.valueNode(v.X); x != 0 {
a.copy(obj+1, x, a.sizeof(tConc))
}
case *ssa.FieldAddr:
if xobj := a.objectNode(cgn, v.X); xobj != 0 {
obj = xobj + nodeid(a.offsetOf(mustDeref(v.X.Type()), v.Field))
}
case *ssa.IndexAddr:
if xobj := a.objectNode(cgn, v.X); xobj != 0 {
obj = xobj + 1
}
case *ssa.Slice:
obj = a.objectNode(cgn, v.X)
case *ssa.Convert:
// TODO(adonovan): opt: handle these cases too:
// - unsafe.Pointer->*T conversion acts like Alloc
// - string->[]byte/[]rune conversion acts like MakeSlice
}
//.........这里部分代码省略.........