summaryrefslogtreecommitdiff
path: root/bindings
diff options
context:
space:
mode:
authorAmaury Sechet <deadalnix@gmail.com>2016-11-18 10:11:02 +0000
committerAmaury Sechet <deadalnix@gmail.com>2016-11-18 10:11:02 +0000
commitd1894a13cc9a764bf7fcee218c69d36f29924d7b (patch)
tree18939ed19ec313e16eba64c04e079a8987c66b1c /bindings
parent35b775d13a246892a85c639e21c98bfde870faef (diff)
Fix go binding to adapt the new attribute API
https://reviews.llvm.org/D26339 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287328 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'bindings')
-rw-r--r--bindings/go/llvm/ir.go96
-rw-r--r--bindings/go/llvm/ir_test.go97
2 files changed, 193 insertions, 0 deletions
diff --git a/bindings/go/llvm/ir.go b/bindings/go/llvm/ir.go
index f399c1c800b..b263c07c512 100644
--- a/bindings/go/llvm/ir.go
+++ b/bindings/go/llvm/ir.go
@@ -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
index 00000000000..13e113957b4
--- /dev/null
+++ b/bindings/go/llvm/ir_test.go
@@ -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)
+ }
+}