[Bindings] Remove go bindings

Remove the unmaintained Go bindings per
https://discourse.llvm.org/t/rfc-remove-the-go-bindings/65725.

The tinygo project provides maintained Go bindings at
https://github.com/tinygo-org/go-llvm.

Differential Revision: https://reviews.llvm.org/D135436
This commit is contained in:
Nikita Popov 2022-10-07 12:10:42 +02:00
parent 36b13eb8bb
commit bc839b4b4e
39 changed files with 1 additions and 4801 deletions

6
llvm/.gitignore vendored
View File

@ -50,12 +50,6 @@ docs/_build
.vscode
.vs
#==============================================================================#
# Files created in tree by the Go bindings.
#==============================================================================#
bindings/go/llvm/llvm_config.go
bindings/go/llvm/workdir
#==============================================================================#
# File extensions to be ignored anywhere in the tree.
# Placed at the end to override any previous ! patterns.

View File

@ -1,61 +0,0 @@
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++14
$ export CGO_LDFLAGS="`/path/to/llvm-build/bin/llvm-config --ldflags --libs --system-libs all`"
$ go build -tags byollvm
If you see a compilation error while compiling your code with Go 1.9.4 or later as follows,
go build llvm.org/llvm/bindings/go/llvm: invalid flag in #cgo LDFLAGS: -Wl,-headerpad_max_install_names
you need to setup $CGO_LDFLAGS_ALLOW to allow a compiler to specify some linker options:
$ export CGO_LDFLAGS_ALLOW='-Wl,(-search_paths_first|-headerpad_max_install_names)'

View File

@ -1,28 +0,0 @@
#!/bin/sh -xe
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"
llvm_go="$llvm_builddir/bin/llvm-go"
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-go
llvm_components="$($llvm_go print-components)"
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_go print-config > $gollvmdir/llvm_config.go

View File

@ -1,16 +0,0 @@
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)
}

View File

@ -1,75 +0,0 @@
//===- IRBindings.cpp - Additional bindings for ir ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines additional C bindings for the ir component.
//
//===----------------------------------------------------------------------===//
#include "IRBindings.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
using namespace llvm;
LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef C) {
return wrap(ConstantAsMetadata::get(unwrap<Constant>(C)));
}
LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen) {
return wrap(MDString::get(*unwrap(C), StringRef(Str, SLen)));
}
LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count) {
return wrap(
MDNode::get(*unwrap(C), ArrayRef<Metadata *>(unwrap(MDs), Count)));
}
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
LLVMMetadataRef Val) {
NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name);
if (!N)
return;
if (!Val)
return;
N->addOperand(unwrap<MDNode>(Val));
}
void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) {
MDNode *N = MD ? unwrap<MDNode>(MD) : nullptr;
unwrap<Instruction>(Inst)->setMetadata(KindID, N);
}
void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt) {
if (!Scope)
unwrap(Bref)->SetCurrentDebugLocation(DebugLoc());
else
unwrap(Bref)->SetCurrentDebugLocation(DILocation::get(
unwrap<MDNode>(Scope)->getContext(), Line, Col, unwrap<MDNode>(Scope),
InlinedAt ? unwrap<MDNode>(InlinedAt) : nullptr));
}
LLVMDebugLocMetadata LLVMGoGetCurrentDebugLocation(LLVMBuilderRef Bref) {
const auto& Loc = unwrap(Bref)->getCurrentDebugLocation();
const auto* InlinedAt = Loc.getInlinedAt();
const LLVMDebugLocMetadata md{
Loc.getLine(),
Loc.getCol(),
wrap(Loc.getScope()),
InlinedAt == nullptr ? nullptr : wrap(InlinedAt->getRawInlinedAt()),
};
return md;
}

View File

@ -1,57 +0,0 @@
//===- IRBindings.h - Additional bindings for IR ----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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 "llvm-c/DebugInfo.h"
#ifdef __cplusplus
#include "llvm/IR/Metadata.h"
#include "llvm/Support/CBindingWrapping.h"
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct LLVMDebugLocMetadata{
unsigned Line;
unsigned Col;
LLVMMetadataRef Scope;
LLVMMetadataRef InlinedAt;
};
LLVMMetadataRef LLVMConstantAsMetadata(LLVMValueRef Val);
LLVMMetadataRef LLVMMDString2(LLVMContextRef C, const char *Str, unsigned SLen);
LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count);
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,
LLVMMetadataRef Val);
void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD);
void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line,
unsigned Col, LLVMMetadataRef Scope,
LLVMMetadataRef InlinedAt);
struct LLVMDebugLocMetadata LLVMGoGetCurrentDebugLocation(LLVMBuilderRef Bref);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,30 +0,0 @@
//===- InstrumentationBindings.cpp - instrumentation bindings -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines C bindings for the instrumentation component.
//
//===----------------------------------------------------------------------===//
#include "InstrumentationBindings.h"
#include "llvm-c/Core.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Instrumentation.h"
using namespace llvm;
void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM,
int ABIListFilesNum,
const char **ABIListFiles) {
std::vector<std::string> ABIListFilesVec;
for (int i = 0; i != ABIListFilesNum; ++i) {
ABIListFilesVec.push_back(ABIListFiles[i]);
}
unwrap(PM)->add(createDataFlowSanitizerLegacyPassPass(ABIListFilesVec));
}

View File

@ -1,33 +0,0 @@
//===- InstrumentationBindings.h - instrumentation bindings -----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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 LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum,
const char **ABIListFiles);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,25 +0,0 @@
//===- SupportBindings.cpp - Additional bindings for support --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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);
}
}

View File

@ -1,29 +0,0 @@
//===- SupportBindings.h - Additional bindings for Support ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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

View File

@ -1,68 +0,0 @@
//===- analysis.go - Bindings for analysis --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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 "llvm-c/Core.h"
#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) }

View File

