Initial version of Go bindings.
authorPeter Collingbourne <peter@pcc.me.uk>
Thu, 16 Oct 2014 22:48:02 +0000 (22:48 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Thu, 16 Oct 2014 22:48:02 +0000 (22:48 +0000)
This code is based on the existing LLVM Go bindings project hosted at:
https://github.com/go-llvm/llvm

Note that all contributors to the gollvm project have agreed to relicense
their changes under the LLVM license and submit them to the LLVM project.

Differential Revision: http://reviews.llvm.org/D5684

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

45 files changed:
.gitignore
Makefile.config.in
autoconf/configure.ac
bindings/Makefile
bindings/go/README.txt [new file with mode: 0644]
bindings/go/build.sh [new file with mode: 0755]
bindings/go/conftest.go [new file with mode: 0644]
bindings/go/llvm/DIBuilderBindings.cpp [new file with mode: 0644]
bindings/go/llvm/DIBuilderBindings.h [new file with mode: 0644]
bindings/go/llvm/IRBindings.cpp [new file with mode: 0644]
bindings/go/llvm/IRBindings.h [new file with mode: 0644]
bindings/go/llvm/InstrumentationBindings.cpp [new file with mode: 0644]
bindings/go/llvm/InstrumentationBindings.h [new file with mode: 0644]
bindings/go/llvm/SupportBindings.cpp [new file with mode: 0644]
bindings/go/llvm/SupportBindings.h [new file with mode: 0644]
bindings/go/llvm/analysis.go [new file with mode: 0644]
bindings/go/llvm/bitreader.go [new file with mode: 0644]
bindings/go/llvm/bitwriter.go [new file with mode: 0644]
bindings/go/llvm/dibuilder.go [new file with mode: 0644]
bindings/go/llvm/executionengine.go [new file with mode: 0644]
bindings/go/llvm/executionengine_test.go [new file with mode: 0644]
bindings/go/llvm/ir.go [new file with mode: 0644]
bindings/go/llvm/ir_test.go [new file with mode: 0644]
bindings/go/llvm/linker.go [new file with mode: 0644]
bindings/go/llvm/llvm_config.go.in [new file with mode: 0644]
bindings/go/llvm/llvm_dep.go [new file with mode: 0644]
bindings/go/llvm/string.go [new file with mode: 0644]
bindings/go/llvm/string_test.go [new file with mode: 0644]
bindings/go/llvm/support.go [new file with mode: 0644]
bindings/go/llvm/target.go [new file with mode: 0644]
bindings/go/llvm/transforms_instrumentation.go [new file with mode: 0644]
bindings/go/llvm/transforms_ipo.go [new file with mode: 0644]
bindings/go/llvm/transforms_pmbuilder.go [new file with mode: 0644]
bindings/go/llvm/transforms_scalar.go [new file with mode: 0644]
bindings/go/llvm/version.go [new file with mode: 0644]
cmake/config-ix.cmake
cmake/modules/AddLLVM.cmake
configure
test/Bindings/Go/go.test [new file with mode: 0644]
test/Bindings/Go/lit.local.cfg [new file with mode: 0644]
test/Bindings/Ocaml/lit.local.cfg
test/Makefile
test/lit.cfg
test/lit.site.cfg.in
utils/lit/lit/discovery.py

index eeebe0d05267db3c3eb32fca9a3278e54fe6fdf6..e806c2c5bed711b52365474d41eb149976609518 100644 (file)
@@ -49,3 +49,9 @@ tools/lld
 tools/polly
 # Sphinx build tree, if building in-source dir.
 docs/_build
+
+#==============================================================================#
+# Files created in tree by the Go bindings.
+#==============================================================================#
+bindings/go/llvm/llvm_config.go
+bindings/go/llvm/workdir
index 6d28a47e6ab26f850717e9a8e17fbedb63c19d78..6d85a4e306269b8e6b57d43dae74cb612c52f65d 100644 (file)
@@ -202,6 +202,7 @@ DOT        := @DOT@
 DOXYGEN    := @DOXYGEN@
 GROFF      := @GROFF@
 GZIPBIN    := @GZIPBIN@
+GO         := @GO@
 OCAMLC     := @OCAMLC@
 OCAMLOPT   := @OCAMLOPT@
 OCAMLDEP   := @OCAMLDEP@
index 3e72ff5ea1a1a8cdb8c8571d0067103193b4f25f..a198280f23d12494568b4828d36ed79b45512f0a 100644 (file)
@@ -1287,6 +1287,7 @@ AC_PATH_PROG(GROFF, [groff])
 AC_PATH_PROG(GZIPBIN, [gzip])
 AC_PATH_PROG(PDFROFF, [pdfroff])
 AC_PATH_PROG(ZIP, [zip])
+AC_PATH_PROG(GO, [go])
 AC_PATH_PROGS(OCAMLC, [ocamlc])
 AC_PATH_PROGS(OCAMLOPT, [ocamlopt])
 AC_PATH_PROGS(OCAMLDEP, [ocamldep])
@@ -1867,6 +1868,11 @@ if test "$BINDINGS_TO_BUILD" = auto ; then
   if test "x$OCAMLC" != x -a "x$OCAMLDEP" != x ; then
     BINDINGS_TO_BUILD="ocaml $BINDINGS_TO_BUILD"
   fi
+  if test "x$GO" != x ; then
+    if $GO run ${srcdir}/bindings/go/conftest.go ; then
+      BINDINGS_TO_BUILD="go $BINDINGS_TO_BUILD"
+    fi
+  fi
 fi
 AC_SUBST(BINDINGS_TO_BUILD,$BINDINGS_TO_BUILD)
 
@@ -1901,6 +1907,19 @@ for a_binding in $BINDINGS_TO_BUILD ; do
       fi
     fi
     ;;
+  go)
+    if test "x$GO" = x ; then
+      AC_MSG_WARN([--enable-bindings=go specified, but go not found. Try configure GO=/path/to/go])
+      binding_prereqs_failed=1
+    else
+      if $GO run ${srcdir}/bindings/go/conftest.go ; then
+        :
+      else
+        AC_MSG_WARN([--enable-bindings=go specified, but need at least Go 1.2. Try configure GO=/path/to/go])
+        binding_prereqs_failed=1
+      fi
+    fi
+    ;;
   esac
 done
 if test "$binding_prereqs_failed" = 1 ; then
index c545b28854cc71645fa205f545e1a64141cab078..70e9e6cc63084765327d22cee41065c2bc96a2ff 100644 (file)
@@ -11,6 +11,10 @@ LEVEL := ..
 
 include $(LEVEL)/Makefile.config
 
-PARALLEL_DIRS = $(BINDINGS_TO_BUILD)
+PARALLEL_DIRS =
+
+ifneq (,$(filter ocaml,$(BINDINGS_TO_BUILD)))
+PARALLEL_DIRS += ocaml
+endif
 
 include $(LEVEL)/Makefile.common
