OSDN Git Service

Fix go binding to adapt the new attribute API
authorAmaury Sechet <deadalnix@gmail.com>
Fri, 18 Nov 2016 10:11:02 +0000 (10:11 +0000)
committerAmaury Sechet <deadalnix@gmail.com>
Fri, 18 Nov 2016 10:11:02 +0000 (10:11 +0000)
https://reviews.llvm.org/D26339

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287328 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/go/llvm/ir.go
bindings/go/llvm/ir_test.go [new file with mode: 0644]

index f399c1c..b263c07 100644 (file)
@@ -58,6 +58,9 @@ type (
        Metadata struct {
                C C.LLVMMetadataRef
        }
+       Attribute struct {
+               C C.LLVMAttributeRef
+       }
        Opcode           C.LLVMOpcode
        TypeKind         C.LLVMTypeKind
        Linkage          C.LLVMLinkage
@@ -78,6 +81,7 @@ func (c ModuleProvider) IsNil() bool { return c.C == nil }
 func (c MemoryBuffer) IsNil() bool   { return c.C == nil }
 func (c PassManager) IsNil() bool    { return c.C == nil }
 func (c Use) IsNil() bool            { return c.C == nil }
+func (c Attribute) IsNil() bool      { return c.C == nil }
 
 // helpers
 func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef    { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) }
@@ -316,6 +320,63 @@ func MDKindID(name string) (id int) {
 }
 
 //-------------------------------------------------------------------------
+// llvm.Attribute
+//-------------------------------------------------------------------------
+
+func AttributeKindID(name string) (id uint) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       id = uint(C.LLVMGetEnumAttributeKindForName(cname, C.size_t(len(name))))
+       return
+}
+
+func (c Context) CreateEnumAttribute(kind uint, val uint64) (a Attribute) {
+  a.C = C.LLVMCreateEnumAttribute(c.C, C.unsigned(kind), C.uint64_t(val))
+  return
+}
+
+func (a Attribute) GetEnumKind() (id int) {
+  id = int(C.LLVMGetEnumAttributeKind(a.C))
+  return
+}
+
+func (a Attribute) GetEnumValue() (val uint64) {
+  val = uint64(C.LLVMGetEnumAttributeValue(a.C))
+  return
+}
+
+func (c Context) CreateStringAttribute(kind string, val string) (a Attribute) {
+  ckind := C.CString(kind)
+  defer C.free(unsafe.Pointer(ckind))
+  cval := C.CString(val)
+  defer C.free(unsafe.Pointer(cval))
+  a.C = C.LLVMCreateStringAttribute(c.C,
+                                    ckind, C.unsigned(len(kind)),
+                                    cval, C.unsigned(len(val)))
+  return
+}
+
+func (a Attribute) GetStringKind() string {
+  length := C.unsigned(0)
+  ckind := C.LLVMGetStringAttributeKind(a.C, &length)
+  return C.GoStringN(ckind, C.int(length))
+}
+
+func (a Attribute) GetStringValue() string {
+  length := C.unsigned(0)
+  ckind := C.LLVMGetStringAttributeValue(a.C, &length)
+  return C.GoStringN(ckind, C.int(length))
+}
+
+func (a Attribute) IsEnum() bool {
+  return C.LLVMIsEnumAttribute(a.C) != 0;
+}
+
+func (a Attribute) IsString() bool {
+  return C.LLVMIsStringAttribute(a.C) != 0;
+}
+
+//-------------------------------------------------------------------------
 // llvm.Module
 //-------------------------------------------------------------------------
 
@@ -993,6 +1054,38 @@ func (v Value) SetGC(name string) {
        defer C.free(unsafe.Pointer(cname))
        C.LLVMSetGC(v.C, cname)
 }