@ -1,50 +0,0 @@
//===- bitreader.go - Bindings for bitreader ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the bitreader component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm-c/BitReader.h"
#include "llvm-c/Core.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.LLVMParseBitcode2(buf, &m.C) == 0 {
return m, nil
}
err := errors.New(C.GoString(errmsg))
C.free(unsafe.Pointer(errmsg))
return Module{}, err
}

View File

@ -1,38 +0,0 @@
//===- bitwriter.go - Bindings for bitwriter ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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

View File

@ -1,711 +0,0 @@
//===- dibuilder.go - Bindings for DIBuilder ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the DIBuilder class.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "IRBindings.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
FlagReserved
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.LLVMCreateDIBuilder(m.C)
return &DIBuilder{ref: d, m: m}
}
// Destroy destroys the DIBuilder.
func (d *DIBuilder) Destroy() {
C.LLVMDisposeDIBuilder(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
SysRoot string
SDK string
}
// CreateCompileUnit creates compile unit debug metadata.
func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
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))
sysroot := C.CString(cu.SysRoot)
defer C.free(unsafe.Pointer(sysroot))
sdk := C.CString(cu.SDK)
defer C.free(unsafe.Pointer(sdk))
result := C.LLVMDIBuilderCreateCompileUnit(
d.ref,
C.LLVMDWARFSourceLanguage(cu.Language),
C.LLVMDIBuilderCreateFile(d.ref, file, C.size_t(len(cu.File)), dir, C.size_t(len(cu.Dir))),
producer, C.size_t(len(cu.Producer)),
C.LLVMBool(boolToCInt(cu.Optimized)),
flags, C.size_t(len(cu.Flags)),
C.unsigned(cu.RuntimeVersion),
/*SplitName=*/ nil, 0,
C.LLVMDWARFEmissionFull,
/*DWOId=*/ 0,
/*SplitDebugInlining*/ C.LLVMBool(boolToCInt(true)),
/*DebugInfoForProfiling*/ C.LLVMBool(boolToCInt(false)),
sysroot, C.size_t(len(cu.SysRoot)),
sdk, C.size_t(len(cu.SDK)),
)
return Metadata{C: result}
}
// CreateFile creates file debug metadata.
func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
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, C.size_t(len(filename)),
cdir, C.size_t(len(dir)))
return Metadata{C: result}
}
// DILexicalBlock holds the values for creating lexical block debug metadata.
type DILexicalBlock struct {
File Metadata
Line int
Column int
}
// CreateLexicalBlock creates lexical block debug metadata.
func (d *DIBuilder) CreateLexicalBlock(diScope Metadata, b DILexicalBlock) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlock(
d.ref,
diScope.C,
b.File.C,
C.unsigned(b.Line),
C.unsigned(b.Column),
)
return Metadata{C: result}
}
func (d *DIBuilder) CreateLexicalBlockFile(diScope Metadata, diFile Metadata, discriminator int) Metadata {
result := C.LLVMDIBuilderCreateLexicalBlockFile(d.ref, diScope.C, diFile.C,
C.unsigned(discriminator))
return Metadata{C: result}
}
// DIFunction holds the values for creating function debug metadata.
type DIFunction struct {
Name string
LinkageName string
File Metadata
Line int
Type Metadata
LocalToUnit bool
IsDefinition bool
ScopeLine int
Flags int
Optimized bool
}
// CreateFunction creates function debug metadata.
func (d *DIBuilder) CreateFunction(diScope Metadata, f DIFunction) Metadata {
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, C.size_t(len(f.Name)),
linkageName, C.size_t(len(f.LinkageName)),
f.File.C,
C.unsigned(f.Line),
f.Type.C,
C.LLVMBool(boolToCInt(f.LocalToUnit)),
C.LLVMBool(boolToCInt(f.IsDefinition)),
C.unsigned(f.ScopeLine),
C.LLVMDIFlags(f.Flags),
C.LLVMBool(boolToCInt(f.Optimized)),
)
return Metadata{C: result}
}
// DIAutoVariable holds the values for creating auto variable debug metadata.
type DIAutoVariable struct {
Name string
File Metadata
Line int
Type Metadata
AlwaysPreserve bool
Flags int
AlignInBits uint32
}
// CreateAutoVariable creates local variable debug metadata.
func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
name := C.CString(v.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateAutoVariable(
d.ref,
scope.C,
name, C.size_t(len(v.Name)),
v.File.C,
C.unsigned(v.Line),
v.Type.C,
C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
C.LLVMDIFlags(v.Flags),
C.uint32_t(v.AlignInBits),
)
return Metadata{C: result}
}
// DIParameterVariable holds the values for creating parameter variable debug metadata.
type DIParameterVariable struct {
Name string
File Metadata
Line int
Type Metadata
AlwaysPreserve bool
Flags int
// ArgNo is the 1-based index of the argument in the function's
// parameter list.
ArgNo int
}
// CreateParameterVariable creates parameter variable debug metadata.
func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
name := C.CString(v.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateParameterVariable(
d.ref,
scope.C,
name, C.size_t(len(v.Name)),
C.unsigned(v.ArgNo),
v.File.C,
C.unsigned(v.Line),
v.Type.C,
C.LLVMBool(boolToCInt(v.AlwaysPreserve)),
C.LLVMDIFlags(v.Flags),
)
return Metadata{C: result}
}
// DIBasicType holds the values for creating basic type debug metadata.
type DIBasicType struct {
Name string
SizeInBits uint64
Encoding DwarfTypeEncoding
}
// CreateBasicType creates basic type debug metadata.
func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateBasicType(
d.ref,
name,
C.size_t(len(t.Name)),
C.uint64_t(t.SizeInBits),
C.LLVMDWARFTypeEncoding(t.Encoding),
C.LLVMDIFlags(0),
)
return Metadata{C: result}
}
// DIPointerType holds the values for creating pointer type debug metadata.
type DIPointerType struct {
Pointee Metadata
SizeInBits uint64
AlignInBits uint32 // optional
AddressSpace uint32
Name string // optional
}
// CreatePointerType creates a type that represents a pointer to another type.
func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
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.uint32_t(t.AlignInBits),
C.unsigned(t.AddressSpace),
name,
C.size_t(len(t.Name)),
)
return Metadata{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 Metadata
// Parameters contains the subroutine parameter types,
// including the return type at the 0th index.
Parameters []Metadata
Flags int
}
// CreateSubroutineType creates subroutine type debug metadata.
func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
params, length := llvmMetadataRefs(t.Parameters)
result := C.LLVMDIBuilderCreateSubroutineType(
d.ref,
t.File.C,
params,
length,
C.LLVMDIFlags(t.Flags),
)
return Metadata{C: result}
}
// DIStructType holds the values for creating struct type debug metadata.
type DIStructType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint32
Flags int
DerivedFrom Metadata
Elements []Metadata
VTableHolder Metadata // optional
UniqueID string
}
// CreateStructType creates struct type debug metadata.
func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
elements, length := llvmMetadataRefs(t.Elements)
name := C.CString(t.Name)
uniqueID := C.CString(t.UniqueID)
defer C.free(unsafe.Pointer(name))
defer C.free(unsafe.Pointer(uniqueID))
result := C.LLVMDIBuilderCreateStructType(
d.ref,
scope.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.LLVMDIFlags(t.Flags),
t.DerivedFrom.C,
elements,
length,
C.unsigned(0), // Optional Objective-C runtime version.
t.VTableHolder.C,
uniqueID,
C.size_t(len(t.UniqueID)),
)
return Metadata{C: result}
}
// DIReplaceableCompositeType holds the values for creating replaceable
// composite type debug metadata.
type DIReplaceableCompositeType struct {
Tag dwarf.Tag
Name string
File Metadata
Line int
RuntimeLang int
SizeInBits uint64
AlignInBits uint32
Flags int
UniqueID string
}
// CreateReplaceableCompositeType creates replaceable composite type debug metadata.
func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
name := C.CString(t.Name)
uniqueID := C.CString(t.UniqueID)
defer C.free(unsafe.Pointer(name))
defer C.free(unsafe.Pointer(uniqueID))
result := C.LLVMDIBuilderCreateReplaceableCompositeType(
d.ref,
C.unsigned(t.Tag),
name,
C.size_t(len(t.Name)),
scope.C,
t.File.C,
C.unsigned(t.Line),
C.unsigned(t.RuntimeLang),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.LLVMDIFlags(t.Flags),
uniqueID,
C.size_t(len(t.UniqueID)),
)
return Metadata{C: result}
}
// DIMemberType holds the values for creating member type debug metadata.
type DIMemberType struct {
Name string
File Metadata
Line int
SizeInBits uint64
AlignInBits uint32
OffsetInBits uint64
Flags int
Type Metadata
}
// CreateMemberType creates struct type debug metadata.
func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateMemberType(
d.ref,
scope.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
C.uint64_t(t.OffsetInBits),
C.LLVMDIFlags(t.Flags),
t.Type.C,
)
return Metadata{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 uint32
ElementType Metadata
Subscripts []DISubrange
}
// CreateArrayType creates struct type debug metadata.
func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
subscriptsSlice := make([]Metadata, len(t.Subscripts))
for i, s := range t.Subscripts {
subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
}
subscripts, length := llvmMetadataRefs(subscriptsSlice)
result := C.LLVMDIBuilderCreateArrayType(
d.ref,
C.uint64_t(t.SizeInBits),
C.uint32_t(t.AlignInBits),
t.ElementType.C,
subscripts,
length,
)
return Metadata{C: result}
}
// DITypedef holds the values for creating typedef type debug metadata.
type DITypedef struct {
Type Metadata
Name string
File Metadata
Line int
Context Metadata
AlignInBits uint32
}
// CreateTypedef creates typedef type debug metadata.
func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
name := C.CString(t.Name)
defer C.free(unsafe.Pointer(name))
result := C.LLVMDIBuilderCreateTypedef(
d.ref,
t.Type.C,
name,
C.size_t(len(t.Name)),
t.File.C,
C.unsigned(t.Line),
t.Context.C,
C.uint32_t(t.AlignInBits),
)
return Metadata{C: result}
}
// getOrCreateSubrange gets a metadata node for the specified subrange,
// creating if required.
func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
result := C.LLVMDIBuilderGetOrCreateSubrange(d.ref, C.int64_t(lo), C.int64_t(count))
return Metadata{C: result}
}
// getOrCreateArray gets a metadata node containing the specified values,
// creating if required.
func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateArray(d.ref, data, C.size_t(length))
return Metadata{C: result}
}
// getOrCreateTypeArray gets a metadata node for a type array containing the
// specified values, creating if required.
func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
if len(values) == 0 {
return Metadata{}
}
data, length := llvmMetadataRefs(values)
result := C.LLVMDIBuilderGetOrCreateTypeArray(d.ref, data, C.size_t(length))
return Metadata{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 []uint64) Metadata {
var data *C.uint64_t
if len(addr) > 0 {
data = (*C.uint64_t)(unsafe.Pointer(&addr[0]))
}
result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr)))
return Metadata{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 Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
loc := C.LLVMDIBuilderCreateDebugLocation(
d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
result := C.LLVMDIBuilderInsertDeclareAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
return Value{C: result}
}
// InsertValueAtEnd inserts a call to llvm.dbg.value at the end of the
// specified basic block for the given value and associated debug metadata.
func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) Value {
loc := C.LLVMDIBuilderCreateDebugLocation(
d.m.Context().C, C.uint(l.Line), C.uint(l.Col), l.Scope.C, l.InlinedAt.C)
result := C.LLVMDIBuilderInsertDbgValueAtEnd(d.ref, v.C, diVarInfo.C, expr.C, loc, bb.C)
return Value{C: result}
}
func (v Value) SetSubprogram(sp Metadata) {
C.LLVMSetSubprogram(v.C, sp.C)
}
func (v Value) Subprogram() (md Metadata) {
md.C = C.LLVMGetSubprogram(v.C)
return
}
func boolToCInt(v bool) C.int {
if v {
return 1
}
return 0
}
//-------------------------------------------------------------------------
// llvm.Metadata
//-------------------------------------------------------------------------
func (c Context) TemporaryMDNode(mds []Metadata) (md Metadata) {
ptr, nvals := llvmMetadataRefs(mds)
md.C = C.LLVMTemporaryMDNode(c.C, ptr, C.size_t(nvals))
return
}
func (md Metadata) ReplaceAllUsesWith(new Metadata) {
C.LLVMMetadataReplaceAllUsesWith(md.C, new.C)
}
type MetadataKind C.LLVMMetadataKind
const (
MDStringMetadataKind = C.LLVMMDStringMetadataKind
ConstantAsMetadataMetadataKind = C.LLVMConstantAsMetadataMetadataKind
LocalAsMetadataMetadataKind = C.LLVMLocalAsMetadataMetadataKind
DistinctMDOperandPlaceholderMetadataKind = C.LLVMDistinctMDOperandPlaceholderMetadataKind
MDTupleMetadataKind = C.LLVMMDTupleMetadataKind
DILocationMetadataKind = C.LLVMDILocationMetadataKind
DIExpressionMetadataKind = C.LLVMDIExpressionMetadataKind
DIGlobalVariableExpressionMetadataKind = C.LLVMDIGlobalVariableExpressionMetadataKind
GenericDINodeMetadataKind = C.LLVMGenericDINodeMetadataKind
DISubrangeMetadataKind = C.LLVMDISubrangeMetadataKind
DIEnumeratorMetadataKind = C.LLVMDIEnumeratorMetadataKind
DIBasicTypeMetadataKind = C.LLVMDIBasicTypeMetadataKind
DIDerivedTypeMetadataKind = C.LLVMDIDerivedTypeMetadataKind
DICompositeTypeMetadataKind = C.LLVMDICompositeTypeMetadataKind
DISubroutineTypeMetadataKind = C.LLVMDISubroutineTypeMetadataKind
DIFileMetadataKind = C.LLVMDIFileMetadataKind
DICompileUnitMetadataKind = C.LLVMDICompileUnitMetadataKind
DISubprogramMetadataKind = C.LLVMDISubprogramMetadataKind
DILexicalBlockMetadataKind = C.LLVMDILexicalBlockMetadataKind
DILexicalBlockFileMetadataKind = C.LLVMDILexicalBlockFileMetadataKind
DINamespaceMetadataKind = C.LLVMDINamespaceMetadataKind
DIModuleMetadataKind = C.LLVMDIModuleMetadataKind
DITemplateTypeParameterMetadataKind = C.LLVMDITemplateTypeParameterMetadataKind
DITemplateValueParameterMetadataKind = C.LLVMDITemplateValueParameterMetadataKind
DIGlobalVariableMetadataKind = C.LLVMDIGlobalVariableMetadataKind
DILocalVariableMetadataKind = C.LLVMDILocalVariableMetadataKind
DILabelMetadataKind = C.LLVMDILabelMetadataKind
DIObjCPropertyMetadataKind = C.LLVMDIObjCPropertyMetadataKind
DIImportedEntityMetadataKind = C.LLVMDIImportedEntityMetadataKind
DIMacroMetadataKind = C.LLVMDIMacroMetadataKind
DIMacroFileMetadataKind = C.LLVMDIMacroFileMetadataKind
DICommonBlockMetadataKind = C.LLVMDICommonBlockMetadataKind
)
// Kind returns the metadata kind.
func (md Metadata) Kind() MetadataKind {
return MetadataKind(C.LLVMGetMetadataKind(md.C))
}
// FileDirectory returns the directory of a DIFile metadata node.
func (md Metadata) FileDirectory() string {
var length C.unsigned
ptr := C.LLVMDIFileGetDirectory(md.C, &length)
return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
}
// FileFilename returns the filename of a DIFile metadata node.
func (md Metadata) FileFilename() string {
var length C.unsigned
ptr := C.LLVMDIFileGetFilename(md.C, &length)
return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
}
// FileSource returns the source of a DIFile metadata node.
func (md Metadata) FileSource() string {
var length C.unsigned
ptr := C.LLVMDIFileGetSource(md.C, &length)
return string(((*[1 << 20]byte)(unsafe.Pointer(ptr)))[:length:length])
}
// LocationLine returns the line number of a DILocation.
func (md Metadata) LocationLine() uint {
return uint(C.LLVMDILocationGetLine(md.C))
}
// LocationColumn returns the column (offset from the start of the line) of a
// DILocation.
func (md Metadata) LocationColumn() uint {
return uint(C.LLVMDILocationGetColumn(md.C))
}
// LocationScope returns the local scope associated with this debug location.
func (md Metadata) LocationScope() Metadata {
return Metadata{C.LLVMDILocationGetScope(md.C)}
}
// LocationInlinedAt return the "inline at" location associated with this debug
// location.
func (md Metadata) LocationInlinedAt() Metadata {
return Metadata{C.LLVMDILocationGetInlinedAt(md.C)}
}
// ScopeFile returns the file (DIFile) of a given scope.
func (md Metadata) ScopeFile() Metadata {
return Metadata{C.LLVMDIScopeGetFile(md.C)}
}

