• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Golang types.Identical函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了Golang中github.com/axw/llgo/types.Identical函数的典型用法代码示例。如果您正苦于以下问题:Golang Identical函数的具体用法?Golang Identical怎么用?Golang Identical使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了Identical函数的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。

示例1: UnaryOp

func (v *LLVMValue) UnaryOp(op token.Token) Value {
	b := v.compiler.builder
	switch op {
	case token.SUB:
		var value llvm.Value
		isfp := types.Identical(types.Underlying(v.typ), types.Float32) ||
			types.Identical(types.Underlying(v.typ), types.Float64)
		if isfp {
			zero := llvm.ConstNull(v.compiler.types.ToLLVM(v.Type()))
			value = b.CreateFSub(zero, v.LLVMValue(), "")
		} else {
			value = b.CreateNeg(v.LLVMValue(), "")
		}
		return v.compiler.NewLLVMValue(value, v.typ)
	case token.ADD:
		return v // No-op
	case token.AND:
		return v.pointer
	case token.NOT:
		value := b.CreateNot(v.LLVMValue(), "")
		return v.compiler.NewLLVMValue(value, v.typ)
	case token.XOR:
		lhs := v.LLVMValue()
		rhs := llvm.ConstAllOnes(lhs.Type())
		value := b.CreateXor(lhs, rhs, "")
		return v.compiler.NewLLVMValue(value, v.typ)
	default:
		panic("Unhandled operator: ") // + expr.Op)
	}
	panic("unreachable")
}
开发者ID:spate,项目名称:llgo,代码行数:31,代码来源:value.go


示例2: Convert

func (v ConstValue) Convert(dst_typ types.Type) Value {
	// Get the underlying type, if any.
	if name, isname := dst_typ.(*types.Name); isname {
		dst_typ = types.Underlying(name)
	}

	if !types.Identical(v.typ, dst_typ) {
		// Get the Basic type.
		isBasic := false
		if name, isname := types.Underlying(dst_typ).(*types.Name); isname {
			_, isBasic = name.Underlying.(*types.Basic)
		}

		compiler := v.compiler
		if isBasic {
			return ConstValue{*v.Const.Convert(&dst_typ), compiler, dst_typ}
		} else {
			return compiler.NewLLVMValue(v.LLVMValue(), v.Type()).Convert(dst_typ)
			//panic(fmt.Errorf("unhandled conversion from %v to %v", v.typ, dst_typ))
		}
	} else {
		// TODO convert to dst type. ConstValue may need to change to allow
		// storage of types other than Basic.
	}
	return v
}
开发者ID:prattmic,项目名称:llgo,代码行数:26,代码来源:value.go


示例3: Convert

func (v ConstValue) Convert(dstTyp types.Type) Value {
	// Get the underlying type, if any.
	origDstTyp := dstTyp
	dstTyp = types.Underlying(dstTyp)

	if !types.Identical(v.typ, dstTyp) {
		isBasic := false
		if name, isname := types.Underlying(dstTyp).(*types.Name); isname {
			_, isBasic = name.Underlying.(*types.Basic)
		}

		compiler := v.compiler
		if isBasic {
			return ConstValue{v.Const.Convert(&dstTyp), compiler, origDstTyp}
		} else {
			return compiler.NewLLVMValue(v.LLVMValue(), v.Type()).Convert(origDstTyp)
			//panic(fmt.Errorf("unhandled conversion from %v to %v", v.typ, dstTyp))
		}
	} else {
		v.typ = origDstTyp
	}
	return v
}
开发者ID:spate,项目名称:llgo,代码行数:23,代码来源:value.go


示例4: VisitSelectorExpr


