222 changes: 222 additions & 0 deletions llvm/bindings/go/llvm/DIBuilderBindings.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 123 additions & 0 deletions llvm/bindings/go/llvm/DIBuilderBindings.h
Original file line number Diff line number Diff line change
@@ -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 changes: 47 additions & 0 deletions llvm/bindings/go/llvm/IRBindings.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 37 additions & 0 deletions llvm/bindings/go/llvm/IRBindings.h
Original file line number Diff line number Diff line change
@@ -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 changes: 42 additions & 0 deletions llvm/bindings/go/llvm/InstrumentationBindings.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 38 additions & 0 deletions llvm/bindings/go/llvm/InstrumentationBindings.h
Original file line number Diff line number Diff line change
@@ -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 changes: 27 additions & 0 deletions llvm/bindings/go/llvm/SupportBindings.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions llvm/bindings/go/llvm/SupportBindings.h
Original file line number Diff line number Diff line change
@@ -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 changes: 68 additions & 0 deletions llvm/bindings/go/llvm/analysis.go
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions llvm/bindings/go/llvm/bitreader.go
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions llvm/bindings/go/llvm/bitwriter.go
Original file line number Diff line number Diff line change
@@ -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 changes: 492 additions & 0 deletions llvm/bindings/go/llvm/dibuilder.go

Large diffs are not rendered by default.

163 changes: 163 additions & 0 deletions llvm/bindings/go/llvm/executionengine.go
Original file line number Diff line number Diff line change
@@ -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 changes: 93 additions & 0 deletions llvm/bindings/go/llvm/executionengine_test.go
Original file line number Diff line number Diff line change
@@ -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))
}
}
1,823 changes: 1,823 additions & 0 deletions llvm/bindings/go/llvm/ir.go

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions llvm/bindings/go/llvm/ir_test.go
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions llvm/bindings/go/llvm/linker.go
Original file line number Diff line number Diff line change
@@ -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 changes: 12 additions & 0 deletions llvm/bindings/go/llvm/llvm_config.go.in
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions llvm/bindings/go/llvm/llvm_dep.go
Original file line number Diff line number Diff line change
@@ -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 changes: 105 additions & 0 deletions llvm/bindings/go/llvm/string.go
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions llvm/bindings/go/llvm/string_test.go
Original file line number Diff line number Diff line change
@@ -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 changes: 54 additions & 0 deletions llvm/bindings/go/llvm/support.go
Original file line number Diff line number Diff line change
@@ -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 changes: 300 additions & 0 deletions llvm/bindings/go/llvm/target.go
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 0 deletions llvm/bindings/go/llvm/transforms_instrumentation.go
Original file line number Diff line number Diff line change
@@ -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 changes: 42 additions & 0 deletions llvm/bindings/go/llvm/transforms_ipo.go
Original file line number Diff line number Diff line change
@@ -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 changes: 48 additions & 0 deletions llvm/bindings/go/llvm/transforms_pmbuilder.go
Original file line number Diff line number Diff line change
@@ -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 changes: 45 additions & 0 deletions llvm/bindings/go/llvm/transforms_scalar.go
Original file line number Diff line number Diff line change
@@ -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 changes: 3 additions & 0 deletions llvm/bindings/go/llvm/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package llvm

const Version = "3.6.0svn"
15 changes: 15 additions & 0 deletions llvm/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
3 changes: 3 additions & 0 deletions llvm/cmake/modules/AddLLVM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
64 changes: 63 additions & 1 deletion llvm/configure
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ GROFF
GZIPBIN
PDFROFF
ZIP
GO
OCAMLC
OCAMLOPT
OCAMLDEP
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions llvm/test/Bindings/Go/go.test
Original file line number Diff line number Diff line change
@@ -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 changes: 33 additions & 0 deletions llvm/test/Bindings/Go/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 1 addition & 2 deletions llvm/test/Bindings/Ocaml/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions llvm/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions llvm/test/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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) )
Expand Down
5 changes: 4 additions & 1 deletion llvm/test/lit.site.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@"
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/lit/lit/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def search1(path_in_suite):

# 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)
Expand Down