View File

@ -1,177 +0,0 @@
//===- executionengine.go - Bindings for executionengine ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the executionengine component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm-c/Core.h"
#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 {
C C.struct_LLVMMCJITCompilerOptions
}
func (options *MCJITCompilerOptions) SetMCJITOptimizationLevel(level uint) {
options.C.OptLevel = C.uint(level)
}
func (options *MCJITCompilerOptions) SetMCJITNoFramePointerElim(nfp bool) {
options.C.NoFramePointerElim = boolToLLVMBool(nfp)
}
func (options *MCJITCompilerOptions) SetMCJITEnableFastISel(fastisel bool) {
options.C.EnableFastISel = boolToLLVMBool(fastisel)
}
func (options *MCJITCompilerOptions) SetMCJITCodeModel(CodeModel CodeModel) {
options.C.CodeModel = C.LLVMCodeModel(CodeModel)
}
// 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 NewMCJITCompilerOptions() MCJITCompilerOptions {
var options C.struct_LLVMMCJITCompilerOptions
C.LLVMInitializeMCJITCompilerOptions(&options, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})))
return MCJITCompilerOptions{options}
}
func NewMCJITCompiler(m Module, options MCJITCompilerOptions) (ee ExecutionEngine, err error) {
var cmsg *C.char
fail := C.LLVMCreateMCJITCompilerForModule(&ee.C, m.C, &options.C, C.size_t(unsafe.Sizeof(C.struct_LLVMMCJITCompilerOptions{})), &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)
}

