mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-27 21:50:40 +00:00
Initial version of Go bindings.
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
This commit is contained in:
parent
86b3d8eb43
commit
798ace2e58
6
.gitignore
vendored
6
.gitignore
vendored
@ -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
|
||||
|
@ -202,6 +202,7 @@ DOT := @DOT@
|
||||
DOXYGEN := @DOXYGEN@
|
||||
GROFF := @GROFF@
|
||||
GZIPBIN := @GZIPBIN@
|
||||
GO := @GO@
|
||||
OCAMLC := @OCAMLC@
|
||||
OCAMLOPT := @OCAMLOPT@
|
||||
OCAMLDEP := @OCAMLDEP@
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
53
bindings/go/README.txt
Normal file
53
bindings/go/README.txt
Normal file
@ -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
|
67
bindings/go/build.sh
Executable file
67
bindings/go/build.sh
Executable file
@ -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
|
16
bindings/go/conftest.go
Normal file
16
bindings/go/conftest.go
Normal file
@ -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)
|
||||
}
|
222
bindings/go/llvm/DIBuilderBindings.cpp
Normal file
222
bindings/go/llvm/DIBuilderBindings.cpp
Normal file
@ -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);
|
||||
}
|
123
bindings/go/llvm/DIBuilderBindings.h
Normal file
123
bindings/go/llvm/DIBuilderBindings.h
Normal file
@ -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
|
47
bindings/go/llvm/IRBindings.cpp
Normal file
47
bindings/go/llvm/IRBindings.cpp
Normal file
@ -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);
|
||||
}
|
37
bindings/go/llvm/IRBindings.h
Normal file
37
bindings/go/llvm/IRBindings.h
Normal file
@ -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
|
42
bindings/go/llvm/InstrumentationBindings.cpp
Normal file
42
bindings/go/llvm/InstrumentationBindings.cpp
Normal file
@ -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));
|
||||
}
|
38
bindings/go/llvm/InstrumentationBindings.h
Normal file
38
bindings/go/llvm/InstrumentationBindings.h
Normal file
@ -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
|
27
bindings/go/llvm/SupportBindings.cpp
Normal file
27
bindings/go/llvm/SupportBindings.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
30
bindings/go/llvm/SupportBindings.h
Normal file
30
bindings/go/llvm/SupportBindings.h
Normal file
@ -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
|
68
bindings/go/llvm/analysis.go
Normal file
68
bindings/go/llvm/analysis.go
Normal file
@ -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) }
|
50
bindings/go/llvm/bitreader.go
Normal file
50
bindings/go/llvm/bitreader.go
Normal file
@ -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
|
||||
}
|
39
bindings/go/llvm/bitwriter.go
Normal file
39
bindings/go/llvm/bitwriter.go
Normal file
@ -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
|
492
bindings/go/llvm/dibuilder.go
Normal file
492
bindings/go/llvm/dibuilder.go
Normal file
@ -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
|
||||
}
|
163
bindings/go/llvm/executionengine.go
Normal file
163
bindings/go/llvm/executionengine.go
Normal file
@ -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)
|
||||
}
|
93
bindings/go/llvm/executionengine_test.go
Normal file
93
bindings/go/llvm/executionengine_test.go
Normal file
@ -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))
|
||||
}
|
||||
}
|
1823
bindings/go/llvm/ir.go
Normal file
1823
bindings/go/llvm/ir.go
Normal file
File diff suppressed because it is too large
Load Diff
95
bindings/go/llvm/ir_test.go
Normal file
95
bindings/go/llvm/ir_test.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
39
bindings/go/llvm/linker.go
Normal file
39
bindings/go/llvm/linker.go
Normal file
@ -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
|
||||
}
|
12
bindings/go/llvm/llvm_config.go.in
Normal file
12
bindings/go/llvm/llvm_config.go.in
Normal file
@ -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)
|
19
bindings/go/llvm/llvm_dep.go
Normal file
19
bindings/go/llvm/llvm_dep.go
Normal file
@ -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
|
105
bindings/go/llvm/string.go
Normal file
105
bindings/go/llvm/string.go
Normal file
@ -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
|
||||
}
|
28
bindings/go/llvm/string_test.go
Normal file
28
bindings/go/llvm/string_test.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
54
bindings/go/llvm/support.go
Normal file
54
bindings/go/llvm/support.go
Normal file
@ -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)
|
||||
}
|
300
bindings/go/llvm/target.go
Normal file
300
bindings/go/llvm/target.go
Normal file
@ -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
|
||||
}
|
43
bindings/go/llvm/transforms_instrumentation.go
Normal file
43
bindings/go/llvm/transforms_instrumentation.go
Normal file
@ -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)
|
||||
}
|
42
bindings/go/llvm/transforms_ipo.go
Normal file
42
bindings/go/llvm/transforms_ipo.go
Normal file
@ -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) }
|
48
bindings/go/llvm/transforms_pmbuilder.go
Normal file
48
bindings/go/llvm/transforms_pmbuilder.go
Normal file
@ -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)
|
||||
}
|
45
bindings/go/llvm/transforms_scalar.go
Normal file
45
bindings/go/llvm/transforms_scalar.go
Normal file
@ -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) }
|
3
bindings/go/llvm/version.go
Normal file
3
bindings/go/llvm/version.go
Normal file
@ -0,0 +1,3 @@
|
||||
package llvm
|
||||
|
||||
const Version = "3.6.0svn"
|
@ -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()
|
||||
|
@ -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()
|
||||
|
||||
|
64
configure
vendored
64
configure
vendored
@ -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
|
||||
|
8
test/Bindings/Go/go.test
Normal file
8
test/Bindings/Go/go.test
Normal file
@ -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
|
33
test/Bindings/Go/lit.local.cfg
Normal file
33
test/Bindings/Go/lit.local.cfg
Normal file
@ -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)
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) )
|
||||
|
@ -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@"
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user