+func (v Value) AddAttributeAtIndex(i int, a Attribute) {
+  C.LLVMAddAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), a.C)
+}
+func (v Value) AddFunctionAttr(a Attribute) {
+  v.AddAttributeAtIndex(C.LLVMAttributeFunctionIndex, a);
+}
+func (v Value) GetEnumAttributeAtIndex(i int, kind uint) (a Attribute) {
+  a.C = C.LLVMGetEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind))
+  return
+}
+func (v Value) GetEnumFunctionAttribute(kind uint) Attribute {
+  return v.GetEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind)
+}
+func (v Value) GetStringAttributeAtIndex(i int, kind string) (a Attribute) {
+  ckind := C.CString(kind)
+  defer C.free(unsafe.Pointer(ckind))
+  a.C = C.LLVMGetStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i),
+                                        ckind, C.unsigned(len(kind)))
+  return
+}
+func (v Value) RemoveEnumAttributeAtIndex(i int, kind uint) {
+  C.LLVMRemoveEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind))
+}
+func (v Value) RemoveEnumFunctionAttribute(kind uint) {
+  v.RemoveEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind);
+}
+func (v Value) RemoveStringAttributeAtIndex(i int, kind string) {
+  ckind := C.CString(kind)
+  defer C.free(unsafe.Pointer(ckind))
+  C.LLVMRemoveStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i),
+                                     ckind, C.unsigned(len(kind)))
+}
 func (v Value) AddTargetDependentFunctionAttr(attr, value string) {
        cattr := C.CString(attr)
        defer C.free(unsafe.Pointer(cattr))
@@ -1082,6 +1175,9 @@ func (v Value) SetInstructionCallConv(cc CallConv) {
 func (v Value) InstructionCallConv() CallConv {
        return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C)))
 }
+func (v Value) AddCallSiteAttribute(i int, a Attribute) {
+       C.LLVMAddCallSiteAttribute(v.C, C.LLVMAttributeIndex(i), a.C)
+}
 func (v Value) SetInstrParamAlignment(i int, align int) {
        C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align))
 }
diff --git a/bindings/go/llvm/ir_test.go b/bindings/go/llvm/ir_test.go
new file mode 100644 (file)
index 0000000..13e1139
--- /dev/null
@@ -0,0 +1,97 @@
+//===- ir_test.go - Tests for ir ------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+       "strings"
+       "testing"
+)
+
+func testAttribute(t *testing.T, name string) {
+       mod := NewModule("")
+       defer mod.Dispose()
+
+       ftyp := FunctionType(VoidType(), nil, false)
+       fn := AddFunction(mod, "foo", ftyp)
+
+       kind := AttributeKindID(name)
+       attr := mod.Context().CreateEnumAttribute(kind, 0)
+
+       fn.AddFunctionAttr(attr)
+       newattr := fn.GetEnumFunctionAttribute(kind)
+       if attr != newattr {
+               t.Errorf("got attribute mask %d, want %d", newattr, attr)
+       }
+
+       text := mod.String()
+       if !strings.Contains(text, " "+name+" ") {
+               t.Errorf("expected attribute '%s', got:\n%s", name, text)
+       }
+
+       fn.RemoveEnumFunctionAttribute(kind)
+       newattr = fn.GetEnumFunctionAttribute(kind)
+       if !newattr.IsNil() {
+               t.Errorf("got attribute mask %d, want 0", newattr)
+       }
+}
+
+func TestAttributes(t *testing.T) {
+       // Tests that our attribute constants haven't drifted from LLVM's.
+       attrTests := []string{
+               "sanitize_address",
+               "alwaysinline",
+               "builtin",
+               "byval",
+               "convergent",
+               "inalloca",
+               "inlinehint",
+               "inreg",
+               "jumptable",
+               "minsize",
+               "naked",
+               "nest",
+               "noalias",
+               "nobuiltin",
+               "nocapture",
+               "noduplicate",
+               "noimplicitfloat",
+               "noinline",
+               "nonlazybind",
+               "nonnull",
+               "noredzone",
+               "noreturn",
+               "nounwind",
+               "optnone",
+               "optsize",
+               "readnone",
+               "readonly",
+               "returned",
+               "returns_twice",
+               "signext",
+               "safestack",
+               "ssp",
+               "sspreq",
+               "sspstrong",
+               "sret",
+               "sanitize_thread",
+               "sanitize_memory",
+               "uwtable",
+               "zeroext",
+               "cold",
+       }
+
+       for _, name := range attrTests {
+               testAttribute(t, name)
+       }
+}