View File

@ -1,95 +0,0 @@
//===- executionengine_test.go - Tests for executionengine ----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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
}
options := NewMCJITCompilerOptions()
options.SetMCJITOptimizationLevel(2)
options.SetMCJITEnableFastISel(true)
options.SetMCJITNoFramePointerElim(true)
options.SetMCJITCodeModel(CodeModelJITDefault)
engine, err := NewMCJITCompiler(mod, options)
if err != nil {
t.Errorf("Error creating JIT: %s", err)
return
}
defer engine.Dispose()
pass := NewPassManager()
defer pass.Dispose()
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))
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,164 +0,0 @@
//===- ir_test.go - Tests for ir ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file tests bindings for the ir component.
//
//===----------------------------------------------------------------------===//
package llvm
import (
"strings"
"testing"
)
func testAttribute(t *testing.T, name string) {
mod := NewModule("")
defer mod.Dispose()
ftyp := FunctionType(VoidType(), nil, false)
fn := AddFunction(mod, "foo", ftyp)
kind := AttributeKindID(name)
attr := mod.Context().CreateEnumAttribute(kind, 0)
fn.AddFunctionAttr(attr)
newattr := fn.GetEnumFunctionAttribute(kind)
if attr != newattr {
t.Errorf("got attribute %p, want %p", newattr.C, attr.C)
}
text := mod.String()
if !strings.Contains(text, " "+name+" ") {
t.Errorf("expected attribute '%s', got:\n%s", name, text)
}
fn.RemoveEnumFunctionAttribute(kind)
newattr = fn.GetEnumFunctionAttribute(kind)
if !newattr.IsNil() {
t.Errorf("got attribute %p, want 0", newattr.C)
}
}
func TestAttributes(t *testing.T) {
// Tests that our attribute constants haven't drifted from LLVM's.
attrTests := []string{
"sanitize_address",
"alwaysinline",
"builtin",
"convergent",
"inlinehint",
"inreg",
"jumptable",
"minsize",
"naked",
"nest",
"noalias",
"nobuiltin",
"nocapture",
"noduplicate",
"noimplicitfloat",
"noinline",
"nonlazybind",
"nonnull",
"noredzone",
"noreturn",
"nounwind",
"nosanitize_bounds",
"nosanitize_coverage",
"optnone",
"optsize",
"readnone",
"readonly",
"returned",
"returns_twice",
"signext",
"safestack",
"ssp",
"sspreq",
"sspstrong",
"sanitize_thread",
"sanitize_memory",
"zeroext",
"cold",
"nocf_check",
}
for _, name := range attrTests {
testAttribute(t, name)
}
}
func TestDebugLoc(t *testing.T) {
mod := NewModule("")
defer mod.Dispose()
ctx := mod.Context()
b := ctx.NewBuilder()
defer b.Dispose()
d := NewDIBuilder(mod)
defer func() {
d.Destroy()
}()
file := d.CreateFile("dummy_file", "dummy_dir")
voidInfo := d.CreateBasicType(DIBasicType{Name: "void"})
typeInfo := d.CreateSubroutineType(DISubroutineType{
File: file,
Parameters: []Metadata{voidInfo},
Flags: 0,
})
scope := d.CreateFunction(file, DIFunction{
Name: "foo",
LinkageName: "foo",
Line: 10,
ScopeLine: 10,
Type: typeInfo,
File: file,
IsDefinition: true,
})
b.SetCurrentDebugLocation(10, 20, scope, Metadata{})
loc := b.GetCurrentDebugLocation()
if loc.Line != 10 {
t.Errorf("Got line %d, though wanted 10", loc.Line)
}
if loc.Col != 20 {
t.Errorf("Got column %d, though wanted 20", loc.Col)
}
if loc.Scope.C != scope.C {
t.Errorf("Got metadata %v as scope, though wanted %v", loc.Scope.C, scope.C)
}
}
func TestSubtypes(t *testing.T) {
cont := NewContext()
defer cont.Dispose()
int_pointer := PointerType(cont.Int32Type(), 0)
int_inner := int_pointer.Subtypes()
if len(int_inner) != 1 {
t.Errorf("Got size %d, though wanted 1", len(int_inner))
}
if int_inner[0] != cont.Int32Type() {
t.Errorf("Expected int32 type")
}
st_pointer := cont.StructType([]Type{cont.Int32Type(), cont.Int8Type()}, false)
st_inner := st_pointer.Subtypes()
if len(st_inner) != 2 {
t.Errorf("Got size %d, though wanted 2", len(int_inner))
}
if st_inner[0] != cont.Int32Type() {
t.Errorf("Expected first struct field to be int32")
}
if st_inner[1] != cont.Int8Type() {
t.Errorf("Expected second struct field to be int8")
}
}