diff --git a/bindings/go/README.txt b/bindings/go/README.txt
new file mode 100644 (file)
index 0000000..2fc4afa
--- /dev/null
@@ -0,0 +1,53 @@
+This directory contains LLVM bindings for the Go programming language
+(http://golang.org).
+
+Prerequisites
+-------------
+
+* Go 1.2+.
+* CMake (to build LLVM).
+
+Using the bindings
+------------------
+
+The package path "llvm.org/llvm/bindings/go/llvm" can be used to
+import the latest development version of LLVM from SVN. Paths such as
+"llvm.org/llvm.v36/bindings/go/llvm" refer to released versions of LLVM.
+
+It is recommended to use the "-d" flag with "go get" to download the
+package or a dependency, as an additional step is required to build LLVM
+(see "Building LLVM" below).
+
+Building LLVM
+-------------
+
+The script "build.sh" in this directory can be used to build LLVM and prepare
+it to be used by the bindings. If you receive an error message from "go build"
+like this:
+
+    ./analysis.go:4:84: fatal error: llvm-c/Analysis.h: No such file or directory
+     #include <llvm-c/Analysis.h> // If you are getting an error here read bindings/go/README.txt
+
+or like this:
+
+    ./llvm_dep.go:5: undefined: run_build_sh
+
+it means that LLVM needs to be built or updated by running the script.
+
+    $ $GOPATH/src/llvm.org/llvm/bindings/go/build.sh
+
+Any command line arguments supplied to the script are passed to LLVM's CMake
+build system. A good set of arguments to use during development are:
+
+    $ $GOPATH/src/llvm.org/llvm/bindings/go/build.sh -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD=host -DBUILD_SHARED_LIBS=ON
+
+Note that CMake keeps a cache of build settings so once you have built
+LLVM there is no need to pass these arguments again after updating.
+
+Alternatively, you can build LLVM yourself, but you must then set the
+CGO_CPPFLAGS, CGO_CXXFLAGS and CGO_LDFLAGS environment variables:
+
+    $ export CGO_CPPFLAGS="`/path/to/llvm-build/bin/llvm-config --cppflags`"
+    $ export CGO_CXXFLAGS=-std=c++11
+    $ export CGO_LDFLAGS="`/path/to/llvm-build/bin/llvm-config --ldflags --libs --system-libs all`"
+    $ go build -tags byollvm
diff --git a/bindings/go/build.sh b/bindings/go/build.sh
new file mode 100755 (executable)
index 0000000..df4855b
--- /dev/null
@@ -0,0 +1,67 @@
+#!/bin/sh -xe
+
+llvm_components="\
+all-targets \
+analysis \
+asmparser \
+asmprinter \
+bitreader \
+bitwriter \
+codegen \
+core \
+debuginfo \
+executionengine \
+instrumentation \
+interpreter \
+ipo \
+irreader \
+linker \
+mc \
+mcjit \
+objcarcopts \
+option \
+profiledata \
+scalaropts \
+support \
+target \
+"
+
+if [ "$1" == "--print-components" ] ; then
+  echo $llvm_components
+  exit 0
+fi
+
+gollvmdir=$(dirname "$0")/llvm
+
+workdir=$gollvmdir/workdir
+llvmdir=$gollvmdir/../../..
+llvm_builddir=$workdir/llvm_build
+
+mkdir -p $llvm_builddir
+
+cmake_flags="../../../../.. $@"
+llvm_config="$llvm_builddir/bin/llvm-config"
+
+if test -n "`which ninja`" ; then
+  # If Ninja is available, we can speed up the build by building only the
+  # required subset of LLVM.
+  (cd $llvm_builddir && cmake -G Ninja $cmake_flags)
+  ninja -C $llvm_builddir llvm-config
+  llvm_buildtargets="$($llvm_config --libs $llvm_components | sed -e 's/-l//g')"
+  ninja -C $llvm_builddir $llvm_buildtargets FileCheck
+else
+  (cd $llvm_builddir && cmake $cmake_flags)
+  make -C $llvm_builddir -j4
+fi
+
+llvm_version="$($llvm_config --version)"
+llvm_cflags="$($llvm_config --cppflags)"
+llvm_ldflags="$($llvm_config --ldflags) $($llvm_config --libs $llvm_components) $($llvm_config --system-libs)"
+if [ $(uname) != "Darwin" ]; then
+  # OS X doesn't like -rpath with cgo. See:
+  # https://code.google.com/p/go/issues/detail?id=7293
+  llvm_ldflags="-Wl,-rpath,$($llvm_config --libdir) $llvm_ldflags"
+fi
+sed -e "s#@LLVM_CFLAGS@#$llvm_cflags#g; s#@LLVM_LDFLAGS@#$llvm_ldflags#g" $gollvmdir/llvm_config.go.in > \
+  $gollvmdir/llvm_config.go
+printf "package llvm\n\nconst Version = \"%s\"\n" "$llvm_version" > $gollvmdir/version.go
diff --git a/bindings/go/conftest.go b/bindings/go/conftest.go
new file mode 100644 (file)
index 0000000..d97fb89
--- /dev/null
@@ -0,0 +1,16 @@
+package main
+
+import (
+       "go/build"
+       "os"
+)
+
+// Tests that the Go compiler is at least version 1.2.
+func main() {
+       for _, tag := range build.Default.ReleaseTags {
+               if tag == "go1.2" {
+                       os.Exit(0)
+               }
+       }
+       os.Exit(1)
+}
diff --git a/bindings/go/llvm/DIBuilderBindings.cpp b/bindings/go/llvm/DIBuilderBindings.cpp
new file mode 100644 (file)
index 0000000..94fa96f
--- /dev/null
@@ -0,0 +1,222 @@
+//===- DIBuilderBindings.cpp - Bindings for DIBuilder ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DIBuilderBindings.h"
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/DIBuilder.h"
+
+using namespace llvm;
+
+namespace {
+template <typename T>
+T unwrapDI(LLVMValueRef v) {
+  return v ? T(unwrap<MDNode>(v)) : T();
+}
+}
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DIBuilder, LLVMDIBuilderRef)
+
+LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef mref) {
+  Module *m = unwrap(mref);
+  return wrap(new DIBuilder(*m));
+}
+
+void LLVMDIBuilderDestroy(LLVMDIBuilderRef dref) {
+  DIBuilder *d = unwrap(dref);
+  delete d;
+}
+
+void LLVMDIBuilderFinalize(LLVMDIBuilderRef dref) { unwrap(dref)->finalize(); }
+
+LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef Dref,
+                                            unsigned Lang, const char *File,
+                                            const char *Dir,
+                                            const char *Producer, int Optimized,
+                                            const char *Flags,
+                                            unsigned RuntimeVersion) {
+  DIBuilder *D = unwrap(Dref);
+  DICompileUnit CU = D->createCompileUnit(Lang, File, Dir, Producer, Optimized,
+                                          Flags, RuntimeVersion);
+  return wrap(CU);
+}
+
+LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef Dref, const char *File,
+                                     const char *Dir) {
+  DIBuilder *D = unwrap(Dref);
+  DIFile F = D->createFile(File, Dir);
+  return wrap(F);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef Dref,
+                                             LLVMValueRef Scope,
+                                             LLVMValueRef File, unsigned Line,
+                                             unsigned Column) {
+  DIBuilder *D = unwrap(Dref);
+  DILexicalBlock LB = D->createLexicalBlock(
+      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Line, Column);
+  return wrap(LB);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Dref,
+                                                 LLVMValueRef Scope,
+                                                 LLVMValueRef File,
+                                                 unsigned Discriminator) {
+  DIBuilder *D = unwrap(Dref);
+  DILexicalBlockFile LBF = D->createLexicalBlockFile(
+      unwrapDI<DIDescriptor>(Scope), unwrapDI<DIFile>(File), Discriminator);
+  return wrap(LBF);
+}
+
+LLVMValueRef LLVMDIBuilderCreateFunction(
+    LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+    const char *LinkageName, LLVMValueRef File, unsigned Line,
+    LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition,
+    unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Func) {
+  DIBuilder *D = unwrap(Dref);
+  DISubprogram SP = D->createFunction(
+      unwrapDI<DIDescriptor>(Scope), Name, LinkageName, unwrapDI<DIFile>(File),
+      Line, unwrapDI<DICompositeType>(CompositeType), IsLocalToUnit,
+      IsDefinition, ScopeLine, Flags, IsOptimized, unwrap<Function>(Func));
+  return wrap(SP);
+}
+
+LLVMValueRef LLVMDIBuilderCreateLocalVariable(
+    LLVMDIBuilderRef Dref, unsigned Tag, LLVMValueRef Scope, const char *Name,
+    LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve,
+    unsigned Flags, unsigned ArgNo) {
+  DIBuilder *D = unwrap(Dref);
+  DIVariable V = D->createLocalVariable(
+      Tag, unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+      unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo);
+  return wrap(V);
+}
+
+LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Dref,
+                                          const char *Name, uint64_t SizeInBits,
+                                          uint64_t AlignInBits,
+                                          unsigned Encoding) {
+  DIBuilder *D = unwrap(Dref);
+  DIBasicType T = D->createBasicType(Name, SizeInBits, AlignInBits, Encoding);
+  return wrap(T);
+}
+
+LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
+                                            LLVMValueRef PointeeType,
+                                            uint64_t SizeInBits,
+                                            uint64_t AlignInBits,
+                                            const char *Name) {
+  DIBuilder *D = unwrap(Dref);
+  DIDerivedType T = D->createPointerType(unwrapDI<DIType>(PointeeType),
+                                         SizeInBits, AlignInBits, Name);
+  return wrap(T);
+}
+
+LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Dref,
+                                               LLVMValueRef File,
+                                               LLVMValueRef ParameterTypes) {
+  DIBuilder *D = unwrap(Dref);
+  DICompositeType CT = D->createSubroutineType(
+      unwrapDI<DIFile>(File), unwrapDI<DITypeArray>(ParameterTypes));
+  return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateStructType(
+    LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+    LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+    unsigned Flags, LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes) {
+  DIBuilder *D = unwrap(Dref);
+  DICompositeType CT = D->createStructType(
+      unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+      SizeInBits, AlignInBits, Flags, unwrapDI<DIType>(DerivedFrom),
+      unwrapDI<DIArray>(ElementTypes));
+  return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateMemberType(
+    LLVMDIBuilderRef Dref, LLVMValueRef Scope, const char *Name,
+    LLVMValueRef File, unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+    uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty) {
+  DIBuilder *D = unwrap(Dref);
+  DIDerivedType DT = D->createMemberType(
+      unwrapDI<DIDescriptor>(Scope), Name, unwrapDI<DIFile>(File), Line,
+      SizeInBits, AlignInBits, OffsetInBits, Flags, unwrapDI<DIType>(Ty));
+  return wrap(DT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Dref,
+                                          uint64_t SizeInBits,
+                                          uint64_t AlignInBits,
+                                          LLVMValueRef ElementType,
+                                          LLVMValueRef Subscripts) {
+  DIBuilder *D = unwrap(Dref);
+  DICompositeType CT =
+      D->createArrayType(SizeInBits, AlignInBits, unwrapDI<DIType>(ElementType),
+                         unwrapDI<DIArray>(Subscripts));
+  return wrap(CT);
+}
+
+LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Dref, LLVMValueRef Ty,
+                                        const char *Name, LLVMValueRef File,
+                                        unsigned Line, LLVMValueRef Context) {
+  DIBuilder *D = unwrap(Dref);
+  DIDerivedType DT =
+      D->createTypedef(unwrapDI<DIType>(Ty), Name, unwrapDI<DIFile>(File), Line,
+                       unwrapDI<DIDescriptor>(Context));
+  return wrap(DT);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Dref, int64_t Lo,
+                                              int64_t Count) {
+  DIBuilder *D = unwrap(Dref);
+  DISubrange S = D->getOrCreateSubrange(Lo, Count);
+  return wrap(S);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Dref,
+                                           LLVMValueRef *Data, size_t Length) {
+  DIBuilder *D = unwrap(Dref);
+  Value **DataValue = unwrap(Data);
+  ArrayRef<Value *> Elements(DataValue, Length);
+  DIArray A = D->getOrCreateArray(Elements);
+  return wrap(A);
+}
+
+LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Dref,
+                                               LLVMValueRef *Data,
+                                               size_t Length) {
+  DIBuilder *D = unwrap(Dref);
+  Value **DataValue = unwrap(Data);
+  ArrayRef<Value *> Elements(DataValue, Length);
+  DITypeArray A = D->getOrCreateTypeArray(Elements);
+  return wrap(A);
+}
+
+LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr,
+                                           size_t Length) {
+  DIBuilder *D = unwrap(Dref);
+  DIExpression Expr = D->createExpression(ArrayRef<int64_t>(Addr, Length));
+  return wrap(Expr);
+}
+
+LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef Dref,
+                                             LLVMValueRef Storage,
+                                             LLVMValueRef VarInfo,
+                                             LLVMValueRef Expr,
+                                             LLVMBasicBlockRef Block) {
+  DIBuilder *D = unwrap(Dref);
+  Instruction *Instr =
+      D->insertDeclare(unwrap(Storage), unwrapDI<DIVariable>(VarInfo),
+                       unwrapDI<DIExpression>(Expr), unwrap(Block));
+  return wrap(Instr);
+}
diff --git a/bindings/go/llvm/DIBuilderBindings.h b/bindings/go/llvm/DIBuilderBindings.h
new file mode 100644 (file)
index 0000000..e6fe02a
--- /dev/null
@@ -0,0 +1,123 @@
+//===- DIBuilderBindings.h - Bindings for DIBuilder -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_DIBUILDERBINDINGS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// FIXME: These bindings shouldn't be Go-specific and should eventually move to
+// a (somewhat) less stable collection of C APIs for use in creating bindings of
+// LLVM in other languages.
+
+typedef struct LLVMOpaqueDIBuilder *LLVMDIBuilderRef;
+
+LLVMDIBuilderRef LLVMNewDIBuilder(LLVMModuleRef m);
+
+void LLVMDIBuilderDestroy(LLVMDIBuilderRef d);
+void LLVMDIBuilderFinalize(LLVMDIBuilderRef d);
+
+LLVMValueRef LLVMDIBuilderCreateCompileUnit(LLVMDIBuilderRef D,
+                                            unsigned Language, const char *File,
+                                            const char *Dir,
+                                            const char *Producer, int Optimized,
+                                            const char *Flags,
+                                            unsigned RuntimeVersion);
+
+LLVMValueRef LLVMDIBuilderCreateFile(LLVMDIBuilderRef D, const char *File,
+                                     const char *Dir);
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlock(LLVMDIBuilderRef D,
+                                             LLVMValueRef Scope,
+                                             LLVMValueRef File, unsigned Line,
+                                             unsigned Column);
+
+LLVMValueRef LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef D,
+                                                 LLVMValueRef Scope,
+                                                 LLVMValueRef File,
+                                                 unsigned Discriminator);
+
+LLVMValueRef LLVMDIBuilderCreateFunction(
+    LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name,
+    const char *LinkageName, LLVMValueRef File, unsigned Line,
+    LLVMValueRef CompositeType, int IsLocalToUnit, int IsDefinition,
+    unsigned ScopeLine, unsigned Flags, int IsOptimized, LLVMValueRef Function);
+
+LLVMValueRef LLVMDIBuilderCreateLocalVariable(
+    LLVMDIBuilderRef D, unsigned Tag, LLVMValueRef Scope, const char *Name,
+    LLVMValueRef File, unsigned Line, LLVMValueRef Ty, int AlwaysPreserve,
+    unsigned Flags, unsigned ArgNo);
+
+LLVMValueRef LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef D, const char *Name,
+                                          uint64_t SizeInBits,
+                                          uint64_t AlignInBits,
+                                          unsigned Encoding);
+
+LLVMValueRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef D,
+                                            LLVMValueRef PointeeType,
+                                            uint64_t SizeInBits,
+                                            uint64_t AlignInBits,
+                                            const char *Name);
+
+LLVMValueRef LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef D,
+                                               LLVMValueRef File,
+                                               LLVMValueRef ParameterTypes);
+
+LLVMValueRef LLVMDIBuilderCreateStructType(
+    LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File,
+    unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+    LLVMValueRef DerivedFrom, LLVMValueRef ElementTypes);
+
+LLVMValueRef LLVMDIBuilderCreateMemberType(
+    LLVMDIBuilderRef D, LLVMValueRef Scope, const char *Name, LLVMValueRef File,
+    unsigned Line, uint64_t SizeInBits, uint64_t AlignInBits,
+    uint64_t OffsetInBits, unsigned Flags, LLVMValueRef Ty);
+
+LLVMValueRef LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef D,
+                                          uint64_t SizeInBits,
+                                          uint64_t AlignInBits,
+                                          LLVMValueRef ElementType,
+                                          LLVMValueRef Subscripts);
+
+LLVMValueRef LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef D, LLVMValueRef Ty,
+                                        const char *Name, LLVMValueRef File,
+                                        unsigned Line, LLVMValueRef Context);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef D, int64_t Lo,
+                                              int64_t Count);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef D,
+                                           LLVMValueRef *Data, size_t Length);
+
+LLVMValueRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef D,
+                                               LLVMValueRef *Data,
+                                               size_t Length);
+
+LLVMValueRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Dref, int64_t *Addr,
+                                           size_t Length);
+
+LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(LLVMDIBuilderRef D,
+                                             LLVMValueRef Storage,
+                                             LLVMValueRef VarInfo,
+                                             LLVMValueRef Expr,
+                                             LLVMBasicBlockRef Block);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/bindings/go/llvm/IRBindings.cpp b/bindings/go/llvm/IRBindings.cpp
new file mode 100644 (file)
index 0000000..67a54a2
--- /dev/null
@@ -0,0 +1,47 @@
+//===- IRBindings.cpp - Additional bindings 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 defines additional C bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IRBindings.h"
+
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Function.h"
+
+using namespace llvm;
+
+void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA) {
+  Function *Func = unwrap<Function>(Fn);
+  const AttributeSet PAL = Func->getAttributes();
+  AttrBuilder B(PA);
+  const AttributeSet PALnew =
+    PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex,
+                      AttributeSet::get(Func->getContext(),
+                                        AttributeSet::FunctionIndex, B));
+  Func->setAttributes(PALnew);
+}
+
+uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn) {
+  Function *Func = unwrap<Function>(Fn);
+  const AttributeSet PAL = Func->getAttributes();
+  return PAL.Raw(AttributeSet::FunctionIndex);
+}
+
+void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA) {
+  Function *Func = unwrap<Function>(Fn);
+  const AttributeSet PAL = Func->getAttributes();
+  AttrBuilder B(PA);
+  const AttributeSet PALnew =
+    PAL.removeAttributes(Func->getContext(), AttributeSet::FunctionIndex,
+                         AttributeSet::get(Func->getContext(),
+                                           AttributeSet::FunctionIndex, B));
+  Func->setAttributes(PALnew);
+}
diff --git a/bindings/go/llvm/IRBindings.h b/bindings/go/llvm/IRBindings.h
new file mode 100644 (file)
index 0000000..cc63e4e
--- /dev/null
@@ -0,0 +1,37 @@
+//===- IRBindings.h - Additional bindings for IR ----------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the IR component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_IRBINDINGS_H
+
+#include "llvm-c/Core.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These functions duplicate the LLVM*FunctionAttr functions in the stable C
+// API. We cannot use the existing functions because they take 32-bit attribute
+// values, and the Go bindings expose all of the LLVM attributes, some of which
+// have values >= 1<<32.
+
+void LLVMAddFunctionAttr2(LLVMValueRef Fn, uint64_t PA);
+uint64_t LLVMGetFunctionAttr2(LLVMValueRef Fn);
+void LLVMRemoveFunctionAttr2(LLVMValueRef Fn, uint64_t PA);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/InstrumentationBindings.cpp b/bindings/go/llvm/InstrumentationBindings.cpp
new file mode 100644 (file)
index 0000000..b604abb
--- /dev/null
@@ -0,0 +1,42 @@
+//===- InstrumentationBindings.cpp - instrumentation bindings -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InstrumentationBindings.h"
+
+#include "llvm-c/Core.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Transforms/Instrumentation.h"
+
+using namespace llvm;
+
+void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createAddressSanitizerFunctionPass());
+}
+
+void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createAddressSanitizerModulePass());
+}
+
+void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createThreadSanitizerPass());
+}
+
+void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM) {
+  unwrap(PM)->add(createMemorySanitizerPass());
+}
+
+void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
+                                  const char *ABIListFile) {
+  unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFile));
+}
diff --git a/bindings/go/llvm/InstrumentationBindings.h b/bindings/go/llvm/InstrumentationBindings.h
new file mode 100644 (file)
index 0000000..e8dbd59
--- /dev/null
@@ -0,0 +1,38 @@
+//===- InstrumentationBindings.h - instrumentation bindings -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines C bindings for the Transforms/Instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_INSTRUMENTATIONBINDINGS_H
+
+#include "llvm-c/Core.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// FIXME: These bindings shouldn't be Go-specific and should eventually move to
+// a (somewhat) less stable collection of C APIs for use in creating bindings of
+// LLVM in other languages.
+
+void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM);
+void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM);
+void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM);
+void LLVMAddMemorySanitizerPass(LLVMPassManagerRef PM);
+void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
+                                  const char *ABIListFile);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/SupportBindings.cpp b/bindings/go/llvm/SupportBindings.cpp
new file mode 100644 (file)
index 0000000..df5f865
--- /dev/null
@@ -0,0 +1,27 @@
+//===- SupportBindings.cpp - Additional bindings for support --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the support component.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SupportBindings.h"
+
+#include "llvm/Support/DynamicLibrary.h"
+#include <stdlib.h>
+#include <string.h>
+
+void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) {
+  std::string ErrMsgStr;
+  if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) {
+    *ErrMsg = static_cast<char *>(malloc(ErrMsgStr.size() + 1));
+    memcpy(static_cast<void *>(*ErrMsg),
+           static_cast<const void *>(ErrMsgStr.c_str()), ErrMsgStr.size() + 1);
+  }
+}
diff --git a/bindings/go/llvm/SupportBindings.h b/bindings/go/llvm/SupportBindings.h
new file mode 100644 (file)
index 0000000..efcd667
--- /dev/null
@@ -0,0 +1,30 @@
+//===- SupportBindings.h - Additional bindings for Support ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines additional C bindings for the Support component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H
+#define LLVM_BINDINGS_GO_LLVM_SUPPORTBINDINGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This function duplicates the LLVMLoadLibraryPermanently function in the
+// stable C API and adds an extra ErrMsg parameter to retrieve the error
+// message.
+void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bindings/go/llvm/analysis.go b/bindings/go/llvm/analysis.go
new file mode 100644 (file)
index 0000000..7b0d8e3
--- /dev/null
@@ -0,0 +1,68 @@
+//===- analysis.go - Bindings for analysis --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the analysis component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Analysis.h" // If you are getting an error here read bindings/go/README.txt
+#include <stdlib.h>
+*/
+import "C"
+import "errors"
+
+type VerifierFailureAction C.LLVMVerifierFailureAction
+
+const (
+       // verifier will print to stderr and abort()
+       AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction
+       // verifier will print to stderr and return 1
+       PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction
+       // verifier will just return 1
+       ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction
+)
+
+// Verifies that a module is valid, taking the specified action if not.
+// Optionally returns a human-readable description of any invalid constructs.
+func VerifyModule(m Module, a VerifierFailureAction) error {
+       var cmsg *C.char
+       broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg)
+
+       // C++'s verifyModule means isModuleBroken, so it returns false if
+       // there are no errors
+       if broken != 0 {
+               err := errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+               return err
+       }
+       return nil
+}
+
+var verifyFunctionError = errors.New("Function is broken")
+
+// Verifies that a single function is valid, taking the specified action.
+// Useful for debugging.
+func VerifyFunction(f Value, a VerifierFailureAction) error {
+       broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a))
+
+       // C++'s verifyFunction means isFunctionBroken, so it returns false if
+       // there are no errors
+       if broken != 0 {
+               return verifyFunctionError
+       }
+       return nil
+}
+
+// Open up a ghostview window that displays the CFG of the current function.
+// Useful for debugging.
+func ViewFunctionCFG(f Value)     { C.LLVMViewFunctionCFG(f.C) }
+func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) }
diff --git a/bindings/go/llvm/bitreader.go b/bindings/go/llvm/bitreader.go
new file mode 100644 (file)
index 0000000..98112a9
--- /dev/null
@@ -0,0 +1,50 @@
+//===- bitreader.go - Bindings for bitreader ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the bitreader component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/BitReader.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+       "errors"
+       "unsafe"
+)
+
+// ParseBitcodeFile parses the LLVM IR (bitcode) in the file with the
+// specified name, and returns a new LLVM module.
+func ParseBitcodeFile(name string) (Module, error) {
+       var buf C.LLVMMemoryBufferRef
+       var errmsg *C.char
+       var cfilename *C.char = C.CString(name)
+       defer C.free(unsafe.Pointer(cfilename))
+       result := C.LLVMCreateMemoryBufferWithContentsOfFile(cfilename, &buf, &errmsg)
+       if result != 0 {
+               err := errors.New(C.GoString(errmsg))
+               C.free(unsafe.Pointer(errmsg))
+               return Module{}, err
+       }
+       defer C.LLVMDisposeMemoryBuffer(buf)
+
+       var m Module
+       if C.LLVMParseBitcode(buf, &m.C, &errmsg) == 0 {
+               return m, nil
+       }
+
+       err := errors.New(C.GoString(errmsg))
+       C.free(unsafe.Pointer(errmsg))
+       return Module{}, err
+}
diff --git a/bindings/go/llvm/bitwriter.go b/bindings/go/llvm/bitwriter.go
new file mode 100644 (file)
index 0000000..e03699c
--- /dev/null
@@ -0,0 +1,39 @@
+//===- bitwriter.go - Bindings for bitwriter ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the bitwriter component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/BitWriter.h"
+#include <stdlib.h>
+*/
+import "C"
+import "os"
+import "errors"
+
+var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file")
+
+func WriteBitcodeToFile(m Module, file *os.File) error {
+       fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0))
+       if fail != 0 {
+               return writeBitcodeToFileErr
+       }
+       return nil
+}
+
+func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer {
+       mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C)
+       return MemoryBuffer{mb}
+}
+
+// TODO(nsf): Figure out way how to make it work with io.Writer
diff --git a/bindings/go/llvm/dibuilder.go b/bindings/go/llvm/dibuilder.go
new file mode 100644 (file)
index 0000000..1d07e98
--- /dev/null
@@ -0,0 +1,492 @@
+//===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the DIBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "DIBuilderBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+       "debug/dwarf"
+       "unsafe"
+)
+
+type DwarfTag uint32
+
+const (
+       DW_TAG_lexical_block   DwarfTag = 0x0b
+       DW_TAG_compile_unit    DwarfTag = 0x11
+       DW_TAG_variable        DwarfTag = 0x34
+       DW_TAG_base_type       DwarfTag = 0x24
+       DW_TAG_pointer_type    DwarfTag = 0x0F
+       DW_TAG_structure_type  DwarfTag = 0x13
+       DW_TAG_subroutine_type DwarfTag = 0x15
+       DW_TAG_file_type       DwarfTag = 0x29
+       DW_TAG_subprogram      DwarfTag = 0x2E
+       DW_TAG_auto_variable   DwarfTag = 0x100
+       DW_TAG_arg_variable    DwarfTag = 0x101
+)
+
+const (
+       FlagPrivate = 1 << iota
+       FlagProtected
+       FlagFwdDecl
+       FlagAppleBlock
+       FlagBlockByrefStruct
+       FlagVirtual
+       FlagArtificial
+       FlagExplicit
+       FlagPrototyped
+       FlagObjcClassComplete
+       FlagObjectPointer
+       FlagVector
+       FlagStaticMember
+       FlagIndirectVariable
+)
+
+type DwarfLang uint32
+
+const (
+       // http://dwarfstd.org/ShowIssue.php?issue=101014.1&type=open
+       DW_LANG_Go DwarfLang = 0x0016
+)
+
+type DwarfTypeEncoding uint32
+
+const (
+       DW_ATE_address         DwarfTypeEncoding = 0x01
+       DW_ATE_boolean         DwarfTypeEncoding = 0x02
+       DW_ATE_complex_float   DwarfTypeEncoding = 0x03
+       DW_ATE_float           DwarfTypeEncoding = 0x04
+       DW_ATE_signed          DwarfTypeEncoding = 0x05
+       DW_ATE_signed_char     DwarfTypeEncoding = 0x06
+       DW_ATE_unsigned        DwarfTypeEncoding = 0x07
+       DW_ATE_unsigned_char   DwarfTypeEncoding = 0x08
+       DW_ATE_imaginary_float DwarfTypeEncoding = 0x09
+       DW_ATE_packed_decimal  DwarfTypeEncoding = 0x0a
+       DW_ATE_numeric_string  DwarfTypeEncoding = 0x0b
+       DW_ATE_edited          DwarfTypeEncoding = 0x0c
+       DW_ATE_signed_fixed    DwarfTypeEncoding = 0x0d
+       DW_ATE_unsigned_fixed  DwarfTypeEncoding = 0x0e
+       DW_ATE_decimal_float   DwarfTypeEncoding = 0x0f
+       DW_ATE_UTF             DwarfTypeEncoding = 0x10
+       DW_ATE_lo_user         DwarfTypeEncoding = 0x80
+       DW_ATE_hi_user         DwarfTypeEncoding = 0xff
+)
+
+// DIBuilder is a wrapper for the LLVM DIBuilder class.
+type DIBuilder struct {
+       ref C.LLVMDIBuilderRef
+       m   Module
+}
+
+// NewDIBuilder creates a new DIBuilder, associated with the given module.
+func NewDIBuilder(m Module) *DIBuilder {
+       d := C.LLVMNewDIBuilder(m.C)
+       return &DIBuilder{ref: d, m: m}
+}
+
+// Destroy destroys the DIBuilder.
+func (d *DIBuilder) Destroy() {
+       C.LLVMDIBuilderDestroy(d.ref)
+}
+
+// FInalize finalizes the debug information generated by the DIBuilder.
+func (d *DIBuilder) Finalize() {
+       C.LLVMDIBuilderFinalize(d.ref)
+}
+
+// DICompileUnit holds the values for creating compile unit debug metadata.
+type DICompileUnit struct {
+       Language       DwarfLang
+       File           string
+       Dir            string
+       Producer       string
+       Optimized      bool
+       Flags          string
+       RuntimeVersion int
+}
+
+// CreateCompileUnit creates compile unit debug metadata.
+func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Value {
+       file := C.CString(cu.File)
+       defer C.free(unsafe.Pointer(file))
+       dir := C.CString(cu.Dir)
+       defer C.free(unsafe.Pointer(dir))
+       producer := C.CString(cu.Producer)
+       defer C.free(unsafe.Pointer(producer))
+       flags := C.CString(cu.Flags)
+       defer C.free(unsafe.Pointer(flags))
+       result := C.LLVMDIBuilderCreateCompileUnit(
+               d.ref,
+               C.unsigned(cu.Language),
+               file, dir,
+               producer,
+               boolToCInt(cu.Optimized),
+               flags,
+               C.unsigned(cu.RuntimeVersion),
+       )
+       return Value{C: result}
+}
+
+// CreateCompileUnit creates file debug metadata.
+func (d *DIBuilder) CreateFile(filename, dir string) Value {
+       cfilename := C.CString(filename)
+       defer C.free(unsafe.Pointer(cfilename))
+       cdir := C.CString(dir)
+       defer C.free(unsafe.Pointer(cdir))
+       result := C.LLVMDIBuilderCreateFile(d.ref, cfilename, cdir)
+       return Value{C: result}
+}
+
+// DILexicalBlock holds the values for creating lexical block debug metadata.
+type DILexicalBlock struct {
+       File   Value
+       Line   int
+       Column int
+}
+
+// CreateCompileUnit creates lexical block debug metadata.
+func (d *DIBuilder) CreateLexicalBlock(diScope Value, b DILexicalBlock) Value {
+       result := C.LLVMDIBuilderCreateLexicalBlock(
+               d.ref,
+               diScope.C,
+               b.File.C,
+               C.unsigned(b.Line),
+               C.unsigned(b.Column),
+       )
+       return Value{C: result}
+}
+
+func (d *DIBuilder) CreateLexicalBlockFile(diScope Value, diFile Value, discriminator int) Value {
+       result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
+               C.unsigned(discriminator))
+       return Value{C: result}
+}
+
+// DIFunction holds the values for creating function debug metadata.
+type DIFunction struct {
+       Name         string
+       LinkageName  string
+       File         Value
+       Line         int
+       Type         Value
+       LocalToUnit  bool
+       IsDefinition bool
+       ScopeLine    int
+       Flags        int
+       Optimized    bool
+       Function     Value
+}
+
+// CreateCompileUnit creates function debug metadata.
+func (d *DIBuilder) CreateFunction(diScope Value, f DIFunction) Value {
+       name := C.CString(f.Name)
+       defer C.free(unsafe.Pointer(name))
+       linkageName := C.CString(f.LinkageName)
+       defer C.free(unsafe.Pointer(linkageName))
+       result := C.LLVMDIBuilderCreateFunction(
+               d.ref,
+               diScope.C,
+               name,
+               linkageName,
+               f.File.C,
+               C.unsigned(f.Line),
+               f.Type.C,
+               boolToCInt(f.LocalToUnit),
+               boolToCInt(f.IsDefinition),
+               C.unsigned(f.ScopeLine),
+               C.unsigned(f.Flags),
+               boolToCInt(f.Optimized),
+               f.Function.C,
+       )
+       return Value{C: result}
+}
+
+// DILocalVariable holds the values for creating local variable debug metadata.
+type DILocalVariable struct {
+       Tag            dwarf.Tag
+       Name           string
+       File           Value
+       Line           int
+       Type           Value
+       AlwaysPreserve bool
+       Flags          int
+
+       // ArgNo is the 1-based index of the argument in the function's
+       // parameter list if it is an argument, or 0 otherwise.
+       ArgNo int
+}
+
+// CreateLocalVariable creates local variable debug metadata.
+func (d *DIBuilder) CreateLocalVariable(scope Value, v DILocalVariable) Value {
+       name := C.CString(v.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreateLocalVariable(
+               d.ref,
+               C.unsigned(v.Tag),
+               scope.C,
+               name,
+               v.File.C,
+               C.unsigned(v.Line),
+               v.Type.C,
+               boolToCInt(v.AlwaysPreserve),
+               C.unsigned(v.Flags),
+               C.unsigned(v.ArgNo),
+       )
+       return Value{C: result}
+}
+
+// DIBasicType holds the values for creating basic type debug metadata.
+type DIBasicType struct {
+       Name        string
+       SizeInBits  uint64
+       AlignInBits uint64
+       Encoding    DwarfTypeEncoding
+}
+
+// CreateBasicType creates basic type debug metadata.
+func (d *DIBuilder) CreateBasicType(t DIBasicType) Value {
+       name := C.CString(t.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreateBasicType(
+               d.ref,
+               name,
+               C.uint64_t(t.SizeInBits),
+               C.uint64_t(t.AlignInBits),
+               C.unsigned(t.Encoding),
+       )
+       return Value{C: result}
+}
+
+// DIPointerType holds the values for creating pointer type debug metadata.
+type DIPointerType struct {
+       Pointee     Value
+       SizeInBits  uint64
+       AlignInBits uint64 // optional
+       Name        string // optional
+}
+
+// CreateBasicType creates basic type debug metadata.
+func (d *DIBuilder) CreatePointerType(t DIPointerType) Value {
+       name := C.CString(t.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreatePointerType(
+               d.ref,
+               t.Pointee.C,
+               C.uint64_t(t.SizeInBits),
+               C.uint64_t(t.AlignInBits),
+               name,
+       )
+       return Value{C: result}
+}
+
+// DISubroutineType holds the values for creating subroutine type debug metadata.
+type DISubroutineType struct {
+       // File is the file in which the subroutine type is defined.
+       File Value
+
+       // Parameters contains the subroutine parameter types,
+       // including the return type at the 0th index.
+       Parameters []Value
+}
+
+// CreateSubroutineType creates subroutine type debug metadata.
+func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Value {
+       params := d.getOrCreateTypeArray(t.Parameters)
+       result := C.LLVMDIBuilderCreateSubroutineType(d.ref, t.File.C, params.C)
+       return Value{C: result}
+}
+
+// DIStructType holds the values for creating struct type debug metadata.
+type DIStructType struct {
+       Name        string
+       File        Value
+       Line        int
+       SizeInBits  uint64
+       AlignInBits uint64
+       Flags       int
+       DerivedFrom Value
+       Elements    []Value
+}
+
+// CreateStructType creates struct type debug metadata.
+func (d *DIBuilder) CreateStructType(scope Value, t DIStructType) Value {
+       elements := d.getOrCreateArray(t.Elements)
+       name := C.CString(t.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreateStructType(
+               d.ref,
+               scope.C,
+               name,
+               t.File.C,
+               C.unsigned(t.Line),
+               C.uint64_t(t.SizeInBits),
+               C.uint64_t(t.AlignInBits),
+               C.unsigned(t.Flags),
+               t.DerivedFrom.C,
+               elements.C,
+       )
+       return Value{C: result}
+}
+
+// DIMemberType holds the values for creating member type debug metadata.
+type DIMemberType struct {
+       Name         string
+       File         Value
+       Line         int
+       SizeInBits   uint64
+       AlignInBits  uint64
+       OffsetInBits uint64
+       Flags        int
+       Type         Value
+}
+
+// CreateMemberType creates struct type debug metadata.
+func (d *DIBuilder) CreateMemberType(scope Value, t DIMemberType) Value {
+       name := C.CString(t.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreateMemberType(
+               d.ref,
+               scope.C,
+               name,
+               t.File.C,
+               C.unsigned(t.Line),
+               C.uint64_t(t.SizeInBits),
+               C.uint64_t(t.AlignInBits),
+               C.uint64_t(t.OffsetInBits),
+               C.unsigned(t.Flags),
+               t.Type.C,
+       )
+       return Value{C: result}
+}
+
+// DISubrange describes an integer value range.
+type DISubrange struct {
+       Lo    int64
+       Count int64
+}
+
+// DIArrayType holds the values for creating array type debug metadata.
+type DIArrayType struct {
+       SizeInBits  uint64
+       AlignInBits uint64
+       ElementType Value
+       Subscripts  []DISubrange
+}
+
+// CreateArrayType creates struct type debug metadata.
+func (d *DIBuilder) CreateArrayType(t DIArrayType) Value {
+       subscriptsSlice := make([]Value, len(t.Subscripts))
+       for i, s := range t.Subscripts {
+               subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
+       }
+       subscripts := d.getOrCreateArray(subscriptsSlice)
+       result := C.LLVMDIBuilderCreateArrayType(
+               d.ref,
+               C.uint64_t(t.SizeInBits),
+               C.uint64_t(t.AlignInBits),
+               t.ElementType.C,
+               subscripts.C,
+       )
+       return Value{C: result}
+}
+
+// DITypedef holds the values for creating typedef type debug metadata.
+type DITypedef struct {
+       Type    Value
+       Name    string
+       File    Value
+       Line    int
+       Context Value
+}
+
+// CreateTypedef creates typedef type debug metadata.
+func (d *DIBuilder) CreateTypedef(t DITypedef) Value {
+       name := C.CString(t.Name)
+       defer C.free(unsafe.Pointer(name))
+       result := C.LLVMDIBuilderCreateTypedef(
+               d.ref,
+               t.Type.C,
+               name,
+               t.File.C,
+               C.unsigned(t.Line),
+               t.Context.C,
+       )
+       return Value{C: result}
+}
+
+// getOrCreateSubrange gets a metadata node for the specified subrange,
+// creating if required.
+func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Value {
+       result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
+       return Value{C: result}
+}
+
+// getOrCreateArray gets a metadata node containing the specified values,
+// creating if required.
+func (d *DIBuilder) getOrCreateArray(values []Value) Value {
+       if len(values) == 0 {
+               return Value{}
+       }
+       var data *C.LLVMValueRef
+       length := len(values)
+       if length > 0 {
+               data = &values[0].C
+       }
+       result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
+       return Value{C: result}
+}
+
+// getOrCreateTypeArray gets a metadata node for a type array containing the
+// specified values, creating if required.
+func (d *DIBuilder) getOrCreateTypeArray(values []Value) Value {
+       if len(values) == 0 {
+               return Value{}
+       }
+       var data *C.LLVMValueRef
+       length := len(values)
+       if length > 0 {
+               data = &values[0].C
+       }
+       result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
+       return Value{C: result}
+}
+
+// CreateExpression creates a new descriptor for the specified
+// variable which has a complex address expression for its address.
+func (d *DIBuilder) CreateExpression(addr []int64) Value {
+       var data *C.int64_t
+       if len(addr) > 0 {
+               data = (*C.int64_t)(unsafe.Pointer(&addr[0]))
+       }
+       result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
+       return Value{C: result}
+}
+
+// InsertDeclareAtEnd inserts a call to llvm.dbg.declare at the end of the
+// specified basic block for the given value and associated debug metadata.
+func (d *DIBuilder) InsertDeclareAtEnd(v, diVarInfo, expr Value, bb BasicBlock) Value {
+       result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, bb.C)
+       return Value{C: result}
+}
+
+func boolToCInt(v bool) C.int {
+       if v {
+               return 1
+       }
+       return 0
+}
diff --git a/bindings/go/llvm/executionengine.go b/bindings/go/llvm/executionengine.go
new file mode 100644 (file)
index 0000000..26b7524
--- /dev/null
@@ -0,0 +1,163 @@
+//===- executionengine.go - Bindings for executionengine ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the executionengine component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/ExecutionEngine.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+func LinkInMCJIT()       { C.LLVMLinkInMCJIT() }
+func LinkInInterpreter() { C.LLVMLinkInInterpreter() }
+
+type GenericValue struct {
+       C C.LLVMGenericValueRef
+}
+type ExecutionEngine struct {
+       C C.LLVMExecutionEngineRef
+}
+type MCJITCompilerOptions struct {
+       OptLevel           uint
+       CodeModel          CodeModel
+       NoFramePointerElim bool
+       EnableFastISel     bool
+}
+
+// helpers
+func llvmGenericValueRefPtr(t *GenericValue) *C.LLVMGenericValueRef {
+       return (*C.LLVMGenericValueRef)(unsafe.Pointer(t))
+}
+
+//-------------------------------------------------------------------------
+// llvm.GenericValue
+//-------------------------------------------------------------------------
+
+func NewGenericValueFromInt(t Type, n uint64, signed bool) (g GenericValue) {
+       g.C = C.LLVMCreateGenericValueOfInt(t.C, C.ulonglong(n), boolToLLVMBool(signed))
+       return
+}
+func NewGenericValueFromPointer(p unsafe.Pointer) (g GenericValue) {
+       g.C = C.LLVMCreateGenericValueOfPointer(p)
+       return
+}
+func NewGenericValueFromFloat(t Type, n float64) (g GenericValue) {
+       g.C = C.LLVMCreateGenericValueOfFloat(t.C, C.double(n))
+       return
+}
+func (g GenericValue) IntWidth() int { return int(C.LLVMGenericValueIntWidth(g.C)) }
+func (g GenericValue) Int(signed bool) uint64 {
+       return uint64(C.LLVMGenericValueToInt(g.C, boolToLLVMBool(signed)))
+}
+func (g GenericValue) Float(t Type) float64 {
+       return float64(C.LLVMGenericValueToFloat(t.C, g.C))
+}
+func (g GenericValue) Pointer() unsafe.Pointer {
+       return C.LLVMGenericValueToPointer(g.C)
+}
+func (g GenericValue) Dispose() { C.LLVMDisposeGenericValue(g.C) }
+
+//-------------------------------------------------------------------------
+// llvm.ExecutionEngine
+//-------------------------------------------------------------------------
+
+func NewExecutionEngine(m Module) (ee ExecutionEngine, err error) {
+       var cmsg *C.char
+       fail := C.LLVMCreateExecutionEngineForModule(&ee.C, m.C, &cmsg)
+       if fail != 0 {
+               ee.C = nil
+               err = errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+       }
+       return
+}
+
+func NewInterpreter(m Module) (ee ExecutionEngine, err error) {
+       var cmsg *C.char
+       fail := C.LLVMCreateInterpreterForModule(&ee.C, m.C, &cmsg)
+       if fail != 0 {
+               ee.C = nil
+               err = errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+       }
+       return
+}
+
+func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) {
+       var cmsg *C.char
+       copts := C.struct_LLVMMCJITCompilerOptions{
+               OptLevel:           C.unsigned(options.OptLevel),
+               CodeModel:          C.LLVMCodeModel(options.CodeModel),
+               NoFramePointerElim: boolToLLVMBool(options.NoFramePointerElim),
+               EnableFastISel:     boolToLLVMBool(options.EnableFastISel),
+       }
+       fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &copts, C.size_t(unsafe.Sizeof(copts)), &cmsg)
+       if fail != 0 {
+               ee.C = nil
+               err = errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+       }
+       return
+}
+
+func (ee ExecutionEngine) Dispose()               { C.LLVMDisposeExecutionEngine(ee.C) }
+func (ee ExecutionEngine) RunStaticConstructors() { C.LLVMRunStaticConstructors(ee.C) }
+func (ee ExecutionEngine) RunStaticDestructors()  { C.LLVMRunStaticDestructors(ee.C) }
+
+func (ee ExecutionEngine) RunFunction(f Value, args []GenericValue) (g GenericValue) {
+       nargs := len(args)
+       var argptr *GenericValue
+       if nargs > 0 {
+               argptr = &args[0]
+       }
+       g.C = C.LLVMRunFunction(ee.C, f.C,
+               C.unsigned(nargs), llvmGenericValueRefPtr(argptr))
+       return
+}
+
+func (ee ExecutionEngine) FreeMachineCodeForFunction(f Value) {
+       C.LLVMFreeMachineCodeForFunction(ee.C, f.C)
+}
+func (ee ExecutionEngine) AddModule(m Module) { C.LLVMAddModule(ee.C, m.C) }
+
+func (ee ExecutionEngine) RemoveModule(m Module) {
+       var modtmp C.LLVMModuleRef
+       C.LLVMRemoveModule(ee.C, m.C, &modtmp, nil)
+}
+
+func (ee ExecutionEngine) FindFunction(name string) (f Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       C.LLVMFindFunction(ee.C, cname, &f.C)
+       return
+}
+
+func (ee ExecutionEngine) RecompileAndRelinkFunction(f Value) unsafe.Pointer {
+       return C.LLVMRecompileAndRelinkFunction(ee.C, f.C)
+}
+
+func (ee ExecutionEngine) TargetData() (td TargetData) {
+       td.C = C.LLVMGetExecutionEngineTargetData(ee.C)
+       return
+}
+
+func (ee ExecutionEngine) AddGlobalMapping(global Value, addr unsafe.Pointer) {
+       C.LLVMAddGlobalMapping(ee.C, global.C, addr)
+}
+
+func (ee ExecutionEngine) PointerToGlobal(global Value) unsafe.Pointer {
+       return C.LLVMGetPointerToGlobal(ee.C, global.C)
+}
diff --git a/bindings/go/llvm/executionengine_test.go b/bindings/go/llvm/executionengine_test.go
new file mode 100644 (file)
index 0000000..1a3fd45
--- /dev/null
@@ -0,0 +1,93 @@
+//===- executionengine_test.go - Tests for executionengine ----------------===//
+//
+//                     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 executionengine component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+       "testing"
+)
+
+func TestFactorial(t *testing.T) {
+       LinkInMCJIT()
+       InitializeNativeTarget()
+       InitializeNativeAsmPrinter()
+
+       mod := NewModule("fac_module")
+
+       fac_args := []Type{Int32Type()}
+       fac_type := FunctionType(Int32Type(), fac_args, false)
+       fac := AddFunction(mod, "fac", fac_type)
+       fac.SetFunctionCallConv(CCallConv)
+       n := fac.Param(0)
+
+       entry := AddBasicBlock(fac, "entry")
+       iftrue := AddBasicBlock(fac, "iftrue")
+       iffalse := AddBasicBlock(fac, "iffalse")
+       end := AddBasicBlock(fac, "end")
+
+       builder := NewBuilder()
+       defer builder.Dispose()
+
+       builder.SetInsertPointAtEnd(entry)
+       If := builder.CreateICmp(IntEQ, n, ConstInt(Int32Type(), 0, false), "cmptmp")
+       builder.CreateCondBr(If, iftrue, iffalse)
+
+       builder.SetInsertPointAtEnd(iftrue)
+       res_iftrue := ConstInt(Int32Type(), 1, false)
+       builder.CreateBr(end)
+
+       builder.SetInsertPointAtEnd(iffalse)
+       n_minus := builder.CreateSub(n, ConstInt(Int32Type(), 1, false), "subtmp")
+       call_fac_args := []Value{n_minus}
+       call_fac := builder.CreateCall(fac, call_fac_args, "calltmp")
+       res_iffalse := builder.CreateMul(n, call_fac, "multmp")
+       builder.CreateBr(end)
+
+       builder.SetInsertPointAtEnd(end)
+       res := builder.CreatePHI(Int32Type(), "result")
+       phi_vals := []Value{res_iftrue, res_iffalse}
+       phi_blocks := []BasicBlock{iftrue, iffalse}
+       res.AddIncoming(phi_vals, phi_blocks)
+       builder.CreateRet(res)
+
+       err := VerifyModule(mod, ReturnStatusAction)
+       if err != nil {
+               t.Errorf("Error verifying module: %s", err)
+               return
+       }
+
+       engine, err := NewMCJITCompiler(mod, MCJITCompilerOptions{OptLevel: 2})
+       if err != nil {
+               t.Errorf("Error creating JIT: %s", err)
+               return
+       }
+       defer engine.Dispose()
+
+       pass := NewPassManager()
+       defer pass.Dispose()
+
+       pass.Add(engine.TargetData())
+       pass.AddConstantPropagationPass()
+       pass.AddInstructionCombiningPass()
+       pass.AddPromoteMemoryToRegisterPass()
+       pass.AddGVNPass()
+       pass.AddCFGSimplificationPass()
+       pass.Run(mod)
+
+       exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)}
+       exec_res := engine.RunFunction(fac, exec_args)
+       var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
+       if exec_res.Int(false) != fac10 {
+               t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false))
+       }
+}
diff --git a/bindings/go/llvm/ir.go b/bindings/go/llvm/ir.go
new file mode 100644 (file)
index 0000000..520bd21
--- /dev/null
@@ -0,0 +1,1823 @@
+//===- ir.go - Bindings 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 defines bindings for the ir component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Core.h"
+#include "IRBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+type (
+       // We use these weird structs here because *Ref types are pointers and
+       // Go's spec says that a pointer cannot be used as a receiver base type.
+       Context struct {
+               C C.LLVMContextRef
+       }
+       Module struct {
+               C C.LLVMModuleRef
+       }
+       Type struct {
+               C C.LLVMTypeRef
+       }
+       Value struct {
+               C C.LLVMValueRef
+       }
+       BasicBlock struct {
+               C C.LLVMBasicBlockRef
+       }
+       Builder struct {
+               C C.LLVMBuilderRef
+       }
+       ModuleProvider struct {
+               C C.LLVMModuleProviderRef
+       }
+       MemoryBuffer struct {
+               C C.LLVMMemoryBufferRef
+       }
+       PassManager struct {
+               C C.LLVMPassManagerRef
+       }
+       Use struct {
+               C C.LLVMUseRef
+       }
+       Attribute        uint64
+       Opcode           C.LLVMOpcode
+       TypeKind         C.LLVMTypeKind
+       Linkage          C.LLVMLinkage
+       Visibility       C.LLVMVisibility
+       CallConv         C.LLVMCallConv
+       IntPredicate     C.LLVMIntPredicate
+       FloatPredicate   C.LLVMRealPredicate
+       LandingPadClause C.LLVMLandingPadClauseTy
+)
+
+func (c Context) IsNil() bool        { return c.C == nil }
+func (c Module) IsNil() bool         { return c.C == nil }
+func (c Type) IsNil() bool           { return c.C == nil }
+func (c Value) IsNil() bool          { return c.C == nil }
+func (c BasicBlock) IsNil() bool     { return c.C == nil }
+func (c Builder) IsNil() bool        { return c.C == nil }
+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 }
+
+// helpers
+func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef    { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) }
+func llvmValueRefPtr(t *Value) *C.LLVMValueRef { return (*C.LLVMValueRef)(unsafe.Pointer(t)) }
+func llvmBasicBlockRefPtr(t *BasicBlock) *C.LLVMBasicBlockRef {
+       return (*C.LLVMBasicBlockRef)(unsafe.Pointer(t))
+}
+func boolToLLVMBool(b bool) C.LLVMBool {
+       if b {
+               return C.LLVMBool(1)
+       }
+       return C.LLVMBool(0)
+}
+
+func llvmValueRefs(values []Value) (*C.LLVMValueRef, C.unsigned) {
+       var pt *C.LLVMValueRef
+       ptlen := C.unsigned(len(values))
+       if ptlen > 0 {
+               pt = llvmValueRefPtr(&values[0])
+       }
+       return pt, ptlen
+}
+
+//-------------------------------------------------------------------------
+// llvm.Attribute
+//-------------------------------------------------------------------------
+
+const (
+       NoneAttribute               Attribute = 0
+       ZExtAttribute               Attribute = C.LLVMZExtAttribute
+       SExtAttribute               Attribute = C.LLVMSExtAttribute
+       NoReturnAttribute           Attribute = C.LLVMNoReturnAttribute
+       InRegAttribute              Attribute = C.LLVMInRegAttribute
+       StructRetAttribute          Attribute = C.LLVMStructRetAttribute
+       NoUnwindAttribute           Attribute = C.LLVMNoUnwindAttribute
+       NoAliasAttribute            Attribute = C.LLVMNoAliasAttribute
+       ByValAttribute              Attribute = C.LLVMByValAttribute
+       NestAttribute               Attribute = C.LLVMNestAttribute
+       ReadNoneAttribute           Attribute = C.LLVMReadNoneAttribute
+       ReadOnlyAttribute           Attribute = C.LLVMReadOnlyAttribute
+       NoInlineAttribute           Attribute = C.LLVMNoInlineAttribute
+       AlwaysInlineAttribute       Attribute = C.LLVMAlwaysInlineAttribute
+       OptimizeForSizeAttribute    Attribute = C.LLVMOptimizeForSizeAttribute
+       StackProtectAttribute       Attribute = C.LLVMStackProtectAttribute
+       StackProtectReqAttribute    Attribute = C.LLVMStackProtectReqAttribute
+       Alignment                   Attribute = C.LLVMAlignment
+       NoCaptureAttribute          Attribute = C.LLVMNoCaptureAttribute
+       NoRedZoneAttribute          Attribute = C.LLVMNoRedZoneAttribute
+       NoImplicitFloatAttribute    Attribute = C.LLVMNoImplicitFloatAttribute
+       NakedAttribute              Attribute = C.LLVMNakedAttribute
+       InlineHintAttribute         Attribute = C.LLVMInlineHintAttribute
+       StackAlignment              Attribute = C.LLVMStackAlignment
+       ReturnsTwiceAttribute       Attribute = C.LLVMReturnsTwice
+       UWTableAttribute            Attribute = C.LLVMUWTable
+       NonLazyBindAttribute        Attribute = 1 << 31
+       SanitizeAddressAttribute    Attribute = 1 << 32
+       MinSizeAttribute            Attribute = 1 << 33
+       NoDuplicateAttribute        Attribute = 1 << 34
+       StackProtectStrongAttribute Attribute = 1 << 35
+       SanitizeThreadAttribute     Attribute = 1 << 36
+       SanitizeMemoryAttribute     Attribute = 1 << 37
+       NoBuiltinAttribute          Attribute = 1 << 38
+       ReturnedAttribute           Attribute = 1 << 39
+       ColdAttribute               Attribute = 1 << 40
+       BuiltinAttribute            Attribute = 1 << 41
+       OptimizeNoneAttribute       Attribute = 1 << 42
+       InAllocaAttribute           Attribute = 1 << 43
+       NonNullAttribute            Attribute = 1 << 44
+       JumpTableAttribute          Attribute = 1 << 45
+)
+
+//-------------------------------------------------------------------------
+// llvm.Opcode
+//-------------------------------------------------------------------------
+
+const (
+       Ret         Opcode = C.LLVMRet
+       Br          Opcode = C.LLVMBr
+       Switch      Opcode = C.LLVMSwitch
+       IndirectBr  Opcode = C.LLVMIndirectBr
+       Invoke      Opcode = C.LLVMInvoke
+       Unreachable Opcode = C.LLVMUnreachable
+
+       // Standard Binary Operators
+       Add  Opcode = C.LLVMAdd
+       FAdd Opcode = C.LLVMFAdd
+       Sub  Opcode = C.LLVMSub
+       FSub Opcode = C.LLVMFSub
+       Mul  Opcode = C.LLVMMul
+       FMul Opcode = C.LLVMFMul
+       UDiv Opcode = C.LLVMUDiv
+       SDiv Opcode = C.LLVMSDiv
+       FDiv Opcode = C.LLVMFDiv
+       URem Opcode = C.LLVMURem
+       SRem Opcode = C.LLVMSRem
+       FRem Opcode = C.LLVMFRem
+
+       // Logical Operators
+       Shl  Opcode = C.LLVMShl
+       LShr Opcode = C.LLVMLShr
+       AShr Opcode = C.LLVMAShr
+       And  Opcode = C.LLVMAnd
+       Or   Opcode = C.LLVMOr
+       Xor  Opcode = C.LLVMXor
+
+       // Memory Operators
+       Alloca        Opcode = C.LLVMAlloca
+       Load          Opcode = C.LLVMLoad
+       Store         Opcode = C.LLVMStore
+       GetElementPtr Opcode = C.LLVMGetElementPtr
+
+       // Cast Operators
+       Trunc    Opcode = C.LLVMTrunc
+       ZExt     Opcode = C.LLVMZExt
+       SExt     Opcode = C.LLVMSExt
+       FPToUI   Opcode = C.LLVMFPToUI
+       FPToSI   Opcode = C.LLVMFPToSI
+       UIToFP   Opcode = C.LLVMUIToFP
+       SIToFP   Opcode = C.LLVMSIToFP
+       FPTrunc  Opcode = C.LLVMFPTrunc
+       FPExt    Opcode = C.LLVMFPExt
+       PtrToInt Opcode = C.LLVMPtrToInt
+       IntToPtr Opcode = C.LLVMIntToPtr
+       BitCast  Opcode = C.LLVMBitCast
+
+       // Other Operators
+       ICmp   Opcode = C.LLVMICmp
+       FCmp   Opcode = C.LLVMFCmp
+       PHI    Opcode = C.LLVMPHI
+       Call   Opcode = C.LLVMCall
+       Select Opcode = C.LLVMSelect
+       // UserOp1
+       // UserOp2
+       VAArg          Opcode = C.LLVMVAArg
+       ExtractElement Opcode = C.LLVMExtractElement
+       InsertElement  Opcode = C.LLVMInsertElement
+       ShuffleVector  Opcode = C.LLVMShuffleVector
+       ExtractValue   Opcode = C.LLVMExtractValue
+       InsertValue    Opcode = C.LLVMInsertValue
+)
+
+//-------------------------------------------------------------------------
+// llvm.TypeKind
+//-------------------------------------------------------------------------
+
+const (
+       VoidTypeKind      TypeKind = C.LLVMVoidTypeKind
+       FloatTypeKind     TypeKind = C.LLVMFloatTypeKind
+       DoubleTypeKind    TypeKind = C.LLVMDoubleTypeKind
+       X86_FP80TypeKind  TypeKind = C.LLVMX86_FP80TypeKind
+       FP128TypeKind     TypeKind = C.LLVMFP128TypeKind
+       PPC_FP128TypeKind TypeKind = C.LLVMPPC_FP128TypeKind
+       LabelTypeKind     TypeKind = C.LLVMLabelTypeKind
+       IntegerTypeKind   TypeKind = C.LLVMIntegerTypeKind
+       FunctionTypeKind  TypeKind = C.LLVMFunctionTypeKind
+       StructTypeKind    TypeKind = C.LLVMStructTypeKind
+       ArrayTypeKind     TypeKind = C.LLVMArrayTypeKind
+       PointerTypeKind   TypeKind = C.LLVMPointerTypeKind
+       VectorTypeKind    TypeKind = C.LLVMVectorTypeKind
+       MetadataTypeKind  TypeKind = C.LLVMMetadataTypeKind
+)
+
+//-------------------------------------------------------------------------
+// llvm.Linkage
+//-------------------------------------------------------------------------
+
+const (
+       ExternalLinkage            Linkage = C.LLVMExternalLinkage
+       AvailableExternallyLinkage Linkage = C.LLVMAvailableExternallyLinkage
+       LinkOnceAnyLinkage         Linkage = C.LLVMLinkOnceAnyLinkage
+       LinkOnceODRLinkage         Linkage = C.LLVMLinkOnceODRLinkage
+       WeakAnyLinkage             Linkage = C.LLVMWeakAnyLinkage
+       WeakODRLinkage             Linkage = C.LLVMWeakODRLinkage
+       AppendingLinkage           Linkage = C.LLVMAppendingLinkage
+       InternalLinkage            Linkage = C.LLVMInternalLinkage
+       PrivateLinkage             Linkage = C.LLVMPrivateLinkage
+       ExternalWeakLinkage        Linkage = C.LLVMExternalWeakLinkage
+       CommonLinkage              Linkage = C.LLVMCommonLinkage
+)
+
+//-------------------------------------------------------------------------
+// llvm.Visibility
+//-------------------------------------------------------------------------
+
+const (
+       DefaultVisibility   Visibility = C.LLVMDefaultVisibility
+       HiddenVisibility    Visibility = C.LLVMHiddenVisibility
+       ProtectedVisibility Visibility = C.LLVMProtectedVisibility
+)
+
+//-------------------------------------------------------------------------
+// llvm.CallConv
+//-------------------------------------------------------------------------
+
+const (
+       CCallConv           CallConv = C.LLVMCCallConv
+       FastCallConv        CallConv = C.LLVMFastCallConv
+       ColdCallConv        CallConv = C.LLVMColdCallConv
+       X86StdcallCallConv  CallConv = C.LLVMX86StdcallCallConv
+       X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv
+)
+
+//-------------------------------------------------------------------------
+// llvm.IntPredicate
+//-------------------------------------------------------------------------
+
+const (
+       IntEQ  IntPredicate = C.LLVMIntEQ
+       IntNE  IntPredicate = C.LLVMIntNE
+       IntUGT IntPredicate = C.LLVMIntUGT
+       IntUGE IntPredicate = C.LLVMIntUGE
+       IntULT IntPredicate = C.LLVMIntULT
+       IntULE IntPredicate = C.LLVMIntULE
+       IntSGT IntPredicate = C.LLVMIntSGT
+       IntSGE IntPredicate = C.LLVMIntSGE
+       IntSLT IntPredicate = C.LLVMIntSLT
+       IntSLE IntPredicate = C.LLVMIntSLE
+)
+
+//-------------------------------------------------------------------------
+// llvm.FloatPredicate
+//-------------------------------------------------------------------------
+
+const (
+       FloatPredicateFalse FloatPredicate = C.LLVMRealPredicateFalse
+       FloatOEQ            FloatPredicate = C.LLVMRealOEQ
+       FloatOGT            FloatPredicate = C.LLVMRealOGT
+       FloatOGE            FloatPredicate = C.LLVMRealOGE
+       FloatOLT            FloatPredicate = C.LLVMRealOLT
+       FloatOLE            FloatPredicate = C.LLVMRealOLE
+       FloatONE            FloatPredicate = C.LLVMRealONE
+       FloatORD            FloatPredicate = C.LLVMRealORD
+       FloatUNO            FloatPredicate = C.LLVMRealUNO
+       FloatUEQ            FloatPredicate = C.LLVMRealUEQ
+       FloatUGT            FloatPredicate = C.LLVMRealUGT
+       FloatUGE            FloatPredicate = C.LLVMRealUGE
+       FloatULT            FloatPredicate = C.LLVMRealULT
+       FloatULE            FloatPredicate = C.LLVMRealULE
+       FloatUNE            FloatPredicate = C.LLVMRealUNE
+       FloatPredicateTrue  FloatPredicate = C.LLVMRealPredicateTrue
+)
+
+//-------------------------------------------------------------------------
+// llvm.LandingPadClause
+//-------------------------------------------------------------------------
+
+const (
+       LandingPadCatch  LandingPadClause = C.LLVMLandingPadCatch
+       LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter
+)
+
+//-------------------------------------------------------------------------
+// llvm.Context
+//-------------------------------------------------------------------------
+
+func NewContext() Context    { return Context{C.LLVMContextCreate()} }
+func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} }
+func (c Context) Dispose()   { C.LLVMContextDispose(c.C) }
+
+func (c Context) MDKindID(name string) (id int) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       id = int(C.LLVMGetMDKindIDInContext(c.C, cname, C.unsigned(len(name))))
+       return
+}
+
+func MDKindID(name string) (id int) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name))))
+       return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Module
+//-------------------------------------------------------------------------
+
+// Create and destroy modules.
+// See llvm::Module::Module.
+func NewModule(name string) (m Module) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       m.C = C.LLVMModuleCreateWithName(cname)
+       return
+}
+
+func (c Context) NewModule(name string) (m Module) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       m.C = C.LLVMModuleCreateWithNameInContext(cname, c.C)
+       return
+}
+
+// See llvm::Module::~Module
+func (m Module) Dispose() { C.LLVMDisposeModule(m.C) }
+
+// Data layout. See Module::getDataLayout.
+func (m Module) DataLayout() string {
+       clayout := C.LLVMGetDataLayout(m.C)
+       return C.GoString(clayout)
+}
+
+func (m Module) SetDataLayout(layout string) {
+       clayout := C.CString(layout)
+       defer C.free(unsafe.Pointer(clayout))
+       C.LLVMSetDataLayout(m.C, clayout)
+}
+
+// Target triple. See Module::getTargetTriple.
+func (m Module) Target() string {
+       ctarget := C.LLVMGetTarget(m.C)
+       return C.GoString(ctarget)
+}
+func (m Module) SetTarget(target string) {
+       ctarget := C.CString(target)
+       defer C.free(unsafe.Pointer(ctarget))
+       C.LLVMSetTarget(m.C, ctarget)
+}
+
+func (m Module) GetTypeByName(name string) (t Type) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       t.C = C.LLVMGetTypeByName(m.C, cname)
+       return
+}
+
+// See Module::dump.
+func (m Module) Dump() {
+       C.LLVMDumpModule(m.C)
+}
+
+func (m Module) String() string {
+       cir := C.LLVMPrintModuleToString(m.C)
+       defer C.free(unsafe.Pointer(cir))
+       ir := C.GoString(cir)
+       return ir
+}
+
+// See Module::setModuleInlineAsm.
+func (m Module) SetInlineAsm(asm string) {
+       casm := C.CString(asm)
+       defer C.free(unsafe.Pointer(casm))
+       C.LLVMSetModuleInlineAsm(m.C, casm)
+}
+
+func (m Module) AddNamedMetadataOperand(name string, operand Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       C.LLVMAddNamedMetadataOperand(m.C, cname, operand.C)
+}
+
+func (m Module) Context() (c Context) {
+       c.C = C.LLVMGetModuleContext(m.C)
+       return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Type
+//-------------------------------------------------------------------------
+
+// LLVM types conform to the following hierarchy:
+//
+//   types:
+//     integer type
+//     real type
+//     function type
+//     sequence types:
+//       array type
+//       pointer type
+//       vector type
+//     void type
+//     label type
+//     opaque type
+
+// See llvm::LLVMTypeKind::getTypeID.
+func (t Type) TypeKind() TypeKind { return TypeKind(C.LLVMGetTypeKind(t.C)) }
+
+// See llvm::LLVMType::getContext.
+func (t Type) Context() (c Context) {
+       c.C = C.LLVMGetTypeContext(t.C)
+       return
+}
+
+// Operations on integer types
+func (c Context) Int1Type() (t Type)  { t.C = C.LLVMInt1TypeInContext(c.C); return }
+func (c Context) Int8Type() (t Type)  { t.C = C.LLVMInt8TypeInContext(c.C); return }
+func (c Context) Int16Type() (t Type) { t.C = C.LLVMInt16TypeInContext(c.C); return }
+func (c Context) Int32Type() (t Type) { t.C = C.LLVMInt32TypeInContext(c.C); return }
+func (c Context) Int64Type() (t Type) { t.C = C.LLVMInt64TypeInContext(c.C); return }
+func (c Context) IntType(numbits int) (t Type) {
+       t.C = C.LLVMIntTypeInContext(c.C, C.unsigned(numbits))
+       return
+}
+
+func Int1Type() (t Type)  { t.C = C.LLVMInt1Type(); return }
+func Int8Type() (t Type)  { t.C = C.LLVMInt8Type(); return }
+func Int16Type() (t Type) { t.C = C.LLVMInt16Type(); return }
+func Int32Type() (t Type) { t.C = C.LLVMInt32Type(); return }
+func Int64Type() (t Type) { t.C = C.LLVMInt64Type(); return }
+
+func IntType(numbits int) (t Type) {
+       t.C = C.LLVMIntType(C.unsigned(numbits))
+       return
+}
+
+func (t Type) IntTypeWidth() int {
+       return int(C.LLVMGetIntTypeWidth(t.C))
+}
+
+// Operations on real types
+func (c Context) FloatType() (t Type)    { t.C = C.LLVMFloatTypeInContext(c.C); return }
+func (c Context) DoubleType() (t Type)   { t.C = C.LLVMDoubleTypeInContext(c.C); return }
+func (c Context) X86FP80Type() (t Type)  { t.C = C.LLVMX86FP80TypeInContext(c.C); return }
+func (c Context) FP128Type() (t Type)    { t.C = C.LLVMFP128TypeInContext(c.C); return }
+func (c Context) PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128TypeInContext(c.C); return }
+
+func FloatType() (t Type)    { t.C = C.LLVMFloatType(); return }
+func DoubleType() (t Type)   { t.C = C.LLVMDoubleType(); return }
+func X86FP80Type() (t Type)  { t.C = C.LLVMX86FP80Type(); return }
+func FP128Type() (t Type)    { t.C = C.LLVMFP128Type(); return }
+func PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128Type(); return }
+
+// Operations on function types
+func FunctionType(returnType Type, paramTypes []Type, isVarArg bool) (t Type) {
+       var pt *C.LLVMTypeRef
+       var ptlen C.unsigned
+       if len(paramTypes) > 0 {
+               pt = llvmTypeRefPtr(&paramTypes[0])
+               ptlen = C.unsigned(len(paramTypes))
+       }
+       t.C = C.LLVMFunctionType(returnType.C,
+               pt,
+               ptlen,
+               boolToLLVMBool(isVarArg))
+       return
+}
+
+func (t Type) IsFunctionVarArg() bool { return C.LLVMIsFunctionVarArg(t.C) != 0 }
+func (t Type) ReturnType() (rt Type)  { rt.C = C.LLVMGetReturnType(t.C); return }
+func (t Type) ParamTypesCount() int   { return int(C.LLVMCountParamTypes(t.C)) }
+func (t Type) ParamTypes() []Type {
+       count := t.ParamTypesCount()
+       if count > 0 {
+               out := make([]Type, count)
+               C.LLVMGetParamTypes(t.C, llvmTypeRefPtr(&out[0]))
+               return out
+       }
+       return nil
+}
+
+// Operations on struct types
+func (c Context) StructType(elementTypes []Type, packed bool) (t Type) {
+       var pt *C.LLVMTypeRef
+       var ptlen C.unsigned
+       if len(elementTypes) > 0 {
+               pt = llvmTypeRefPtr(&elementTypes[0])
+               ptlen = C.unsigned(len(elementTypes))
+       }
+       t.C = C.LLVMStructTypeInContext(c.C,
+               pt,
+               ptlen,
+               boolToLLVMBool(packed))
+       return
+}
+
+func StructType(elementTypes []Type, packed bool) (t Type) {
+       var pt *C.LLVMTypeRef
+       var ptlen C.unsigned
+       if len(elementTypes) > 0 {
+               pt = llvmTypeRefPtr(&elementTypes[0])
+               ptlen = C.unsigned(len(elementTypes))
+       }
+       t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed))
+       return
+}
+
+func (c Context) StructCreateNamed(name string) (t Type) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       t.C = C.LLVMStructCreateNamed(c.C, cname)
+       return
+}
+
+func (t Type) StructName() string {
+       return C.GoString(C.LLVMGetStructName(t.C))
+}
+
+func (t Type) StructSetBody(elementTypes []Type, packed bool) {
+       var pt *C.LLVMTypeRef
+       var ptlen C.unsigned
+       if len(elementTypes) > 0 {
+               pt = llvmTypeRefPtr(&elementTypes[0])
+               ptlen = C.unsigned(len(elementTypes))
+       }
+       C.LLVMStructSetBody(t.C, pt, ptlen, boolToLLVMBool(packed))
+}
+
+func (t Type) IsStructPacked() bool         { return C.LLVMIsPackedStruct(t.C) != 0 }
+func (t Type) StructElementTypesCount() int { return int(C.LLVMCountStructElementTypes(t.C)) }
+func (t Type) StructElementTypes() []Type {
+       out := make([]Type, t.StructElementTypesCount())
+       if len(out) > 0 {
+               C.LLVMGetStructElementTypes(t.C, llvmTypeRefPtr(&out[0]))
+       }
+       return out
+}
+
+// Operations on array, pointer, and vector types (sequence types)
+func ArrayType(elementType Type, elementCount int) (t Type) {
+       t.C = C.LLVMArrayType(elementType.C, C.unsigned(elementCount))
+       return
+}
+func PointerType(elementType Type, addressSpace int) (t Type) {
+       t.C = C.LLVMPointerType(elementType.C, C.unsigned(addressSpace))
+       return
+}
+func VectorType(elementType Type, elementCount int) (t Type) {
+       t.C = C.LLVMVectorType(elementType.C, C.unsigned(elementCount))
+       return
+}
+
+func (t Type) ElementType() (rt Type)   { rt.C = C.LLVMGetElementType(t.C); return }
+func (t Type) ArrayLength() int         { return int(C.LLVMGetArrayLength(t.C)) }
+func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) }
+func (t Type) VectorSize() int          { return int(C.LLVMGetVectorSize(t.C)) }
+
+// Operations on other types
+func (c Context) VoidType() (t Type)  { t.C = C.LLVMVoidTypeInContext(c.C); return }
+func (c Context) LabelType() (t Type) { t.C = C.LLVMLabelTypeInContext(c.C); return }
+
+func VoidType() (t Type)  { t.C = C.LLVMVoidType(); return }
+func LabelType() (t Type) { t.C = C.LLVMLabelType(); return }
+
+//-------------------------------------------------------------------------
+// llvm.Value
+//-------------------------------------------------------------------------
+
+// Operations on all values
+func (v Value) Type() (t Type) { t.C = C.LLVMTypeOf(v.C); return }
+func (v Value) Name() string   { return C.GoString(C.LLVMGetValueName(v.C)) }
+func (v Value) SetName(name string) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       C.LLVMSetValueName(v.C, cname)
+}
+func (v Value) Dump()                       { C.LLVMDumpValue(v.C) }
+func (v Value) ReplaceAllUsesWith(nv Value) { C.LLVMReplaceAllUsesWith(v.C, nv.C) }
+func (v Value) HasMetadata() bool           { return C.LLVMHasMetadata(v.C) != 0 }
+func (v Value) Metadata(kind int) (rv Value) {
+       rv.C = C.LLVMGetMetadata(v.C, C.unsigned(kind))
+       return
+}
+func (v Value) SetMetadata(kind int, node Value) {
+       C.LLVMSetMetadata(v.C, C.unsigned(kind), node.C)
+}
+
+// Conversion functions.
+// Return the input value if it is an instance of the specified class, otherwise NULL.
+// See llvm::dyn_cast_or_null<>.
+func (v Value) IsAArgument() (rv Value)   { rv.C = C.LLVMIsAArgument(v.C); return }
+func (v Value) IsABasicBlock() (rv Value) { rv.C = C.LLVMIsABasicBlock(v.C); return }
+func (v Value) IsAInlineAsm() (rv Value)  { rv.C = C.LLVMIsAInlineAsm(v.C); return }
+func (v Value) IsAUser() (rv Value)       { rv.C = C.LLVMIsAUser(v.C); return }
+func (v Value) IsAConstant() (rv Value)   { rv.C = C.LLVMIsAConstant(v.C); return }
+func (v Value) IsAConstantAggregateZero() (rv Value) {
+       rv.C = C.LLVMIsAConstantAggregateZero(v.C)
+       return
+}
+func (v Value) IsAConstantArray() (rv Value)       { rv.C = C.LLVMIsAConstantArray(v.C); return }
+func (v Value) IsAConstantExpr() (rv Value)        { rv.C = C.LLVMIsAConstantExpr(v.C); return }
+func (v Value) IsAConstantFP() (rv Value)          { rv.C = C.LLVMIsAConstantFP(v.C); return }
+func (v Value) IsAConstantInt() (rv Value)         { rv.C = C.LLVMIsAConstantInt(v.C); return }
+func (v Value) IsAConstantPointerNull() (rv Value) { rv.C = C.LLVMIsAConstantPointerNull(v.C); return }
+func (v Value) IsAConstantStruct() (rv Value)      { rv.C = C.LLVMIsAConstantStruct(v.C); return }
+func (v Value) IsAConstantVector() (rv Value)      { rv.C = C.LLVMIsAConstantVector(v.C); return }
+func (v Value) IsAGlobalValue() (rv Value)         { rv.C = C.LLVMIsAGlobalValue(v.C); return }
+func (v Value) IsAFunction() (rv Value)            { rv.C = C.LLVMIsAFunction(v.C); return }
+func (v Value) IsAGlobalAlias() (rv Value)         { rv.C = C.LLVMIsAGlobalAlias(v.C); return }
+func (v Value) IsAGlobalVariable() (rv Value)      { rv.C = C.LLVMIsAGlobalVariable(v.C); return }
+func (v Value) IsAUndefValue() (rv Value)          { rv.C = C.LLVMIsAUndefValue(v.C); return }
+func (v Value) IsAInstruction() (rv Value)         { rv.C = C.LLVMIsAInstruction(v.C); return }
+func (v Value) IsABinaryOperator() (rv Value)      { rv.C = C.LLVMIsABinaryOperator(v.C); return }
+func (v Value) IsACallInst() (rv Value)            { rv.C = C.LLVMIsACallInst(v.C); return }
+func (v Value) IsAIntrinsicInst() (rv Value)       { rv.C = C.LLVMIsAIntrinsicInst(v.C); return }
+func (v Value) IsADbgInfoIntrinsic() (rv Value)    { rv.C = C.LLVMIsADbgInfoIntrinsic(v.C); return }
+func (v Value) IsADbgDeclareInst() (rv Value)      { rv.C = C.LLVMIsADbgDeclareInst(v.C); return }
+func (v Value) IsAMemIntrinsic() (rv Value)        { rv.C = C.LLVMIsAMemIntrinsic(v.C); return }
+func (v Value) IsAMemCpyInst() (rv Value)          { rv.C = C.LLVMIsAMemCpyInst(v.C); return }
+func (v Value) IsAMemMoveInst() (rv Value)         { rv.C = C.LLVMIsAMemMoveInst(v.C); return }
+func (v Value) IsAMemSetInst() (rv Value)          { rv.C = C.LLVMIsAMemSetInst(v.C); return }
+func (v Value) IsACmpInst() (rv Value)             { rv.C = C.LLVMIsACmpInst(v.C); return }
+func (v Value) IsAFCmpInst() (rv Value)            { rv.C = C.LLVMIsAFCmpInst(v.C); return }
+func (v Value) IsAICmpInst() (rv Value)            { rv.C = C.LLVMIsAICmpInst(v.C); return }
+func (v Value) IsAExtractElementInst() (rv Value)  { rv.C = C.LLVMIsAExtractElementInst(v.C); return }
+func (v Value) IsAGetElementPtrInst() (rv Value)   { rv.C = C.LLVMIsAGetElementPtrInst(v.C); return }
+func (v Value) IsAInsertElementInst() (rv Value)   { rv.C = C.LLVMIsAInsertElementInst(v.C); return }
+func (v Value) IsAInsertValueInst() (rv Value)     { rv.C = C.LLVMIsAInsertValueInst(v.C); return }
+func (v Value) IsAPHINode() (rv Value)             { rv.C = C.LLVMIsAPHINode(v.C); return }
+func (v Value) IsASelectInst() (rv Value)          { rv.C = C.LLVMIsASelectInst(v.C); return }
+func (v Value) IsAShuffleVectorInst() (rv Value)   { rv.C = C.LLVMIsAShuffleVectorInst(v.C); return }
+func (v Value) IsAStoreInst() (rv Value)           { rv.C = C.LLVMIsAStoreInst(v.C); return }
+func (v Value) IsATerminatorInst() (rv Value)      { rv.C = C.LLVMIsATerminatorInst(v.C); return }
+func (v Value) IsABranchInst() (rv Value)          { rv.C = C.LLVMIsABranchInst(v.C); return }
+func (v Value) IsAInvokeInst() (rv Value)          { rv.C = C.LLVMIsAInvokeInst(v.C); return }
+func (v Value) IsAReturnInst() (rv Value)          { rv.C = C.LLVMIsAReturnInst(v.C); return }
+func (v Value) IsASwitchInst() (rv Value)          { rv.C = C.LLVMIsASwitchInst(v.C); return }
+func (v Value) IsAUnreachableInst() (rv Value)     { rv.C = C.LLVMIsAUnreachableInst(v.C); return }
+func (v Value) IsAUnaryInstruction() (rv Value)    { rv.C = C.LLVMIsAUnaryInstruction(v.C); return }
+func (v Value) IsAAllocaInst() (rv Value)          { rv.C = C.LLVMIsAAllocaInst(v.C); return }
+func (v Value) IsACastInst() (rv Value)            { rv.C = C.LLVMIsACastInst(v.C); return }
+func (v Value) IsABitCastInst() (rv Value)         { rv.C = C.LLVMIsABitCastInst(v.C); return }
+func (v Value) IsAFPExtInst() (rv Value)           { rv.C = C.LLVMIsAFPExtInst(v.C); return }
+func (v Value) IsAFPToSIInst() (rv Value)          { rv.C = C.LLVMIsAFPToSIInst(v.C); return }
+func (v Value) IsAFPToUIInst() (rv Value)          { rv.C = C.LLVMIsAFPToUIInst(v.C); return }
+func (v Value) IsAFPTruncInst() (rv Value)         { rv.C = C.LLVMIsAFPTruncInst(v.C); return }
+func (v Value) IsAIntToPtrInst() (rv Value)        { rv.C = C.LLVMIsAIntToPtrInst(v.C); return }
+func (v Value) IsAPtrToIntInst() (rv Value)        { rv.C = C.LLVMIsAPtrToIntInst(v.C); return }
+func (v Value) IsASExtInst() (rv Value)            { rv.C = C.LLVMIsASExtInst(v.C); return }
+func (v Value) IsASIToFPInst() (rv Value)          { rv.C = C.LLVMIsASIToFPInst(v.C); return }
+func (v Value) IsATruncInst() (rv Value)           { rv.C = C.LLVMIsATruncInst(v.C); return }
+func (v Value) IsAUIToFPInst() (rv Value)          { rv.C = C.LLVMIsAUIToFPInst(v.C); return }
+func (v Value) IsAZExtInst() (rv Value)            { rv.C = C.LLVMIsAZExtInst(v.C); return }
+func (v Value) IsAExtractValueInst() (rv Value)    { rv.C = C.LLVMIsAExtractValueInst(v.C); return }
+func (v Value) IsALoadInst() (rv Value)            { rv.C = C.LLVMIsALoadInst(v.C); return }
+func (v Value) IsAVAArgInst() (rv Value)           { rv.C = C.LLVMIsAVAArgInst(v.C); return }
+
+// Operations on Uses
+func (v Value) FirstUse() (u Use)  { u.C = C.LLVMGetFirstUse(v.C); return }
+func (u Use) NextUse() (ru Use)    { ru.C = C.LLVMGetNextUse(u.C); return }
+func (u Use) User() (v Value)      { v.C = C.LLVMGetUser(u.C); return }
+func (u Use) UsedValue() (v Value) { v.C = C.LLVMGetUsedValue(u.C); return }
+
+// Operations on Users
+func (v Value) Operand(i int) (rv Value)   { rv.C = C.LLVMGetOperand(v.C, C.unsigned(i)); return }
+func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) }
+func (v Value) OperandsCount() int         { return int(C.LLVMGetNumOperands(v.C)) }
+
+// Operations on constants of any type
+func ConstNull(t Type) (v Value)        { v.C = C.LLVMConstNull(t.C); return }
+func ConstAllOnes(t Type) (v Value)     { v.C = C.LLVMConstAllOnes(t.C); return }
+func Undef(t Type) (v Value)            { v.C = C.LLVMGetUndef(t.C); return }
+func (v Value) IsConstant() bool        { return C.LLVMIsConstant(v.C) != 0 }
+func (v Value) IsNull() bool            { return C.LLVMIsNull(v.C) != 0 }
+func (v Value) IsUndef() bool           { return C.LLVMIsUndef(v.C) != 0 }
+func ConstPointerNull(t Type) (v Value) { v.C = C.LLVMConstPointerNull(t.C); return }
+
+// Operations on metadata
+func (c Context) MDString(str string) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMMDStringInContext(c.C, cstr, C.unsigned(len(str)))
+       return
+}
+func MDString(str string) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMMDString(cstr, C.unsigned(len(str)))
+       return
+}
+func (c Context) MDNode(vals []Value) (v Value) {
+       ptr, nvals := llvmValueRefs(vals)
+       v.C = C.LLVMMDNodeInContext(c.C, ptr, nvals)
+       return
+}
+func MDNode(vals []Value) (v Value) {
+       ptr, nvals := llvmValueRefs(vals)
+       v.C = C.LLVMMDNode(ptr, nvals)
+       return
+}
+
+// Operations on scalar constants
+func ConstInt(t Type, n uint64, signExtend bool) (v Value) {
+       v.C = C.LLVMConstInt(t.C,
+               C.ulonglong(n),
+               boolToLLVMBool(signExtend))
+       return
+}
+func ConstIntFromString(t Type, str string, radix int) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMConstIntOfString(t.C, cstr, C.uint8_t(radix))
+       return
+}
+func ConstFloat(t Type, n float64) (v Value) {
+       v.C = C.LLVMConstReal(t.C, C.double(n))
+       return
+}
+func ConstFloatFromString(t Type, str string) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMConstRealOfString(t.C, cstr)
+       return
+}
+
+func (v Value) ZExtValue() uint64 { return uint64(C.LLVMConstIntGetZExtValue(v.C)) }
+func (v Value) SExtValue() int64  { return int64(C.LLVMConstIntGetSExtValue(v.C)) }
+
+// Operations on composite constants
+func (c Context) ConstString(str string, addnull bool) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMConstStringInContext(c.C, cstr,
+               C.unsigned(len(str)), boolToLLVMBool(!addnull))
+       return
+}
+func (c Context) ConstStruct(constVals []Value, packed bool) (v Value) {
+       ptr, nvals := llvmValueRefs(constVals)
+       v.C = C.LLVMConstStructInContext(c.C, ptr, nvals,
+               boolToLLVMBool(packed))
+       return
+}
+func ConstNamedStruct(t Type, constVals []Value) (v Value) {
+       ptr, nvals := llvmValueRefs(constVals)
+       v.C = C.LLVMConstNamedStruct(t.C, ptr, nvals)
+       return
+}
+func ConstString(str string, addnull bool) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       v.C = C.LLVMConstString(cstr,
+               C.unsigned(len(str)), boolToLLVMBool(!addnull))
+       return
+}
+func ConstArray(t Type, constVals []Value) (v Value) {
+       ptr, nvals := llvmValueRefs(constVals)
+       v.C = C.LLVMConstArray(t.C, ptr, nvals)
+       return
+}
+func ConstStruct(constVals []Value, packed bool) (v Value) {
+       ptr, nvals := llvmValueRefs(constVals)
+       v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed))
+       return
+}
+func ConstVector(scalarConstVals []Value, packed bool) (v Value) {
+       ptr, nvals := llvmValueRefs(scalarConstVals)
+       v.C = C.LLVMConstVector(ptr, nvals)
+       return
+}
+
+// Constant expressions
+func (v Value) Opcode() Opcode                { return Opcode(C.LLVMGetConstOpcode(v.C)) }
+func (v Value) InstructionOpcode() Opcode     { return Opcode(C.LLVMGetInstructionOpcode(v.C)) }
+func AlignOf(t Type) (v Value)                { v.C = C.LLVMAlignOf(t.C); return }
+func SizeOf(t Type) (v Value)                 { v.C = C.LLVMSizeOf(t.C); return }
+func ConstNeg(v Value) (rv Value)             { rv.C = C.LLVMConstNeg(v.C); return }
+func ConstNSWNeg(v Value) (rv Value)          { rv.C = C.LLVMConstNSWNeg(v.C); return }
+func ConstNUWNeg(v Value) (rv Value)          { rv.C = C.LLVMConstNUWNeg(v.C); return }
+func ConstFNeg(v Value) (rv Value)            { rv.C = C.LLVMConstFNeg(v.C); return }
+func ConstNot(v Value) (rv Value)             { rv.C = C.LLVMConstNot(v.C); return }
+func ConstAdd(lhs, rhs Value) (v Value)       { v.C = C.LLVMConstAdd(lhs.C, rhs.C); return }
+func ConstNSWAdd(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNSWAdd(lhs.C, rhs.C); return }
+func ConstNUWAdd(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.C); return }
+func ConstFAdd(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstFAdd(lhs.C, rhs.C); return }
+func ConstSub(lhs, rhs Value) (v Value)       { v.C = C.LLVMConstSub(lhs.C, rhs.C); return }
+func ConstNSWSub(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return }
+func ConstNUWSub(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return }
+func ConstFSub(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstFSub(lhs.C, rhs.C); return }
+func ConstMul(lhs, rhs Value) (v Value)       { v.C = C.LLVMConstMul(lhs.C, rhs.C); return }
+func ConstNSWMul(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return }
+func ConstNUWMul(lhs, rhs Value) (v Value)    { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return }
+func ConstFMul(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstFMul(lhs.C, rhs.C); return }
+func ConstUDiv(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstUDiv(lhs.C, rhs.C); return }
+func ConstSDiv(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstSDiv(lhs.C, rhs.C); return }
+func ConstExactSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstExactSDiv(lhs.C, rhs.C); return }
+func ConstFDiv(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstFDiv(lhs.C, rhs.C); return }
+func ConstURem(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstURem(lhs.C, rhs.C); return }
+func ConstSRem(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstSRem(lhs.C, rhs.C); return }
+func ConstFRem(lhs, rhs Value) (v Value)      { v.C = C.LLVMConstFRem(lhs.C, rhs.C); return }
+func ConstAnd(lhs, rhs Value) (v Value)       { v.C = C.LLVMConstAnd(lhs.C, rhs.C); return }
+func ConstOr(lhs, rhs Value) (v Value)        { v.C = C.LLVMConstOr(lhs.C, rhs.C); return }
+func ConstXor(lhs, rhs Value) (v Value)       { v.C = C.LLVMConstXor(lhs.C, rhs.C); return }
+
+func ConstICmp(pred IntPredicate, lhs, rhs Value) (v Value) {
+       v.C = C.LLVMConstICmp(C.LLVMIntPredicate(pred), lhs.C, rhs.C)
+       return
+}
+func ConstFCmp(pred FloatPredicate, lhs, rhs Value) (v Value) {
+       v.C = C.LLVMConstFCmp(C.LLVMRealPredicate(pred), lhs.C, rhs.C)
+       return
+}
+
+func ConstShl(lhs, rhs Value) (v Value)  { v.C = C.LLVMConstShl(lhs.C, rhs.C); return }
+func ConstLShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstLShr(lhs.C, rhs.C); return }
+func ConstAShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAShr(lhs.C, rhs.C); return }
+
+func ConstGEP(v Value, indices []Value) (rv Value) {
+       ptr, nvals := llvmValueRefs(indices)
+       rv.C = C.LLVMConstGEP(v.C, ptr, nvals)
+       return
+}
+func ConstInBoundsGEP(v Value, indices []Value) (rv Value) {
+       ptr, nvals := llvmValueRefs(indices)
+       rv.C = C.LLVMConstInBoundsGEP(v.C, ptr, nvals)
+       return
+}
+func ConstTrunc(v Value, t Type) (rv Value)         { rv.C = C.LLVMConstTrunc(v.C, t.C); return }
+func ConstSExt(v Value, t Type) (rv Value)          { rv.C = C.LLVMConstSExt(v.C, t.C); return }
+func ConstZExt(v Value, t Type) (rv Value)          { rv.C = C.LLVMConstZExt(v.C, t.C); return }
+func ConstFPTrunc(v Value, t Type) (rv Value)       { rv.C = C.LLVMConstFPTrunc(v.C, t.C); return }
+func ConstFPExt(v Value, t Type) (rv Value)         { rv.C = C.LLVMConstFPExt(v.C, t.C); return }
+func ConstUIToFP(v Value, t Type) (rv Value)        { rv.C = C.LLVMConstUIToFP(v.C, t.C); return }
+func ConstSIToFP(v Value, t Type) (rv Value)        { rv.C = C.LLVMConstSIToFP(v.C, t.C); return }
+func ConstFPToUI(v Value, t Type) (rv Value)        { rv.C = C.LLVMConstFPToUI(v.C, t.C); return }
+func ConstFPToSI(v Value, t Type) (rv Value)        { rv.C = C.LLVMConstFPToSI(v.C, t.C); return }
+func ConstPtrToInt(v Value, t Type) (rv Value)      { rv.C = C.LLVMConstPtrToInt(v.C, t.C); return }
+func ConstIntToPtr(v Value, t Type) (rv Value)      { rv.C = C.LLVMConstIntToPtr(v.C, t.C); return }
+func ConstBitCast(v Value, t Type) (rv Value)       { rv.C = C.LLVMConstBitCast(v.C, t.C); return }
+func ConstZExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExtOrBitCast(v.C, t.C); return }
+func ConstSExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExtOrBitCast(v.C, t.C); return }
+func ConstTruncOrBitCast(v Value, t Type) (rv Value) {
+       rv.C = C.LLVMConstTruncOrBitCast(v.C, t.C)
+       return
+}
+func ConstPointerCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPointerCast(v.C, t.C); return }
+func ConstIntCast(v Value, t Type, signed bool) (rv Value) {
+       rv.C = C.LLVMConstIntCast(v.C, t.C, boolToLLVMBool(signed))
+       return
+}
+func ConstFPCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPCast(v.C, t.C); return }
+func ConstSelect(cond, iftrue, iffalse Value) (rv Value) {
+       rv.C = C.LLVMConstSelect(cond.C, iftrue.C, iffalse.C)
+       return
+}
+func ConstExtractElement(vec, i Value) (rv Value) {
+       rv.C = C.LLVMConstExtractElement(vec.C, i.C)
+       return
+}
+func ConstInsertElement(vec, elem, i Value) (rv Value) {
+       rv.C = C.LLVMConstInsertElement(vec.C, elem.C, i.C)
+       return
+}
+func ConstShuffleVector(veca, vecb, mask Value) (rv Value) {
+       rv.C = C.LLVMConstShuffleVector(veca.C, vecb.C, mask.C)
+       return
+}
+
+//TODO
+//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList,
+//                                   unsigned NumIdx);
+
+func ConstExtractValue(agg Value, indices []uint32) (rv Value) {
+       n := len(indices)
+       if n == 0 {
+               panic("one or more indices are required")
+       }
+       ptr := (*C.unsigned)(&indices[0])
+       rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n))
+       return
+}
+
+func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) {
+       n := len(indices)
+       if n == 0 {
+               panic("one or more indices are required")
+       }
+       ptr := (*C.unsigned)(&indices[0])
+       rv.C = C.LLVMConstInsertValue(agg.C, val.C, ptr, C.unsigned(n))
+       return
+}
+
+func BlockAddress(f Value, bb BasicBlock) (v Value) {
+       v.C = C.LLVMBlockAddress(f.C, bb.C)
+       return
+}
+
+// Operations on global variables, functions, and aliases (globals)
+func (v Value) GlobalParent() (m Module) { m.C = C.LLVMGetGlobalParent(v.C); return }
+func (v Value) IsDeclaration() bool      { return C.LLVMIsDeclaration(v.C) != 0 }
+func (v Value) Linkage() Linkage         { return Linkage(C.LLVMGetLinkage(v.C)) }
+func (v Value) SetLinkage(l Linkage)     { C.LLVMSetLinkage(v.C, C.LLVMLinkage(l)) }
+func (v Value) Section() string          { return C.GoString(C.LLVMGetSection(v.C)) }
+func (v Value) SetSection(str string) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       C.LLVMSetSection(v.C, cstr)
+}
+func (v Value) Visibility() Visibility      { return Visibility(C.LLVMGetVisibility(v.C)) }
+func (v Value) SetVisibility(vi Visibility) { C.LLVMSetVisibility(v.C, C.LLVMVisibility(vi)) }
+func (v Value) Alignment() int              { return int(C.LLVMGetAlignment(v.C)) }
+func (v Value) SetAlignment(a int)          { C.LLVMSetAlignment(v.C, C.unsigned(a)) }
+
+// Operations on global variables
+func AddGlobal(m Module, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMAddGlobal(m.C, t.C, cname)
+       return
+}
+func AddGlobalInAddressSpace(m Module, t Type, name string, addressSpace int) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMAddGlobalInAddressSpace(m.C, t.C, cname, C.unsigned(addressSpace))
+       return
+}
+func (m Module) NamedGlobal(name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMGetNamedGlobal(m.C, cname)
+       return
+}
+
+func (m Module) FirstGlobal() (v Value)   { v.C = C.LLVMGetFirstGlobal(m.C); return }
+func (m Module) LastGlobal() (v Value)    { v.C = C.LLVMGetLastGlobal(m.C); return }
+func NextGlobal(v Value) (rv Value)       { rv.C = C.LLVMGetNextGlobal(v.C); return }
+func PrevGlobal(v Value) (rv Value)       { rv.C = C.LLVMGetPreviousGlobal(v.C); return }
+func (v Value) EraseFromParentAsGlobal()  { C.LLVMDeleteGlobal(v.C) }
+func (v Value) Initializer() (rv Value)   { rv.C = C.LLVMGetInitializer(v.C); return }
+func (v Value) SetInitializer(cv Value)   { C.LLVMSetInitializer(v.C, cv.C) }
+func (v Value) IsThreadLocal() bool       { return C.LLVMIsThreadLocal(v.C) != 0 }
+func (v Value) SetThreadLocal(tl bool)    { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) }
+func (v Value) IsGlobalConstant() bool    { return C.LLVMIsGlobalConstant(v.C) != 0 }
+func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) }
+
+// Operations on aliases
+func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMAddAlias(m.C, t.C, aliasee.C, cname)
+       return
+}
+
+// Operations on functions
+func AddFunction(m Module, name string, ft Type) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMAddFunction(m.C, cname, ft.C)
+       return
+}
+
+func (m Module) NamedFunction(name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMGetNamedFunction(m.C, cname)
+       return
+}
+
+func (m Module) FirstFunction() (v Value)  { v.C = C.LLVMGetFirstFunction(m.C); return }
+func (m Module) LastFunction() (v Value)   { v.C = C.LLVMGetLastFunction(m.C); return }
+func NextFunction(v Value) (rv Value)      { rv.C = C.LLVMGetNextFunction(v.C); return }
+func PrevFunction(v Value) (rv Value)      { rv.C = C.LLVMGetPreviousFunction(v.C); return }
+func (v Value) EraseFromParentAsFunction() { C.LLVMDeleteFunction(v.C) }
+func (v Value) IntrinsicID() int           { return int(C.LLVMGetIntrinsicID(v.C)) }
+func (v Value) FunctionCallConv() CallConv {
+       return CallConv(C.LLVMCallConv(C.LLVMGetFunctionCallConv(v.C)))
+}
+func (v Value) SetFunctionCallConv(cc CallConv) { C.LLVMSetFunctionCallConv(v.C, C.unsigned(cc)) }
+func (v Value) GC() string                      { return C.GoString(C.LLVMGetGC(v.C)) }
+func (v Value) SetGC(name string) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       C.LLVMSetGC(v.C, cname)
+}
+func (v Value) AddFunctionAttr(a Attribute)    { C.LLVMAddFunctionAttr2(v.C, C.uint64_t(a)) }
+func (v Value) FunctionAttr() Attribute        { return Attribute(C.LLVMGetFunctionAttr2(v.C)) }
+func (v Value) RemoveFunctionAttr(a Attribute) { C.LLVMRemoveFunctionAttr2(v.C, C.uint64_t(a)) }
+func (v Value) AddTargetDependentFunctionAttr(attr, value string) {
+       cattr := C.CString(attr)
+       defer C.free(unsafe.Pointer(cattr))
+       cvalue := C.CString(value)
+       defer C.free(unsafe.Pointer(cvalue))
+       C.LLVMAddTargetDependentFunctionAttr(v.C, cattr, cvalue)
+}
+
+// Operations on parameters
+func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) }
+func (v Value) Params() []Value {
+       out := make([]Value, v.ParamsCount())
+       if len(out) > 0 {
+               C.LLVMGetParams(v.C, llvmValueRefPtr(&out[0]))
+       }
+       return out
+}
+func (v Value) Param(i int) (rv Value)  { rv.C = C.LLVMGetParam(v.C, C.unsigned(i)); return }
+func (v Value) ParamParent() (rv Value) { rv.C = C.LLVMGetParamParent(v.C); return }
+func (v Value) FirstParam() (rv Value)  { rv.C = C.LLVMGetFirstParam(v.C); return }
+func (v Value) LastParam() (rv Value)   { rv.C = C.LLVMGetLastParam(v.C); return }
+func NextParam(v Value) (rv Value)      { rv.C = C.LLVMGetNextParam(v.C); return }
+func PrevParam(v Value) (rv Value)      { rv.C = C.LLVMGetPreviousParam(v.C); return }
+func (v Value) AddAttribute(a Attribute) {
+       if a >= 1<<32 {
+               panic("attribute value currently unsupported")
+       }
+       C.LLVMAddAttribute(v.C, C.LLVMAttribute(a))
+}
+func (v Value) RemoveAttribute(a Attribute) {
+       if a >= 1<<32 {
+               panic("attribute value currently unsupported")
+       }
+       C.LLVMRemoveAttribute(v.C, C.LLVMAttribute(a))
+}
+func (v Value) Attribute() Attribute        { return Attribute(C.LLVMGetAttribute(v.C)) }
+func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) }
+
+// Operations on basic blocks
+func (bb BasicBlock) AsValue() (v Value)      { v.C = C.LLVMBasicBlockAsValue(bb.C); return }
+func (v Value) IsBasicBlock() bool            { return C.LLVMValueIsBasicBlock(v.C) != 0 }
+func (v Value) AsBasicBlock() (bb BasicBlock) { bb.C = C.LLVMValueAsBasicBlock(v.C); return }
+func (bb BasicBlock) Parent() (v Value)       { v.C = C.LLVMGetBasicBlockParent(bb.C); return }
+func (v Value) BasicBlocksCount() int         { return int(C.LLVMCountBasicBlocks(v.C)) }
+func (v Value) BasicBlocks() []BasicBlock {
+       out := make([]BasicBlock, v.BasicBlocksCount())
+       C.LLVMGetBasicBlocks(v.C, llvmBasicBlockRefPtr(&out[0]))
+       return out
+}
+func (v Value) FirstBasicBlock() (bb BasicBlock)    { bb.C = C.LLVMGetFirstBasicBlock(v.C); return }
+func (v Value) LastBasicBlock() (bb BasicBlock)     { bb.C = C.LLVMGetLastBasicBlock(v.C); return }
+func NextBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetNextBasicBlock(bb.C); return }
+func PrevBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetPreviousBasicBlock(bb.C); return }
+func (v Value) EntryBasicBlock() (bb BasicBlock)    { bb.C = C.LLVMGetEntryBasicBlock(v.C); return }
+func (c Context) AddBasicBlock(f Value, name string) (bb BasicBlock) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       bb.C = C.LLVMAppendBasicBlockInContext(c.C, f.C, cname)
+       return
+}
+func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       bb.C = C.LLVMInsertBasicBlockInContext(c.C, ref.C, cname)
+       return
+}
+func AddBasicBlock(f Value, name string) (bb BasicBlock) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       bb.C = C.LLVMAppendBasicBlock(f.C, cname)
+       return
+}
+func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       bb.C = C.LLVMInsertBasicBlock(ref.C, cname)
+       return
+}
+func (bb BasicBlock) EraseFromParent()          { C.LLVMDeleteBasicBlock(bb.C) }
+func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) }
+func (bb BasicBlock) MoveAfter(pos BasicBlock)  { C.LLVMMoveBasicBlockAfter(bb.C, pos.C) }
+
+// Operations on instructions
+func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return }
+func (bb BasicBlock) FirstInstruction() (v Value)  { v.C = C.LLVMGetFirstInstruction(bb.C); return }
+func (bb BasicBlock) LastInstruction() (v Value)   { v.C = C.LLVMGetLastInstruction(bb.C); return }
+func NextInstruction(v Value) (rv Value)           { rv.C = C.LLVMGetNextInstruction(v.C); return }
+func PrevInstruction(v Value) (rv Value)           { rv.C = C.LLVMGetPreviousInstruction(v.C); return }
+
+// Operations on call sites
+func (v Value) SetInstructionCallConv(cc CallConv) {
+       C.LLVMSetInstructionCallConv(v.C, C.unsigned(cc))
+}
+func (v Value) InstructionCallConv() CallConv {
+       return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C)))
+}
+func (v Value) AddInstrAttribute(i int, a Attribute) {
+       if a >= 1<<32 {
+               panic("attribute value currently unsupported")
+       }
+       C.LLVMAddInstrAttribute(v.C, C.unsigned(i), C.LLVMAttribute(a))
+}
+func (v Value) RemoveInstrAttribute(i int, a Attribute) {
+       if a >= 1<<32 {
+               panic("attribute value currently unsupported")
+       }
+       C.LLVMRemoveInstrAttribute(v.C, C.unsigned(i), C.LLVMAttribute(a))
+}
+func (v Value) SetInstrParamAlignment(i int, align int) {
+       C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align))
+}
+
+// Operations on call instructions (only)
+func (v Value) IsTailCall() bool    { return C.LLVMIsTailCall(v.C) != 0 }
+func (v Value) SetTailCall(is bool) { C.LLVMSetTailCall(v.C, boolToLLVMBool(is)) }
+
+// Operations on phi nodes
+func (v Value) AddIncoming(vals []Value, blocks []BasicBlock) {
+       ptr, nvals := llvmValueRefs(vals)
+       C.LLVMAddIncoming(v.C, ptr, llvmBasicBlockRefPtr(&blocks[0]), nvals)
+}
+func (v Value) IncomingCount() int { return int(C.LLVMCountIncoming(v.C)) }
+func (v Value) IncomingValue(i int) (rv Value) {
+       rv.C = C.LLVMGetIncomingValue(v.C, C.unsigned(i))
+       return
+}
+func (v Value) IncomingBlock(i int) (bb BasicBlock) {
+       bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i))
+       return
+}
+
+//-------------------------------------------------------------------------
+// llvm.Builder
+//-------------------------------------------------------------------------
+
+// An instruction builder represents a point within a basic block, and is the
+// exclusive means of building instructions using the C interface.
+
+func (c Context) NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilderInContext(c.C); return }
+func NewBuilder() (b Builder)             { b.C = C.LLVMCreateBuilder(); return }
+func (b Builder) SetInsertPoint(block BasicBlock, instr Value) {
+       C.LLVMPositionBuilder(b.C, block.C, instr.C)
+}
+func (b Builder) SetInsertPointBefore(instr Value)     { C.LLVMPositionBuilderBefore(b.C, instr.C) }
+func (b Builder) SetInsertPointAtEnd(block BasicBlock) { C.LLVMPositionBuilderAtEnd(b.C, block.C) }
+func (b Builder) GetInsertBlock() (bb BasicBlock)      { bb.C = C.LLVMGetInsertBlock(b.C); return }
+func (b Builder) ClearInsertionPoint()                 { C.LLVMClearInsertionPosition(b.C) }
+func (b Builder) Insert(instr Value)                   { C.LLVMInsertIntoBuilder(b.C, instr.C) }
+func (b Builder) InsertWithName(instr Value, name string) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       C.LLVMInsertIntoBuilderWithName(b.C, instr.C, cname)
+}
+func (b Builder) Dispose() { C.LLVMDisposeBuilder(b.C) }
+
+// Metadata
+func (b Builder) SetCurrentDebugLocation(v Value) { C.LLVMSetCurrentDebugLocation(b.C, v.C) }
+func (b Builder) CurrentDebugLocation() (v Value) { v.C = C.LLVMGetCurrentDebugLocation(b.C); return }
+func (b Builder) SetInstDebugLocation(v Value)    { C.LLVMSetInstDebugLocation(b.C, v.C) }
+func (b Builder) InsertDeclare(module Module, storage Value, md Value) Value {
+       f := module.NamedFunction("llvm.dbg.declare")
+       if f.IsNil() {
+               ftyp := FunctionType(VoidType(), []Type{storage.Type(), md.Type()}, false)
+               f = AddFunction(module, "llvm.dbg.declare", ftyp)
+       }
+       return b.CreateCall(f, []Value{storage, md}, "")
+}
+
+// Terminators
+func (b Builder) CreateRetVoid() (rv Value)    { rv.C = C.LLVMBuildRetVoid(b.C); return }
+func (b Builder) CreateRet(v Value) (rv Value) { rv.C = C.LLVMBuildRet(b.C, v.C); return }
+func (b Builder) CreateAggregateRet(vs []Value) (rv Value) {
+       ptr, nvals := llvmValueRefs(vs)
+       rv.C = C.LLVMBuildAggregateRet(b.C, ptr, nvals)
+       return
+}
+func (b Builder) CreateBr(bb BasicBlock) (rv Value) { rv.C = C.LLVMBuildBr(b.C, bb.C); return }
+func (b Builder) CreateCondBr(ifv Value, thenb, elseb BasicBlock) (rv Value) {
+       rv.C = C.LLVMBuildCondBr(b.C, ifv.C, thenb.C, elseb.C)
+       return
+}
+func (b Builder) CreateSwitch(v Value, elseb BasicBlock, numCases int) (rv Value) {
+       rv.C = C.LLVMBuildSwitch(b.C, v.C, elseb.C, C.unsigned(numCases))
+       return
+}
+func (b Builder) CreateIndirectBr(addr Value, numDests int) (rv Value) {
+       rv.C = C.LLVMBuildIndirectBr(b.C, addr.C, C.unsigned(numDests))
+       return
+}
+func (b Builder) CreateInvoke(fn Value, args []Value, then, catch BasicBlock, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       ptr, nvals := llvmValueRefs(args)
+       rv.C = C.LLVMBuildInvoke(b.C, fn.C, ptr, nvals, then.C, catch.C, cname)
+       return
+}
+func (b Builder) CreateUnreachable() (rv Value) { rv.C = C.LLVMBuildUnreachable(b.C); return }
+
+// Add a case to the switch instruction
+func (v Value) AddCase(on Value, dest BasicBlock) { C.LLVMAddCase(v.C, on.C, dest.C) }
+
+// Add a destination to the indirectbr instruction
+func (v Value) AddDest(dest BasicBlock) { C.LLVMAddDestination(v.C, dest.C) }
+
+// Arithmetic
+func (b Builder) CreateAdd(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildAdd(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNSWAdd(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNSWAdd(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNUWAdd(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNUWAdd(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFAdd(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFAdd(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateSub(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSub(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNSWSub(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNSWSub(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNUWSub(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNUWSub(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFSub(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       v.C = C.LLVMBuildFSub(b.C, lhs.C, rhs.C, cname)
+       C.free(unsafe.Pointer(cname))
+       return
+}
+func (b Builder) CreateMul(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildMul(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNSWMul(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNSWMul(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNUWMul(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildNUWMul(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFMul(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFMul(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateUDiv(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildUDiv(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateSDiv(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSDiv(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateExactSDiv(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildExactSDiv(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFDiv(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFDiv(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateURem(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildURem(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateSRem(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSRem(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFRem(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFRem(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateShl(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildShl(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateLShr(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildLShr(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateAShr(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildAShr(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateAnd(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildAnd(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateOr(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildOr(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateXor(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildXor(b.C, lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateBinOp(op Opcode, lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildBinOp(b.C, C.LLVMOpcode(op), lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateNeg(v Value, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       rv.C = C.LLVMBuildNeg(b.C, v.C, cname)
+       return
+}
+func (b Builder) CreateNSWNeg(v Value, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       rv.C = C.LLVMBuildNSWNeg(b.C, v.C, cname)
+       return
+}
+func (b Builder) CreateNUWNeg(v Value, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       rv.C = C.LLVMBuildNUWNeg(b.C, v.C, cname)
+       return
+}
+func (b Builder) CreateFNeg(v Value, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       rv.C = C.LLVMBuildFNeg(b.C, v.C, cname)
+       return
+}
+func (b Builder) CreateNot(v Value, name string) (rv Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       rv.C = C.LLVMBuildNot(b.C, v.C, cname)
+       return
+}
+
+// Memory
+
+func (b Builder) CreateMalloc(t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildMalloc(b.C, t.C, cname)
+       return
+}
+func (b Builder) CreateArrayMalloc(t Type, val Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildArrayMalloc(b.C, t.C, val.C, cname)
+       return
+}
+func (b Builder) CreateAlloca(t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildAlloca(b.C, t.C, cname)
+       return
+}
+func (b Builder) CreateArrayAlloca(t Type, val Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildArrayAlloca(b.C, t.C, val.C, cname)
+       return
+}
+func (b Builder) CreateFree(p Value) (v Value) {
+       v.C = C.LLVMBuildFree(b.C, p.C)
+       return
+}
+func (b Builder) CreateLoad(p Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildLoad(b.C, p.C, cname)
+       return
+}
+func (b Builder) CreateStore(val Value, p Value) (v Value) {
+       v.C = C.LLVMBuildStore(b.C, val.C, p.C)
+       return
+}
+func (b Builder) CreateGEP(p Value, indices []Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       ptr, nvals := llvmValueRefs(indices)
+       v.C = C.LLVMBuildGEP(b.C, p.C, ptr, nvals, cname)
+       return
+}
+func (b Builder) CreateInBoundsGEP(p Value, indices []Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       ptr, nvals := llvmValueRefs(indices)
+       v.C = C.LLVMBuildInBoundsGEP(b.C, p.C, ptr, nvals, cname)
+       return
+}
+func (b Builder) CreateStructGEP(p Value, i int, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildStructGEP(b.C, p.C, C.unsigned(i), cname)
+       return
+}
+func (b Builder) CreateGlobalString(str, name string) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildGlobalString(b.C, cstr, cname)
+       return
+}
+func (b Builder) CreateGlobalStringPtr(str, name string) (v Value) {
+       cstr := C.CString(str)
+       defer C.free(unsafe.Pointer(cstr))
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildGlobalStringPtr(b.C, cstr, cname)
+       return
+}
+
+// Casts
+func (b Builder) CreateTrunc(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildTrunc(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateZExt(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildZExt(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateSExt(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSExt(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateFPToUI(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFPToUI(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateFPToSI(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFPToSI(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateUIToFP(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildUIToFP(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateSIToFP(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSIToFP(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateFPTrunc(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFPTrunc(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateFPExt(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFPExt(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreatePtrToInt(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildPtrToInt(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateIntToPtr(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildIntToPtr(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateBitCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildBitCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateZExtOrBitCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildZExtOrBitCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateSExtOrBitCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSExtOrBitCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateTruncOrBitCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildTruncOrBitCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateCast(val Value, op Opcode, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildCast(b.C, C.LLVMOpcode(op), val.C, t.C, cname)
+       return
+} //
+func (b Builder) CreatePointerCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildPointerCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateIntCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildIntCast(b.C, val.C, t.C, cname)
+       return
+}
+func (b Builder) CreateFPCast(val Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFPCast(b.C, val.C, t.C, cname)
+       return
+}
+
+// Comparisons
+func (b Builder) CreateICmp(pred IntPredicate, lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildICmp(b.C, C.LLVMIntPredicate(pred), lhs.C, rhs.C, cname)
+       return
+}
+func (b Builder) CreateFCmp(pred FloatPredicate, lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildFCmp(b.C, C.LLVMRealPredicate(pred), lhs.C, rhs.C, cname)
+       return
+}
+
+// Miscellaneous instructions
+func (b Builder) CreatePHI(t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildPhi(b.C, t.C, cname)
+       return
+}
+func (b Builder) CreateCall(fn Value, args []Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       ptr, nvals := llvmValueRefs(args)
+       v.C = C.LLVMBuildCall(b.C, fn.C, ptr, nvals, cname)
+       return
+}
+
+func (b Builder) CreateSelect(ifv, thenv, elsev Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildSelect(b.C, ifv.C, thenv.C, elsev.C, cname)
+       return
+}
+
+func (b Builder) CreateVAArg(list Value, t Type, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildVAArg(b.C, list.C, t.C, cname)
+       return
+}
+func (b Builder) CreateExtractElement(vec, i Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildExtractElement(b.C, vec.C, i.C, cname)
+       return
+}
+func (b Builder) CreateInsertElement(vec, elt, i Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildInsertElement(b.C, vec.C, elt.C, i.C, cname)
+       return
+}
+func (b Builder) CreateShuffleVector(v1, v2, mask Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildShuffleVector(b.C, v1.C, v2.C, mask.C, cname)
+       return
+}
+func (b Builder) CreateExtractValue(agg Value, i int, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildExtractValue(b.C, agg.C, C.unsigned(i), cname)
+       return
+}
+func (b Builder) CreateInsertValue(agg, elt Value, i int, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildInsertValue(b.C, agg.C, elt.C, C.unsigned(i), cname)
+       return
+}
+
+func (b Builder) CreateIsNull(val Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildIsNull(b.C, val.C, cname)
+       return
+}
+func (b Builder) CreateIsNotNull(val Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildIsNotNull(b.C, val.C, cname)
+       return
+}
+func (b Builder) CreatePtrDiff(lhs, rhs Value, name string) (v Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       v.C = C.LLVMBuildPtrDiff(b.C, lhs.C, rhs.C, cname)
+       return
+}
+
+func (b Builder) CreateLandingPad(t Type, personality Value, nclauses int, name string) (l Value) {
+       cname := C.CString(name)
+       defer C.free(unsafe.Pointer(cname))
+       l.C = C.LLVMBuildLandingPad(b.C, t.C, personality.C, C.unsigned(nclauses), cname)
+       return l
+}
+
+func (l Value) AddClause(v Value) {
+       C.LLVMAddClause(l.C, v.C)
+}
+
+func (l Value) SetCleanup(cleanup bool) {
+       C.LLVMSetCleanup(l.C, boolToLLVMBool(cleanup))
+}
+
+func (b Builder) CreateResume(ex Value) (v Value) {
+       v.C = C.LLVMBuildResume(b.C, ex.C)
+       return
+}
+
+//-------------------------------------------------------------------------
+// llvm.ModuleProvider
+//-------------------------------------------------------------------------
+
+// Changes the type of M so it can be passed to FunctionPassManagers and the
+// JIT. They take ModuleProviders for historical reasons.
+func NewModuleProviderForModule(m Module) (mp ModuleProvider) {
+       mp.C = C.LLVMCreateModuleProviderForExistingModule(m.C)
+       return
+}
+
+// Destroys the module M.
+func (mp ModuleProvider) Dispose() { C.LLVMDisposeModuleProvider(mp.C) }
+
+//-------------------------------------------------------------------------
+// llvm.MemoryBuffer
+//-------------------------------------------------------------------------
+
+func NewMemoryBufferFromFile(path string) (b MemoryBuffer, err error) {
+       var cmsg *C.char
+       cpath := C.CString(path)
+       defer C.free(unsafe.Pointer(cpath))
+       fail := C.LLVMCreateMemoryBufferWithContentsOfFile(cpath, &b.C, &cmsg)
+       if fail != 0 {
+               b.C = nil
+               err = errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+       }
+       return
+}
+
+func NewMemoryBufferFromStdin() (b MemoryBuffer, err error) {
+       var cmsg *C.char
+       fail := C.LLVMCreateMemoryBufferWithSTDIN(&b.C, &cmsg)
+       if fail != 0 {
+               b.C = nil
+               err = errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+       }
+       return
+}
+
+func (b MemoryBuffer) Bytes() []byte {
+       cstart := C.LLVMGetBufferStart(b.C)
+       csize := C.LLVMGetBufferSize(b.C)
+       return C.GoBytes(unsafe.Pointer(cstart), C.int(csize))
+}
+
+func (b MemoryBuffer) Dispose() { C.LLVMDisposeMemoryBuffer(b.C) }
+
+//-------------------------------------------------------------------------
+// llvm.PassManager
+//-------------------------------------------------------------------------
+
+// Constructs a new whole-module pass pipeline. This type of pipeline is
+// suitable for link-time optimization and whole-module transformations.
+// See llvm::PassManager::PassManager.
+func NewPassManager() (pm PassManager) { pm.C = C.LLVMCreatePassManager(); return }
+
+// Constructs a new function-by-function pass pipeline over the module
+// provider. It does not take ownership of the module provider. This type of
+// pipeline is suitable for code generation and JIT compilation tasks.
+// See llvm::FunctionPassManager::FunctionPassManager.
+func NewFunctionPassManagerForModule(m Module) (pm PassManager) {
+       pm.C = C.LLVMCreateFunctionPassManagerForModule(m.C)
+       return
+}
+
+// Initializes, executes on the provided module, and finalizes all of the
+// passes scheduled in the pass manager. Returns 1 if any of the passes
+// modified the module, 0 otherwise. See llvm::PassManager::run(Module&).
+func (pm PassManager) Run(m Module) bool { return C.LLVMRunPassManager(pm.C, m.C) != 0 }
+
+// Initializes all of the function passes scheduled in the function pass
+// manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+// See llvm::FunctionPassManager::doInitialization.
+func (pm PassManager) InitializeFunc() bool { return C.LLVMInitializeFunctionPassManager(pm.C) != 0 }
+
+// Executes all of the function passes scheduled in the function pass manager
+// on the provided function. Returns 1 if any of the passes modified the
+// function, false otherwise.
+// See llvm::FunctionPassManager::run(Function&).
+func (pm PassManager) RunFunc(f Value) bool { return C.LLVMRunFunctionPassManager(pm.C, f.C) != 0 }
+
+// Finalizes all of the function passes scheduled in in the function pass
+// manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+// See llvm::FunctionPassManager::doFinalization.
+func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassManager(pm.C) != 0 }
+
+// Frees the memory of a pass pipeline. For function pipelines, does not free
+// the module provider.
+// See llvm::PassManagerBase::~PassManagerBase.
+func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) }
diff --git a/bindings/go/llvm/ir_test.go b/bindings/go/llvm/ir_test.go
new file mode 100644 (file)
index 0000000..981c94a
--- /dev/null
@@ -0,0 +1,95 @@
+//===- 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, attr Attribute, name string) {
+       mod := NewModule("")
+       defer mod.Dispose()
+
+       ftyp := FunctionType(VoidType(), nil, false)
+       fn := AddFunction(mod, "foo", ftyp)
+
+       fn.AddFunctionAttr(attr)
+       newattr := fn.FunctionAttr()
+       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.RemoveFunctionAttr(attr)
+       newattr = fn.FunctionAttr()
+       if newattr != 0 {
+               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 := []struct {
+               attr Attribute
+               name string
+       }{
+               {SanitizeAddressAttribute, "sanitize_address"},
+               {AlwaysInlineAttribute, "alwaysinline"},
+               {BuiltinAttribute, "builtin"},
+               {ByValAttribute, "byval"},
+               {InAllocaAttribute, "inalloca"},
+               {InlineHintAttribute, "inlinehint"},
+               {InRegAttribute, "inreg"},
+               {JumpTableAttribute, "jumptable"},
+               {MinSizeAttribute, "minsize"},
+               {NakedAttribute, "naked"},
+               {NestAttribute, "nest"},
+               {NoAliasAttribute, "noalias"},
+               {NoBuiltinAttribute, "nobuiltin"},
+               {NoCaptureAttribute, "nocapture"},
+               {NoDuplicateAttribute, "noduplicate"},
+               {NoImplicitFloatAttribute, "noimplicitfloat"},
+               {NoInlineAttribute, "noinline"},
+               {NonLazyBindAttribute, "nonlazybind"},
+               {NonNullAttribute, "nonnull"},
+               {NoRedZoneAttribute, "noredzone"},
+               {NoReturnAttribute, "noreturn"},
+               {NoUnwindAttribute, "nounwind"},
+               {OptimizeNoneAttribute, "optnone"},
+               {OptimizeForSizeAttribute, "optsize"},
+               {ReadNoneAttribute, "readnone"},
+               {ReadOnlyAttribute, "readonly"},
+               {ReturnedAttribute, "returned"},
+               {ReturnsTwiceAttribute, "returns_twice"},
+               {SExtAttribute, "signext"},
+               {StackProtectAttribute, "ssp"},
+               {StackProtectReqAttribute, "sspreq"},
+               {StackProtectStrongAttribute, "sspstrong"},
+               {StructRetAttribute, "sret"},
+               {SanitizeThreadAttribute, "sanitize_thread"},
+               {SanitizeMemoryAttribute, "sanitize_memory"},
+               {UWTableAttribute, "uwtable"},
+               {ZExtAttribute, "zeroext"},
+               {ColdAttribute, "cold"},
+       }
+
+       for _, a := range attrTests {
+               testAttribute(t, a.attr, a.name)
+       }
+}
diff --git a/bindings/go/llvm/linker.go b/bindings/go/llvm/linker.go
new file mode 100644 (file)
index 0000000..31e9ad2
--- /dev/null
@@ -0,0 +1,39 @@
+//===- linker.go - Bindings for linker ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the linker component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Linker.h"
+#include <stdlib.h>
+*/
+import "C"
+import "errors"
+
+type LinkerMode C.LLVMLinkerMode
+
+const (
+       LinkerDestroySource  = C.LLVMLinkerDestroySource
+       LinkerPreserveSource = C.LLVMLinkerPreserveSource
+)
+
+func LinkModules(Dest, Src Module, Mode LinkerMode) error {
+       var cmsg *C.char
+       failed := C.LLVMLinkModules(Dest.C, Src.C, C.LLVMLinkerMode(Mode), &cmsg)
+       if failed != 0 {
+               err := errors.New(C.GoString(cmsg))
+               C.LLVMDisposeMessage(cmsg)
+               return err
+       }
+       return nil
+}
diff --git a/bindings/go/llvm/llvm_config.go.in b/bindings/go/llvm/llvm_config.go.in
new file mode 100644 (file)
index 0000000..41854fa
--- /dev/null
@@ -0,0 +1,12 @@
+// +build !byollvm
+
+package llvm
+
+/*
+#cgo CXXFLAGS: -std=c++11
+#cgo CPPFLAGS: @LLVM_CFLAGS@
+#cgo LDFLAGS: @LLVM_LDFLAGS@
+*/
+import "C"
+
+type (run_build_sh int)
diff --git a/bindings/go/llvm/llvm_dep.go b/bindings/go/llvm/llvm_dep.go
new file mode 100644 (file)
index 0000000..39b4675
--- /dev/null
@@ -0,0 +1,19 @@
+//===- llvm_dep.go - creates LLVM dependency ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file ensures that the LLVM libraries are built before using the
+// bindings.
+//
+//===----------------------------------------------------------------------===//
+
+// +build !byollvm
+
+package llvm
+
+var _ run_build_sh
diff --git a/bindings/go/llvm/string.go b/bindings/go/llvm/string.go
new file mode 100644 (file)
index 0000000..bfe869d
--- /dev/null
@@ -0,0 +1,105 @@
+//===- string.go - Stringer implementation for Type -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Stringer interface for the Type type.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import "fmt"
+
+func (t TypeKind) String() string {
+       switch t {
+       case VoidTypeKind:
+               return "VoidTypeKind"
+       case FloatTypeKind:
+               return "FloatTypeKind"
+       case DoubleTypeKind:
+               return "DoubleTypeKind"
+       case X86_FP80TypeKind:
+               return "X86_FP80TypeKind"
+       case FP128TypeKind:
+               return "FP128TypeKind"
+       case PPC_FP128TypeKind:
+               return "PPC_FP128TypeKind"
+       case LabelTypeKind:
+               return "LabelTypeKind"
+       case IntegerTypeKind:
+               return "IntegerTypeKind"
+       case FunctionTypeKind:
+               return "FunctionTypeKind"
+       case StructTypeKind:
+               return "StructTypeKind"
+       case ArrayTypeKind:
+               return "ArrayTypeKind"
+       case PointerTypeKind:
+               return "PointerTypeKind"
+       case VectorTypeKind:
+               return "VectorTypeKind"
+       case MetadataTypeKind:
+               return "MetadataTypeKind"
+       }
+       panic("unreachable")
+}
+
+func (t Type) String() string {
+       ts := typeStringer{s: make(map[Type]string)}
+       return ts.typeString(t)
+}
+
+type typeStringer struct {
+       s map[Type]string
+}
+
+func (ts *typeStringer) typeString(t Type) string {
+       if s, ok := ts.s[t]; ok {
+               return s
+       }
+
+       k := t.TypeKind()
+       s := k.String()
+       s = s[:len(s)-len("Kind")]
+
+       switch k {
+       case ArrayTypeKind:
+               s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength())
+       case PointerTypeKind:
+               s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType()))
+       case FunctionTypeKind:
+               params := t.ParamTypes()
+               s += "("
+               if len(params) > 0 {
+                       s += fmt.Sprintf("%v", ts.typeString(params[0]))
+                       for i := 1; i < len(params); i++ {
+                               s += fmt.Sprintf(", %v", ts.typeString(params[i]))
+                       }
+               }
+               s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType()))
+       case StructTypeKind:
+               if name := t.StructName(); name != "" {
+                       ts.s[t] = "%" + name
+                       s = fmt.Sprintf("%%%s: %s", name, s)
+               }
+               etypes := t.StructElementTypes()
+               s += "("
+               if n := len(etypes); n > 0 {
+                       s += ts.typeString(etypes[0])
+                       for i := 1; i < n; i++ {
+                               s += fmt.Sprintf(", %v", ts.typeString(etypes[i]))
+                       }
+               }
+               s += ")"
+       case IntegerTypeKind:
+               s += fmt.Sprintf("(%d bits)", t.IntTypeWidth())
+       }
+
+       ts.s[t] = s
+       return s
+}
diff --git a/bindings/go/llvm/string_test.go b/bindings/go/llvm/string_test.go
new file mode 100644 (file)
index 0000000..3008f3e
--- /dev/null
@@ -0,0 +1,28 @@
+//===- string_test.go - test Stringer implementation for Type -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tests the Stringer interface for the Type type.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+import (
+       "testing"
+)
+
+func TestStringRecursiveType(t *testing.T) {
+       ctx := NewContext()
+       defer ctx.Dispose()
+       s := ctx.StructCreateNamed("recursive")
+       s.StructSetBody([]Type{s, s}, false)
+       if str := s.String(); str != "%recursive: StructType(%recursive, %recursive)" {
+               t.Errorf("incorrect string result %q", str)
+       }
+}
diff --git a/bindings/go/llvm/support.go b/bindings/go/llvm/support.go
new file mode 100644 (file)
index 0000000..6f20086
--- /dev/null
@@ -0,0 +1,54 @@
+//===- support.go - Bindings for support ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the support component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Support.h"
+#include "SupportBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+
+import (
+       "errors"
+       "unsafe"
+)
+
+// Loads a dynamic library such that it may be used as an LLVM plugin.
+// See llvm::sys::DynamicLibrary::LoadLibraryPermanently.
+func LoadLibraryPermanently(lib string) error {
+       var errstr *C.char
+       libstr := C.CString(lib)
+       defer C.free(unsafe.Pointer(libstr))
+       C.LLVMLoadLibraryPermanently2(libstr, &errstr)
+       if errstr != nil {
+               err := errors.New(C.GoString(errstr))
+               C.free(unsafe.Pointer(errstr))
+               return err
+       }
+       return nil
+}
+
+// Parse the given arguments using the LLVM command line parser.
+// See llvm::cl::ParseCommandLineOptions.
+func ParseCommandLineOptions(args []string, overview string) {
+       argstrs := make([]*C.char, len(args))
+       for i, arg := range args {
+               argstrs[i] = C.CString(arg)
+               defer C.free(unsafe.Pointer(argstrs[i]))
+       }
+       overviewstr := C.CString(overview)
+       defer C.free(unsafe.Pointer(overviewstr))
+       C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr)
+}
diff --git a/bindings/go/llvm/target.go b/bindings/go/llvm/target.go
new file mode 100644 (file)
index 0000000..bd1d0f3
--- /dev/null
@@ -0,0 +1,300 @@
+//===- target.go - Bindings for target ------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the target component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Target.h"
+#include "llvm-c/TargetMachine.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+import "errors"
+
+type (
+       TargetData struct {
+               C C.LLVMTargetDataRef
+       }
+       Target struct {
+               C C.LLVMTargetRef
+       }
+       TargetMachine struct {
+               C C.LLVMTargetMachineRef
+       }
+       ByteOrdering    C.enum_LLVMByteOrdering
+       RelocMode       C.LLVMRelocMode
+       CodeGenOptLevel C.LLVMCodeGenOptLevel
+       CodeGenFileType C.LLVMCodeGenFileType
+       CodeModel       C.LLVMCodeModel
+)
+
+const (
+       BigEndian    ByteOrdering = C.LLVMBigEndian
+       LittleEndian ByteOrdering = C.LLVMLittleEndian
+)
+
+const (
+       RelocDefault      RelocMode = C.LLVMRelocDefault
+       RelocStatic       RelocMode = C.LLVMRelocStatic
+       RelocPIC          RelocMode = C.LLVMRelocPIC
+       RelocDynamicNoPic RelocMode = C.LLVMRelocDynamicNoPic
+)
+
+const (
+       CodeGenLevelNone       CodeGenOptLevel = C.LLVMCodeGenLevelNone
+       CodeGenLevelLess       CodeGenOptLevel = C.LLVMCodeGenLevelLess
+       CodeGenLevelDefault    CodeGenOptLevel = C.LLVMCodeGenLevelDefault
+       CodeGenLevelAggressive CodeGenOptLevel = C.LLVMCodeGenLevelAggressive
+)
+
+const (
+       CodeModelDefault    CodeModel = C.LLVMCodeModelDefault
+       CodeModelJITDefault CodeModel = C.LLVMCodeModelJITDefault
+       CodeModelSmall      CodeModel = C.LLVMCodeModelSmall
+       CodeModelKernel     CodeModel = C.LLVMCodeModelKernel
+       CodeModelMedium     CodeModel = C.LLVMCodeModelMedium
+       CodeModelLarge      CodeModel = C.LLVMCodeModelLarge
+)
+
+const (
+       AssemblyFile CodeGenFileType = C.LLVMAssemblyFile
+       ObjectFile   CodeGenFileType = C.LLVMObjectFile
+)
+
+// InitializeAllTargetInfos - The main program should call this function if it
+// wants access to all available targets that LLVM is configured to support.
+func InitializeAllTargetInfos() { C.LLVMInitializeAllTargetInfos() }
+
+// InitializeAllTargets - The main program should call this function if it wants
+// to link in all available targets that LLVM is configured to support.
+func InitializeAllTargets() { C.LLVMInitializeAllTargets() }
+
+func InitializeAllTargetMCs() { C.LLVMInitializeAllTargetMCs() }
+
+func InitializeAllAsmParsers() { C.LLVMInitializeAllAsmParsers() }
+
+func InitializeAllAsmPrinters() { C.LLVMInitializeAllAsmPrinters() }
+
+var initializeNativeTargetError = errors.New("Failed to initialize native target")
+
+// InitializeNativeTarget - The main program should call this function to
+// initialize the native target corresponding to the host. This is useful
+// for JIT applications to ensure that the target gets linked in correctly.
+func InitializeNativeTarget() error {
+       fail := C.LLVMInitializeNativeTarget()
+       if fail != 0 {
+               return initializeNativeTargetError
+       }
+       return nil
+}
+
+func InitializeNativeAsmPrinter() error {
+       fail := C.LLVMInitializeNativeAsmPrinter()
+       if fail != 0 {
+               return initializeNativeTargetError
+       }
+       return nil
+}
+
+//-------------------------------------------------------------------------
+// llvm.TargetData
+//-------------------------------------------------------------------------
+
+// Creates target data from a target layout string.
+// See the constructor llvm::TargetData::TargetData.
+func NewTargetData(rep string) (td TargetData) {
+       crep := C.CString(rep)
+       defer C.free(unsafe.Pointer(crep))
+       td.C = C.LLVMCreateTargetData(crep)
+       return
+}
+
+// Adds target data information to a pass manager. This does not take ownership
+// of the target data.
+// See the method llvm::PassManagerBase::add.
+func (pm PassManager) Add(td TargetData) {
+       C.LLVMAddTargetData(td.C, pm.C)
+}
+
+// Converts target data to a target layout string. The string must be disposed
+// with LLVMDisposeMessage.
+// See the constructor llvm::TargetData::TargetData.
+func (td TargetData) String() (s string) {
+       cmsg := C.LLVMCopyStringRepOfTargetData(td.C)
+       s = C.GoString(cmsg)
+       C.LLVMDisposeMessage(cmsg)
+       return
+}
+
+// Returns the byte order of a target, either BigEndian or LittleEndian.
+// See the method llvm::TargetData::isLittleEndian.
+func (td TargetData) ByteOrder() ByteOrdering { return ByteOrdering(C.LLVMByteOrder(td.C)) }
+
+// Returns the pointer size in bytes for a target.
+// See the method llvm::TargetData::getPointerSize.
+func (td TargetData) PointerSize() int { return int(C.LLVMPointerSize(td.C)) }
+
+// Returns the integer type that is the same size as a pointer on a target.
+// See the method llvm::TargetData::getIntPtrType.
+func (td TargetData) IntPtrType() (t Type) { t.C = C.LLVMIntPtrType(td.C); return }
+
+// Computes the size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeSizeInBits.
+func (td TargetData) TypeSizeInBits(t Type) uint64 {
+       return uint64(C.LLVMSizeOfTypeInBits(td.C, t.C))
+}
+
+// Computes the storage size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeStoreSize.
+func (td TargetData) TypeStoreSize(t Type) uint64 {
+       return uint64(C.LLVMStoreSizeOfType(td.C, t.C))
+}
+
+// Computes the ABI size of a type in bytes for a target.
+// See the method llvm::TargetData::getTypeAllocSize.
+func (td TargetData) TypeAllocSize(t Type) uint64 {
+       return uint64(C.LLVMABISizeOfType(td.C, t.C))
+}
+
+// Computes the ABI alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getABITypeAlignment.
+func (td TargetData) ABITypeAlignment(t Type) int {
+       return int(C.LLVMABIAlignmentOfType(td.C, t.C))
+}
+
+// Computes the call frame alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getCallFrameTypeAlignment.
+func (td TargetData) CallFrameTypeAlignment(t Type) int {
+       return int(C.LLVMCallFrameAlignmentOfType(td.C, t.C))
+}
+
+// Computes the preferred alignment of a type in bytes for a target.
+// See the method llvm::TargetData::getPrefTypeAlignment.
+func (td TargetData) PrefTypeAlignment(t Type) int {
+       return int(C.LLVMPreferredAlignmentOfType(td.C, t.C))
+}
+
+// Computes the preferred alignment of a global variable in bytes for a target.
+// See the method llvm::TargetData::getPreferredAlignment.
+func (td TargetData) PreferredAlignment(g Value) int {
+       return int(C.LLVMPreferredAlignmentOfGlobal(td.C, g.C))
+}
+
+// Computes the structure element that contains the byte offset for a target.
+// See the method llvm::StructLayout::getElementContainingOffset.
+func (td TargetData) ElementContainingOffset(t Type, offset uint64) int {
+       return int(C.LLVMElementAtOffset(td.C, t.C, C.ulonglong(offset)))
+}
+
+// Computes the byte offset of the indexed struct element for a target.
+// See the method llvm::StructLayout::getElementOffset.
+func (td TargetData) ElementOffset(t Type, element int) uint64 {
+       return uint64(C.LLVMOffsetOfElement(td.C, t.C, C.unsigned(element)))
+}
+
+// Deallocates a TargetData.
+// See the destructor llvm::TargetData::~TargetData.
+func (td TargetData) Dispose() { C.LLVMDisposeTargetData(td.C) }
+
+//-------------------------------------------------------------------------
+// llvm.Target
+//-------------------------------------------------------------------------
+
+func FirstTarget() Target {
+       return Target{C.LLVMGetFirstTarget()}
+}
+
+func (t Target) NextTarget() Target {
+       return Target{C.LLVMGetNextTarget(t.C)}
+}
+
+func GetTargetFromTriple(triple string) (t Target, err error) {
+       var errstr *C.char
+       ctriple := C.CString(triple)
+       defer C.free(unsafe.Pointer(ctriple))
+       fail := C.LLVMGetTargetFromTriple(ctriple, &t.C, &errstr)
+       if fail != 0 {
+               err = errors.New(C.GoString(errstr))
+               C.free(unsafe.Pointer(errstr))
+       }
+       return
+}
+
+func (t Target) Name() string {
+       return C.GoString(C.LLVMGetTargetName(t.C))
+}
+
+func (t Target) Description() string {
+       return C.GoString(C.LLVMGetTargetDescription(t.C))
+}
+
+//-------------------------------------------------------------------------
+// llvm.TargetMachine
+//-------------------------------------------------------------------------
+
+// CreateTargetMachine creates a new TargetMachine.
+func (t Target) CreateTargetMachine(Triple string, CPU string, Features string,
+       Level CodeGenOptLevel, Reloc RelocMode,
+       CodeModel CodeModel) (tm TargetMachine) {
+       cTriple := C.CString(Triple)
+       defer C.free(unsafe.Pointer(cTriple))
+       cCPU := C.CString(CPU)
+       defer C.free(unsafe.Pointer(cCPU))
+       cFeatures := C.CString(Features)
+       defer C.free(unsafe.Pointer(cFeatures))
+       tm.C = C.LLVMCreateTargetMachine(t.C, cTriple, cCPU, cFeatures,
+               C.LLVMCodeGenOptLevel(Level),
+               C.LLVMRelocMode(Reloc),
+               C.LLVMCodeModel(CodeModel))
+       return
+}
+
+// Triple returns the triple describing the machine (arch-vendor-os).
+func (tm TargetMachine) Triple() string {
+       cstr := C.LLVMGetTargetMachineTriple(tm.C)
+       return C.GoString(cstr)
+}
+
+// TargetData returns the TargetData for the machine.
+func (tm TargetMachine) TargetData() TargetData {
+       return TargetData{C.LLVMGetTargetMachineData(tm.C)}
+}
+
+func (tm TargetMachine) EmitToMemoryBuffer(m Module, ft CodeGenFileType) (MemoryBuffer, error) {
+       var errstr *C.char
+       var mb MemoryBuffer
+       fail := C.LLVMTargetMachineEmitToMemoryBuffer(tm.C, m.C, C.LLVMCodeGenFileType(ft), &errstr, &mb.C)
+       if fail != 0 {
+               err := errors.New(C.GoString(errstr))
+               C.free(unsafe.Pointer(errstr))
+               return MemoryBuffer{}, err
+       }
+       return mb, nil
+}
+
+func (tm TargetMachine) AddAnalysisPasses(pm PassManager) {
+       C.LLVMAddAnalysisPasses(tm.C, pm.C)
+}
+
+// Dispose releases resources related to the TargetMachine.
+func (tm TargetMachine) Dispose() {
+       C.LLVMDisposeTargetMachine(tm.C)
+}
+
+func DefaultTargetTriple() (triple string) {
+       cTriple := C.LLVMGetDefaultTargetTriple()
+       defer C.free(unsafe.Pointer(cTriple))
+       triple = C.GoString(cTriple)
+       return
+}
diff --git a/bindings/go/llvm/transforms_instrumentation.go b/bindings/go/llvm/transforms_instrumentation.go
new file mode 100644 (file)
index 0000000..9b191b2
--- /dev/null
@@ -0,0 +1,43 @@
+//===- transforms_instrumentation.go - Bindings for instrumentation -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the instrumentation component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "InstrumentationBindings.h"
+#include <stdlib.h>
+*/
+import "C"
+import "unsafe"
+
+func (pm PassManager) AddAddressSanitizerFunctionPass() {
+       C.LLVMAddAddressSanitizerFunctionPass(pm.C)
+}
+
+func (pm PassManager) AddAddressSanitizerModulePass() {
+       C.LLVMAddAddressSanitizerModulePass(pm.C)
+}
+
+func (pm PassManager) AddThreadSanitizerPass() {
+       C.LLVMAddThreadSanitizerPass(pm.C)
+}
+
+func (pm PassManager) AddMemorySanitizerPass() {
+       C.LLVMAddMemorySanitizerPass(pm.C)
+}
+
+func (pm PassManager) AddDataFlowSanitizerPass(abilist string) {
+       cabilist := C.CString(abilist)
+       defer C.free(unsafe.Pointer(cabilist))
+       C.LLVMAddDataFlowSanitizerPass(pm.C, cabilist)
+}
diff --git a/bindings/go/llvm/transforms_ipo.go b/bindings/go/llvm/transforms_ipo.go
new file mode 100644 (file)
index 0000000..12d972b
--- /dev/null
@@ -0,0 +1,42 @@
+//===- transforms_ipo.go - Bindings for ipo -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the ipo component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/IPO.h"
+*/
+import "C"
+
+// helpers
+func boolToUnsigned(b bool) C.unsigned {
+       if b {
+               return 1
+       }
+       return 0
+}
+
+func (pm PassManager) AddArgumentPromotionPass()     { C.LLVMAddArgumentPromotionPass(pm.C) }
+func (pm PassManager) AddConstantMergePass()         { C.LLVMAddConstantMergePass(pm.C) }
+func (pm PassManager) AddDeadArgEliminationPass()    { C.LLVMAddDeadArgEliminationPass(pm.C) }
+func (pm PassManager) AddFunctionAttrsPass()         { C.LLVMAddFunctionAttrsPass(pm.C) }
+func (pm PassManager) AddFunctionInliningPass()      { C.LLVMAddFunctionInliningPass(pm.C) }
+func (pm PassManager) AddGlobalDCEPass()             { C.LLVMAddGlobalDCEPass(pm.C) }
+func (pm PassManager) AddGlobalOptimizerPass()       { C.LLVMAddGlobalOptimizerPass(pm.C) }
+func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) }
+func (pm PassManager) AddPruneEHPass()               { C.LLVMAddPruneEHPass(pm.C) }
+func (pm PassManager) AddIPSCCPPass()                { C.LLVMAddIPSCCPPass(pm.C) }
+func (pm PassManager) AddInternalizePass(allButMain bool) {
+       C.LLVMAddInternalizePass(pm.C, boolToUnsigned(allButMain))
+}
+func (pm PassManager) AddStripDeadPrototypesPass() { C.LLVMAddStripDeadPrototypesPass(pm.C) }
diff --git a/bindings/go/llvm/transforms_pmbuilder.go b/bindings/go/llvm/transforms_pmbuilder.go
new file mode 100644 (file)
index 0000000..3d79d6e
--- /dev/null
@@ -0,0 +1,48 @@
+//===- transforms_pmbuilder.go - Bindings for PassManagerBuilder ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the PassManagerBuilder class.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/PassManagerBuilder.h"
+*/
+import "C"
+
+type PassManagerBuilder struct {
+       C C.LLVMPassManagerBuilderRef
+}
+
+func NewPassManagerBuilder() (pmb PassManagerBuilder) {
+       pmb.C = C.LLVMPassManagerBuilderCreate()
+       return
+}
+
+func (pmb PassManagerBuilder) SetOptLevel(level int) {
+       C.LLVMPassManagerBuilderSetOptLevel(pmb.C, C.uint(level))
+}
+
+func (pmb PassManagerBuilder) SetSizeLevel(level int) {
+       C.LLVMPassManagerBuilderSetSizeLevel(pmb.C, C.uint(level))
+}
+
+func (pmb PassManagerBuilder) Populate(pm PassManager) {
+       C.LLVMPassManagerBuilderPopulateModulePassManager(pmb.C, pm.C)
+}
+
+func (pmb PassManagerBuilder) PopulateFunc(pm PassManager) {
+       C.LLVMPassManagerBuilderPopulateFunctionPassManager(pmb.C, pm.C)
+}
+
+func (pmb PassManagerBuilder) Dispose() {
+       C.LLVMPassManagerBuilderDispose(pmb.C)
+}
diff --git a/bindings/go/llvm/transforms_scalar.go b/bindings/go/llvm/transforms_scalar.go
new file mode 100644 (file)
index 0000000..6492a85
--- /dev/null
@@ -0,0 +1,45 @@
+//===- transforms_scalar.go - Bindings for scalaropts ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines bindings for the scalaropts component.
+//
+//===----------------------------------------------------------------------===//
+
+package llvm
+
+/*
+#include "llvm-c/Transforms/Scalar.h"
+*/
+import "C"
+
+func (pm PassManager) AddAggressiveDCEPass()           { C.LLVMAddAggressiveDCEPass(pm.C) }
+func (pm PassManager) AddCFGSimplificationPass()       { C.LLVMAddCFGSimplificationPass(pm.C) }
+func (pm PassManager) AddDeadStoreEliminationPass()    { C.LLVMAddDeadStoreEliminationPass(pm.C) }
+func (pm PassManager) AddGVNPass()                     { C.LLVMAddGVNPass(pm.C) }
+func (pm PassManager) AddIndVarSimplifyPass()          { C.LLVMAddIndVarSimplifyPass(pm.C) }
+func (pm PassManager) AddInstructionCombiningPass()    { C.LLVMAddInstructionCombiningPass(pm.C) }
+func (pm PassManager) AddJumpThreadingPass()           { C.LLVMAddJumpThreadingPass(pm.C) }
+func (pm PassManager) AddLICMPass()                    { C.LLVMAddLICMPass(pm.C) }
+func (pm PassManager) AddLoopDeletionPass()            { C.LLVMAddLoopDeletionPass(pm.C) }
+func (pm PassManager) AddLoopRotatePass()              { C.LLVMAddLoopRotatePass(pm.C) }
+func (pm PassManager) AddLoopUnrollPass()              { C.LLVMAddLoopUnrollPass(pm.C) }
+func (pm PassManager) AddLoopUnswitchPass()            { C.LLVMAddLoopUnswitchPass(pm.C) }
+func (pm PassManager) AddMemCpyOptPass()               { C.LLVMAddMemCpyOptPass(pm.C) }
+func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) }
+func (pm PassManager) AddReassociatePass()             { C.LLVMAddReassociatePass(pm.C) }
+func (pm PassManager) AddSCCPPass()                    { C.LLVMAddSCCPPass(pm.C) }
+func (pm PassManager) AddScalarReplAggregatesPass()    { C.LLVMAddScalarReplAggregatesPass(pm.C) }
+func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) {
+       C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold))
+}
+func (pm PassManager) AddSimplifyLibCallsPass()       { C.LLVMAddSimplifyLibCallsPass(pm.C) }
+func (pm PassManager) AddTailCallEliminationPass()    { C.LLVMAddTailCallEliminationPass(pm.C) }
+func (pm PassManager) AddConstantPropagationPass()    { C.LLVMAddConstantPropagationPass(pm.C) }
+func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) }
+func (pm PassManager) AddVerifierPass()               { C.LLVMAddVerifierPass(pm.C) }
diff --git a/bindings/go/llvm/version.go b/bindings/go/llvm/version.go
new file mode 100644 (file)
index 0000000..5938583
--- /dev/null
@@ -0,0 +1,3 @@
+package llvm
+
+const Version = "3.6.0svn"
index 849da2dc14849c486c6c514505c438d4dfa3c972..358a32cd10736b71ee88d3060a106a586a582048 100755 (executable)
@@ -491,3 +491,18 @@ if (LLVM_ENABLE_SPHINX)
 else()
   message(STATUS "Sphinx disabled.")
 endif()
+
+set(LLVM_BINDINGS "")
+find_program(GO_EXECUTABLE NAMES go DOC "go executable")
+if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
+  message(STATUS "Go bindings disabled.")
+else()
+  execute_process(COMMAND ${GO_EXECUTABLE} run ${CMAKE_SOURCE_DIR}/bindings/go/conftest.go
+                  RESULT_VARIABLE GO_CONFTEST)
+  if(GO_CONFTEST STREQUAL "0")
+    set(LLVM_BINDINGS "${LLVM_BINDINGS} go")
+    message(STATUS "Go bindings enabled.")
+  else()
+    message(STATUS "Go bindings disabled, need at least Go 1.2.")
+  endif()
+endif()
index 57e8955ccd9ba6ea5176a95c150310686788c4a6..8a65693fea2e12d858da215d11c6435b15da9f7f 100644 (file)
@@ -651,6 +651,9 @@ function(configure_lit_site_cfg input output)
   set(HOST_OS ${CMAKE_SYSTEM_NAME})
   set(HOST_ARCH ${CMAKE_SYSTEM_PROCESSOR})
 
+  set(HOST_CC "${CMAKE_C_COMPILER}")
+  set(HOST_CXX "${CMAKE_CXX_COMPILER}")
+
   configure_file(${input} ${output} @ONLY)
 endfunction()
 
index 0943056dad7145c217c335b1d807b3dc2397de63..17a81154aa8c74a055ceb0cd4a0276c6976b0401 100755 (executable)
--- a/configure
+++ b/configure
@@ -752,6 +752,7 @@ GROFF
 GZIPBIN
 PDFROFF
 ZIP
+GO
 OCAMLC
 OCAMLOPT
 OCAMLDEP
@@ -6871,6 +6872,46 @@ echo "${ECHO_T}no" >&6; }
 fi
 
 
+# Extract the first word of "go", so it can be a program name with args.
+set dummy go; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_GO+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $GO in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GO="$GO" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GO="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+GO=$ac_cv_path_GO
+if test -n "$GO"; then
+  { echo "$as_me:$LINENO: result: $GO" >&5
+echo "${ECHO_T}$GO" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
 for ac_prog in ocamlc
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -18613,6 +18654,11 @@ if test "$BINDINGS_TO_BUILD" = auto ; then
   if test "x$OCAMLC" != x -a "x$OCAMLDEP" != x ; then
     BINDINGS_TO_BUILD="ocaml $BINDINGS_TO_BUILD"
   fi
+  if test "x$GO" != x ; then
+    if $GO run ${srcdir}/bindings/go/conftest.go ; then
+      BINDINGS_TO_BUILD="go $BINDINGS_TO_BUILD"
+    fi
+  fi
 fi
 BINDINGS_TO_BUILD=$BINDINGS_TO_BUILD
 
@@ -18652,6 +18698,21 @@ echo "$as_me: WARNING: --enable-bindings=ocaml specified, but ocamlopt not found
       fi
     fi
     ;;
+  go)
+    if test "x$GO" = x ; then
+      { echo "$as_me:$LINENO: WARNING: --enable-bindings=go specified, but go not found. Try configure GO=/path/to/go" >&5
+echo "$as_me: WARNING: --enable-bindings=go specified, but go not found. Try configure GO=/path/to/go" >&2;}
+      binding_prereqs_failed=1
+    else
+      if $GO run ${srcdir}/bindings/go/conftest.go ; then
+        :
+      else
+        { echo "$as_me:$LINENO: WARNING: --enable-bindings=go specified, but need at least Go 1.2. Try configure GO=/path/to/go" >&5
+echo "$as_me: WARNING: --enable-bindings=go specified, but need at least Go 1.2. Try configure GO=/path/to/go" >&2;}
+        binding_prereqs_failed=1
+      fi
+    fi
+    ;;
   esac
 done
 if test "$binding_prereqs_failed" = 1 ; then
@@ -19679,6 +19740,7 @@ GROFF!$GROFF$ac_delim
 GZIPBIN!$GZIPBIN$ac_delim
 PDFROFF!$PDFROFF$ac_delim
 ZIP!$ZIP$ac_delim
+GO!$GO$ac_delim
 OCAMLC!$OCAMLC$ac_delim
 OCAMLOPT!$OCAMLOPT$ac_delim
 OCAMLDEP!$OCAMLDEP$ac_delim
@@ -19724,7 +19786,7 @@ LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 96; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/test/Bindings/Go/go.test b/test/Bindings/Go/go.test
new file mode 100644 (file)
index 0000000..ec860ba
--- /dev/null
@@ -0,0 +1,8 @@
+; RUN: cd %S/../../../bindings/go/llvm && \
+; RUN: env CGO_CPPFLAGS="$(llvm-config --cppflags)" \
+; RUN:     CGO_CXXFLAGS=-std=c++11 \
+; RUN:     CGO_LDFLAGS="$(llvm-config --ldflags --libs --system-libs \
+; RUN:                                $(../build.sh --print-components))" \
+; RUN:     %go test -tags byollvm .
+
+; REQUIRES: shell
diff --git a/test/Bindings/Go/lit.local.cfg b/test/Bindings/Go/lit.local.cfg
new file mode 100644 (file)
index 0000000..5053e2c
--- /dev/null
@@ -0,0 +1,33 @@
+import distutils.spawn
+import os
+import pipes
+import shlex
+
+if not 'go' in config.root.llvm_bindings:
+    config.unsupported = True
+
+# Resolve certain symlinks in the first word of compiler.
+#
+# This is a Go-specific hack. cgo and other Go tools check $CC and $CXX for the
+# substring 'clang' to determine if the compiler is Clang. This won't work if
+# $CC is cc and cc is a symlink pointing to clang, as it is on Darwin.
+def fixup_compiler_path(compiler):
+    args = shlex.split(compiler)
+    path = distutils.spawn.find_executable(args[0])
+
+    try:
+        if path.endswith('/cc') and os.readlink(path) == 'clang':
+            args[0] = path[:len(path)-2] + 'clang'
+    except OSError:
+        skip
+
+    try:
+        if path.endswith('/c++') and os.readlink(path) == 'clang++':
+            args[0] = path[:len(path)-3] + 'clang++'
+    except OSError:
+        skip
+
+    return ' '.join([pipes.quote(arg) for arg in args])
+
+config.environment['CC'] = fixup_compiler_path(config.host_cc)
+config.environment['CXX'] = fixup_compiler_path(config.host_cxx)
index c38d89ab09e9edb7e1aa28221382739575d287c8..364b97c632e83fca4d367fef1d36722a6f09763b 100644 (file)
@@ -1,5 +1,4 @@
 config.suffixes = ['.ml']
 
-bindings = set([s.strip() for s in config.root.llvm_bindings.split(',')])
-if not 'ocaml' in bindings:
+if not 'ocaml' in config.root.llvm_bindings:
     config.unsupported = True
index 92ced039d5cdf93394d98e12857dee955cf45db8..546266a838f112b3a7d07c35aa9ccb4546c70745 100644 (file)
@@ -133,6 +133,9 @@ lit.site.cfg: FORCE
        @$(ECHOPATH) s=@EXEEXT@=$(EXEEXT)=g >> lit.tmp
        @$(ECHOPATH) s=@PYTHON_EXECUTABLE@=$(PYTHON)=g >> lit.tmp
        @$(ECHOPATH) s=@OCAMLOPT@=$(OCAMLOPT) -cc $(subst *,'\\\"',*$(subst =,"\\=",$(CXX_FOR_OCAMLOPT))*) -cclib -L$(LibDir) -I $(LibDir)/ocaml=g >> lit.tmp
+       @$(ECHOPATH) s=@GO_EXECUTABLE@=$(GO)=g >> lit.tmp
+       @$(ECHOPATH) s!@HOST_CC@!$(CC)!g >> lit.tmp
+       @$(ECHOPATH) s!@HOST_CXX@!$(CXX)!g >> lit.tmp
        @$(ECHOPATH) s=@ENABLE_SHARED@=$(ENABLE_SHARED)=g >> lit.tmp
        @$(ECHOPATH) s=@ENABLE_ASSERTIONS@=$(ENABLE_ASSERTIONS)=g >> lit.tmp
        @$(ECHOPATH) s=@TARGETS_TO_BUILD@=$(TARGETS_TO_BUILD)=g >> lit.tmp
index 323d3ce10d36615144591b25ac8bbb830277fe9c..1b4df11192114905b8e00ff0a77d3d4782c8f61e 100644 (file)
@@ -168,6 +168,7 @@ config.substitutions.append( ('%llc_dwarf', llc_dwarf) )
 
 # Add site-specific substitutions.
 config.substitutions.append( ('%ocamlopt', config.ocamlopt_executable) )
+config.substitutions.append( ('%go', config.go_executable) )
 config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
 config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )
 config.substitutions.append( ('%exeext', config.llvm_exe_ext) )
index 8a9582a597ade6b22b91baa0274c703db7044e37..65551c03a87402ad99de61ba11573fca0ced5295 100644 (file)
@@ -13,12 +13,15 @@ config.llvm_exe_ext = "@EXEEXT@"
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.python_executable = "@PYTHON_EXECUTABLE@"
 config.ocamlopt_executable = "@OCAMLOPT@"
+config.go_executable = "@GO_EXECUTABLE@"
 config.enable_shared = @ENABLE_SHARED@
 config.enable_assertions = @ENABLE_ASSERTIONS@
 config.targets_to_build = "@TARGETS_TO_BUILD@"
-config.llvm_bindings = "@LLVM_BINDINGS@"
+config.llvm_bindings = "@LLVM_BINDINGS@".split(' ')
 config.host_os = "@HOST_OS@"
 config.host_arch = "@HOST_ARCH@"
+config.host_cc = "@HOST_CC@"
+config.host_cxx = "@HOST_CXX@"
 config.llvm_use_intel_jitevents = "@LLVM_USE_INTEL_JITEVENTS@"
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
 config.have_zlib = "@HAVE_LIBZ@"
index 876d4f31e95038f59181f7146d37d0d229f8ae7a..4befe582d454c37dfb33c1f302793695bafa0fe0 100644 (file)
@@ -91,7 +91,7 @@ def getLocalConfig(ts, path_in_suite, litConfig, cache):
 
         # Otherwise, copy the current config and load the local configuration
         # file into it.
-        config = copy.copy(parent)
+        config = copy.deepcopy(parent)
         if litConfig.debug:
             litConfig.note('loading local config %r' % cfgpath)
         config.load_from_path(cfgpath, litConfig)