//.........这里部分代码省略.........
		ftype.Recv = nil
		method := c.NewLLVMValue(f, ftype)
		method.receiver = c.NewLLVMValue(receiver, i8ptr)
		return method
	}

	// Search through embedded types for field/method.
	var result selectorCandidate
	curr := []selectorCandidate{{nil, lhs.Type()}}
	for result.Type == nil && len(curr) > 0 {
		var next []selectorCandidate
		for _, candidate := range curr {
			indices := candidate.Indices[0:]
			t := candidate.Type

			if p, ok := types.Underlying(t).(*types.Pointer); ok {
				if _, ok := types.Underlying(p.Base).(*types.Struct); ok {
					t = p.Base
				}
			}

			if n, ok := t.(*types.Name); ok {
				i := sort.Search(len(n.Methods), func(i int) bool {
					return n.Methods[i].Name >= name
				})
				if i < len(n.Methods) && n.Methods[i].Name == name {
					result.Indices = indices
					result.Type = t
				}
			}

			if t, ok := types.Underlying(t).(*types.Struct); ok {
				if i, ok := t.FieldIndices[name]; ok {
					result.Indices = append(indices, int(i))
					result.Type = t
				} else {
					// Add embedded types to the next set of types
					// to check.
					for i, field := range t.Fields {
						if field.Name == "" {
							indices = append(indices[0:], i)
							t := field.Type.(types.Type)
							candidate := selectorCandidate{indices, t}
							next = append(next, candidate)
						}
					}
				}
			}
		}
		curr = next
	}

	// Get a pointer to the field/receiver.
	recvValue := lhs.(*LLVMValue)
	if len(result.Indices) > 0 {
		if _, ok := types.Underlying(lhs.Type()).(*types.Pointer); !ok {
			recvValue = recvValue.pointer
			//recvValue = c.NewLLVMValue(recvValue.LLVMValue(), recvValue.Type())
		}
		for _, v := range result.Indices {
			ptr := recvValue.LLVMValue()
			field := types.Underlying(types.Deref(recvValue.typ)).(*types.Struct).Fields[v]
			fieldPtr := c.builder.CreateStructGEP(ptr, v, "")
			fieldPtrTyp := &types.Pointer{Base: field.Type.(types.Type)}
			recvValue = c.NewLLVMValue(fieldPtr, fieldPtrTyp)

			// GEP returns a pointer; if the field is a pointer,
			// we must load our pointer-to-a-pointer.
			if _, ok := field.Type.(*types.Pointer); ok {
				recvValue = recvValue.makePointee()
			}
		}
	}

	// Method?
	if expr.Sel.Obj.Kind == ast.Fun {
		method := c.Resolve(expr.Sel.Obj).(*LLVMValue)
		methodType := expr.Sel.Obj.Type.(*types.Func)
		receiverType := methodType.Recv.Type.(types.Type)
		if types.Identical(recvValue.Type(), receiverType) {
			method.receiver = recvValue
		} else if types.Identical(&types.Pointer{Base: recvValue.Type()}, receiverType) {
			method.receiver = recvValue.pointer
		} else {
			method.receiver = recvValue.makePointee()
		}
		return method
	} else {
		resultType := expr.Sel.Obj.Type.(types.Type)
		if types.Identical(recvValue.Type(), resultType) {
			// no-op
		} else if types.Identical(&types.Pointer{Base: recvValue.Type()}, resultType) {
			recvValue = recvValue.pointer
		} else {
			recvValue = recvValue.makePointee()
		}
		return recvValue
	}
	panic("unreachable")
}
开发者ID:kisielk,项目名称:llgo,代码行数:101,代码来源:expr.go


示例5: VisitSelectorExpr

