forked from go-llvm/llgo
/
len.go
66 lines (61 loc) · 1.99 KB
/
len.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright 2011 The llgo Authors.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
package llgo
import (
"code.google.com/p/go.tools/go/types"
"github.com/axw/gollvm/llvm"
"go/ast"
)
func (c *compiler) VisitCap(expr *ast.CallExpr) Value {
value := c.VisitExpr(expr.Args[0])
typ := value.Type()
if name, ok := typ.Underlying().(*types.Named); ok {
typ = name.Underlying()
}
var capvalue llvm.Value
switch typ := typ.Underlying().(type) {
case *types.Pointer:
atyp := typ.Elem().Underlying().(*types.Array)
capvalue = llvm.ConstInt(c.llvmtypes.inttype, uint64(atyp.Len()), false)
case *types.Array:
capvalue = llvm.ConstInt(c.llvmtypes.inttype, uint64(typ.Len()), false)
case *types.Slice:
sliceval := value.LLVMValue()
capvalue = c.builder.CreateExtractValue(sliceval, 2, "")
case *types.Chan:
panic("cap(chan) unimplemented")
}
return c.NewValue(capvalue, types.Typ[types.Int])
}
func (c *compiler) VisitLen(expr *ast.CallExpr) Value {
value := c.VisitExpr(expr.Args[0])
typ := value.Type()
if name, ok := typ.Underlying().(*types.Named); ok {
typ = name.Underlying()
}
var lenvalue llvm.Value
switch typ := typ.Underlying().(type) {
case *types.Pointer:
atyp := typ.Elem().Underlying().(*types.Array)
lenvalue = llvm.ConstInt(c.llvmtypes.inttype, uint64(atyp.Len()), false)
case *types.Slice:
sliceval := value.LLVMValue()
lenvalue = c.builder.CreateExtractValue(sliceval, 1, "")
case *types.Map:
mapval := value.LLVMValue()
f := c.NamedFunction("runtime.maplen", "func f(m uintptr) int")
lenvalue = c.builder.CreateCall(f, []llvm.Value{mapval}, "")
case *types.Array:
lenvalue = llvm.ConstInt(c.llvmtypes.inttype, uint64(typ.Len()), false)
case *types.Basic:
if isString(typ) {
value := value.(*LLVMValue)
lenvalue = c.builder.CreateExtractValue(value.LLVMValue(), 1, "")
}
case *types.Chan:
panic("len(chan) unimplemented")
}
return c.NewValue(lenvalue, types.Typ[types.Int])
}
// vim: set ft=go :