View File

@ -1,30 +0,0 @@
//===- linker.go - Bindings for linker ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the linker component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm-c/Core.h"
#include "llvm-c/Linker.h"
#include <stdlib.h>
*/
import "C"
import "errors"
func LinkModules(Dest, Src Module) error {
failed := C.LLVMLinkModules2(Dest.C, Src.C)
if failed != 0 {
err := errors.New("Linking failed")
return err
}
return nil
}

View File

@ -1,12 +0,0 @@
// +build !byollvm
package llvm
/*
#cgo CXXFLAGS: -std=c++14
#cgo CPPFLAGS: @LLVM_CFLAGS@
#cgo LDFLAGS: @LLVM_LDFLAGS@
*/
import "C"
type (run_build_sh int)

View File

@ -1,18 +0,0 @@
//===- llvm_dep.go - creates LLVM dependency ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file ensures that the LLVM libraries are built before using the
// bindings.
//
//===----------------------------------------------------------------------===//
// +build !byollvm
package llvm
var _ run_build_sh

View File

@ -1,106 +0,0 @@
//===- string.go - Stringer implementation for Type -----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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 MetadataTypeKind:
return "MetadataTypeKind"
case VectorTypeKind:
return "VectorTypeKind"
case ScalableVectorTypeKind:
return "ScalableVectorTypeKind"
}
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
}