func (c *compiler) VisitSelectorExpr(expr *ast.SelectorExpr) Value {
	lhs := c.VisitExpr(expr.X)
	if lhs == nil {
		// The only time we should get a nil result is if the object is
		// a package.
		obj := expr.Sel.Obj
		if obj.Kind == ast.Typ {
			return TypeValue{obj.Type.(types.Type)}
		}
		return c.Resolve(obj)
	}

	// TODO(?) record path to field/method during typechecking, so we don't
	// have to search again here.

	name := expr.Sel.Name
	if iface, ok := types.Underlying(lhs.Type()).(*types.Interface); ok {
		// validity checked during typechecking.
		i := sort.Search(len(iface.Methods), func(i int) bool {
			return iface.Methods[i].Name >= name
		})
		struct_value := lhs.LLVMValue()
		receiver_value := c.builder.CreateStructGEP(struct_value, 0, "")
		fn_value := c.builder.CreateStructGEP(struct_value, i+2, "")
		method_type := c.ObjGetType(iface.Methods[i]).(*types.Func)
		method := c.NewLLVMValue(
			c.builder.CreateBitCast(
				c.builder.CreateLoad(fn_value, ""),
				c.types.ToLLVM(method_type), ""), method_type)
		method.receiver = c.NewLLVMValue(
			c.builder.CreateLoad(receiver_value, ""),
			method_type.Recv.Type.(types.Type))
		return method
	}

	// Search through embedded types for field/method.
	var result selectorCandidate
	curr := []selectorCandidate{{nil, lhs.Type()}}
	for result.Type == nil && len(curr) > 0 {
		var next []selectorCandidate
		for _, candidate := range curr {
			indices := candidate.Indices[0:]
			t := candidate.Type

			if p, ok := types.Underlying(t).(*types.Pointer); ok {
				if _, ok := types.Underlying(p.Base).(*types.Struct); ok {
					indices = append(indices, 0)
					t = p.Base
				}
			}

			if n, ok := t.(*types.Name); ok {
				i := sort.Search(len(n.Methods), func(i int) bool {
					return n.Methods[i].Name >= name
				})
				if i < len(n.Methods) && n.Methods[i].Name == name {
					result.Indices = indices
					result.Type = t
				}
			}

			if t, ok := types.Underlying(t).(*types.Struct); ok {
				if i, ok := t.FieldIndices[name]; ok {
					result.Indices = append(indices, i)
					result.Type = t
				} else {
					// Add embedded types to the next set of types
					// to check.
					for i, field := range t.Fields {
						if field.Name == "" {
							indices = append(indices[0:], uint64(i))
							t := field.Type.(types.Type)
							candidate := selectorCandidate{indices, t}
							next = append(next, candidate)
						}
					}
				}
			}
		}
		curr = next
	}

	// Get a pointer to the field/struct for field/method invocation.
	indices := make([]llvm.Value, len(result.Indices))
	for i, v := range result.Indices {
		indices[i] = llvm.ConstInt(llvm.Int32Type(), v, false)
	}

	// Method?
	if expr.Sel.Obj.Kind == ast.Fun {
		method := c.Resolve(expr.Sel.Obj).(*LLVMValue)
		methodType := expr.Sel.Obj.Type.(*types.Func)
		receiverType := methodType.Recv.Type.(types.Type)
		if len(indices) > 0 {
			receiverValue := c.builder.CreateGEP(lhs.LLVMValue(), indices, "")
			if types.Identical(result.Type, receiverType) {
				receiverValue = c.builder.CreateLoad(receiverValue, "")
			}
			method.receiver = c.NewLLVMValue(receiverValue, receiverType)
		} else {
//.........这里部分代码省略.........
开发者ID:prattmic,项目名称:llgo,代码行数:101,代码来源:expr.go


示例6: convertV2I


//.........这里部分代码省略.........
	} else {
		// If the value fits exactly in a pointer, then we can just
		// bitcast it. Otherwise we need to malloc, and create a shim
		// function to load the receiver.
		c := v.compiler
		ptrsize := c.target.PointerSize()
		if c.target.TypeStoreSize(lv.Type()) <= uint64(ptrsize) {
			bits := c.target.TypeSizeInBits(lv.Type())
			if bits > 0 {
				lv = c.coerce(lv, llvm.IntType(int(bits)))
				ptr = builder.CreateIntToPtr(lv, element_types[1], "")
			} else {
				ptr = llvm.ConstNull(element_types[1])
			}
		} else {
			ptr = c.createTypeMalloc(v.compiler.types.ToLLVM(srctyp))
			builder.CreateStore(lv, ptr)
			ptr = builder.CreateBitCast(ptr, element_types[1], "")
			overwide = true
		}
	}
	runtimeType := v.compiler.types.ToRuntime(v.Type())
	runtimeType = builder.CreateBitCast(runtimeType, element_types[0], "")
	iface_struct = builder.CreateInsertValue(iface_struct, runtimeType, 0, "")
	iface_struct = builder.CreateInsertValue(iface_struct, ptr, 1, "")

	// TODO assert either source is a named type (or pointer to), or the
	// interface has an empty methodset.

	if srcname != nil {
		// TODO check whether the functions in the struct take
		// value or pointer receivers.

		// Look up the method by name.
		// TODO check embedded types.
		for i, m := range iface.Methods {
			// TODO make this loop linear by iterating through the
			// interface methods and type methods together.
			var methodobj *ast.Object
			curr := []types.Type{srcname}
			for methodobj == nil && len(curr) > 0 {
				var next []types.Type
				for _, typ := range curr {
					if p, ok := types.Underlying(typ).(*types.Pointer); ok {
						if _, ok := types.Underlying(p.Base).(*types.Struct); ok {
							typ = p.Base
						}
					}
					if n, ok := typ.(*types.Name); ok {
						methods := n.Methods
						mi := sort.Search(len(methods), func(i int) bool {
							return methods[i].Name >= m.Name
						})
						if mi < len(methods) && methods[mi].Name == m.Name {
							methodobj = methods[mi]
							break
						}
					}
					if typ, ok := types.Underlying(typ).(*types.Struct); ok {
						for _, field := range typ.Fields {
							if field.Name == "" {
								typ := field.Type.(types.Type)
								next = append(next, typ)
							}
						}
					}
				}
				curr = next
			}
			if methodobj == nil {
				msg := fmt.Sprintf("Failed to locate (%s).%s", srcname.Obj.Name, m.Name)
				panic(msg)
			}
			method := v.compiler.Resolve(methodobj).(*LLVMValue)
			llvm_value := method.LLVMValue()

			// If we have a receiver wider than a word, or a pointer
			// receiver value and non-pointer receiver method, then
			// we must use the "wrapper" pointer method.
			fntyp := methodobj.Type.(*types.Func)
			recvtyp := fntyp.Recv.Type.(types.Type)
			needload := overwide
			if !needload {
				// TODO handle embedded types here.
				//needload = types.Identical(v.Type(), recvtyp)
				if p, ok := v.Type().(*types.Pointer); ok {
					needload = types.Identical(p.Base, recvtyp)
				}
			}
			if needload {
				ifname := fmt.Sprintf("*%s.%s", recvtyp, methodobj.Name)
				llvm_value = v.compiler.module.NamedFunction(ifname)
			}
			llvm_value = builder.CreateBitCast(llvm_value, element_types[i+2], "")
			iface_struct = builder.CreateInsertValue(iface_struct, llvm_value, i+2, "")
		}
	}

	return v.compiler.NewLLVMValue(iface_struct, iface)
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:101,代码来源:interfaces.go


示例7: BinaryOp

func (lhs *LLVMValue) BinaryOp(op token.Token, rhs_ Value) Value {
	if op == token.NEQ {
		result := lhs.BinaryOp(token.EQL, rhs_)
		return result.UnaryOp(token.NOT)
	}

	var result llvm.Value
	c := lhs.compiler
	b := lhs.compiler.builder

	// Later we can do better by treating constants specially. For now, let's
	// convert to LLVMValue's.
	var rhs *LLVMValue
	rhsisnil := false
	switch rhs_ := rhs_.(type) {
	case *LLVMValue:
		rhs = rhs_
	case NilValue:
		rhsisnil = true
		switch rhs_ := rhs_.Convert(lhs.Type()).(type) {
		case ConstValue:
			rhs = c.NewLLVMValue(rhs_.LLVMValue(), rhs_.Type())
		case *LLVMValue:
			rhs = rhs_
		}
	case ConstValue:
		value := rhs_.Convert(lhs.Type())
		rhs = c.NewLLVMValue(value.LLVMValue(), value.Type())
	}

	switch typ := types.Underlying(lhs.typ).(type) {
	case *types.Struct:
		// TODO check types are the same.
		element_types_count := lhs.LLVMValue().Type().StructElementTypesCount()
		struct_fields := typ.Fields
		if element_types_count > 0 {
			t := c.ObjGetType(struct_fields[0])
			first_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), t)
			first_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), 0, ""), t)
			first := first_lhs.BinaryOp(op, first_rhs)

			logical_op := token.LAND
			if op == token.NEQ {
				logical_op = token.LOR
			}

			result := first
			for i := 1; i < element_types_count; i++ {
				t := c.ObjGetType(struct_fields[i])
				next_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), i, ""), t)
				next_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), i, ""), t)
				next := next_lhs.BinaryOp(op, next_rhs)
				result = result.BinaryOp(logical_op, next)
			}
			return result
		}

	case *types.Interface:
		if rhsisnil {
			valueNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
			typeNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
			result := b.CreateAnd(typeNull, valueNull, "")
			return c.NewLLVMValue(result, types.Bool)
		}
		// TODO check for interface/interface comparison vs. interface/value comparison.
		return lhs.compareI2I(rhs)

	case *types.Slice:
		// []T == nil
		isnil := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
		return c.NewLLVMValue(isnil, types.Bool)
	}

	// Strings.
	if types.Underlying(lhs.typ) == types.String {
		if types.Underlying(rhs.typ) == types.String {
			switch op {
			case token.ADD:
				return c.concatenateStrings(lhs, rhs)
			case token.EQL, token.LSS, token.GTR, token.LEQ, token.GEQ:
				return c.compareStrings(lhs, rhs, op)
			default:
				panic(fmt.Sprint("Unimplemented operator: ", op))
			}
		}
		panic("unimplemented")
	}

	// Determine whether to use integer or floating point instructions.
	// TODO determine the NaN rules.
	isfp := types.Identical(types.Underlying(lhs.typ), types.Float32) ||
		types.Identical(types.Underlying(lhs.typ), types.Float64)

	switch op {
	case token.MUL:
		if isfp {
			result = b.CreateFMul(lhs.LLVMValue(), rhs.LLVMValue(), "")
		} else {
			result = b.CreateMul(lhs.LLVMValue(), rhs.LLVMValue(), "")
		}
//.........这里部分代码省略.........
开发者ID:spate,项目名称:llgo,代码行数:101,代码来源:value.go


示例8: VisitSelectorExpr

func (c *compiler) VisitSelectorExpr(expr *ast.SelectorExpr) Value {
	lhs := c.VisitExpr(expr.X)
	if lhs == nil {
		// The only time we should get a nil result is if the object is
		// a package.
		obj := expr.Sel.Obj
		if obj.Kind == ast.Typ {
			return TypeValue{obj.Type.(types.Type)}
		}
		return c.Resolve(obj)
	}

	// TODO(?) record path to field/method during typechecking, so we don't
	// have to search again here.

	name := expr.Sel.Name
	if iface, ok := types.Underlying(lhs.Type()).(*types.Interface); ok {
		i := sort.Search(len(iface.Methods), func(i int) bool {
			return iface.Methods[i].Name >= name
		})
		structValue := lhs.LLVMValue()
		receiver := c.builder.CreateExtractValue(structValue, 0, "")
		f := c.builder.CreateExtractValue(structValue, i+2, "")
		ftype := c.ObjGetType(iface.Methods[i]).(*types.Func)
		method := c.NewLLVMValue(c.builder.CreateBitCast(f, c.types.ToLLVM(ftype), ""), ftype)
		method.receiver = c.NewLLVMValue(receiver, ftype.Recv.Type.(types.Type))
		return method
	}

	// Search through embedded types for field/method.
	var result selectorCandidate
	curr := []selectorCandidate{{nil, lhs.Type()}}
	for result.Type == nil && len(curr) > 0 {
		var next []selectorCandidate
		for _, candidate := range curr {
			indices := candidate.Indices[0:]
			t := candidate.Type

			if p, ok := types.Underlying(t).(*types.Pointer); ok {
				if _, ok := types.Underlying(p.Base).(*types.Struct); ok {
					t = p.Base
				}
			}

			if n, ok := t.(*types.Name); ok {
				i := sort.Search(len(n.Methods), func(i int) bool {
					return n.Methods[i].Name >= name
				})
				if i < len(n.Methods) && n.Methods[i].Name == name {
					result.Indices = indices
					result.Type = t
				}
			}

			if t, ok := types.Underlying(t).(*types.Struct); ok {
				if i, ok := t.FieldIndices[name]; ok {
					result.Indices = append(indices, int(i))
					result.Type = t
				} else {
					// Add embedded types to the next set of types
					// to check.
					for i, field := range t.Fields {
						if field.Name == "" {
							indices = append(indices[0:], i)
							t := field.Type.(types.Type)
							candidate := selectorCandidate{indices, t}
							next = append(next, candidate)
						}
					}
				}
			}
		}
		curr = next
	}

	// Get a pointer to the field/receiver.
	recvValue := lhs.(*LLVMValue)
	if _, ok := types.Underlying(lhs.Type()).(*types.Pointer); !ok {
		recvValue = recvValue.pointer
	}
	recvValue = c.NewLLVMValue(recvValue.LLVMValue(), recvValue.Type())
	if len(result.Indices) > 0 {
		for _, v := range result.Indices {
			ptr := recvValue.LLVMValue()
			field := types.Underlying(types.Deref(recvValue.typ)).(*types.Struct).Fields[v]
			fieldPtr := c.builder.CreateStructGEP(ptr, v, "")
			fieldPtrTyp := &types.Pointer{Base: field.Type.(types.Type)}
			recvValue = c.NewLLVMValue(fieldPtr, fieldPtrTyp)

			// GEP returns a pointer; if the field is a pointer,
			// we must load our pointer-to-a-pointer.
			if _, ok := field.Type.(*types.Pointer); ok {
				recvValue = recvValue.makePointee()
			}
		}
	}
	if !types.Identical(recvValue.typ, expr.Sel.Obj.Type.(types.Type)) {
		recvValue = recvValue.makePointee()
	}

//.........这里部分代码省略.........
开发者ID:spate,项目名称:llgo,代码行数:101,代码来源:expr.go


示例9: Convert

func (v *LLVMValue) Convert(dst_typ types.Type) Value {
	b := v.compiler.builder

	// If it's a stack allocated value, we'll want to compare the
	// value type, not the pointer type.
	src_typ := v.typ

	// Get the underlying type, if any.
	orig_dst_typ := dst_typ
	dst_typ = types.Underlying(dst_typ)
	src_typ = types.Underlying(src_typ)

	// Identical (underlying) types? Just swap in the destination type.
	if types.Identical(src_typ, dst_typ) {
		// TODO avoid load here by reusing pointer value, if exists.
		return v.compiler.NewLLVMValue(v.LLVMValue(), orig_dst_typ)
	}

	// Both pointer types with identical underlying types? Same as above.
	if src_typ, ok := src_typ.(*types.Pointer); ok {
		if dst_typ, ok := dst_typ.(*types.Pointer); ok {
			src_typ := types.Underlying(src_typ.Base)
			dst_typ := types.Underlying(dst_typ.Base)
			if types.Identical(src_typ, dst_typ) {
				return v.compiler.NewLLVMValue(v.LLVMValue(), orig_dst_typ)
			}
		}
	}

	// Convert from an interface type.
	if _, isinterface := src_typ.(*types.Interface); isinterface {
		if interface_, isinterface := dst_typ.(*types.Interface); isinterface {
			result, _ := v.convertI2I(interface_)
			return result
		} else {
			result, _ := v.convertI2V(orig_dst_typ)
			return result
		}
	}

	// Converting to an interface type.
	if interface_, isinterface := dst_typ.(*types.Interface); isinterface {
		return v.convertV2I(interface_)
	}

	// string -> []byte
	byteslice := &types.Slice{Elt: types.Byte}
	if src_typ == types.String && types.Identical(dst_typ, byteslice) {
		c := v.compiler
		value := v.LLVMValue()
		strdata := c.builder.CreateExtractValue(value, 0, "")
		strlen := c.builder.CreateExtractValue(value, 1, "")
		struct_ := llvm.Undef(c.types.ToLLVM(byteslice))
		struct_ = c.builder.CreateInsertValue(struct_, strdata, 0, "")
		struct_ = c.builder.CreateInsertValue(struct_, strlen, 1, "")
		struct_ = c.builder.CreateInsertValue(struct_, strlen, 2, "")
		return c.NewLLVMValue(struct_, byteslice)
	}

	// []byte -> string
	if types.Identical(src_typ, byteslice) && dst_typ == types.String {
		c := v.compiler
		value := v.LLVMValue()
		data := c.builder.CreateExtractValue(value, 0, "")
		len := c.builder.CreateExtractValue(value, 1, "")
		struct_ := llvm.Undef(c.types.ToLLVM(types.String))
		struct_ = c.builder.CreateInsertValue(struct_, data, 0, "")
		struct_ = c.builder.CreateInsertValue(struct_, len, 1, "")
		return c.NewLLVMValue(struct_, types.String)
	}

	// Rune to string conversion.
	if dst_typ == types.String && isIntType(src_typ) {
		return v.runeToString()
	}

	// TODO other special conversions?
	llvm_type := v.compiler.types.ToLLVM(dst_typ)

	// Unsafe pointer conversions.
	if dst_typ == types.UnsafePointer { // X -> unsafe.Pointer
		if _, isptr := src_typ.(*types.Pointer); isptr {
			value := b.CreatePtrToInt(v.LLVMValue(), llvm_type, "")
			return v.compiler.NewLLVMValue(value, orig_dst_typ)
		} else if src_typ == types.Uintptr {
			return v.compiler.NewLLVMValue(v.LLVMValue(), orig_dst_typ)
		}
	} else if src_typ == types.UnsafePointer { // unsafe.Pointer -> X
		if _, isptr := dst_typ.(*types.Pointer); isptr {
			value := b.CreateIntToPtr(v.LLVMValue(), llvm_type, "")
			return v.compiler.NewLLVMValue(value, orig_dst_typ)
		} else if dst_typ == types.Uintptr {
			return v.compiler.NewLLVMValue(v.LLVMValue(), orig_dst_typ)
		}
	}

	// FIXME select the appropriate cast here, depending on size, type (int/float)
	// and sign.
	lv := v.LLVMValue()
	srcType := lv.Type()
//.........这里部分代码省略.........
开发者ID:kisielk,项目名称:llgo,代码行数:101,代码来源:value.go


示例10: BinaryOp

func (lhs *LLVMValue) BinaryOp(op token.Token, rhs_ Value) Value {
	if op == token.NEQ {
		result := lhs.BinaryOp(token.EQL, rhs_)
		return result.UnaryOp(token.NOT)
	}

	var result llvm.Value
	c := lhs.compiler
	b := lhs.compiler.builder

	// Later we can do better by treating constants specially. For now, let's
	// convert to LLVMValue's.
	var rhs *LLVMValue
	switch rhs_ := rhs_.(type) {
	case *LLVMValue:
		rhs = rhs_
	case NilValue:
		switch rhs_ := rhs_.Convert(lhs.Type()).(type) {
		case ConstValue:
			rhs = c.NewLLVMValue(rhs_.LLVMValue(), rhs_.Type())
		case *LLVMValue:
			rhs = rhs_
		}
	case ConstValue:
		value := rhs_.Convert(lhs.Type())
		rhs = c.NewLLVMValue(value.LLVMValue(), value.Type())
	}

	// Special case for structs.
	// TODO handle strings as an even more special case.
	if struct_type, ok := types.Underlying(lhs.typ).(*types.Struct); ok {
		// TODO check types are the same.

		element_types_count := lhs.LLVMValue().Type().StructElementTypesCount()
		struct_fields := struct_type.Fields

		if element_types_count > 0 {
			t := c.ObjGetType(struct_fields[0])
			first_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), t)
			first_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), 0, ""), t)
			first := first_lhs.BinaryOp(op, first_rhs)

			logical_op := token.LAND
			if op == token.NEQ {
				logical_op = token.LOR
			}

			result := first
			for i := 1; i < element_types_count; i++ {
				t := c.ObjGetType(struct_fields[i])
				next_lhs := c.NewLLVMValue(b.CreateExtractValue(lhs.LLVMValue(), i, ""), t)
				next_rhs := c.NewLLVMValue(b.CreateExtractValue(rhs.LLVMValue(), i, ""), t)
				next := next_lhs.BinaryOp(op, next_rhs)
				result = result.BinaryOp(logical_op, next)
			}
			return result
		}
	}

	// Interfaces.
	if _, ok := types.Underlying(lhs.typ).(*types.Interface); ok {
		// TODO check for interface/interface comparison vs. interface/value comparison.

		// nil comparison
		if /*rhs.LLVMValue().IsConstant() &&*/ rhs.LLVMValue().IsNull() {
			var result llvm.Value
			if op == token.EQL {
				valueNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
				typeNull := b.CreateIsNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
				result = b.CreateAnd(typeNull, valueNull, "")
			} else {
				valueNotNull := b.CreateIsNotNull(b.CreateExtractValue(lhs.LLVMValue(), 0, ""), "")
				typeNotNull := b.CreateIsNotNull(b.CreateExtractValue(lhs.LLVMValue(), 1, ""), "")
				result = b.CreateOr(typeNotNull, valueNotNull, "")
			}
			return c.NewLLVMValue(result, types.Bool)
		}

		// First, check that the dynamic types are identical.
		// FIXME provide runtime function for type identity comparison, and
		// value comparisons.
		lhsType := b.CreateExtractValue(lhs.LLVMValue(), 1, "")
		rhsType := b.CreateExtractValue(rhs.LLVMValue(), 1, "")
		diff := b.CreatePtrDiff(lhsType, rhsType, "")
		zero := llvm.ConstNull(diff.Type())

		var result llvm.Value
		if op == token.EQL {
			typesIdentical := b.CreateICmp(llvm.IntEQ, diff, zero, "")
			//valuesEqual := ...
			//result = b.CreateAnd(typesIdentical, valuesEqual, "")
			result = typesIdentical
		} else {
			typesDifferent := b.CreateICmp(llvm.IntNE, diff, zero, "")
			//valuesUnequal := ...
			//result = b.CreateOr(typesDifferent, valuesUnequal, "")
			result = typesDifferent
		}
		return c.NewLLVMValue(result, types.Bool)
	}
