本文整理汇总了Golang中code/google/com/p/go/tools/ssa.Value类的典型用法代码示例。如果您正苦于以下问题:Golang Value类的具体用法?Golang Value怎么用?Golang Value使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Value类的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: describePointer
// describePointer runs the pointer analysis of the selected SSA value.
func describePointer(o *Oracle, v ssa.Value, indirect bool) (ptrs []pointerResult, err error) {
buildSSA(o)
// TODO(adonovan): don't run indirect pointer analysis on non-ptr-ptrlike types.
o.config.Queries = map[ssa.Value]pointer.Indirect{v: pointer.Indirect(indirect)}
ptares := ptrAnalysis(o)
// Combine the PT sets from all contexts.
pointers := ptares.Queries[v]
if pointers == nil {
return nil, fmt.Errorf("PTA did not encounter this expression (dead code?)")
}
pts := pointer.PointsToCombined(pointers)
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{}) {
combined := pointer.PointsToCombined(pta.([]pointer.Pointer))
labels := combined.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
}
示例2: 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))
}
示例3: 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.
//
// Nodes for locals are created en masse during genFunc and are
// implicitly contextualized by the function currently being analyzed
// (i.e. parameter to genFunc).
//
func (a *analysis) valueNode(v ssa.Value) nodeid {
id, ok := a.valNode[v]
if !ok {
switch v := v.(type) {
case *ssa.Function:
id = a.makeFunction(v)
case *ssa.Global:
id = a.makeGlobal(v)
case *ssa.Const:
id = a.makeConstant(v)
case *ssa.Capture:
// TODO(adonovan): treat captures context-sensitively.
id = a.addNodes(v.Type(), "capture")
default:
// *ssa.Parameters and ssa.Instruction values
// are created by genFunc.
// *Builtins are not true values.
panic(v)
}
a.setValueNode(v, id)
}
return id
}
示例4: get
func (fr *frame) get(key ssa.Value) value {
switch key := key.(type) {
case nil:
// Hack; simplifies handling of optional attributes
// such as ssa.Slice.{Low,High}.
return nil
case *ssa.Function, *ssa.Builtin:
return key
case *ssa.Const:
return constValue(key)
case *ssa.Global:
if r, ok := fr.i.globals[key]; ok {
return r
}
}
if r, ok := fr.env[key]; ok {
return r
}
panic(fmt.Sprintf("get: no value for %T: %v", key, key.Name()))
}
示例5: 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)
// Combine the PT sets from all contexts.
var pointers []pointer.Pointer
if isAddr {
pointers = ptares.IndirectQueries[v]
} else {
pointers = ptares.Queries[v]
}
if pointers == nil {
return nil, fmt.Errorf("pointer analysis did not find expression (dead code?)")
}
pts := pointer.PointsToCombined(pointers)
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{}) {
combined := pointer.PointsToCombined(pta.([]pointer.Pointer))
labels := combined.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
}
示例6: 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.addOneNode(v.Type(), comment, nil)
if obj := a.objectNode(nil, v); obj != 0 {
a.addressOf(id, obj)
}
a.setValueNode(v, id, nil)
}
return id
}
示例7: setValueNode
// setValueNode associates node id with the value v.
// TODO(adonovan): disambiguate v by its CallGraphNode, if it's a local.
func (a *analysis) setValueNode(v ssa.Value, id nodeid) {
a.valNode[v] = id
if a.log != nil {
fmt.Fprintf(a.log, "\tval[%s] = n%d (%T)\n", v.Name(), id, v)
}
// Record the (v, id) relation if the client has queried v.
if indirect, ok := a.config.Queries[v]; ok {
if indirect {
tmp := a.addNodes(v.Type(), "query.indirect")
a.load(tmp, id, a.sizeof(v.Type()))
id = tmp
}
a.queries[v] = append(a.queries[v], ptr{a, id})
}
}
示例8: 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)
}
// Record the (v, id) relation if the client has queried v.
if indirect, ok := a.config.Queries[v]; ok {
if indirect {
tmp := a.addNodes(v.Type(), "query.indirect")
a.genLoad(cgn, tmp, v, 0, a.sizeof(v.Type()))
id = tmp
}
a.result.Queries[v] = append(a.result.Queries[v], ptr{a, cgn, id})
}
}
示例9: 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
}
示例10: describeValue
func describeValue(o *Oracle, qpos *QueryPos, path []ast.Node) (*describeValueResult, error) {
var expr ast.Expr
var obj types.Object
switch n := path[0].(type) {
case *ast.ValueSpec:
// ambiguous ValueSpec containing multiple names
return nil, fmt.Errorf("multiple value specification")
case *ast.Ident:
obj = qpos.info.ObjectOf(n)
expr = n
case ast.Expr:
expr = n
default:
// Is this reachable?
return nil, fmt.Errorf("unexpected AST for expr: %T", n)
}
typ := qpos.info.TypeOf(expr)
constVal := qpos.info.ValueOf(expr)
// From this point on, we cannot fail with an error.
// Failure to run the pointer analysis will be reported later.
//
// Our disposition to pointer analysis may be one of the following:
// - ok: ssa.Value was const or func.
// - error: no ssa.Value for expr (e.g. trivially dead code)
// - ok: ssa.Value is non-pointerlike
// - error: no Pointer for ssa.Value (e.g. analytically unreachable)
// - ok: Pointer has empty points-to set
// - ok: Pointer has non-empty points-to set
// ptaErr is non-nil only in the "error:" cases.
var ptaErr error
var ptrs []pointerResult
// Only run pointer analysis on pointerlike expression types.
if pointer.CanPoint(typ) {
// Determine the ssa.Value for the expression.
var value ssa.Value
if obj != nil {
// def/ref of func/var/const object
value, ptaErr = ssaValueForIdent(o.prog, qpos.info, obj, path)
} else {
// any other expression
if qpos.info.ValueOf(path[0].(ast.Expr)) == nil { // non-constant?
value, ptaErr = ssaValueForExpr(o.prog, qpos.info, path)
}
}
if value != nil {
// TODO(adonovan): IsIdentical may be too strict;
// perhaps we need is-assignable or even
// has-same-underlying-representation?
indirect := types.IsIdentical(types.NewPointer(typ), value.Type())
ptrs, ptaErr = describePointer(o, value, indirect)
}
}
return &describeValueResult{
qpos: qpos,
expr: expr,
typ: typ,
constVal: constVal,
obj: obj,
ptaErr: ptaErr,
ptrs: ptrs,
}, nil
}
示例11: 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:
if t, ok := v.Type().Underlying().(*types.Slice); ok && !v.IsNil() {
// Non-nil []byte or []rune constant.
obj = a.nextNode()
a.addNodes(sliceToArray(t), "array in slice constant")
a.endObject(obj, nil, v)
}
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:
//.........这里部分代码省略.........