View File

@ -1,27 +0,0 @@
//===- string_test.go - test Stringer implementation for Type -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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)
}
}

View File

@ -1,53 +0,0 @@
//===- support.go - Bindings for support ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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)
}

View File

@ -1,296 +0,0 @@
//===- target.go - Bindings for target ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the target component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm-c/Core.h"
#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
CodeModelTiny CodeModel = C.LLVMCodeModelTiny
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
}
// 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
}
// CreateTargetData returns a new TargetData describing the TargetMachine's
// data layout. The returned TargetData is owned by the caller, who is
// responsible for disposing of it by calling the TargetData.Dispose method.
func (tm TargetMachine) CreateTargetData() TargetData {
return TargetData{C.LLVMCreateTargetDataLayout(tm.C)}
}
// Triple returns the triple describing the machine (arch-vendor-os).
func (tm TargetMachine) Triple() string {
cstr := C.LLVMGetTargetMachineTriple(tm.C)
return C.GoString(cstr)
}
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
}

View File

@ -1,29 +0,0 @@
//===- transforms_instrumentation.go - Bindings for instrumentation -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the instrumentation component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "InstrumentationBindings.h"
#include <stdlib.h>
*/
import "C"
import "unsafe"
func (pm PassManager) AddDataFlowSanitizerPass(abilist []string) {
abiliststrs := make([]*C.char, len(abilist))
for i, arg := range abilist {
abiliststrs[i] = C.CString(arg)
defer C.free(unsafe.Pointer(abiliststrs[i]))
}
C.LLVMAddDataFlowSanitizerPass(pm.C, C.int(len(abilist)), &abiliststrs[0])
}

View File

@ -1,38 +0,0 @@
//===- transforms_ipo.go - Bindings for ipo -------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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) 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) 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) }

View File

@ -1,63 +0,0 @@
//===- transforms_pmbuilder.go - Bindings for PassManagerBuilder ----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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)
}
func (pmb PassManagerBuilder) SetDisableUnitAtATime(val bool) {
C.LLVMPassManagerBuilderSetDisableUnitAtATime(pmb.C, boolToLLVMBool(val))
}
func (pmb PassManagerBuilder) SetDisableUnrollLoops(val bool) {
C.LLVMPassManagerBuilderSetDisableUnrollLoops(pmb.C, boolToLLVMBool(val))
}
func (pmb PassManagerBuilder) SetDisableSimplifyLibCalls(val bool) {
C.LLVMPassManagerBuilderSetDisableSimplifyLibCalls(pmb.C, boolToLLVMBool(val))
}
func (pmb PassManagerBuilder) UseInlinerWithThreshold(threshold uint) {
C.LLVMPassManagerBuilderUseInlinerWithThreshold(pmb.C, C.uint(threshold))
}

View File

@ -1,43 +0,0 @@
//===- transforms_scalar.go - Bindings for scalaropts ---------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines bindings for the scalaropts component.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/Transforms/Utils.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) 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) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) }
func (pm PassManager) AddVerifierPass() { C.LLVMAddVerifierPass(pm.C) }

View File

@ -1,20 +0,0 @@
//===- version.go - LLVM version info -------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines LLVM version information.
//
//===----------------------------------------------------------------------===//
package llvm
/*
#include "llvm/Config/llvm-config.h"
*/
import "C"
const Version = C.LLVM_VERSION_STRING

View File

@ -603,25 +603,6 @@ else()
message(STATUS "Doxygen disabled.")
endif()
set(LLVM_BINDINGS "")
find_program(GO_EXECUTABLE NAMES go DOC "go executable")
if(WIN32 OR NOT LLVM_ENABLE_BINDINGS)
message(STATUS "Go bindings disabled.")
else()
if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
message(STATUS "Go bindings disabled.")
else()
execute_process(COMMAND ${GO_EXECUTABLE} run ${PROJECT_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()
endif()
find_program(GOLD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.gold ld.gold ${LLVM_DEFAULT_TARGET_TRIPLE}-ld ld DOC "The gold linker")
set(LLVM_BINUTILS_INCDIR "" CACHE PATH
"PATH to binutils/include containing plugin-api.h for gold plugin.")
@ -659,6 +640,7 @@ if(CMAKE_HOST_APPLE AND APPLE)
endif()
# Keep the version requirements in sync with bindings/ocaml/README.txt.
set(LLVM_BINDINGS "")
include(FindOCaml)
include(AddOCaml)
if(WIN32 OR NOT LLVM_ENABLE_BINDINGS)

View File

@ -1,5 +0,0 @@
; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
; REQUIRES: shell, default_triple
;; Building Go bindings with Clang is currently unsupported on AIX.
; UNSUPPORTED: asan, ubsan, msan, -aix

View File

@ -1,63 +0,0 @@
import os
import pipes
import shlex
import sys
if not 'go' in config.root.llvm_bindings:
config.unsupported = True
if not config.root.include_go_tests:
config.unsupported = True
if config.have_tf_aot or config.have_tf_api:
config.unsupported = True
def find_executable(executable, path=None):
if path is None:
path = os.environ['PATH']
paths = path.split(os.pathsep)
base, ext = os.path.splitext(executable)
if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
executable = executable + '.exe'
if not os.path.isfile(executable):
for p in paths:
f = os.path.join(p, executable)
if os.path.isfile(f):
return f
return None
else:
return executable
# 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.
#
# Go tools also have problems with ccache, so we disable it.
def fixup_compiler_path(compiler):
args = shlex.split(compiler)
if args[0].endswith('ccache') or args[0].endswith('gomacc'):
args = args[1:]
path = find_executable(args[0])
try:
if path.endswith('/cc') and os.readlink(path) == 'clang':
args[0] = path[:len(path)-2] + 'clang'
except (AttributeError, OSError):
pass
try:
if path.endswith('/c++') and os.readlink(path) == 'clang++':
args[0] = path[:len(path)-3] + 'clang++'
except (AttributeError, OSError):
pass
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)
config.environment['CGO_LDFLAGS'] = config.host_ldflags

View File

@ -162,10 +162,6 @@ if(TARGET LLVMgold)
set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} LLVMgold)
endif()
if(TARGET llvm-go)
set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} llvm-go)
endif()
if(TARGET LTO)
set(LLVM_TEST_DEPENDS ${LLVM_TEST_DEPENDS} LTO)
endif()

View File

@ -142,7 +142,6 @@ tools = [
ToolSubst('%llvm', FindTool('llvm'), unresolved='ignore'),
ToolSubst('%lli', FindTool('lli'), post='.', extra_args=lli_args),
ToolSubst('%llc_dwarf', FindTool('llc'), extra_args=llc_args),
ToolSubst('%go', config.go_executable, unresolved='ignore'),
ToolSubst('%gold', config.gold_executable, unresolved='ignore'),
ToolSubst('%ld64', ld64_cmd, unresolved='ignore'),
ToolSubst('%ocamlc', ocamlc_command, unresolved='ignore'),
@ -175,7 +174,6 @@ tools.extend([
# The following tools are optional
tools.extend([
ToolSubst('llvm-go', unresolved='ignore'),
ToolSubst('llvm-mt', unresolved='ignore'),
ToolSubst('Kaleidoscope-Ch3', unresolved='ignore'),
ToolSubst('Kaleidoscope-Ch4', unresolved='ignore'),

View File

@ -22,7 +22,6 @@ config.ocamlfind_executable = "@OCAMLFIND@"
config.have_ocamlopt = @HAVE_OCAMLOPT@
config.ocaml_flags = "@OCAMLFLAGS@"
config.include_go_tests = @LLVM_INCLUDE_GO_TESTS@
config.go_executable = "@GO_EXECUTABLE@"
config.ptxas_executable = "@PTXAS_EXECUTABLE@"
config.enable_shared = @ENABLE_SHARED@
config.enable_assertions = @ENABLE_ASSERTIONS@

View File

@ -1,9 +0,0 @@
if(LLVM_BINDINGS MATCHES "go")
set(binpath ${CMAKE_BINARY_DIR}/bin/llvm-go${CMAKE_EXECUTABLE_SUFFIX})
add_custom_command(OUTPUT ${binpath}
COMMAND ${GO_EXECUTABLE} build -o ${binpath} llvm-go.go
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/llvm-go.go
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Building Go executable llvm-go")
add_custom_target(llvm-go ALL DEPENDS ${binpath})
endif()

View File

@ -1,315 +0,0 @@
//===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This tool lets us build LLVM components within the tree by setting up a
// $GOPATH that resembles a tree fetched in the normal way with "go get".
//
//===----------------------------------------------------------------------===//
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
)
const (
linkmodeComponentLibs = "component-libs"
linkmodeDylib = "dylib"
)
type pkg struct {
llvmpath, pkgpath string
}
var packages = []pkg{
{"bindings/go/llvm", "llvm.org/llvm/bindings/go/llvm"},
}
type compilerFlags struct {
cpp, cxx, ld string
}
var components = []string{
"all-targets",
"analysis",
"asmparser",
"asmprinter",
"bitreader",
"bitwriter",
"codegen",
"core",
"coroutines",
"debuginfodwarf",
"executionengine",
"instrumentation",
"interpreter",
"ipo",
"irreader",
"linker",
"mc",
"mcjit",
"objcarcopts",
"option",
"profiledata",
"scalaropts",
"support",
"target",
}
func llvmConfig(args ...string) string {
configpath := os.Getenv("LLVM_CONFIG")
if configpath == "" {
bin, _ := filepath.Split(os.Args[0])
configpath = filepath.Join(bin, "llvm-config")
}
cmd := exec.Command(configpath, args...)
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
panic(err.Error())
}
outstr := string(out)
outstr = strings.TrimSuffix(outstr, "\n")
outstr = strings.Replace(outstr, "\n", " ", -1)
return outstr
}
func llvmFlags() compilerFlags {
args := append([]string{"--ldflags", "--libs", "--system-libs"}, components...)
ldflags := llvmConfig(args...)
stdLibOption := ""
if strings.Contains(llvmConfig("--cxxflags"), "-stdlib=libc++") {
// If libc++ is used to build LLVM libraries, -stdlib=libc++ is
// needed to resolve dependent symbols
stdLibOption = "-stdlib=libc++"
}
if runtime.GOOS == "aix" {
// AIX linker does not honour `-rpath`, the closest substitution
// is `-blibpath`
ldflags = "-Wl,-blibpath:" + llvmConfig("--libdir") + " " + ldflags
} else if runtime.GOOS != "darwin" {
// OS X doesn't like -rpath with cgo. See:
// https://github.com/golang/go/issues/7293
ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags
}
return compilerFlags{
cpp: llvmConfig("--cppflags"),
cxx: "-std=c++14" + " " + stdLibOption,
ld: ldflags,
}
}
func addTag(args []string, tag string) []string {
args = append([]string{}, args...)
addedTag := false
for i, a := range args {
if strings.HasPrefix(a, "-tags=") {
args[i] = a + " " + tag
addedTag = true
} else if a == "-tags" && i+1 < len(args) {
args[i+1] = args[i+1] + " " + tag
addedTag = true
}
}
if !addedTag {
args = append([]string{args[0], "-tags", tag}, args[1:]...)
}
return args
}
func printComponents() {
fmt.Println(strings.Join(components, " "))
}
func printConfig() {
flags := llvmFlags()
fmt.Printf(`// +build !byollvm
// This file is generated by llvm-go, do not edit.
package llvm
/*
#cgo CPPFLAGS: %s
#cgo CXXFLAGS: %s
#cgo LDFLAGS: %s
*/
import "C"
type (run_build_sh int)
`, flags.cpp, flags.cxx, flags.ld)
}
func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string, packages []pkg) {
args = addTag(args, "byollvm")
srcdir := llvmConfig("--src-root")
tmpgopath, err := ioutil.TempDir("", "gopath")
if err != nil {
panic(err.Error())
}
for _, p := range packages {
path := filepath.Join(tmpgopath, "src", p.pkgpath)
err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
if err != nil {
panic(err.Error())
}
abspath := p.llvmpath
if !filepath.IsAbs(abspath) {
abspath = filepath.Join(srcdir, abspath)
}
err = os.Symlink(abspath, path)
if err != nil {
panic(err.Error())
}
}
newpath := os.Getenv("PATH")
newgopathlist := []string{tmpgopath}
newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
flags := llvmFlags()
newenv := []string{
"CC=" + cc,
"CXX=" + cxx,
"CGO_CPPFLAGS=" + flags.cpp + " " + cppflags,
"CGO_CXXFLAGS=" + flags.cxx + " " + cxxflags,
"CGO_LDFLAGS=" + flags.ld + " " + ldflags,
"GOPATH=" + newgopath,
"PATH=" + newpath,
}
if llgo != "" {
newenv = append(newenv, "GCCGO="+llgo)
}
for _, v := range os.Environ() {
if !strings.HasPrefix(v, "CC=") &&
!strings.HasPrefix(v, "CXX=") &&
!strings.HasPrefix(v, "CGO_CPPFLAGS=") &&
!strings.HasPrefix(v, "CGO_CXXFLAGS=") &&
!strings.HasPrefix(v, "CGO_LDFLAGS=") &&
!strings.HasPrefix(v, "GCCGO=") &&
!strings.HasPrefix(v, "GOPATH=") &&
!strings.HasPrefix(v, "PATH=") {
newenv = append(newenv, v)
}
}
gocmdpath, err := exec.LookPath(gocmd)
if err != nil {
panic(err.Error())
}
proc, err := os.StartProcess(gocmdpath, append([]string{gocmd}, args...),
&os.ProcAttr{
Env: newenv,
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
})
if err != nil {
panic(err.Error())
}
ps, err := proc.Wait()
if err != nil {
panic(err.Error())
}
os.RemoveAll(tmpgopath)
if !ps.Success() {
os.Exit(1)
}
}
func usage() {
fmt.Println(`Usage: llvm-go subcommand [flags]
Available subcommands: build get install run test print-components print-config`)
os.Exit(0)
}
func main() {
cc := os.Getenv("CC")
cxx := os.Getenv("CXX")
cppflags := os.Getenv("CGO_CPPFLAGS")
cxxflags := os.Getenv("CGO_CXXFLAGS")
ldflags := os.Getenv("CGO_LDFLAGS")
gocmd := "go"
llgo := ""
packagesString := ""
flags := []struct {
name string
dest *string
}{
{"cc", &cc},
{"cxx", &cxx},
{"go", &gocmd},
{"llgo", &llgo},
{"cppflags", &cppflags},
{"ldflags", &ldflags},
{"packages", &packagesString},
}
args := os.Args[1:]
LOOP:
for {
if len(args) == 0 {
usage()
}
for _, flag := range flags {
if strings.HasPrefix(args[0], flag.name+"=") {
*flag.dest = args[0][len(flag.name)+1:]
args = args[1:]
continue LOOP
}
}
break
}
packages := packages
if packagesString != "" {
for _, field := range strings.Fields(packagesString) {
pos := strings.IndexRune(field, '=')
if pos == -1 {
fmt.Fprintf(os.Stderr, "invalid packages value %q, expected 'pkgpath=llvmpath [pkgpath=llvmpath ...]'\n", packagesString)
os.Exit(1)
}
packages = append(packages, pkg{
pkgpath: field[:pos],
llvmpath: field[pos+1:],
})
}
}
switch args[0] {
case "build", "get", "install", "run", "test":
runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, packages)
case "print-components":
printComponents()
case "print-config":
printConfig()
default:
usage()
}
}

View File

@ -23,10 +23,6 @@ class FindTool(object):
if self.name == 'llc' and os.environ.get('LLVM_ENABLE_MACHINE_VERIFIER') == '1':
command += ' -verify-machineinstrs'
elif self.name == 'llvm-go':
exe = getattr(config.config, 'go_executable', None)
if exe:
command += ' go=' + exe
return command