//.........这里部分代码省略.........
开发者ID:prattmic,项目名称:llgo,代码行数:101,代码来源:value.go


示例11: uncommonType

func (tm *TypeMap) uncommonType(n *types.Name, ptr bool) llvm.Value {
	uncommonTypeInit := llvm.ConstNull(tm.runtimeUncommonType)
	namePtr := tm.globalStringPtr(n.Obj.Name)
	uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, namePtr, []uint32{0})
	var pkgpathPtr llvm.Value
	if n.Package != "" {
		pkgpathPtr = tm.globalStringPtr(n.Package)
		uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, pkgpathPtr, []uint32{1})
	}

	// Store methods.
	methods := make([]llvm.Value, 0, len(n.Methods))
	for _, m := range n.Methods {
		ftyp := m.Type.(*types.Func)
		ptrrecv := !types.Identical(ftyp.Recv.Type.(types.Type), n)
		if !ptr && ptrrecv {
			// For a type T, we only store methods where the
			// receiver is T and not *T. For *T we store both.
			continue
		}

		method := llvm.ConstNull(tm.runtimeMethod)
		name := tm.globalStringPtr(m.Name)
		name = llvm.ConstBitCast(name, tm.runtimeMethod.StructElementTypes()[0])
		// name
		method = llvm.ConstInsertValue(method, name, []uint32{0})
		// pkgPath
		method = llvm.ConstInsertValue(method, pkgpathPtr, []uint32{1})
		// mtyp (method type, no receiver)
		{
			recv := ftyp.Recv
			ftyp.Recv = nil
			mtyp := tm.ToRuntime(ftyp)
			method = llvm.ConstInsertValue(method, mtyp, []uint32{2})
			ftyp.Recv = recv
		}
		// typ (function type, with receiver)
		typ := tm.ToRuntime(ftyp)
		method = llvm.ConstInsertValue(method, typ, []uint32{3})

		// tfn (standard method/function pointer for plain method calls)
		tfn := tm.resolver.Resolve(m).LLVMValue()
		tfn = llvm.ConstPtrToInt(tfn, tm.target.IntPtrType())

		// ifn (single-word receiver function pointer for interface calls)
		ifn := tfn
		needload := ptr && !ptrrecv
		if !needload {
			recvtyp := tm.ToLLVM(ftyp.Recv.Type.(types.Type))
			needload = int(tm.target.TypeAllocSize(recvtyp)) > tm.target.PointerSize()
		}
		if needload {
			// If the receiver type is wider than a word, we
			// need to use an intermediate function which takes
			// a pointer-receiver, loads it, and then calls the
			// standard receiver function.
			fname := fmt.Sprintf("*%s.%s", ftyp.Recv.Type, m.Name)
			ifn = tm.module.NamedFunction(fname)
			ifn = llvm.ConstPtrToInt(ifn, tm.target.IntPtrType())
		}

		method = llvm.ConstInsertValue(method, ifn, []uint32{4})
		method = llvm.ConstInsertValue(method, tfn, []uint32{5})
		methods = append(methods, method)
	}

	var methodsGlobalPtr llvm.Value
	if len(methods) > 0 {
		methodsArray := llvm.ConstArray(tm.runtimeMethod, methods)
		methodsGlobalPtr = llvm.AddGlobal(tm.module, methodsArray.Type(), "")
		methodsGlobalPtr.SetInitializer(methodsArray)
		i32zero := llvm.ConstNull(llvm.Int32Type())
		methodsGlobalPtr = llvm.ConstGEP(methodsGlobalPtr, []llvm.Value{i32zero, i32zero})
	} else {
		methodsGlobalPtr = llvm.ConstNull(llvm.PointerType(tm.runtimeMethod, 0))
	}
	len_ := llvm.ConstInt(llvm.Int32Type(), uint64(len(methods)), false)
	methodsSliceType := tm.runtimeUncommonType.StructElementTypes()[2]
	methodsSlice := llvm.ConstNull(methodsSliceType)
	methodsSlice = llvm.ConstInsertValue(methodsSlice, methodsGlobalPtr, []uint32{0})
	methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{1})
	methodsSlice = llvm.ConstInsertValue(methodsSlice, len_, []uint32{2})
	uncommonTypeInit = llvm.ConstInsertValue(uncommonTypeInit, methodsSlice, []uint32{2})
	return uncommonTypeInit
}
开发者ID:kelsieflynn,项目名称:llgo,代码行数:85,代码来源:llvmtypes.go



注:本文中的github.com/axw/llgo/types.Identical函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Golang types.Underlying函数代码示例发布时间:2022-05-24
下一篇:
Golang llgo.Module类代码示例发布时间:2022-05-24
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap