diff --git a/llvm/bindings/go/build.sh b/llvm/bindings/go/build.sh deleted file mode 100755 --- a/llvm/bindings/go/build.sh +++ /dev/null @@ -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 diff --git a/llvm/bindings/go/llvm/IRBindings.h b/llvm/bindings/go/llvm/IRBindings.h deleted file mode 100644 --- a/llvm/bindings/go/llvm/IRBindings.h +++ /dev/null @@ -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 - -#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 diff --git a/llvm/bindings/go/llvm/IRBindings.cpp b/llvm/bindings/go/llvm/IRBindings.cpp deleted file mode 100644 --- a/llvm/bindings/go/llvm/IRBindings.cpp +++ /dev/null @@ -1,72 +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(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(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(Val)); -} - -void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) { - MDNode *N = MD ? unwrap(MD) : nullptr; - unwrap(Inst)->setMetadata(KindID, N); -} - -void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line, - unsigned Col, LLVMMetadataRef Scope, - LLVMMetadataRef InlinedAt) { - unwrap(Bref)->SetCurrentDebugLocation( - DebugLoc::get(Line, Col, Scope ? unwrap(Scope) : nullptr, - InlinedAt ? unwrap(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; -} - diff --git a/llvm/bindings/go/llvm/InstrumentationBindings.h b/llvm/bindings/go/llvm/InstrumentationBindings.h deleted file mode 100644 --- a/llvm/bindings/go/llvm/InstrumentationBindings.h +++ /dev/null @@ -1,37 +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 LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM); -void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM); -void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); -void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM); -void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum, - const char **ABIListFiles); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/llvm/bindings/go/llvm/InstrumentationBindings.cpp b/llvm/bindings/go/llvm/InstrumentationBindings.cpp deleted file mode 100644 --- a/llvm/bindings/go/llvm/InstrumentationBindings.cpp +++ /dev/null @@ -1,48 +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/Transforms/Instrumentation.h" -#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" -#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" -#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" - -using namespace llvm; - -void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createAddressSanitizerFunctionPass()); -} - -void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createModuleAddressSanitizerLegacyPassPass()); -} - -void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createThreadSanitizerLegacyPassPass()); -} - -void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) { - unwrap(PM)->add(createMemorySanitizerLegacyPassPass()); -} - -void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, - int ABIListFilesNum, - const char **ABIListFiles) { - std::vector ABIListFilesVec; - for (int i = 0; i != ABIListFilesNum; ++i) { - ABIListFilesVec.push_back(ABIListFiles[i]); - } - unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec)); -} diff --git a/llvm/bindings/go/llvm/SupportBindings.h b/llvm/bindings/go/llvm/SupportBindings.h deleted file mode 100644 --- a/llvm/bindings/go/llvm/SupportBindings.h +++ /dev/null @@ -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 diff --git a/llvm/bindings/go/llvm/SupportBindings.cpp b/llvm/bindings/go/llvm/SupportBindings.cpp deleted file mode 100644 --- a/llvm/bindings/go/llvm/SupportBindings.cpp +++ /dev/null @@ -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 -#include - -void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) { - std::string ErrMsgStr; - if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) { - *ErrMsg = static_cast(malloc(ErrMsgStr.size() + 1)); - memcpy(static_cast(*ErrMsg), - static_cast(ErrMsgStr.c_str()), ErrMsgStr.size() + 1); - } -} diff --git a/llvm/bindings/go/llvm/analysis.go b/llvm/bindings/go/llvm/analysis.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/analysis.go +++ /dev/null @@ -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 -*/ -import "C" -import "errors" - -type VerifierFailureAction C.LLVMVerifierFailureAction - -const ( - // verifier will print to stderr and abort() - AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction - // verifier will print to stderr and return 1 - PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction - // verifier will just return 1 - ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction -) - -// Verifies that a module is valid, taking the specified action if not. -// Optionally returns a human-readable description of any invalid constructs. -func VerifyModule(m Module, a VerifierFailureAction) error { - var cmsg *C.char - broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg) - - // C++'s verifyModule means isModuleBroken, so it returns false if - // there are no errors - if broken != 0 { - err := errors.New(C.GoString(cmsg)) - C.LLVMDisposeMessage(cmsg) - return err - } - return nil -} - -var verifyFunctionError = errors.New("Function is broken") - -// Verifies that a single function is valid, taking the specified action. -// Useful for debugging. -func VerifyFunction(f Value, a VerifierFailureAction) error { - broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a)) - - // C++'s verifyFunction means isFunctionBroken, so it returns false if - // there are no errors - if broken != 0 { - return verifyFunctionError - } - return nil -} - -// Open up a ghostview window that displays the CFG of the current function. -// Useful for debugging. -func ViewFunctionCFG(f Value) { C.LLVMViewFunctionCFG(f.C) } -func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) } diff --git a/llvm/bindings/go/llvm/bitreader.go b/llvm/bindings/go/llvm/bitreader.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/bitreader.go +++ /dev/null @@ -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 -*/ -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 -} diff --git a/llvm/bindings/go/llvm/bitwriter.go b/llvm/bindings/go/llvm/bitwriter.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/bitwriter.go +++ /dev/null @@ -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 -*/ -import "C" -import "os" -import "errors" - -var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file") - -func WriteBitcodeToFile(m Module, file *os.File) error { - fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0)) - if fail != 0 { - return writeBitcodeToFileErr - } - return nil -} - -func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer { - mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C) - return MemoryBuffer{mb} -} - -// TODO(nsf): Figure out way how to make it work with io.Writer diff --git a/llvm/bindings/go/llvm/dibuilder.go b/llvm/bindings/go/llvm/dibuilder.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/dibuilder.go +++ /dev/null @@ -1,707 +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 -*/ -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 -} - -// 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)) - 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)), - ) - 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 []int64) Metadata { - var data *C.int64_t - if len(addr) > 0 { - data = (*C.int64_t)(unsafe.Pointer(&addr[0])) - } - result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr))) - return 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)} -} diff --git a/llvm/bindings/go/llvm/executionengine.go b/llvm/bindings/go/llvm/executionengine.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/executionengine.go +++ /dev/null @@ -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 -*/ -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) -} diff --git a/llvm/bindings/go/llvm/executionengine_test.go b/llvm/bindings/go/llvm/executionengine_test.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/executionengine_test.go +++ /dev/null @@ -1,96 +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.AddConstantPropagationPass() - pass.AddInstructionCombiningPass() - pass.AddPromoteMemoryToRegisterPass() - pass.AddGVNPass() - pass.AddCFGSimplificationPass() - pass.Run(mod) - - exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)} - exec_res := engine.RunFunction(fac, exec_args) - var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 - if exec_res.Int(false) != fac10 { - t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false)) - } -} diff --git a/llvm/bindings/go/llvm/ir.go b/llvm/bindings/go/llvm/ir.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/ir.go +++ /dev/null @@ -1,2014 +0,0 @@ -//===- ir.go - 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 bindings for the ir component. -// -//===----------------------------------------------------------------------===// - -package llvm - -/* -#include "llvm-c/Core.h" -#include "llvm-c/Comdat.h" -#include "IRBindings.h" -#include -*/ -import "C" -import "unsafe" -import "errors" - -type ( - // We use these weird structs here because *Ref types are pointers and - // Go's spec says that a pointer cannot be used as a receiver base type. - Context struct { - C C.LLVMContextRef - } - Module struct { - C C.LLVMModuleRef - } - Type struct { - C C.LLVMTypeRef - } - Value struct { - C C.LLVMValueRef - } - Comdat struct { - C C.LLVMComdatRef - } - BasicBlock struct { - C C.LLVMBasicBlockRef - } - Builder struct { - C C.LLVMBuilderRef - } - ModuleProvider struct { - C C.LLVMModuleProviderRef - } - MemoryBuffer struct { - C C.LLVMMemoryBufferRef - } - PassManager struct { - C C.LLVMPassManagerRef - } - Use struct { - C C.LLVMUseRef - } - Metadata struct { - C C.LLVMMetadataRef - } - Attribute struct { - C C.LLVMAttributeRef - } - Opcode C.LLVMOpcode - AtomicRMWBinOp C.LLVMAtomicRMWBinOp - AtomicOrdering C.LLVMAtomicOrdering - TypeKind C.LLVMTypeKind - Linkage C.LLVMLinkage - Visibility C.LLVMVisibility - CallConv C.LLVMCallConv - ComdatSelectionKind C.LLVMComdatSelectionKind - IntPredicate C.LLVMIntPredicate - FloatPredicate C.LLVMRealPredicate - LandingPadClause C.LLVMLandingPadClauseTy - InlineAsmDialect C.LLVMInlineAsmDialect -) - -func (c Context) IsNil() bool { return c.C == nil } -func (c Module) IsNil() bool { return c.C == nil } -func (c Type) IsNil() bool { return c.C == nil } -func (c Value) IsNil() bool { return c.C == nil } -func (c BasicBlock) IsNil() bool { return c.C == nil } -func (c Builder) IsNil() bool { return c.C == nil } -func (c ModuleProvider) IsNil() bool { return c.C == nil } -func (c MemoryBuffer) IsNil() bool { return c.C == nil } -func (c PassManager) IsNil() bool { return c.C == nil } -func (c Use) IsNil() bool { return c.C == nil } -func (c Attribute) IsNil() bool { return c.C == nil } -func (c Metadata) IsNil() bool { return c.C == nil } - -// helpers -func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) } -func llvmValueRefPtr(t *Value) *C.LLVMValueRef { return (*C.LLVMValueRef)(unsafe.Pointer(t)) } -func llvmMetadataRefPtr(t *Metadata) *C.LLVMMetadataRef { - return (*C.LLVMMetadataRef)(unsafe.Pointer(t)) -} -func llvmBasicBlockRefPtr(t *BasicBlock) *C.LLVMBasicBlockRef { - return (*C.LLVMBasicBlockRef)(unsafe.Pointer(t)) -} -func boolToLLVMBool(b bool) C.LLVMBool { - if b { - return C.LLVMBool(1) - } - return C.LLVMBool(0) -} - -func llvmValueRefs(values []Value) (*C.LLVMValueRef, C.unsigned) { - var pt *C.LLVMValueRef - ptlen := C.unsigned(len(values)) - if ptlen > 0 { - pt = llvmValueRefPtr(&values[0]) - } - return pt, ptlen -} - -func llvmMetadataRefs(mds []Metadata) (*C.LLVMMetadataRef, C.unsigned) { - var pt *C.LLVMMetadataRef - ptlen := C.unsigned(len(mds)) - if ptlen > 0 { - pt = llvmMetadataRefPtr(&mds[0]) - } - return pt, ptlen -} - -//------------------------------------------------------------------------- -// llvm.Opcode -//------------------------------------------------------------------------- - -const ( - Ret Opcode = C.LLVMRet - Br Opcode = C.LLVMBr - Switch Opcode = C.LLVMSwitch - IndirectBr Opcode = C.LLVMIndirectBr - Invoke Opcode = C.LLVMInvoke - Unreachable Opcode = C.LLVMUnreachable - - // Standard Binary Operators - Add Opcode = C.LLVMAdd - FAdd Opcode = C.LLVMFAdd - Sub Opcode = C.LLVMSub - FSub Opcode = C.LLVMFSub - Mul Opcode = C.LLVMMul - FMul Opcode = C.LLVMFMul - UDiv Opcode = C.LLVMUDiv - SDiv Opcode = C.LLVMSDiv - FDiv Opcode = C.LLVMFDiv - URem Opcode = C.LLVMURem - SRem Opcode = C.LLVMSRem - FRem Opcode = C.LLVMFRem - - // Logical Operators - Shl Opcode = C.LLVMShl - LShr Opcode = C.LLVMLShr - AShr Opcode = C.LLVMAShr - And Opcode = C.LLVMAnd - Or Opcode = C.LLVMOr - Xor Opcode = C.LLVMXor - - // Memory Operators - Alloca Opcode = C.LLVMAlloca - Load Opcode = C.LLVMLoad - Store Opcode = C.LLVMStore - GetElementPtr Opcode = C.LLVMGetElementPtr - - // Cast Operators - Trunc Opcode = C.LLVMTrunc - ZExt Opcode = C.LLVMZExt - SExt Opcode = C.LLVMSExt - FPToUI Opcode = C.LLVMFPToUI - FPToSI Opcode = C.LLVMFPToSI - UIToFP Opcode = C.LLVMUIToFP - SIToFP Opcode = C.LLVMSIToFP - FPTrunc Opcode = C.LLVMFPTrunc - FPExt Opcode = C.LLVMFPExt - PtrToInt Opcode = C.LLVMPtrToInt - IntToPtr Opcode = C.LLVMIntToPtr - BitCast Opcode = C.LLVMBitCast - - // Other Operators - ICmp Opcode = C.LLVMICmp - FCmp Opcode = C.LLVMFCmp - PHI Opcode = C.LLVMPHI - Call Opcode = C.LLVMCall - Select Opcode = C.LLVMSelect - // UserOp1 - // UserOp2 - VAArg Opcode = C.LLVMVAArg - ExtractElement Opcode = C.LLVMExtractElement - InsertElement Opcode = C.LLVMInsertElement - ShuffleVector Opcode = C.LLVMShuffleVector - ExtractValue Opcode = C.LLVMExtractValue - InsertValue Opcode = C.LLVMInsertValue -) - -const ( - AtomicRMWBinOpXchg AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXchg - AtomicRMWBinOpAdd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAdd - AtomicRMWBinOpSub AtomicRMWBinOp = C.LLVMAtomicRMWBinOpSub - AtomicRMWBinOpAnd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAnd - AtomicRMWBinOpNand AtomicRMWBinOp = C.LLVMAtomicRMWBinOpNand - AtomicRMWBinOpOr AtomicRMWBinOp = C.LLVMAtomicRMWBinOpOr - AtomicRMWBinOpXor AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXor - AtomicRMWBinOpMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMax - AtomicRMWBinOpMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMin - AtomicRMWBinOpUMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMax - AtomicRMWBinOpUMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMin -) - -const ( - AtomicOrderingNotAtomic AtomicOrdering = C.LLVMAtomicOrderingNotAtomic - AtomicOrderingUnordered AtomicOrdering = C.LLVMAtomicOrderingUnordered - AtomicOrderingMonotonic AtomicOrdering = C.LLVMAtomicOrderingMonotonic - AtomicOrderingAcquire AtomicOrdering = C.LLVMAtomicOrderingAcquire - AtomicOrderingRelease AtomicOrdering = C.LLVMAtomicOrderingRelease - AtomicOrderingAcquireRelease AtomicOrdering = C.LLVMAtomicOrderingAcquireRelease - AtomicOrderingSequentiallyConsistent AtomicOrdering = C.LLVMAtomicOrderingSequentiallyConsistent -) - -//------------------------------------------------------------------------- -// llvm.TypeKind -//------------------------------------------------------------------------- - -const ( - VoidTypeKind TypeKind = C.LLVMVoidTypeKind - FloatTypeKind TypeKind = C.LLVMFloatTypeKind - DoubleTypeKind TypeKind = C.LLVMDoubleTypeKind - X86_FP80TypeKind TypeKind = C.LLVMX86_FP80TypeKind - FP128TypeKind TypeKind = C.LLVMFP128TypeKind - PPC_FP128TypeKind TypeKind = C.LLVMPPC_FP128TypeKind - LabelTypeKind TypeKind = C.LLVMLabelTypeKind - IntegerTypeKind TypeKind = C.LLVMIntegerTypeKind - FunctionTypeKind TypeKind = C.LLVMFunctionTypeKind - StructTypeKind TypeKind = C.LLVMStructTypeKind - ArrayTypeKind TypeKind = C.LLVMArrayTypeKind - PointerTypeKind TypeKind = C.LLVMPointerTypeKind - VectorTypeKind TypeKind = C.LLVMVectorTypeKind - MetadataTypeKind TypeKind = C.LLVMMetadataTypeKind - TokenTypeKind TypeKind = C.LLVMTokenTypeKind -) - -//------------------------------------------------------------------------- -// llvm.Linkage -//------------------------------------------------------------------------- - -const ( - ExternalLinkage Linkage = C.LLVMExternalLinkage - AvailableExternallyLinkage Linkage = C.LLVMAvailableExternallyLinkage - LinkOnceAnyLinkage Linkage = C.LLVMLinkOnceAnyLinkage - LinkOnceODRLinkage Linkage = C.LLVMLinkOnceODRLinkage - WeakAnyLinkage Linkage = C.LLVMWeakAnyLinkage - WeakODRLinkage Linkage = C.LLVMWeakODRLinkage - AppendingLinkage Linkage = C.LLVMAppendingLinkage - InternalLinkage Linkage = C.LLVMInternalLinkage - PrivateLinkage Linkage = C.LLVMPrivateLinkage - ExternalWeakLinkage Linkage = C.LLVMExternalWeakLinkage - CommonLinkage Linkage = C.LLVMCommonLinkage -) - -//------------------------------------------------------------------------- -// llvm.Visibility -//------------------------------------------------------------------------- - -const ( - DefaultVisibility Visibility = C.LLVMDefaultVisibility - HiddenVisibility Visibility = C.LLVMHiddenVisibility - ProtectedVisibility Visibility = C.LLVMProtectedVisibility -) - -//------------------------------------------------------------------------- -// llvm.CallConv -//------------------------------------------------------------------------- - -const ( - CCallConv CallConv = C.LLVMCCallConv - FastCallConv CallConv = C.LLVMFastCallConv - ColdCallConv CallConv = C.LLVMColdCallConv - X86StdcallCallConv CallConv = C.LLVMX86StdcallCallConv - X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv -) - -//------------------------------------------------------------------------- -// llvm.ComdatSelectionKind -//------------------------------------------------------------------------- - -const ( - AnyComdatSelectionKind ComdatSelectionKind = C.LLVMAnyComdatSelectionKind - ExactMatchComdatSelectionKind ComdatSelectionKind = C.LLVMExactMatchComdatSelectionKind - LargestComdatSelectionKind ComdatSelectionKind = C.LLVMLargestComdatSelectionKind - NoDuplicatesComdatSelectionKind ComdatSelectionKind = C.LLVMNoDuplicatesComdatSelectionKind - SameSizeComdatSelectionKind ComdatSelectionKind = C.LLVMSameSizeComdatSelectionKind -) - -//------------------------------------------------------------------------- -// llvm.IntPredicate -//------------------------------------------------------------------------- - -const ( - IntEQ IntPredicate = C.LLVMIntEQ - IntNE IntPredicate = C.LLVMIntNE - IntUGT IntPredicate = C.LLVMIntUGT - IntUGE IntPredicate = C.LLVMIntUGE - IntULT IntPredicate = C.LLVMIntULT - IntULE IntPredicate = C.LLVMIntULE - IntSGT IntPredicate = C.LLVMIntSGT - IntSGE IntPredicate = C.LLVMIntSGE - IntSLT IntPredicate = C.LLVMIntSLT - IntSLE IntPredicate = C.LLVMIntSLE -) - -//------------------------------------------------------------------------- -// llvm.FloatPredicate -//------------------------------------------------------------------------- - -const ( - FloatPredicateFalse FloatPredicate = C.LLVMRealPredicateFalse - FloatOEQ FloatPredicate = C.LLVMRealOEQ - FloatOGT FloatPredicate = C.LLVMRealOGT - FloatOGE FloatPredicate = C.LLVMRealOGE - FloatOLT FloatPredicate = C.LLVMRealOLT - FloatOLE FloatPredicate = C.LLVMRealOLE - FloatONE FloatPredicate = C.LLVMRealONE - FloatORD FloatPredicate = C.LLVMRealORD - FloatUNO FloatPredicate = C.LLVMRealUNO - FloatUEQ FloatPredicate = C.LLVMRealUEQ - FloatUGT FloatPredicate = C.LLVMRealUGT - FloatUGE FloatPredicate = C.LLVMRealUGE - FloatULT FloatPredicate = C.LLVMRealULT - FloatULE FloatPredicate = C.LLVMRealULE - FloatUNE FloatPredicate = C.LLVMRealUNE - FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue -) - -//------------------------------------------------------------------------- -// llvm.LandingPadClause -//------------------------------------------------------------------------- - -const ( - LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch - LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter -) - -//------------------------------------------------------------------------- -// llvm.InlineAsmDialect -//------------------------------------------------------------------------- - -const ( - InlineAsmDialectATT InlineAsmDialect = C.LLVMInlineAsmDialectATT - InlineAsmDialectIntel InlineAsmDialect = C.LLVMInlineAsmDialectIntel -) - -//------------------------------------------------------------------------- -// llvm.Context -//------------------------------------------------------------------------- - -func NewContext() Context { return Context{C.LLVMContextCreate()} } -func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} } -func (c Context) Dispose() { C.LLVMContextDispose(c.C) } - -func (c Context) MDKindID(name string) (id int) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - id = int(C.LLVMGetMDKindIDInContext(c.C, cname, C.unsigned(len(name)))) - return -} - -func MDKindID(name string) (id int) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name)))) - return -} - -//------------------------------------------------------------------------- -// llvm.Attribute -//------------------------------------------------------------------------- - -func AttributeKindID(name string) (id uint) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - id = uint(C.LLVMGetEnumAttributeKindForName(cname, C.size_t(len(name)))) - return -} - -func (c Context) CreateEnumAttribute(kind uint, val uint64) (a Attribute) { - a.C = C.LLVMCreateEnumAttribute(c.C, C.unsigned(kind), C.uint64_t(val)) - return -} - -func (a Attribute) GetEnumKind() (id int) { - id = int(C.LLVMGetEnumAttributeKind(a.C)) - return -} - -func (a Attribute) GetEnumValue() (val uint64) { - val = uint64(C.LLVMGetEnumAttributeValue(a.C)) - return -} - -func (c Context) CreateStringAttribute(kind string, val string) (a Attribute) { - ckind := C.CString(kind) - defer C.free(unsafe.Pointer(ckind)) - cval := C.CString(val) - defer C.free(unsafe.Pointer(cval)) - a.C = C.LLVMCreateStringAttribute(c.C, - ckind, C.unsigned(len(kind)), - cval, C.unsigned(len(val))) - return -} - -func (a Attribute) GetStringKind() string { - length := C.unsigned(0) - ckind := C.LLVMGetStringAttributeKind(a.C, &length) - return C.GoStringN(ckind, C.int(length)) -} - -func (a Attribute) GetStringValue() string { - length := C.unsigned(0) - ckind := C.LLVMGetStringAttributeValue(a.C, &length) - return C.GoStringN(ckind, C.int(length)) -} - -func (a Attribute) IsEnum() bool { - return C.LLVMIsEnumAttribute(a.C) != 0 -} - -func (a Attribute) IsString() bool { - return C.LLVMIsStringAttribute(a.C) != 0 -} - -//------------------------------------------------------------------------- -// llvm.Module -//------------------------------------------------------------------------- - -// Create and destroy modules. -// See llvm::Module::Module. -func NewModule(name string) (m Module) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - m.C = C.LLVMModuleCreateWithName(cname) - return -} - -func (c Context) NewModule(name string) (m Module) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - m.C = C.LLVMModuleCreateWithNameInContext(cname, c.C) - return -} - -// See llvm::Module::~Module -func (m Module) Dispose() { C.LLVMDisposeModule(m.C) } - -// Data layout. See Module::getDataLayout. -func (m Module) DataLayout() string { - clayout := C.LLVMGetDataLayout(m.C) - return C.GoString(clayout) -} - -func (m Module) SetDataLayout(layout string) { - clayout := C.CString(layout) - defer C.free(unsafe.Pointer(clayout)) - C.LLVMSetDataLayout(m.C, clayout) -} - -// Target triple. See Module::getTargetTriple. -func (m Module) Target() string { - ctarget := C.LLVMGetTarget(m.C) - return C.GoString(ctarget) -} -func (m Module) SetTarget(target string) { - ctarget := C.CString(target) - defer C.free(unsafe.Pointer(ctarget)) - C.LLVMSetTarget(m.C, ctarget) -} - -func (m Module) GetTypeByName(name string) (t Type) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - t.C = C.LLVMGetTypeByName(m.C, cname) - return -} - -// See Module::dump. -func (m Module) Dump() { - C.LLVMDumpModule(m.C) -} - -func (m Module) String() string { - cir := C.LLVMPrintModuleToString(m.C) - defer C.free(unsafe.Pointer(cir)) - ir := C.GoString(cir) - return ir -} - -// See Module::setModuleInlineAsm. -func (m Module) SetInlineAsm(asm string) { - casm := C.CString(asm) - defer C.free(unsafe.Pointer(casm)) - C.LLVMSetModuleInlineAsm(m.C, casm) -} - -func (m Module) AddNamedMetadataOperand(name string, operand Metadata) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - C.LLVMAddNamedMetadataOperand2(m.C, cname, operand.C) -} - -func (m Module) Context() (c Context) { - c.C = C.LLVMGetModuleContext(m.C) - return -} - -//------------------------------------------------------------------------- -// llvm.Type -//------------------------------------------------------------------------- - -// LLVM types conform to the following hierarchy: -// -// types: -// integer type -// real type -// function type -// sequence types: -// array type -// pointer type -// vector type -// void type -// label type -// opaque type - -// See llvm::LLVMTypeKind::getTypeID. -func (t Type) TypeKind() TypeKind { return TypeKind(C.LLVMGetTypeKind(t.C)) } - -// See llvm::LLVMType::getContext. -func (t Type) Context() (c Context) { - c.C = C.LLVMGetTypeContext(t.C) - return -} - -// Operations on integer types -func (c Context) Int1Type() (t Type) { t.C = C.LLVMInt1TypeInContext(c.C); return } -func (c Context) Int8Type() (t Type) { t.C = C.LLVMInt8TypeInContext(c.C); return } -func (c Context) Int16Type() (t Type) { t.C = C.LLVMInt16TypeInContext(c.C); return } -func (c Context) Int32Type() (t Type) { t.C = C.LLVMInt32TypeInContext(c.C); return } -func (c Context) Int64Type() (t Type) { t.C = C.LLVMInt64TypeInContext(c.C); return } -func (c Context) IntType(numbits int) (t Type) { - t.C = C.LLVMIntTypeInContext(c.C, C.unsigned(numbits)) - return -} - -func Int1Type() (t Type) { t.C = C.LLVMInt1Type(); return } -func Int8Type() (t Type) { t.C = C.LLVMInt8Type(); return } -func Int16Type() (t Type) { t.C = C.LLVMInt16Type(); return } -func Int32Type() (t Type) { t.C = C.LLVMInt32Type(); return } -func Int64Type() (t Type) { t.C = C.LLVMInt64Type(); return } - -func IntType(numbits int) (t Type) { - t.C = C.LLVMIntType(C.unsigned(numbits)) - return -} - -func (t Type) IntTypeWidth() int { - return int(C.LLVMGetIntTypeWidth(t.C)) -} - -// Operations on real types -func (c Context) FloatType() (t Type) { t.C = C.LLVMFloatTypeInContext(c.C); return } -func (c Context) DoubleType() (t Type) { t.C = C.LLVMDoubleTypeInContext(c.C); return } -func (c Context) X86FP80Type() (t Type) { t.C = C.LLVMX86FP80TypeInContext(c.C); return } -func (c Context) FP128Type() (t Type) { t.C = C.LLVMFP128TypeInContext(c.C); return } -func (c Context) PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128TypeInContext(c.C); return } - -func FloatType() (t Type) { t.C = C.LLVMFloatType(); return } -func DoubleType() (t Type) { t.C = C.LLVMDoubleType(); return } -func X86FP80Type() (t Type) { t.C = C.LLVMX86FP80Type(); return } -func FP128Type() (t Type) { t.C = C.LLVMFP128Type(); return } -func PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128Type(); return } - -// Operations on function types -func FunctionType(returnType Type, paramTypes []Type, isVarArg bool) (t Type) { - var pt *C.LLVMTypeRef - var ptlen C.unsigned - if len(paramTypes) > 0 { - pt = llvmTypeRefPtr(¶mTypes[0]) - ptlen = C.unsigned(len(paramTypes)) - } - t.C = C.LLVMFunctionType(returnType.C, - pt, - ptlen, - boolToLLVMBool(isVarArg)) - return -} - -func (t Type) IsFunctionVarArg() bool { return C.LLVMIsFunctionVarArg(t.C) != 0 } -func (t Type) ReturnType() (rt Type) { rt.C = C.LLVMGetReturnType(t.C); return } -func (t Type) ParamTypesCount() int { return int(C.LLVMCountParamTypes(t.C)) } -func (t Type) ParamTypes() []Type { - count := t.ParamTypesCount() - if count > 0 { - out := make([]Type, count) - C.LLVMGetParamTypes(t.C, llvmTypeRefPtr(&out[0])) - return out - } - return nil -} - -// Operations on struct types -func (c Context) StructType(elementTypes []Type, packed bool) (t Type) { - var pt *C.LLVMTypeRef - var ptlen C.unsigned - if len(elementTypes) > 0 { - pt = llvmTypeRefPtr(&elementTypes[0]) - ptlen = C.unsigned(len(elementTypes)) - } - t.C = C.LLVMStructTypeInContext(c.C, - pt, - ptlen, - boolToLLVMBool(packed)) - return -} - -func StructType(elementTypes []Type, packed bool) (t Type) { - var pt *C.LLVMTypeRef - var ptlen C.unsigned - if len(elementTypes) > 0 { - pt = llvmTypeRefPtr(&elementTypes[0]) - ptlen = C.unsigned(len(elementTypes)) - } - t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed)) - return -} - -func (c Context) StructCreateNamed(name string) (t Type) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - t.C = C.LLVMStructCreateNamed(c.C, cname) - return -} - -func (t Type) StructName() string { - return C.GoString(C.LLVMGetStructName(t.C)) -} - -func (t Type) StructSetBody(elementTypes []Type, packed bool) { - var pt *C.LLVMTypeRef - var ptlen C.unsigned - if len(elementTypes) > 0 { - pt = llvmTypeRefPtr(&elementTypes[0]) - ptlen = C.unsigned(len(elementTypes)) - } - C.LLVMStructSetBody(t.C, pt, ptlen, boolToLLVMBool(packed)) -} - -func (t Type) IsStructPacked() bool { return C.LLVMIsPackedStruct(t.C) != 0 } -func (t Type) StructElementTypesCount() int { return int(C.LLVMCountStructElementTypes(t.C)) } -func (t Type) StructElementTypes() []Type { - out := make([]Type, t.StructElementTypesCount()) - if len(out) > 0 { - C.LLVMGetStructElementTypes(t.C, llvmTypeRefPtr(&out[0])) - } - return out -} - -// Operations on array, pointer, and vector types (sequence types) -func (t Type) Subtypes() (ret []Type) { - ret = make([]Type, C.LLVMGetNumContainedTypes(t.C)) - C.LLVMGetSubtypes(t.C, llvmTypeRefPtr(&ret[0])) - return -} - -func ArrayType(elementType Type, elementCount int) (t Type) { - t.C = C.LLVMArrayType(elementType.C, C.unsigned(elementCount)) - return -} -func PointerType(elementType Type, addressSpace int) (t Type) { - t.C = C.LLVMPointerType(elementType.C, C.unsigned(addressSpace)) - return -} -func VectorType(elementType Type, elementCount int) (t Type) { - t.C = C.LLVMVectorType(elementType.C, C.unsigned(elementCount)) - return -} - -func (t Type) ElementType() (rt Type) { rt.C = C.LLVMGetElementType(t.C); return } -func (t Type) ArrayLength() int { return int(C.LLVMGetArrayLength(t.C)) } -func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) } -func (t Type) VectorSize() int { return int(C.LLVMGetVectorSize(t.C)) } - -// Operations on other types -func (c Context) VoidType() (t Type) { t.C = C.LLVMVoidTypeInContext(c.C); return } -func (c Context) LabelType() (t Type) { t.C = C.LLVMLabelTypeInContext(c.C); return } -func (c Context) TokenType() (t Type) { t.C = C.LLVMTokenTypeInContext(c.C); return } - -func VoidType() (t Type) { t.C = C.LLVMVoidType(); return } -func LabelType() (t Type) { t.C = C.LLVMLabelType(); return } - -//------------------------------------------------------------------------- -// llvm.Value -//------------------------------------------------------------------------- - -// Operations on all values -func (v Value) Type() (t Type) { t.C = C.LLVMTypeOf(v.C); return } -func (v Value) Name() string { return C.GoString(C.LLVMGetValueName(v.C)) } -func (v Value) SetName(name string) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - C.LLVMSetValueName(v.C, cname) -} -func (v Value) Dump() { C.LLVMDumpValue(v.C) } -func (v Value) ReplaceAllUsesWith(nv Value) { C.LLVMReplaceAllUsesWith(v.C, nv.C) } -func (v Value) HasMetadata() bool { return C.LLVMHasMetadata(v.C) != 0 } -func (v Value) Metadata(kind int) (rv Value) { - rv.C = C.LLVMGetMetadata(v.C, C.unsigned(kind)) - return -} -func (v Value) SetMetadata(kind int, node Metadata) { - C.LLVMSetMetadata2(v.C, C.unsigned(kind), node.C) -} - -// Conversion functions. -// Return the input value if it is an instance of the specified class, otherwise NULL. -// See llvm::dyn_cast_or_null<>. -func (v Value) IsAArgument() (rv Value) { rv.C = C.LLVMIsAArgument(v.C); return } -func (v Value) IsABasicBlock() (rv Value) { rv.C = C.LLVMIsABasicBlock(v.C); return } -func (v Value) IsAInlineAsm() (rv Value) { rv.C = C.LLVMIsAInlineAsm(v.C); return } -func (v Value) IsAUser() (rv Value) { rv.C = C.LLVMIsAUser(v.C); return } -func (v Value) IsAConstant() (rv Value) { rv.C = C.LLVMIsAConstant(v.C); return } -func (v Value) IsAConstantAggregateZero() (rv Value) { - rv.C = C.LLVMIsAConstantAggregateZero(v.C) - return -} -func (v Value) IsAConstantArray() (rv Value) { rv.C = C.LLVMIsAConstantArray(v.C); return } -func (v Value) IsAConstantExpr() (rv Value) { rv.C = C.LLVMIsAConstantExpr(v.C); return } -func (v Value) IsAConstantFP() (rv Value) { rv.C = C.LLVMIsAConstantFP(v.C); return } -func (v Value) IsAConstantInt() (rv Value) { rv.C = C.LLVMIsAConstantInt(v.C); return } -func (v Value) IsAConstantPointerNull() (rv Value) { rv.C = C.LLVMIsAConstantPointerNull(v.C); return } -func (v Value) IsAConstantStruct() (rv Value) { rv.C = C.LLVMIsAConstantStruct(v.C); return } -func (v Value) IsAConstantVector() (rv Value) { rv.C = C.LLVMIsAConstantVector(v.C); return } -func (v Value) IsAGlobalValue() (rv Value) { rv.C = C.LLVMIsAGlobalValue(v.C); return } -func (v Value) IsAFunction() (rv Value) { rv.C = C.LLVMIsAFunction(v.C); return } -func (v Value) IsAGlobalAlias() (rv Value) { rv.C = C.LLVMIsAGlobalAlias(v.C); return } -func (v Value) IsAGlobalVariable() (rv Value) { rv.C = C.LLVMIsAGlobalVariable(v.C); return } -func (v Value) IsAUndefValue() (rv Value) { rv.C = C.LLVMIsAUndefValue(v.C); return } -func (v Value) IsAInstruction() (rv Value) { rv.C = C.LLVMIsAInstruction(v.C); return } -func (v Value) IsABinaryOperator() (rv Value) { rv.C = C.LLVMIsABinaryOperator(v.C); return } -func (v Value) IsACallInst() (rv Value) { rv.C = C.LLVMIsACallInst(v.C); return } -func (v Value) IsAIntrinsicInst() (rv Value) { rv.C = C.LLVMIsAIntrinsicInst(v.C); return } -func (v Value) IsADbgInfoIntrinsic() (rv Value) { rv.C = C.LLVMIsADbgInfoIntrinsic(v.C); return } -func (v Value) IsADbgDeclareInst() (rv Value) { rv.C = C.LLVMIsADbgDeclareInst(v.C); return } -func (v Value) IsAMemIntrinsic() (rv Value) { rv.C = C.LLVMIsAMemIntrinsic(v.C); return } -func (v Value) IsAMemCpyInst() (rv Value) { rv.C = C.LLVMIsAMemCpyInst(v.C); return } -func (v Value) IsAMemMoveInst() (rv Value) { rv.C = C.LLVMIsAMemMoveInst(v.C); return } -func (v Value) IsAMemSetInst() (rv Value) { rv.C = C.LLVMIsAMemSetInst(v.C); return } -func (v Value) IsACmpInst() (rv Value) { rv.C = C.LLVMIsACmpInst(v.C); return } -func (v Value) IsAFCmpInst() (rv Value) { rv.C = C.LLVMIsAFCmpInst(v.C); return } -func (v Value) IsAICmpInst() (rv Value) { rv.C = C.LLVMIsAICmpInst(v.C); return } -func (v Value) IsAExtractElementInst() (rv Value) { rv.C = C.LLVMIsAExtractElementInst(v.C); return } -func (v Value) IsAGetElementPtrInst() (rv Value) { rv.C = C.LLVMIsAGetElementPtrInst(v.C); return } -func (v Value) IsAInsertElementInst() (rv Value) { rv.C = C.LLVMIsAInsertElementInst(v.C); return } -func (v Value) IsAInsertValueInst() (rv Value) { rv.C = C.LLVMIsAInsertValueInst(v.C); return } -func (v Value) IsAPHINode() (rv Value) { rv.C = C.LLVMIsAPHINode(v.C); return } -func (v Value) IsASelectInst() (rv Value) { rv.C = C.LLVMIsASelectInst(v.C); return } -func (v Value) IsAShuffleVectorInst() (rv Value) { rv.C = C.LLVMIsAShuffleVectorInst(v.C); return } -func (v Value) IsAStoreInst() (rv Value) { rv.C = C.LLVMIsAStoreInst(v.C); return } -func (v Value) IsABranchInst() (rv Value) { rv.C = C.LLVMIsABranchInst(v.C); return } -func (v Value) IsAInvokeInst() (rv Value) { rv.C = C.LLVMIsAInvokeInst(v.C); return } -func (v Value) IsAReturnInst() (rv Value) { rv.C = C.LLVMIsAReturnInst(v.C); return } -func (v Value) IsASwitchInst() (rv Value) { rv.C = C.LLVMIsASwitchInst(v.C); return } -func (v Value) IsAUnreachableInst() (rv Value) { rv.C = C.LLVMIsAUnreachableInst(v.C); return } -func (v Value) IsAUnaryInstruction() (rv Value) { rv.C = C.LLVMIsAUnaryInstruction(v.C); return } -func (v Value) IsAAllocaInst() (rv Value) { rv.C = C.LLVMIsAAllocaInst(v.C); return } -func (v Value) IsACastInst() (rv Value) { rv.C = C.LLVMIsACastInst(v.C); return } -func (v Value) IsABitCastInst() (rv Value) { rv.C = C.LLVMIsABitCastInst(v.C); return } -func (v Value) IsAFPExtInst() (rv Value) { rv.C = C.LLVMIsAFPExtInst(v.C); return } -func (v Value) IsAFPToSIInst() (rv Value) { rv.C = C.LLVMIsAFPToSIInst(v.C); return } -func (v Value) IsAFPToUIInst() (rv Value) { rv.C = C.LLVMIsAFPToUIInst(v.C); return } -func (v Value) IsAFPTruncInst() (rv Value) { rv.C = C.LLVMIsAFPTruncInst(v.C); return } -func (v Value) IsAIntToPtrInst() (rv Value) { rv.C = C.LLVMIsAIntToPtrInst(v.C); return } -func (v Value) IsAPtrToIntInst() (rv Value) { rv.C = C.LLVMIsAPtrToIntInst(v.C); return } -func (v Value) IsASExtInst() (rv Value) { rv.C = C.LLVMIsASExtInst(v.C); return } -func (v Value) IsASIToFPInst() (rv Value) { rv.C = C.LLVMIsASIToFPInst(v.C); return } -func (v Value) IsATruncInst() (rv Value) { rv.C = C.LLVMIsATruncInst(v.C); return } -func (v Value) IsAUIToFPInst() (rv Value) { rv.C = C.LLVMIsAUIToFPInst(v.C); return } -func (v Value) IsAZExtInst() (rv Value) { rv.C = C.LLVMIsAZExtInst(v.C); return } -func (v Value) IsAExtractValueInst() (rv Value) { rv.C = C.LLVMIsAExtractValueInst(v.C); return } -func (v Value) IsALoadInst() (rv Value) { rv.C = C.LLVMIsALoadInst(v.C); return } -func (v Value) IsAVAArgInst() (rv Value) { rv.C = C.LLVMIsAVAArgInst(v.C); return } - -// Operations on Uses -func (v Value) FirstUse() (u Use) { u.C = C.LLVMGetFirstUse(v.C); return } -func (u Use) NextUse() (ru Use) { ru.C = C.LLVMGetNextUse(u.C); return } -func (u Use) User() (v Value) { v.C = C.LLVMGetUser(u.C); return } -func (u Use) UsedValue() (v Value) { v.C = C.LLVMGetUsedValue(u.C); return } - -// Operations on Users -func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsigned(i)); return } -func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) } -func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) } - -// Operations on constants of any type -func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return } -func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return } -func Undef(t Type) (v Value) { v.C = C.LLVMGetUndef(t.C); return } -func (v Value) IsConstant() bool { return C.LLVMIsConstant(v.C) != 0 } -func (v Value) IsNull() bool { return C.LLVMIsNull(v.C) != 0 } -func (v Value) IsUndef() bool { return C.LLVMIsUndef(v.C) != 0 } -func ConstPointerNull(t Type) (v Value) { v.C = C.LLVMConstPointerNull(t.C); return } - -// Operations on metadata -func (c Context) MDString(str string) (md Metadata) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - md.C = C.LLVMMDString2(c.C, cstr, C.unsigned(len(str))) - return -} -func (c Context) MDNode(mds []Metadata) (md Metadata) { - ptr, nvals := llvmMetadataRefs(mds) - md.C = C.LLVMMDNode2(c.C, ptr, nvals) - return -} -func (v Value) ConstantAsMetadata() (md Metadata) { - md.C = C.LLVMConstantAsMetadata(v.C) - return -} - -// Operations on scalar constants -func ConstInt(t Type, n uint64, signExtend bool) (v Value) { - v.C = C.LLVMConstInt(t.C, - C.ulonglong(n), - boolToLLVMBool(signExtend)) - return -} -func ConstIntFromString(t Type, str string, radix int) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - v.C = C.LLVMConstIntOfString(t.C, cstr, C.uint8_t(radix)) - return -} -func ConstFloat(t Type, n float64) (v Value) { - v.C = C.LLVMConstReal(t.C, C.double(n)) - return -} -func ConstFloatFromString(t Type, str string) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - v.C = C.LLVMConstRealOfString(t.C, cstr) - return -} - -func (v Value) ZExtValue() uint64 { return uint64(C.LLVMConstIntGetZExtValue(v.C)) } -func (v Value) SExtValue() int64 { return int64(C.LLVMConstIntGetSExtValue(v.C)) } - -// Operations on composite constants -func (c Context) ConstString(str string, addnull bool) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - v.C = C.LLVMConstStringInContext(c.C, cstr, - C.unsigned(len(str)), boolToLLVMBool(!addnull)) - return -} -func (c Context) ConstStruct(constVals []Value, packed bool) (v Value) { - ptr, nvals := llvmValueRefs(constVals) - v.C = C.LLVMConstStructInContext(c.C, ptr, nvals, - boolToLLVMBool(packed)) - return -} -func ConstNamedStruct(t Type, constVals []Value) (v Value) { - ptr, nvals := llvmValueRefs(constVals) - v.C = C.LLVMConstNamedStruct(t.C, ptr, nvals) - return -} -func ConstString(str string, addnull bool) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - v.C = C.LLVMConstString(cstr, - C.unsigned(len(str)), boolToLLVMBool(!addnull)) - return -} -func ConstArray(t Type, constVals []Value) (v Value) { - ptr, nvals := llvmValueRefs(constVals) - v.C = C.LLVMConstArray(t.C, ptr, nvals) - return -} -func ConstStruct(constVals []Value, packed bool) (v Value) { - ptr, nvals := llvmValueRefs(constVals) - v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed)) - return -} -func ConstVector(scalarConstVals []Value, packed bool) (v Value) { - ptr, nvals := llvmValueRefs(scalarConstVals) - v.C = C.LLVMConstVector(ptr, nvals) - return -} - -// Constant expressions -func (v Value) Opcode() Opcode { return Opcode(C.LLVMGetConstOpcode(v.C)) } -func (v Value) InstructionOpcode() Opcode { return Opcode(C.LLVMGetInstructionOpcode(v.C)) } -func AlignOf(t Type) (v Value) { v.C = C.LLVMAlignOf(t.C); return } -func SizeOf(t Type) (v Value) { v.C = C.LLVMSizeOf(t.C); return } -func ConstNeg(v Value) (rv Value) { rv.C = C.LLVMConstNeg(v.C); return } -func ConstNSWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNSWNeg(v.C); return } -func ConstNUWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNUWNeg(v.C); return } -func ConstFNeg(v Value) (rv Value) { rv.C = C.LLVMConstFNeg(v.C); return } -func ConstNot(v Value) (rv Value) { rv.C = C.LLVMConstNot(v.C); return } -func ConstAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAdd(lhs.C, rhs.C); return } -func ConstNSWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWAdd(lhs.C, rhs.C); return } -func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.C); return } -func ConstFAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFAdd(lhs.C, rhs.C); return } -func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return } -func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return } -func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return } -func ConstFSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFSub(lhs.C, rhs.C); return } -func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return } -func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return } -func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return } -func ConstFMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFMul(lhs.C, rhs.C); return } -func ConstUDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstUDiv(lhs.C, rhs.C); return } -func ConstSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSDiv(lhs.C, rhs.C); return } -func ConstExactSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstExactSDiv(lhs.C, rhs.C); return } -func ConstFDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFDiv(lhs.C, rhs.C); return } -func ConstURem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstURem(lhs.C, rhs.C); return } -func ConstSRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSRem(lhs.C, rhs.C); return } -func ConstFRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFRem(lhs.C, rhs.C); return } -func ConstAnd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAnd(lhs.C, rhs.C); return } -func ConstOr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstOr(lhs.C, rhs.C); return } -func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return } - -func ConstICmp(pred IntPredicate, lhs, rhs Value) (v Value) { - v.C = C.LLVMConstICmp(C.LLVMIntPredicate(pred), lhs.C, rhs.C) - return -} -func ConstFCmp(pred FloatPredicate, lhs, rhs Value) (v Value) { - v.C = C.LLVMConstFCmp(C.LLVMRealPredicate(pred), lhs.C, rhs.C) - return -} - -func ConstShl(lhs, rhs Value) (v Value) { v.C = C.LLVMConstShl(lhs.C, rhs.C); return } -func ConstLShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstLShr(lhs.C, rhs.C); return } -func ConstAShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAShr(lhs.C, rhs.C); return } - -func ConstGEP(v Value, indices []Value) (rv Value) { - ptr, nvals := llvmValueRefs(indices) - rv.C = C.LLVMConstGEP(v.C, ptr, nvals) - return -} -func ConstInBoundsGEP(v Value, indices []Value) (rv Value) { - ptr, nvals := llvmValueRefs(indices) - rv.C = C.LLVMConstInBoundsGEP(v.C, ptr, nvals) - return -} -func ConstTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstTrunc(v.C, t.C); return } -func ConstSExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExt(v.C, t.C); return } -func ConstZExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExt(v.C, t.C); return } -func ConstFPTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPTrunc(v.C, t.C); return } -func ConstFPExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPExt(v.C, t.C); return } -func ConstUIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstUIToFP(v.C, t.C); return } -func ConstSIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSIToFP(v.C, t.C); return } -func ConstFPToUI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToUI(v.C, t.C); return } -func ConstFPToSI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToSI(v.C, t.C); return } -func ConstPtrToInt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPtrToInt(v.C, t.C); return } -func ConstIntToPtr(v Value, t Type) (rv Value) { rv.C = C.LLVMConstIntToPtr(v.C, t.C); return } -func ConstBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstBitCast(v.C, t.C); return } -func ConstZExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExtOrBitCast(v.C, t.C); return } -func ConstSExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExtOrBitCast(v.C, t.C); return } -func ConstTruncOrBitCast(v Value, t Type) (rv Value) { - rv.C = C.LLVMConstTruncOrBitCast(v.C, t.C) - return -} -func ConstPointerCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPointerCast(v.C, t.C); return } -func ConstIntCast(v Value, t Type, signed bool) (rv Value) { - rv.C = C.LLVMConstIntCast(v.C, t.C, boolToLLVMBool(signed)) - return -} -func ConstFPCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPCast(v.C, t.C); return } -func ConstSelect(cond, iftrue, iffalse Value) (rv Value) { - rv.C = C.LLVMConstSelect(cond.C, iftrue.C, iffalse.C) - return -} -func ConstExtractElement(vec, i Value) (rv Value) { - rv.C = C.LLVMConstExtractElement(vec.C, i.C) - return -} -func ConstInsertElement(vec, elem, i Value) (rv Value) { - rv.C = C.LLVMConstInsertElement(vec.C, elem.C, i.C) - return -} -func ConstShuffleVector(veca, vecb, mask Value) (rv Value) { - rv.C = C.LLVMConstShuffleVector(veca.C, vecb.C, mask.C) - return -} - -//TODO -//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, -// unsigned NumIdx); - -func ConstExtractValue(agg Value, indices []uint32) (rv Value) { - n := len(indices) - if n == 0 { - panic("one or more indices are required") - } - ptr := (*C.unsigned)(&indices[0]) - rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n)) - return -} - -func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) { - n := len(indices) - if n == 0 { - panic("one or more indices are required") - } - ptr := (*C.unsigned)(&indices[0]) - rv.C = C.LLVMConstInsertValue(agg.C, val.C, ptr, C.unsigned(n)) - return -} - -func BlockAddress(f Value, bb BasicBlock) (v Value) { - v.C = C.LLVMBlockAddress(f.C, bb.C) - return -} - -// Operations on global variables, functions, and aliases (globals) -func (v Value) GlobalParent() (m Module) { m.C = C.LLVMGetGlobalParent(v.C); return } -func (v Value) IsDeclaration() bool { return C.LLVMIsDeclaration(v.C) != 0 } -func (v Value) Linkage() Linkage { return Linkage(C.LLVMGetLinkage(v.C)) } -func (v Value) SetLinkage(l Linkage) { C.LLVMSetLinkage(v.C, C.LLVMLinkage(l)) } -func (v Value) Section() string { return C.GoString(C.LLVMGetSection(v.C)) } -func (v Value) SetSection(str string) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - C.LLVMSetSection(v.C, cstr) -} -func (v Value) Visibility() Visibility { return Visibility(C.LLVMGetVisibility(v.C)) } -func (v Value) SetVisibility(vi Visibility) { C.LLVMSetVisibility(v.C, C.LLVMVisibility(vi)) } -func (v Value) Alignment() int { return int(C.LLVMGetAlignment(v.C)) } -func (v Value) SetAlignment(a int) { C.LLVMSetAlignment(v.C, C.unsigned(a)) } -func (v Value) SetUnnamedAddr(ua bool) { C.LLVMSetUnnamedAddr(v.C, boolToLLVMBool(ua)) } - -// Operations on global variables -func AddGlobal(m Module, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMAddGlobal(m.C, t.C, cname) - return -} -func AddGlobalInAddressSpace(m Module, t Type, name string, addressSpace int) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMAddGlobalInAddressSpace(m.C, t.C, cname, C.unsigned(addressSpace)) - return -} -func (m Module) NamedGlobal(name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMGetNamedGlobal(m.C, cname) - return -} - -func (m Module) FirstGlobal() (v Value) { v.C = C.LLVMGetFirstGlobal(m.C); return } -func (m Module) LastGlobal() (v Value) { v.C = C.LLVMGetLastGlobal(m.C); return } -func NextGlobal(v Value) (rv Value) { rv.C = C.LLVMGetNextGlobal(v.C); return } -func PrevGlobal(v Value) (rv Value) { rv.C = C.LLVMGetPreviousGlobal(v.C); return } -func (v Value) EraseFromParentAsGlobal() { C.LLVMDeleteGlobal(v.C) } -func (v Value) Initializer() (rv Value) { rv.C = C.LLVMGetInitializer(v.C); return } -func (v Value) SetInitializer(cv Value) { C.LLVMSetInitializer(v.C, cv.C) } -func (v Value) IsThreadLocal() bool { return C.LLVMIsThreadLocal(v.C) != 0 } -func (v Value) SetThreadLocal(tl bool) { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) } -func (v Value) IsGlobalConstant() bool { return C.LLVMIsGlobalConstant(v.C) != 0 } -func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) } -func (v Value) IsVolatile() bool { return C.LLVMGetVolatile(v.C) != 0 } -func (v Value) SetVolatile(volatile bool) { C.LLVMSetVolatile(v.C, boolToLLVMBool(volatile)) } -func (v Value) Ordering() AtomicOrdering { return AtomicOrdering(C.LLVMGetOrdering(v.C)) } -func (v Value) SetOrdering(ordering AtomicOrdering) { - C.LLVMSetOrdering(v.C, C.LLVMAtomicOrdering(ordering)) -} -func (v Value) IsAtomicSingleThread() bool { return C.LLVMIsAtomicSingleThread(v.C) != 0 } -func (v Value) SetAtomicSingleThread(singleThread bool) { - C.LLVMSetAtomicSingleThread(v.C, boolToLLVMBool(singleThread)) -} -func (v Value) CmpXchgSuccessOrdering() AtomicOrdering { - return AtomicOrdering(C.LLVMGetCmpXchgSuccessOrdering(v.C)) -} -func (v Value) SetCmpXchgSuccessOrdering(ordering AtomicOrdering) { - C.LLVMSetCmpXchgSuccessOrdering(v.C, C.LLVMAtomicOrdering(ordering)) -} -func (v Value) CmpXchgFailureOrdering() AtomicOrdering { - return AtomicOrdering(C.LLVMGetCmpXchgFailureOrdering(v.C)) -} -func (v Value) SetCmpXchgFailureOrdering(ordering AtomicOrdering) { - C.LLVMSetCmpXchgFailureOrdering(v.C, C.LLVMAtomicOrdering(ordering)) -} - -// Operations on aliases -func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMAddAlias(m.C, t.C, aliasee.C, cname) - return -} - -// Operations on comdat -func (m Module) Comdat(name string) (c Comdat) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - c.C = C.LLVMGetOrInsertComdat(m.C, cname) - return -} - -func (v Value) Comdat() (c Comdat) { c.C = C.LLVMGetComdat(v.C); return } -func (v Value) SetComdat(c Comdat) { C.LLVMSetComdat(v.C, c.C) } - -func (c Comdat) SelectionKind() ComdatSelectionKind { - return ComdatSelectionKind(C.LLVMGetComdatSelectionKind(c.C)) -} - -func (c Comdat) SetSelectionKind(k ComdatSelectionKind) { - C.LLVMSetComdatSelectionKind(c.C, (C.LLVMComdatSelectionKind)(k)) -} - -// Operations on functions -func AddFunction(m Module, name string, ft Type) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMAddFunction(m.C, cname, ft.C) - return -} - -func (m Module) NamedFunction(name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMGetNamedFunction(m.C, cname) - return -} - -func (m Module) FirstFunction() (v Value) { v.C = C.LLVMGetFirstFunction(m.C); return } -func (m Module) LastFunction() (v Value) { v.C = C.LLVMGetLastFunction(m.C); return } -func NextFunction(v Value) (rv Value) { rv.C = C.LLVMGetNextFunction(v.C); return } -func PrevFunction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousFunction(v.C); return } -func (v Value) EraseFromParentAsFunction() { C.LLVMDeleteFunction(v.C) } -func (v Value) IntrinsicID() int { return int(C.LLVMGetIntrinsicID(v.C)) } -func (v Value) FunctionCallConv() CallConv { - return CallConv(C.LLVMCallConv(C.LLVMGetFunctionCallConv(v.C))) -} -func (v Value) SetFunctionCallConv(cc CallConv) { C.LLVMSetFunctionCallConv(v.C, C.unsigned(cc)) } -func (v Value) GC() string { return C.GoString(C.LLVMGetGC(v.C)) } -func (v Value) SetGC(name string) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - C.LLVMSetGC(v.C, cname) -} -func (v Value) AddAttributeAtIndex(i int, a Attribute) { - C.LLVMAddAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), a.C) -} -func (v Value) AddFunctionAttr(a Attribute) { - v.AddAttributeAtIndex(C.LLVMAttributeFunctionIndex, a) -} -func (v Value) GetEnumAttributeAtIndex(i int, kind uint) (a Attribute) { - a.C = C.LLVMGetEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) - return -} -func (v Value) GetEnumFunctionAttribute(kind uint) Attribute { - return v.GetEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) -} -func (v Value) GetStringAttributeAtIndex(i int, kind string) (a Attribute) { - ckind := C.CString(kind) - defer C.free(unsafe.Pointer(ckind)) - a.C = C.LLVMGetStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), - ckind, C.unsigned(len(kind))) - return -} -func (v Value) RemoveEnumAttributeAtIndex(i int, kind uint) { - C.LLVMRemoveEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) -} -func (v Value) RemoveEnumFunctionAttribute(kind uint) { - v.RemoveEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) -} -func (v Value) RemoveStringAttributeAtIndex(i int, kind string) { - ckind := C.CString(kind) - defer C.free(unsafe.Pointer(ckind)) - C.LLVMRemoveStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), - ckind, C.unsigned(len(kind))) -} -func (v Value) AddTargetDependentFunctionAttr(attr, value string) { - cattr := C.CString(attr) - defer C.free(unsafe.Pointer(cattr)) - cvalue := C.CString(value) - defer C.free(unsafe.Pointer(cvalue)) - C.LLVMAddTargetDependentFunctionAttr(v.C, cattr, cvalue) -} -func (v Value) SetPersonality(p Value) { - C.LLVMSetPersonalityFn(v.C, p.C) -} - -// Operations on parameters -func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } -func (v Value) Params() []Value { - out := make([]Value, v.ParamsCount()) - if len(out) > 0 { - C.LLVMGetParams(v.C, llvmValueRefPtr(&out[0])) - } - return out -} -func (v Value) Param(i int) (rv Value) { rv.C = C.LLVMGetParam(v.C, C.unsigned(i)); return } -func (v Value) ParamParent() (rv Value) { rv.C = C.LLVMGetParamParent(v.C); return } -func (v Value) FirstParam() (rv Value) { rv.C = C.LLVMGetFirstParam(v.C); return } -func (v Value) LastParam() (rv Value) { rv.C = C.LLVMGetLastParam(v.C); return } -func NextParam(v Value) (rv Value) { rv.C = C.LLVMGetNextParam(v.C); return } -func PrevParam(v Value) (rv Value) { rv.C = C.LLVMGetPreviousParam(v.C); return } -func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) } - -// Operations on basic blocks -func (bb BasicBlock) AsValue() (v Value) { v.C = C.LLVMBasicBlockAsValue(bb.C); return } -func (v Value) IsBasicBlock() bool { return C.LLVMValueIsBasicBlock(v.C) != 0 } -func (v Value) AsBasicBlock() (bb BasicBlock) { bb.C = C.LLVMValueAsBasicBlock(v.C); return } -func (bb BasicBlock) Parent() (v Value) { v.C = C.LLVMGetBasicBlockParent(bb.C); return } -func (v Value) BasicBlocksCount() int { return int(C.LLVMCountBasicBlocks(v.C)) } -func (v Value) BasicBlocks() []BasicBlock { - out := make([]BasicBlock, v.BasicBlocksCount()) - C.LLVMGetBasicBlocks(v.C, llvmBasicBlockRefPtr(&out[0])) - return out -} -func (v Value) FirstBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetFirstBasicBlock(v.C); return } -func (v Value) LastBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetLastBasicBlock(v.C); return } -func NextBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetNextBasicBlock(bb.C); return } -func PrevBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetPreviousBasicBlock(bb.C); return } -func (v Value) EntryBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetEntryBasicBlock(v.C); return } -func (c Context) AddBasicBlock(f Value, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMAppendBasicBlockInContext(c.C, f.C, cname) - return -} -func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMInsertBasicBlockInContext(c.C, ref.C, cname) - return -} -func AddBasicBlock(f Value, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMAppendBasicBlock(f.C, cname) - return -} -func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - bb.C = C.LLVMInsertBasicBlock(ref.C, cname) - return -} -func (bb BasicBlock) EraseFromParent() { C.LLVMDeleteBasicBlock(bb.C) } -func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) } -func (bb BasicBlock) MoveAfter(pos BasicBlock) { C.LLVMMoveBasicBlockAfter(bb.C, pos.C) } - -// Operations on instructions -func (v Value) EraseFromParentAsInstruction() { C.LLVMInstructionEraseFromParent(v.C) } -func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return } -func (v Value) InstructionDebugLoc() (md Metadata) { md.C = C.LLVMInstructionGetDebugLoc(v.C); return } -func (v Value) InstructionSetDebugLoc(md Metadata) { C.LLVMInstructionSetDebugLoc(v.C, md.C) } -func (bb BasicBlock) FirstInstruction() (v Value) { v.C = C.LLVMGetFirstInstruction(bb.C); return } -func (bb BasicBlock) LastInstruction() (v Value) { v.C = C.LLVMGetLastInstruction(bb.C); return } -func NextInstruction(v Value) (rv Value) { rv.C = C.LLVMGetNextInstruction(v.C); return } -func PrevInstruction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousInstruction(v.C); return } - -// Operations on call sites -func (v Value) SetInstructionCallConv(cc CallConv) { - C.LLVMSetInstructionCallConv(v.C, C.unsigned(cc)) -} -func (v Value) InstructionCallConv() CallConv { - return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C))) -} -func (v Value) AddCallSiteAttribute(i int, a Attribute) { - C.LLVMAddCallSiteAttribute(v.C, C.LLVMAttributeIndex(i), a.C) -} -func (v Value) SetInstrParamAlignment(i int, align int) { - C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align)) -} -func (v Value) CalledValue() (rv Value) { - rv.C = C.LLVMGetCalledValue(v.C) - return -} - -// Operations on call instructions (only) -func (v Value) IsTailCall() bool { return C.LLVMIsTailCall(v.C) != 0 } -func (v Value) SetTailCall(is bool) { C.LLVMSetTailCall(v.C, boolToLLVMBool(is)) } - -// Operations on phi nodes -func (v Value) AddIncoming(vals []Value, blocks []BasicBlock) { - ptr, nvals := llvmValueRefs(vals) - C.LLVMAddIncoming(v.C, ptr, llvmBasicBlockRefPtr(&blocks[0]), nvals) -} -func (v Value) IncomingCount() int { return int(C.LLVMCountIncoming(v.C)) } -func (v Value) IncomingValue(i int) (rv Value) { - rv.C = C.LLVMGetIncomingValue(v.C, C.unsigned(i)) - return -} -func (v Value) IncomingBlock(i int) (bb BasicBlock) { - bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i)) - return -} - -// Operations on inline assembly -func InlineAsm(t Type, asmString, constraints string, hasSideEffects, isAlignStack bool, dialect InlineAsmDialect) (rv Value) { - casm := C.CString(asmString) - defer C.free(unsafe.Pointer(casm)) - cconstraints := C.CString(constraints) - defer C.free(unsafe.Pointer(cconstraints)) - rv.C = C.LLVMGetInlineAsm(t.C, casm, C.size_t(len(asmString)), cconstraints, C.size_t(len(constraints)), boolToLLVMBool(hasSideEffects), boolToLLVMBool(isAlignStack), C.LLVMInlineAsmDialect(dialect)) - return -} - -// Operations on aggregates -func (v Value) Indices() []uint32 { - num := C.LLVMGetNumIndices(v.C) - indicesPtr := C.LLVMGetIndices(v.C) - // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices - rawIndices := (*[1 << 20]C.uint)(unsafe.Pointer(indicesPtr))[:num:num] - indices := make([]uint32, num) - for i := range indices { - indices[i] = uint32(rawIndices[i]) - } - return indices -} - -// Operations on comparisons -func (v Value) IntPredicate() IntPredicate { return IntPredicate(C.LLVMGetICmpPredicate(v.C)) } -func (v Value) FloatPredicate() FloatPredicate { return FloatPredicate(C.LLVMGetFCmpPredicate(v.C)) } - -//------------------------------------------------------------------------- -// llvm.Builder -//------------------------------------------------------------------------- - -// An instruction builder represents a point within a basic block, and is the -// exclusive means of building instructions using the C interface. - -func (c Context) NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilderInContext(c.C); return } -func NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilder(); return } -func (b Builder) SetInsertPoint(block BasicBlock, instr Value) { - C.LLVMPositionBuilder(b.C, block.C, instr.C) -} -func (b Builder) SetInsertPointBefore(instr Value) { C.LLVMPositionBuilderBefore(b.C, instr.C) } -func (b Builder) SetInsertPointAtEnd(block BasicBlock) { C.LLVMPositionBuilderAtEnd(b.C, block.C) } -func (b Builder) GetInsertBlock() (bb BasicBlock) { bb.C = C.LLVMGetInsertBlock(b.C); return } -func (b Builder) ClearInsertionPoint() { C.LLVMClearInsertionPosition(b.C) } -func (b Builder) Insert(instr Value) { C.LLVMInsertIntoBuilder(b.C, instr.C) } -func (b Builder) InsertWithName(instr Value, name string) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - C.LLVMInsertIntoBuilderWithName(b.C, instr.C, cname) -} -func (b Builder) Dispose() { C.LLVMDisposeBuilder(b.C) } - -// Metadata -type DebugLoc struct { - Line, Col uint - Scope Metadata - InlinedAt Metadata -} - -func (b Builder) SetCurrentDebugLocation(line, col uint, scope, inlinedAt Metadata) { - C.LLVMGoSetCurrentDebugLocation(b.C, C.unsigned(line), C.unsigned(col), scope.C, inlinedAt.C) -} - -// Get current debug location. Please do not call this function until setting debug location with SetCurrentDebugLocation() -func (b Builder) GetCurrentDebugLocation() (loc DebugLoc) { - md := C.LLVMGoGetCurrentDebugLocation(b.C) - loc.Line = uint(md.Line) - loc.Col = uint(md.Col) - loc.Scope = Metadata{C: md.Scope} - loc.InlinedAt = Metadata{C: md.InlinedAt} - return -} -func (b Builder) SetInstDebugLocation(v Value) { C.LLVMSetInstDebugLocation(b.C, v.C) } -func (b Builder) InsertDeclare(module Module, storage Value, md Value) Value { - f := module.NamedFunction("llvm.dbg.declare") - if f.IsNil() { - ftyp := FunctionType(VoidType(), []Type{storage.Type(), md.Type()}, false) - f = AddFunction(module, "llvm.dbg.declare", ftyp) - } - return b.CreateCall(f, []Value{storage, md}, "") -} - -// Terminators -func (b Builder) CreateRetVoid() (rv Value) { rv.C = C.LLVMBuildRetVoid(b.C); return } -func (b Builder) CreateRet(v Value) (rv Value) { rv.C = C.LLVMBuildRet(b.C, v.C); return } -func (b Builder) CreateAggregateRet(vs []Value) (rv Value) { - ptr, nvals := llvmValueRefs(vs) - rv.C = C.LLVMBuildAggregateRet(b.C, ptr, nvals) - return -} -func (b Builder) CreateBr(bb BasicBlock) (rv Value) { rv.C = C.LLVMBuildBr(b.C, bb.C); return } -func (b Builder) CreateCondBr(ifv Value, thenb, elseb BasicBlock) (rv Value) { - rv.C = C.LLVMBuildCondBr(b.C, ifv.C, thenb.C, elseb.C) - return -} -func (b Builder) CreateSwitch(v Value, elseb BasicBlock, numCases int) (rv Value) { - rv.C = C.LLVMBuildSwitch(b.C, v.C, elseb.C, C.unsigned(numCases)) - return -} -func (b Builder) CreateIndirectBr(addr Value, numDests int) (rv Value) { - rv.C = C.LLVMBuildIndirectBr(b.C, addr.C, C.unsigned(numDests)) - return -} -func (b Builder) CreateInvoke(fn Value, args []Value, then, catch BasicBlock, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - ptr, nvals := llvmValueRefs(args) - rv.C = C.LLVMBuildInvoke(b.C, fn.C, ptr, nvals, then.C, catch.C, cname) - return -} -func (b Builder) CreateUnreachable() (rv Value) { rv.C = C.LLVMBuildUnreachable(b.C); return } - -// Add a case to the switch instruction -func (v Value) AddCase(on Value, dest BasicBlock) { C.LLVMAddCase(v.C, on.C, dest.C) } - -// Add a destination to the indirectbr instruction -func (v Value) AddDest(dest BasicBlock) { C.LLVMAddDestination(v.C, dest.C) } - -// Arithmetic -func (b Builder) CreateAdd(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildAdd(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNSWAdd(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNSWAdd(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNUWAdd(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNUWAdd(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFAdd(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFAdd(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateSub(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSub(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNSWSub(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNSWSub(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNUWSub(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNUWSub(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFSub(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - v.C = C.LLVMBuildFSub(b.C, lhs.C, rhs.C, cname) - C.free(unsafe.Pointer(cname)) - return -} -func (b Builder) CreateMul(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildMul(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNSWMul(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNSWMul(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNUWMul(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildNUWMul(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFMul(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFMul(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateUDiv(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildUDiv(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateSDiv(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSDiv(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateExactSDiv(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildExactSDiv(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFDiv(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFDiv(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateURem(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildURem(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateSRem(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSRem(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFRem(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFRem(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateShl(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildShl(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateLShr(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildLShr(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateAShr(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildAShr(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateAnd(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildAnd(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateOr(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildOr(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateXor(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildXor(b.C, lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateBinOp(op Opcode, lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildBinOp(b.C, C.LLVMOpcode(op), lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateNeg(v Value, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - rv.C = C.LLVMBuildNeg(b.C, v.C, cname) - return -} -func (b Builder) CreateNSWNeg(v Value, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - rv.C = C.LLVMBuildNSWNeg(b.C, v.C, cname) - return -} -func (b Builder) CreateNUWNeg(v Value, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - rv.C = C.LLVMBuildNUWNeg(b.C, v.C, cname) - return -} -func (b Builder) CreateFNeg(v Value, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - rv.C = C.LLVMBuildFNeg(b.C, v.C, cname) - return -} -func (b Builder) CreateNot(v Value, name string) (rv Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - rv.C = C.LLVMBuildNot(b.C, v.C, cname) - return -} - -// Memory - -func (b Builder) CreateMalloc(t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildMalloc(b.C, t.C, cname) - return -} -func (b Builder) CreateArrayMalloc(t Type, val Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildArrayMalloc(b.C, t.C, val.C, cname) - return -} -func (b Builder) CreateAlloca(t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildAlloca(b.C, t.C, cname) - return -} -func (b Builder) CreateArrayAlloca(t Type, val Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildArrayAlloca(b.C, t.C, val.C, cname) - return -} -func (b Builder) CreateFree(p Value) (v Value) { - v.C = C.LLVMBuildFree(b.C, p.C) - return -} -func (b Builder) CreateLoad(p Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildLoad(b.C, p.C, cname) - return -} -func (b Builder) CreateStore(val Value, p Value) (v Value) { - v.C = C.LLVMBuildStore(b.C, val.C, p.C) - return -} -func (b Builder) CreateGEP(p Value, indices []Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - ptr, nvals := llvmValueRefs(indices) - v.C = C.LLVMBuildGEP(b.C, p.C, ptr, nvals, cname) - return -} -func (b Builder) CreateInBoundsGEP(p Value, indices []Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - ptr, nvals := llvmValueRefs(indices) - v.C = C.LLVMBuildInBoundsGEP(b.C, p.C, ptr, nvals, cname) - return -} -func (b Builder) CreateStructGEP(p Value, i int, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildStructGEP(b.C, p.C, C.unsigned(i), cname) - return -} -func (b Builder) CreateGlobalString(str, name string) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildGlobalString(b.C, cstr, cname) - return -} -func (b Builder) CreateGlobalStringPtr(str, name string) (v Value) { - cstr := C.CString(str) - defer C.free(unsafe.Pointer(cstr)) - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildGlobalStringPtr(b.C, cstr, cname) - return -} -func (b Builder) CreateAtomicRMW(op AtomicRMWBinOp, ptr, val Value, ordering AtomicOrdering, singleThread bool) (v Value) { - v.C = C.LLVMBuildAtomicRMW(b.C, C.LLVMAtomicRMWBinOp(op), ptr.C, val.C, C.LLVMAtomicOrdering(ordering), boolToLLVMBool(singleThread)) - return -} -func (b Builder) CreateAtomicCmpXchg(ptr, cmp, newVal Value, successOrdering, failureOrdering AtomicOrdering, singleThread bool) (v Value) { - v.C = C.LLVMBuildAtomicCmpXchg(b.C, ptr.C, cmp.C, newVal.C, C.LLVMAtomicOrdering(successOrdering), C.LLVMAtomicOrdering(failureOrdering), boolToLLVMBool(singleThread)) - return -} - -// Casts -func (b Builder) CreateTrunc(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildTrunc(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateZExt(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildZExt(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateSExt(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSExt(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateFPToUI(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFPToUI(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateFPToSI(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFPToSI(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateUIToFP(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildUIToFP(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateSIToFP(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSIToFP(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateFPTrunc(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFPTrunc(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateFPExt(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFPExt(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreatePtrToInt(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildPtrToInt(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateIntToPtr(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildIntToPtr(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateBitCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildBitCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateZExtOrBitCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildZExtOrBitCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateSExtOrBitCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSExtOrBitCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateTruncOrBitCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildTruncOrBitCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateCast(val Value, op Opcode, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildCast(b.C, C.LLVMOpcode(op), val.C, t.C, cname) - return -} // -func (b Builder) CreatePointerCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildPointerCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateIntCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildIntCast(b.C, val.C, t.C, cname) - return -} -func (b Builder) CreateFPCast(val Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFPCast(b.C, val.C, t.C, cname) - return -} - -// Comparisons -func (b Builder) CreateICmp(pred IntPredicate, lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildICmp(b.C, C.LLVMIntPredicate(pred), lhs.C, rhs.C, cname) - return -} -func (b Builder) CreateFCmp(pred FloatPredicate, lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildFCmp(b.C, C.LLVMRealPredicate(pred), lhs.C, rhs.C, cname) - return -} - -// Miscellaneous instructions -func (b Builder) CreatePHI(t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildPhi(b.C, t.C, cname) - return -} -func (b Builder) CreateCall(fn Value, args []Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - ptr, nvals := llvmValueRefs(args) - v.C = C.LLVMBuildCall(b.C, fn.C, ptr, nvals, cname) - return -} - -func (b Builder) CreateSelect(ifv, thenv, elsev Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildSelect(b.C, ifv.C, thenv.C, elsev.C, cname) - return -} - -func (b Builder) CreateVAArg(list Value, t Type, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildVAArg(b.C, list.C, t.C, cname) - return -} -func (b Builder) CreateExtractElement(vec, i Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildExtractElement(b.C, vec.C, i.C, cname) - return -} -func (b Builder) CreateInsertElement(vec, elt, i Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildInsertElement(b.C, vec.C, elt.C, i.C, cname) - return -} -func (b Builder) CreateShuffleVector(v1, v2, mask Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildShuffleVector(b.C, v1.C, v2.C, mask.C, cname) - return -} -func (b Builder) CreateExtractValue(agg Value, i int, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildExtractValue(b.C, agg.C, C.unsigned(i), cname) - return -} -func (b Builder) CreateInsertValue(agg, elt Value, i int, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildInsertValue(b.C, agg.C, elt.C, C.unsigned(i), cname) - return -} - -func (b Builder) CreateIsNull(val Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildIsNull(b.C, val.C, cname) - return -} -func (b Builder) CreateIsNotNull(val Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildIsNotNull(b.C, val.C, cname) - return -} -func (b Builder) CreatePtrDiff(lhs, rhs Value, name string) (v Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - v.C = C.LLVMBuildPtrDiff(b.C, lhs.C, rhs.C, cname) - return -} - -func (b Builder) CreateLandingPad(t Type, nclauses int, name string) (l Value) { - cname := C.CString(name) - defer C.free(unsafe.Pointer(cname)) - l.C = C.LLVMBuildLandingPad(b.C, t.C, nil, C.unsigned(nclauses), cname) - return l -} - -func (l Value) AddClause(v Value) { - C.LLVMAddClause(l.C, v.C) -} - -func (l Value) SetCleanup(cleanup bool) { - C.LLVMSetCleanup(l.C, boolToLLVMBool(cleanup)) -} - -func (b Builder) CreateResume(ex Value) (v Value) { - v.C = C.LLVMBuildResume(b.C, ex.C) - return -} - -//------------------------------------------------------------------------- -// llvm.ModuleProvider -//------------------------------------------------------------------------- - -// Changes the type of M so it can be passed to FunctionPassManagers and the -// JIT. They take ModuleProviders for historical reasons. -func NewModuleProviderForModule(m Module) (mp ModuleProvider) { - mp.C = C.LLVMCreateModuleProviderForExistingModule(m.C) - return -} - -// Destroys the module M. -func (mp ModuleProvider) Dispose() { C.LLVMDisposeModuleProvider(mp.C) } - -//------------------------------------------------------------------------- -// llvm.MemoryBuffer -//------------------------------------------------------------------------- - -func NewMemoryBufferFromFile(path string) (b MemoryBuffer, err error) { - var cmsg *C.char - cpath := C.CString(path) - defer C.free(unsafe.Pointer(cpath)) - fail := C.LLVMCreateMemoryBufferWithContentsOfFile(cpath, &b.C, &cmsg) - if fail != 0 { - b.C = nil - err = errors.New(C.GoString(cmsg)) - C.LLVMDisposeMessage(cmsg) - } - return -} - -func NewMemoryBufferFromStdin() (b MemoryBuffer, err error) { - var cmsg *C.char - fail := C.LLVMCreateMemoryBufferWithSTDIN(&b.C, &cmsg) - if fail != 0 { - b.C = nil - err = errors.New(C.GoString(cmsg)) - C.LLVMDisposeMessage(cmsg) - } - return -} - -func (b MemoryBuffer) Bytes() []byte { - cstart := C.LLVMGetBufferStart(b.C) - csize := C.LLVMGetBufferSize(b.C) - return C.GoBytes(unsafe.Pointer(cstart), C.int(csize)) -} - -func (b MemoryBuffer) Dispose() { C.LLVMDisposeMemoryBuffer(b.C) } - -//------------------------------------------------------------------------- -// llvm.PassManager -//------------------------------------------------------------------------- - -// Constructs a new whole-module pass pipeline. This type of pipeline is -// suitable for link-time optimization and whole-module transformations. -// See llvm::PassManager::PassManager. -func NewPassManager() (pm PassManager) { pm.C = C.LLVMCreatePassManager(); return } - -// Constructs a new function-by-function pass pipeline over the module -// provider. It does not take ownership of the module provider. This type of -// pipeline is suitable for code generation and JIT compilation tasks. -// See llvm::FunctionPassManager::FunctionPassManager. -func NewFunctionPassManagerForModule(m Module) (pm PassManager) { - pm.C = C.LLVMCreateFunctionPassManagerForModule(m.C) - return -} - -// Initializes, executes on the provided module, and finalizes all of the -// passes scheduled in the pass manager. Returns 1 if any of the passes -// modified the module, 0 otherwise. See llvm::PassManager::run(Module&). -func (pm PassManager) Run(m Module) bool { return C.LLVMRunPassManager(pm.C, m.C) != 0 } - -// Initializes all of the function passes scheduled in the function pass -// manager. Returns 1 if any of the passes modified the module, 0 otherwise. -// See llvm::FunctionPassManager::doInitialization. -func (pm PassManager) InitializeFunc() bool { return C.LLVMInitializeFunctionPassManager(pm.C) != 0 } - -// Executes all of the function passes scheduled in the function pass manager -// on the provided function. Returns 1 if any of the passes modified the -// function, false otherwise. -// See llvm::FunctionPassManager::run(Function&). -func (pm PassManager) RunFunc(f Value) bool { return C.LLVMRunFunctionPassManager(pm.C, f.C) != 0 } - -// Finalizes all of the function passes scheduled in the function pass -// manager. Returns 1 if any of the passes modified the module, 0 otherwise. -// See llvm::FunctionPassManager::doFinalization. -func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassManager(pm.C) != 0 } - -// Frees the memory of a pass pipeline. For function pipelines, does not free -// the module provider. -// See llvm::PassManagerBase::~PassManagerBase. -func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) } diff --git a/llvm/bindings/go/llvm/ir_test.go b/llvm/bindings/go/llvm/ir_test.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/ir_test.go +++ /dev/null @@ -1,165 +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", - "inalloca", - "inlinehint", - "inreg", - "jumptable", - "minsize", - "naked", - "nest", - "noalias", - "nobuiltin", - "nocapture", - "noduplicate", - "noimplicitfloat", - "noinline", - "nonlazybind", - "nonnull", - "noredzone", - "noreturn", - "nounwind", - "optnone", - "optsize", - "readnone", - "readonly", - "returned", - "returns_twice", - "signext", - "safestack", - "ssp", - "sspreq", - "sspstrong", - "sret", - "sanitize_thread", - "sanitize_memory", - "uwtable", - "zeroext", - "cold", - "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") - } -} diff --git a/llvm/bindings/go/llvm/linker.go b/llvm/bindings/go/llvm/linker.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/linker.go +++ /dev/null @@ -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 -*/ -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 -} diff --git a/llvm/bindings/go/llvm/llvm_config.go.in b/llvm/bindings/go/llvm/llvm_config.go.in deleted file mode 100644 --- a/llvm/bindings/go/llvm/llvm_config.go.in +++ /dev/null @@ -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) diff --git a/llvm/bindings/go/llvm/llvm_dep.go b/llvm/bindings/go/llvm/llvm_dep.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/llvm_dep.go +++ /dev/null @@ -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 diff --git a/llvm/bindings/go/llvm/string.go b/llvm/bindings/go/llvm/string.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/string.go +++ /dev/null @@ -1,104 +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 VectorTypeKind: - return "VectorTypeKind" - case MetadataTypeKind: - return "MetadataTypeKind" - } - panic("unreachable") -} - -func (t Type) String() string { - ts := typeStringer{s: make(map[Type]string)} - return ts.typeString(t) -} - -type typeStringer struct { - s map[Type]string -} - -func (ts *typeStringer) typeString(t Type) string { - if s, ok := ts.s[t]; ok { - return s - } - - k := t.TypeKind() - s := k.String() - s = s[:len(s)-len("Kind")] - - switch k { - case ArrayTypeKind: - s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength()) - case PointerTypeKind: - s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType())) - case FunctionTypeKind: - params := t.ParamTypes() - s += "(" - if len(params) > 0 { - s += fmt.Sprintf("%v", ts.typeString(params[0])) - for i := 1; i < len(params); i++ { - s += fmt.Sprintf(", %v", ts.typeString(params[i])) - } - } - s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType())) - case StructTypeKind: - if name := t.StructName(); name != "" { - ts.s[t] = "%" + name - s = fmt.Sprintf("%%%s: %s", name, s) - } - etypes := t.StructElementTypes() - s += "(" - if n := len(etypes); n > 0 { - s += ts.typeString(etypes[0]) - for i := 1; i < n; i++ { - s += fmt.Sprintf(", %v", ts.typeString(etypes[i])) - } - } - s += ")" - case IntegerTypeKind: - s += fmt.Sprintf("(%d bits)", t.IntTypeWidth()) - } - - ts.s[t] = s - return s -} diff --git a/llvm/bindings/go/llvm/string_test.go b/llvm/bindings/go/llvm/string_test.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/string_test.go +++ /dev/null @@ -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) - } -} diff --git a/llvm/bindings/go/llvm/support.go b/llvm/bindings/go/llvm/support.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/support.go +++ /dev/null @@ -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 -*/ -import "C" - -import ( - "errors" - "unsafe" -) - -// Loads a dynamic library such that it may be used as an LLVM plugin. -// See llvm::sys::DynamicLibrary::LoadLibraryPermanently. -func LoadLibraryPermanently(lib string) error { - var errstr *C.char - libstr := C.CString(lib) - defer C.free(unsafe.Pointer(libstr)) - C.LLVMLoadLibraryPermanently2(libstr, &errstr) - if errstr != nil { - err := errors.New(C.GoString(errstr)) - C.free(unsafe.Pointer(errstr)) - return err - } - return nil -} - -// Parse the given arguments using the LLVM command line parser. -// See llvm::cl::ParseCommandLineOptions. -func ParseCommandLineOptions(args []string, overview string) { - argstrs := make([]*C.char, len(args)) - for i, arg := range args { - argstrs[i] = C.CString(arg) - defer C.free(unsafe.Pointer(argstrs[i])) - } - overviewstr := C.CString(overview) - defer C.free(unsafe.Pointer(overviewstr)) - C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr) -} diff --git a/llvm/bindings/go/llvm/target.go b/llvm/bindings/go/llvm/target.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/target.go +++ /dev/null @@ -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 -*/ -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 -} diff --git a/llvm/bindings/go/llvm/transforms_coroutines.go b/llvm/bindings/go/llvm/transforms_coroutines.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_coroutines.go +++ /dev/null @@ -1,23 +0,0 @@ -//===- transforms_coroutines.go - Bindings for coroutines -----------------===// -// -// 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 coroutines component. -// -//===----------------------------------------------------------------------===// - -package llvm - -/* -#include "llvm-c/Transforms/Coroutines.h" -*/ -import "C" - -func (pm PassManager) AddCoroEarlyPass() { C.LLVMAddCoroEarlyPass(pm.C) } -func (pm PassManager) AddCoroSplitPass() { C.LLVMAddCoroSplitPass(pm.C) } -func (pm PassManager) AddCoroElidePass() { C.LLVMAddCoroElidePass(pm.C) } -func (pm PassManager) AddCoroCleanupPass() { C.LLVMAddCoroCleanupPass(pm.C) } diff --git a/llvm/bindings/go/llvm/transforms_instrumentation.go b/llvm/bindings/go/llvm/transforms_instrumentation.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_instrumentation.go +++ /dev/null @@ -1,45 +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 -*/ -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) AddMemorySanitizerLegacyPassPass() { - C.LLVMAddMemorySanitizerLegacyPassPass(pm.C) -} - -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]) -} diff --git a/llvm/bindings/go/llvm/transforms_ipo.go b/llvm/bindings/go/llvm/transforms_ipo.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_ipo.go +++ /dev/null @@ -1,41 +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) AddArgumentPromotionPass() { C.LLVMAddArgumentPromotionPass(pm.C) } -func (pm PassManager) AddConstantMergePass() { C.LLVMAddConstantMergePass(pm.C) } -func (pm PassManager) AddDeadArgEliminationPass() { C.LLVMAddDeadArgEliminationPass(pm.C) } -func (pm PassManager) AddFunctionAttrsPass() { C.LLVMAddFunctionAttrsPass(pm.C) } -func (pm PassManager) AddFunctionInliningPass() { C.LLVMAddFunctionInliningPass(pm.C) } -func (pm PassManager) AddGlobalDCEPass() { C.LLVMAddGlobalDCEPass(pm.C) } -func (pm PassManager) AddGlobalOptimizerPass() { C.LLVMAddGlobalOptimizerPass(pm.C) } -func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) } -func (pm PassManager) AddPruneEHPass() { C.LLVMAddPruneEHPass(pm.C) } -func (pm PassManager) AddIPSCCPPass() { C.LLVMAddIPSCCPPass(pm.C) } -func (pm PassManager) AddInternalizePass(allButMain bool) { - C.LLVMAddInternalizePass(pm.C, boolToUnsigned(allButMain)) -} -func (pm PassManager) AddStripDeadPrototypesPass() { C.LLVMAddStripDeadPrototypesPass(pm.C) } diff --git a/llvm/bindings/go/llvm/transforms_pmbuilder.go b/llvm/bindings/go/llvm/transforms_pmbuilder.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_pmbuilder.go +++ /dev/null @@ -1,67 +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) PopulateLTOPassManager(pm PassManager, internalize bool, runInliner bool) { - C.LLVMPassManagerBuilderPopulateLTOPassManager(pmb.C, pm.C, boolToLLVMBool(internalize), boolToLLVMBool(runInliner)) -} - -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)) -} diff --git a/llvm/bindings/go/llvm/transforms_scalar.go b/llvm/bindings/go/llvm/transforms_scalar.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/transforms_scalar.go +++ /dev/null @@ -1,45 +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) AddLoopUnswitchPass() { C.LLVMAddLoopUnswitchPass(pm.C) } -func (pm PassManager) AddMemCpyOptPass() { C.LLVMAddMemCpyOptPass(pm.C) } -func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) } -func (pm PassManager) AddReassociatePass() { C.LLVMAddReassociatePass(pm.C) } -func (pm PassManager) AddSCCPPass() { C.LLVMAddSCCPPass(pm.C) } -func (pm PassManager) AddScalarReplAggregatesPass() { C.LLVMAddScalarReplAggregatesPass(pm.C) } -func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) { - C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold)) -} -func (pm PassManager) AddSimplifyLibCallsPass() { C.LLVMAddSimplifyLibCallsPass(pm.C) } -func (pm PassManager) AddTailCallEliminationPass() { C.LLVMAddTailCallEliminationPass(pm.C) } -func (pm PassManager) AddConstantPropagationPass() { C.LLVMAddConstantPropagationPass(pm.C) } -func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) } -func (pm PassManager) AddVerifierPass() { C.LLVMAddVerifierPass(pm.C) } diff --git a/llvm/bindings/go/llvm/version.go b/llvm/bindings/go/llvm/version.go deleted file mode 100644 --- a/llvm/bindings/go/llvm/version.go +++ /dev/null @@ -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 diff --git a/llvm/bindings/go/src/llvm/IRBindings.h b/llvm/bindings/go/src/llvm/IRBindings.h new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/IRBindings.h @@ -0,0 +1,57 @@ +//===- 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 + +#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 diff --git a/llvm/bindings/go/src/llvm/IRBindings.cpp b/llvm/bindings/go/src/llvm/IRBindings.cpp new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/IRBindings.cpp @@ -0,0 +1,72 @@ +//===- 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(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(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(Val)); +} + +void LLVMSetMetadata2(LLVMValueRef Inst, unsigned KindID, LLVMMetadataRef MD) { + MDNode *N = MD ? unwrap(MD) : nullptr; + unwrap(Inst)->setMetadata(KindID, N); +} + +void LLVMGoSetCurrentDebugLocation(LLVMBuilderRef Bref, unsigned Line, + unsigned Col, LLVMMetadataRef Scope, + LLVMMetadataRef InlinedAt) { + unwrap(Bref)->SetCurrentDebugLocation( + DebugLoc::get(Line, Col, Scope ? unwrap(Scope) : nullptr, + InlinedAt ? unwrap(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; +} + diff --git a/llvm/bindings/go/src/llvm/InstrumentationBindings.h b/llvm/bindings/go/src/llvm/InstrumentationBindings.h new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/InstrumentationBindings.h @@ -0,0 +1,37 @@ +//===- 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 LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM); +void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM); +void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM); +void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM); +void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, int ABIListFilesNum, + const char **ABIListFiles); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/llvm/bindings/go/src/llvm/InstrumentationBindings.cpp b/llvm/bindings/go/src/llvm/InstrumentationBindings.cpp new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/InstrumentationBindings.cpp @@ -0,0 +1,48 @@ +//===- 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/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" +#include "llvm/Transforms/Instrumentation/MemorySanitizer.h" +#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h" + +using namespace llvm; + +void LLVMAddAddressSanitizerFunctionPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createAddressSanitizerFunctionPass()); +} + +void LLVMAddAddressSanitizerModulePass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createModuleAddressSanitizerLegacyPassPass()); +} + +void LLVMAddThreadSanitizerPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createThreadSanitizerLegacyPassPass()); +} + +void LLVMAddMemorySanitizerLegacyPassPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createMemorySanitizerLegacyPassPass()); +} + +void LLVMAddDataFlowSanitizerPass(LLVMPassManagerRef PM, + int ABIListFilesNum, + const char **ABIListFiles) { + std::vector ABIListFilesVec; + for (int i = 0; i != ABIListFilesNum; ++i) { + ABIListFilesVec.push_back(ABIListFiles[i]); + } + unwrap(PM)->add(createDataFlowSanitizerPass(ABIListFilesVec)); +} diff --git a/llvm/bindings/go/src/llvm/SupportBindings.h b/llvm/bindings/go/src/llvm/SupportBindings.h new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/SupportBindings.h @@ -0,0 +1,29 @@ +//===- 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 diff --git a/llvm/bindings/go/src/llvm/SupportBindings.cpp b/llvm/bindings/go/src/llvm/SupportBindings.cpp new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/SupportBindings.cpp @@ -0,0 +1,25 @@ +//===- 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 +#include + +void LLVMLoadLibraryPermanently2(const char *Filename, char **ErrMsg) { + std::string ErrMsgStr; + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename, &ErrMsgStr)) { + *ErrMsg = static_cast(malloc(ErrMsgStr.size() + 1)); + memcpy(static_cast(*ErrMsg), + static_cast(ErrMsgStr.c_str()), ErrMsgStr.size() + 1); + } +} diff --git a/llvm/bindings/go/src/llvm/analysis.go b/llvm/bindings/go/src/llvm/analysis.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/analysis.go @@ -0,0 +1,68 @@ +//===- 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 +*/ +import "C" +import "errors" + +type VerifierFailureAction C.LLVMVerifierFailureAction + +const ( + // verifier will print to stderr and abort() + AbortProcessAction VerifierFailureAction = C.LLVMAbortProcessAction + // verifier will print to stderr and return 1 + PrintMessageAction VerifierFailureAction = C.LLVMPrintMessageAction + // verifier will just return 1 + ReturnStatusAction VerifierFailureAction = C.LLVMReturnStatusAction +) + +// Verifies that a module is valid, taking the specified action if not. +// Optionally returns a human-readable description of any invalid constructs. +func VerifyModule(m Module, a VerifierFailureAction) error { + var cmsg *C.char + broken := C.LLVMVerifyModule(m.C, C.LLVMVerifierFailureAction(a), &cmsg) + + // C++'s verifyModule means isModuleBroken, so it returns false if + // there are no errors + if broken != 0 { + err := errors.New(C.GoString(cmsg)) + C.LLVMDisposeMessage(cmsg) + return err + } + return nil +} + +var verifyFunctionError = errors.New("Function is broken") + +// Verifies that a single function is valid, taking the specified action. +// Useful for debugging. +func VerifyFunction(f Value, a VerifierFailureAction) error { + broken := C.LLVMVerifyFunction(f.C, C.LLVMVerifierFailureAction(a)) + + // C++'s verifyFunction means isFunctionBroken, so it returns false if + // there are no errors + if broken != 0 { + return verifyFunctionError + } + return nil +} + +// Open up a ghostview window that displays the CFG of the current function. +// Useful for debugging. +func ViewFunctionCFG(f Value) { C.LLVMViewFunctionCFG(f.C) } +func ViewFunctionCFGOnly(f Value) { C.LLVMViewFunctionCFGOnly(f.C) } diff --git a/llvm/bindings/go/src/llvm/bitreader.go b/llvm/bindings/go/src/llvm/bitreader.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/bitreader.go @@ -0,0 +1,50 @@ +//===- 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 +*/ +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 +} diff --git a/llvm/bindings/go/src/llvm/bitwriter.go b/llvm/bindings/go/src/llvm/bitwriter.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/bitwriter.go @@ -0,0 +1,38 @@ +//===- 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 +*/ +import "C" +import "os" +import "errors" + +var writeBitcodeToFileErr = errors.New("Failed to write bitcode to file") + +func WriteBitcodeToFile(m Module, file *os.File) error { + fail := C.LLVMWriteBitcodeToFD(m.C, C.int(file.Fd()), C.int(0), C.int(0)) + if fail != 0 { + return writeBitcodeToFileErr + } + return nil +} + +func WriteBitcodeToMemoryBuffer(m Module) MemoryBuffer { + mb := C.LLVMWriteBitcodeToMemoryBuffer(m.C) + return MemoryBuffer{mb} +} + +// TODO(nsf): Figure out way how to make it work with io.Writer diff --git a/llvm/bindings/go/src/llvm/dibuilder.go b/llvm/bindings/go/src/llvm/dibuilder.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/dibuilder.go @@ -0,0 +1,707 @@ +//===- 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 +*/ +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 +} + +// 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)) + 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)), + ) + 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 []int64) Metadata { + var data *C.int64_t + if len(addr) > 0 { + data = (*C.int64_t)(unsafe.Pointer(&addr[0])) + } + result := C.LLVMDIBuilderCreateExpression(d.ref, data, C.size_t(len(addr))) + return 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)} +} diff --git a/llvm/bindings/go/src/llvm/executionengine.go b/llvm/bindings/go/src/llvm/executionengine.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/executionengine.go @@ -0,0 +1,177 @@ +//===- 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 +*/ +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) +} diff --git a/llvm/bindings/go/src/llvm/executionengine_test.go b/llvm/bindings/go/src/llvm/executionengine_test.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/executionengine_test.go @@ -0,0 +1,96 @@ +//===- 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.AddConstantPropagationPass() + pass.AddInstructionCombiningPass() + pass.AddPromoteMemoryToRegisterPass() + pass.AddGVNPass() + pass.AddCFGSimplificationPass() + pass.Run(mod) + + exec_args := []GenericValue{NewGenericValueFromInt(Int32Type(), 10, false)} + exec_res := engine.RunFunction(fac, exec_args) + var fac10 uint64 = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 + if exec_res.Int(false) != fac10 { + t.Errorf("Expected %d, got %d", fac10, exec_res.Int(false)) + } +} diff --git a/llvm/bindings/go/src/llvm/ir.go b/llvm/bindings/go/src/llvm/ir.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/ir.go @@ -0,0 +1,2014 @@ +//===- ir.go - 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 bindings for the ir component. +// +//===----------------------------------------------------------------------===// + +package llvm + +/* +#include "llvm-c/Core.h" +#include "llvm-c/Comdat.h" +#include "IRBindings.h" +#include +*/ +import "C" +import "unsafe" +import "errors" + +type ( + // We use these weird structs here because *Ref types are pointers and + // Go's spec says that a pointer cannot be used as a receiver base type. + Context struct { + C C.LLVMContextRef + } + Module struct { + C C.LLVMModuleRef + } + Type struct { + C C.LLVMTypeRef + } + Value struct { + C C.LLVMValueRef + } + Comdat struct { + C C.LLVMComdatRef + } + BasicBlock struct { + C C.LLVMBasicBlockRef + } + Builder struct { + C C.LLVMBuilderRef + } + ModuleProvider struct { + C C.LLVMModuleProviderRef + } + MemoryBuffer struct { + C C.LLVMMemoryBufferRef + } + PassManager struct { + C C.LLVMPassManagerRef + } + Use struct { + C C.LLVMUseRef + } + Metadata struct { + C C.LLVMMetadataRef + } + Attribute struct { + C C.LLVMAttributeRef + } + Opcode C.LLVMOpcode + AtomicRMWBinOp C.LLVMAtomicRMWBinOp + AtomicOrdering C.LLVMAtomicOrdering + TypeKind C.LLVMTypeKind + Linkage C.LLVMLinkage + Visibility C.LLVMVisibility + CallConv C.LLVMCallConv + ComdatSelectionKind C.LLVMComdatSelectionKind + IntPredicate C.LLVMIntPredicate + FloatPredicate C.LLVMRealPredicate + LandingPadClause C.LLVMLandingPadClauseTy + InlineAsmDialect C.LLVMInlineAsmDialect +) + +func (c Context) IsNil() bool { return c.C == nil } +func (c Module) IsNil() bool { return c.C == nil } +func (c Type) IsNil() bool { return c.C == nil } +func (c Value) IsNil() bool { return c.C == nil } +func (c BasicBlock) IsNil() bool { return c.C == nil } +func (c Builder) IsNil() bool { return c.C == nil } +func (c ModuleProvider) IsNil() bool { return c.C == nil } +func (c MemoryBuffer) IsNil() bool { return c.C == nil } +func (c PassManager) IsNil() bool { return c.C == nil } +func (c Use) IsNil() bool { return c.C == nil } +func (c Attribute) IsNil() bool { return c.C == nil } +func (c Metadata) IsNil() bool { return c.C == nil } + +// helpers +func llvmTypeRefPtr(t *Type) *C.LLVMTypeRef { return (*C.LLVMTypeRef)(unsafe.Pointer(t)) } +func llvmValueRefPtr(t *Value) *C.LLVMValueRef { return (*C.LLVMValueRef)(unsafe.Pointer(t)) } +func llvmMetadataRefPtr(t *Metadata) *C.LLVMMetadataRef { + return (*C.LLVMMetadataRef)(unsafe.Pointer(t)) +} +func llvmBasicBlockRefPtr(t *BasicBlock) *C.LLVMBasicBlockRef { + return (*C.LLVMBasicBlockRef)(unsafe.Pointer(t)) +} +func boolToLLVMBool(b bool) C.LLVMBool { + if b { + return C.LLVMBool(1) + } + return C.LLVMBool(0) +} + +func llvmValueRefs(values []Value) (*C.LLVMValueRef, C.unsigned) { + var pt *C.LLVMValueRef + ptlen := C.unsigned(len(values)) + if ptlen > 0 { + pt = llvmValueRefPtr(&values[0]) + } + return pt, ptlen +} + +func llvmMetadataRefs(mds []Metadata) (*C.LLVMMetadataRef, C.unsigned) { + var pt *C.LLVMMetadataRef + ptlen := C.unsigned(len(mds)) + if ptlen > 0 { + pt = llvmMetadataRefPtr(&mds[0]) + } + return pt, ptlen +} + +//------------------------------------------------------------------------- +// llvm.Opcode +//------------------------------------------------------------------------- + +const ( + Ret Opcode = C.LLVMRet + Br Opcode = C.LLVMBr + Switch Opcode = C.LLVMSwitch + IndirectBr Opcode = C.LLVMIndirectBr + Invoke Opcode = C.LLVMInvoke + Unreachable Opcode = C.LLVMUnreachable + + // Standard Binary Operators + Add Opcode = C.LLVMAdd + FAdd Opcode = C.LLVMFAdd + Sub Opcode = C.LLVMSub + FSub Opcode = C.LLVMFSub + Mul Opcode = C.LLVMMul + FMul Opcode = C.LLVMFMul + UDiv Opcode = C.LLVMUDiv + SDiv Opcode = C.LLVMSDiv + FDiv Opcode = C.LLVMFDiv + URem Opcode = C.LLVMURem + SRem Opcode = C.LLVMSRem + FRem Opcode = C.LLVMFRem + + // Logical Operators + Shl Opcode = C.LLVMShl + LShr Opcode = C.LLVMLShr + AShr Opcode = C.LLVMAShr + And Opcode = C.LLVMAnd + Or Opcode = C.LLVMOr + Xor Opcode = C.LLVMXor + + // Memory Operators + Alloca Opcode = C.LLVMAlloca + Load Opcode = C.LLVMLoad + Store Opcode = C.LLVMStore + GetElementPtr Opcode = C.LLVMGetElementPtr + + // Cast Operators + Trunc Opcode = C.LLVMTrunc + ZExt Opcode = C.LLVMZExt + SExt Opcode = C.LLVMSExt + FPToUI Opcode = C.LLVMFPToUI + FPToSI Opcode = C.LLVMFPToSI + UIToFP Opcode = C.LLVMUIToFP + SIToFP Opcode = C.LLVMSIToFP + FPTrunc Opcode = C.LLVMFPTrunc + FPExt Opcode = C.LLVMFPExt + PtrToInt Opcode = C.LLVMPtrToInt + IntToPtr Opcode = C.LLVMIntToPtr + BitCast Opcode = C.LLVMBitCast + + // Other Operators + ICmp Opcode = C.LLVMICmp + FCmp Opcode = C.LLVMFCmp + PHI Opcode = C.LLVMPHI + Call Opcode = C.LLVMCall + Select Opcode = C.LLVMSelect + // UserOp1 + // UserOp2 + VAArg Opcode = C.LLVMVAArg + ExtractElement Opcode = C.LLVMExtractElement + InsertElement Opcode = C.LLVMInsertElement + ShuffleVector Opcode = C.LLVMShuffleVector + ExtractValue Opcode = C.LLVMExtractValue + InsertValue Opcode = C.LLVMInsertValue +) + +const ( + AtomicRMWBinOpXchg AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXchg + AtomicRMWBinOpAdd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAdd + AtomicRMWBinOpSub AtomicRMWBinOp = C.LLVMAtomicRMWBinOpSub + AtomicRMWBinOpAnd AtomicRMWBinOp = C.LLVMAtomicRMWBinOpAnd + AtomicRMWBinOpNand AtomicRMWBinOp = C.LLVMAtomicRMWBinOpNand + AtomicRMWBinOpOr AtomicRMWBinOp = C.LLVMAtomicRMWBinOpOr + AtomicRMWBinOpXor AtomicRMWBinOp = C.LLVMAtomicRMWBinOpXor + AtomicRMWBinOpMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMax + AtomicRMWBinOpMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpMin + AtomicRMWBinOpUMax AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMax + AtomicRMWBinOpUMin AtomicRMWBinOp = C.LLVMAtomicRMWBinOpUMin +) + +const ( + AtomicOrderingNotAtomic AtomicOrdering = C.LLVMAtomicOrderingNotAtomic + AtomicOrderingUnordered AtomicOrdering = C.LLVMAtomicOrderingUnordered + AtomicOrderingMonotonic AtomicOrdering = C.LLVMAtomicOrderingMonotonic + AtomicOrderingAcquire AtomicOrdering = C.LLVMAtomicOrderingAcquire + AtomicOrderingRelease AtomicOrdering = C.LLVMAtomicOrderingRelease + AtomicOrderingAcquireRelease AtomicOrdering = C.LLVMAtomicOrderingAcquireRelease + AtomicOrderingSequentiallyConsistent AtomicOrdering = C.LLVMAtomicOrderingSequentiallyConsistent +) + +//------------------------------------------------------------------------- +// llvm.TypeKind +//------------------------------------------------------------------------- + +const ( + VoidTypeKind TypeKind = C.LLVMVoidTypeKind + FloatTypeKind TypeKind = C.LLVMFloatTypeKind + DoubleTypeKind TypeKind = C.LLVMDoubleTypeKind + X86_FP80TypeKind TypeKind = C.LLVMX86_FP80TypeKind + FP128TypeKind TypeKind = C.LLVMFP128TypeKind + PPC_FP128TypeKind TypeKind = C.LLVMPPC_FP128TypeKind + LabelTypeKind TypeKind = C.LLVMLabelTypeKind + IntegerTypeKind TypeKind = C.LLVMIntegerTypeKind + FunctionTypeKind TypeKind = C.LLVMFunctionTypeKind + StructTypeKind TypeKind = C.LLVMStructTypeKind + ArrayTypeKind TypeKind = C.LLVMArrayTypeKind + PointerTypeKind TypeKind = C.LLVMPointerTypeKind + VectorTypeKind TypeKind = C.LLVMVectorTypeKind + MetadataTypeKind TypeKind = C.LLVMMetadataTypeKind + TokenTypeKind TypeKind = C.LLVMTokenTypeKind +) + +//------------------------------------------------------------------------- +// llvm.Linkage +//------------------------------------------------------------------------- + +const ( + ExternalLinkage Linkage = C.LLVMExternalLinkage + AvailableExternallyLinkage Linkage = C.LLVMAvailableExternallyLinkage + LinkOnceAnyLinkage Linkage = C.LLVMLinkOnceAnyLinkage + LinkOnceODRLinkage Linkage = C.LLVMLinkOnceODRLinkage + WeakAnyLinkage Linkage = C.LLVMWeakAnyLinkage + WeakODRLinkage Linkage = C.LLVMWeakODRLinkage + AppendingLinkage Linkage = C.LLVMAppendingLinkage + InternalLinkage Linkage = C.LLVMInternalLinkage + PrivateLinkage Linkage = C.LLVMPrivateLinkage + ExternalWeakLinkage Linkage = C.LLVMExternalWeakLinkage + CommonLinkage Linkage = C.LLVMCommonLinkage +) + +//------------------------------------------------------------------------- +// llvm.Visibility +//------------------------------------------------------------------------- + +const ( + DefaultVisibility Visibility = C.LLVMDefaultVisibility + HiddenVisibility Visibility = C.LLVMHiddenVisibility + ProtectedVisibility Visibility = C.LLVMProtectedVisibility +) + +//------------------------------------------------------------------------- +// llvm.CallConv +//------------------------------------------------------------------------- + +const ( + CCallConv CallConv = C.LLVMCCallConv + FastCallConv CallConv = C.LLVMFastCallConv + ColdCallConv CallConv = C.LLVMColdCallConv + X86StdcallCallConv CallConv = C.LLVMX86StdcallCallConv + X86FastcallCallConv CallConv = C.LLVMX86FastcallCallConv +) + +//------------------------------------------------------------------------- +// llvm.ComdatSelectionKind +//------------------------------------------------------------------------- + +const ( + AnyComdatSelectionKind ComdatSelectionKind = C.LLVMAnyComdatSelectionKind + ExactMatchComdatSelectionKind ComdatSelectionKind = C.LLVMExactMatchComdatSelectionKind + LargestComdatSelectionKind ComdatSelectionKind = C.LLVMLargestComdatSelectionKind + NoDuplicatesComdatSelectionKind ComdatSelectionKind = C.LLVMNoDuplicatesComdatSelectionKind + SameSizeComdatSelectionKind ComdatSelectionKind = C.LLVMSameSizeComdatSelectionKind +) + +//------------------------------------------------------------------------- +// llvm.IntPredicate +//------------------------------------------------------------------------- + +const ( + IntEQ IntPredicate = C.LLVMIntEQ + IntNE IntPredicate = C.LLVMIntNE + IntUGT IntPredicate = C.LLVMIntUGT + IntUGE IntPredicate = C.LLVMIntUGE + IntULT IntPredicate = C.LLVMIntULT + IntULE IntPredicate = C.LLVMIntULE + IntSGT IntPredicate = C.LLVMIntSGT + IntSGE IntPredicate = C.LLVMIntSGE + IntSLT IntPredicate = C.LLVMIntSLT + IntSLE IntPredicate = C.LLVMIntSLE +) + +//------------------------------------------------------------------------- +// llvm.FloatPredicate +//------------------------------------------------------------------------- + +const ( + FloatPredicateFalse FloatPredicate = C.LLVMRealPredicateFalse + FloatOEQ FloatPredicate = C.LLVMRealOEQ + FloatOGT FloatPredicate = C.LLVMRealOGT + FloatOGE FloatPredicate = C.LLVMRealOGE + FloatOLT FloatPredicate = C.LLVMRealOLT + FloatOLE FloatPredicate = C.LLVMRealOLE + FloatONE FloatPredicate = C.LLVMRealONE + FloatORD FloatPredicate = C.LLVMRealORD + FloatUNO FloatPredicate = C.LLVMRealUNO + FloatUEQ FloatPredicate = C.LLVMRealUEQ + FloatUGT FloatPredicate = C.LLVMRealUGT + FloatUGE FloatPredicate = C.LLVMRealUGE + FloatULT FloatPredicate = C.LLVMRealULT + FloatULE FloatPredicate = C.LLVMRealULE + FloatUNE FloatPredicate = C.LLVMRealUNE + FloatPredicateTrue FloatPredicate = C.LLVMRealPredicateTrue +) + +//------------------------------------------------------------------------- +// llvm.LandingPadClause +//------------------------------------------------------------------------- + +const ( + LandingPadCatch LandingPadClause = C.LLVMLandingPadCatch + LandingPadFilter LandingPadClause = C.LLVMLandingPadFilter +) + +//------------------------------------------------------------------------- +// llvm.InlineAsmDialect +//------------------------------------------------------------------------- + +const ( + InlineAsmDialectATT InlineAsmDialect = C.LLVMInlineAsmDialectATT + InlineAsmDialectIntel InlineAsmDialect = C.LLVMInlineAsmDialectIntel +) + +//------------------------------------------------------------------------- +// llvm.Context +//------------------------------------------------------------------------- + +func NewContext() Context { return Context{C.LLVMContextCreate()} } +func GlobalContext() Context { return Context{C.LLVMGetGlobalContext()} } +func (c Context) Dispose() { C.LLVMContextDispose(c.C) } + +func (c Context) MDKindID(name string) (id int) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + id = int(C.LLVMGetMDKindIDInContext(c.C, cname, C.unsigned(len(name)))) + return +} + +func MDKindID(name string) (id int) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + id = int(C.LLVMGetMDKindID(cname, C.unsigned(len(name)))) + return +} + +//------------------------------------------------------------------------- +// llvm.Attribute +//------------------------------------------------------------------------- + +func AttributeKindID(name string) (id uint) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + id = uint(C.LLVMGetEnumAttributeKindForName(cname, C.size_t(len(name)))) + return +} + +func (c Context) CreateEnumAttribute(kind uint, val uint64) (a Attribute) { + a.C = C.LLVMCreateEnumAttribute(c.C, C.unsigned(kind), C.uint64_t(val)) + return +} + +func (a Attribute) GetEnumKind() (id int) { + id = int(C.LLVMGetEnumAttributeKind(a.C)) + return +} + +func (a Attribute) GetEnumValue() (val uint64) { + val = uint64(C.LLVMGetEnumAttributeValue(a.C)) + return +} + +func (c Context) CreateStringAttribute(kind string, val string) (a Attribute) { + ckind := C.CString(kind) + defer C.free(unsafe.Pointer(ckind)) + cval := C.CString(val) + defer C.free(unsafe.Pointer(cval)) + a.C = C.LLVMCreateStringAttribute(c.C, + ckind, C.unsigned(len(kind)), + cval, C.unsigned(len(val))) + return +} + +func (a Attribute) GetStringKind() string { + length := C.unsigned(0) + ckind := C.LLVMGetStringAttributeKind(a.C, &length) + return C.GoStringN(ckind, C.int(length)) +} + +func (a Attribute) GetStringValue() string { + length := C.unsigned(0) + ckind := C.LLVMGetStringAttributeValue(a.C, &length) + return C.GoStringN(ckind, C.int(length)) +} + +func (a Attribute) IsEnum() bool { + return C.LLVMIsEnumAttribute(a.C) != 0 +} + +func (a Attribute) IsString() bool { + return C.LLVMIsStringAttribute(a.C) != 0 +} + +//------------------------------------------------------------------------- +// llvm.Module +//------------------------------------------------------------------------- + +// Create and destroy modules. +// See llvm::Module::Module. +func NewModule(name string) (m Module) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + m.C = C.LLVMModuleCreateWithName(cname) + return +} + +func (c Context) NewModule(name string) (m Module) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + m.C = C.LLVMModuleCreateWithNameInContext(cname, c.C) + return +} + +// See llvm::Module::~Module +func (m Module) Dispose() { C.LLVMDisposeModule(m.C) } + +// Data layout. See Module::getDataLayout. +func (m Module) DataLayout() string { + clayout := C.LLVMGetDataLayout(m.C) + return C.GoString(clayout) +} + +func (m Module) SetDataLayout(layout string) { + clayout := C.CString(layout) + defer C.free(unsafe.Pointer(clayout)) + C.LLVMSetDataLayout(m.C, clayout) +} + +// Target triple. See Module::getTargetTriple. +func (m Module) Target() string { + ctarget := C.LLVMGetTarget(m.C) + return C.GoString(ctarget) +} +func (m Module) SetTarget(target string) { + ctarget := C.CString(target) + defer C.free(unsafe.Pointer(ctarget)) + C.LLVMSetTarget(m.C, ctarget) +} + +func (m Module) GetTypeByName(name string) (t Type) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + t.C = C.LLVMGetTypeByName(m.C, cname) + return +} + +// See Module::dump. +func (m Module) Dump() { + C.LLVMDumpModule(m.C) +} + +func (m Module) String() string { + cir := C.LLVMPrintModuleToString(m.C) + defer C.free(unsafe.Pointer(cir)) + ir := C.GoString(cir) + return ir +} + +// See Module::setModuleInlineAsm. +func (m Module) SetInlineAsm(asm string) { + casm := C.CString(asm) + defer C.free(unsafe.Pointer(casm)) + C.LLVMSetModuleInlineAsm(m.C, casm) +} + +func (m Module) AddNamedMetadataOperand(name string, operand Metadata) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + C.LLVMAddNamedMetadataOperand2(m.C, cname, operand.C) +} + +func (m Module) Context() (c Context) { + c.C = C.LLVMGetModuleContext(m.C) + return +} + +//------------------------------------------------------------------------- +// llvm.Type +//------------------------------------------------------------------------- + +// LLVM types conform to the following hierarchy: +// +// types: +// integer type +// real type +// function type +// sequence types: +// array type +// pointer type +// vector type +// void type +// label type +// opaque type + +// See llvm::LLVMTypeKind::getTypeID. +func (t Type) TypeKind() TypeKind { return TypeKind(C.LLVMGetTypeKind(t.C)) } + +// See llvm::LLVMType::getContext. +func (t Type) Context() (c Context) { + c.C = C.LLVMGetTypeContext(t.C) + return +} + +// Operations on integer types +func (c Context) Int1Type() (t Type) { t.C = C.LLVMInt1TypeInContext(c.C); return } +func (c Context) Int8Type() (t Type) { t.C = C.LLVMInt8TypeInContext(c.C); return } +func (c Context) Int16Type() (t Type) { t.C = C.LLVMInt16TypeInContext(c.C); return } +func (c Context) Int32Type() (t Type) { t.C = C.LLVMInt32TypeInContext(c.C); return } +func (c Context) Int64Type() (t Type) { t.C = C.LLVMInt64TypeInContext(c.C); return } +func (c Context) IntType(numbits int) (t Type) { + t.C = C.LLVMIntTypeInContext(c.C, C.unsigned(numbits)) + return +} + +func Int1Type() (t Type) { t.C = C.LLVMInt1Type(); return } +func Int8Type() (t Type) { t.C = C.LLVMInt8Type(); return } +func Int16Type() (t Type) { t.C = C.LLVMInt16Type(); return } +func Int32Type() (t Type) { t.C = C.LLVMInt32Type(); return } +func Int64Type() (t Type) { t.C = C.LLVMInt64Type(); return } + +func IntType(numbits int) (t Type) { + t.C = C.LLVMIntType(C.unsigned(numbits)) + return +} + +func (t Type) IntTypeWidth() int { + return int(C.LLVMGetIntTypeWidth(t.C)) +} + +// Operations on real types +func (c Context) FloatType() (t Type) { t.C = C.LLVMFloatTypeInContext(c.C); return } +func (c Context) DoubleType() (t Type) { t.C = C.LLVMDoubleTypeInContext(c.C); return } +func (c Context) X86FP80Type() (t Type) { t.C = C.LLVMX86FP80TypeInContext(c.C); return } +func (c Context) FP128Type() (t Type) { t.C = C.LLVMFP128TypeInContext(c.C); return } +func (c Context) PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128TypeInContext(c.C); return } + +func FloatType() (t Type) { t.C = C.LLVMFloatType(); return } +func DoubleType() (t Type) { t.C = C.LLVMDoubleType(); return } +func X86FP80Type() (t Type) { t.C = C.LLVMX86FP80Type(); return } +func FP128Type() (t Type) { t.C = C.LLVMFP128Type(); return } +func PPCFP128Type() (t Type) { t.C = C.LLVMPPCFP128Type(); return } + +// Operations on function types +func FunctionType(returnType Type, paramTypes []Type, isVarArg bool) (t Type) { + var pt *C.LLVMTypeRef + var ptlen C.unsigned + if len(paramTypes) > 0 { + pt = llvmTypeRefPtr(¶mTypes[0]) + ptlen = C.unsigned(len(paramTypes)) + } + t.C = C.LLVMFunctionType(returnType.C, + pt, + ptlen, + boolToLLVMBool(isVarArg)) + return +} + +func (t Type) IsFunctionVarArg() bool { return C.LLVMIsFunctionVarArg(t.C) != 0 } +func (t Type) ReturnType() (rt Type) { rt.C = C.LLVMGetReturnType(t.C); return } +func (t Type) ParamTypesCount() int { return int(C.LLVMCountParamTypes(t.C)) } +func (t Type) ParamTypes() []Type { + count := t.ParamTypesCount() + if count > 0 { + out := make([]Type, count) + C.LLVMGetParamTypes(t.C, llvmTypeRefPtr(&out[0])) + return out + } + return nil +} + +// Operations on struct types +func (c Context) StructType(elementTypes []Type, packed bool) (t Type) { + var pt *C.LLVMTypeRef + var ptlen C.unsigned + if len(elementTypes) > 0 { + pt = llvmTypeRefPtr(&elementTypes[0]) + ptlen = C.unsigned(len(elementTypes)) + } + t.C = C.LLVMStructTypeInContext(c.C, + pt, + ptlen, + boolToLLVMBool(packed)) + return +} + +func StructType(elementTypes []Type, packed bool) (t Type) { + var pt *C.LLVMTypeRef + var ptlen C.unsigned + if len(elementTypes) > 0 { + pt = llvmTypeRefPtr(&elementTypes[0]) + ptlen = C.unsigned(len(elementTypes)) + } + t.C = C.LLVMStructType(pt, ptlen, boolToLLVMBool(packed)) + return +} + +func (c Context) StructCreateNamed(name string) (t Type) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + t.C = C.LLVMStructCreateNamed(c.C, cname) + return +} + +func (t Type) StructName() string { + return C.GoString(C.LLVMGetStructName(t.C)) +} + +func (t Type) StructSetBody(elementTypes []Type, packed bool) { + var pt *C.LLVMTypeRef + var ptlen C.unsigned + if len(elementTypes) > 0 { + pt = llvmTypeRefPtr(&elementTypes[0]) + ptlen = C.unsigned(len(elementTypes)) + } + C.LLVMStructSetBody(t.C, pt, ptlen, boolToLLVMBool(packed)) +} + +func (t Type) IsStructPacked() bool { return C.LLVMIsPackedStruct(t.C) != 0 } +func (t Type) StructElementTypesCount() int { return int(C.LLVMCountStructElementTypes(t.C)) } +func (t Type) StructElementTypes() []Type { + out := make([]Type, t.StructElementTypesCount()) + if len(out) > 0 { + C.LLVMGetStructElementTypes(t.C, llvmTypeRefPtr(&out[0])) + } + return out +} + +// Operations on array, pointer, and vector types (sequence types) +func (t Type) Subtypes() (ret []Type) { + ret = make([]Type, C.LLVMGetNumContainedTypes(t.C)) + C.LLVMGetSubtypes(t.C, llvmTypeRefPtr(&ret[0])) + return +} + +func ArrayType(elementType Type, elementCount int) (t Type) { + t.C = C.LLVMArrayType(elementType.C, C.unsigned(elementCount)) + return +} +func PointerType(elementType Type, addressSpace int) (t Type) { + t.C = C.LLVMPointerType(elementType.C, C.unsigned(addressSpace)) + return +} +func VectorType(elementType Type, elementCount int) (t Type) { + t.C = C.LLVMVectorType(elementType.C, C.unsigned(elementCount)) + return +} + +func (t Type) ElementType() (rt Type) { rt.C = C.LLVMGetElementType(t.C); return } +func (t Type) ArrayLength() int { return int(C.LLVMGetArrayLength(t.C)) } +func (t Type) PointerAddressSpace() int { return int(C.LLVMGetPointerAddressSpace(t.C)) } +func (t Type) VectorSize() int { return int(C.LLVMGetVectorSize(t.C)) } + +// Operations on other types +func (c Context) VoidType() (t Type) { t.C = C.LLVMVoidTypeInContext(c.C); return } +func (c Context) LabelType() (t Type) { t.C = C.LLVMLabelTypeInContext(c.C); return } +func (c Context) TokenType() (t Type) { t.C = C.LLVMTokenTypeInContext(c.C); return } + +func VoidType() (t Type) { t.C = C.LLVMVoidType(); return } +func LabelType() (t Type) { t.C = C.LLVMLabelType(); return } + +//------------------------------------------------------------------------- +// llvm.Value +//------------------------------------------------------------------------- + +// Operations on all values +func (v Value) Type() (t Type) { t.C = C.LLVMTypeOf(v.C); return } +func (v Value) Name() string { return C.GoString(C.LLVMGetValueName(v.C)) } +func (v Value) SetName(name string) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + C.LLVMSetValueName(v.C, cname) +} +func (v Value) Dump() { C.LLVMDumpValue(v.C) } +func (v Value) ReplaceAllUsesWith(nv Value) { C.LLVMReplaceAllUsesWith(v.C, nv.C) } +func (v Value) HasMetadata() bool { return C.LLVMHasMetadata(v.C) != 0 } +func (v Value) Metadata(kind int) (rv Value) { + rv.C = C.LLVMGetMetadata(v.C, C.unsigned(kind)) + return +} +func (v Value) SetMetadata(kind int, node Metadata) { + C.LLVMSetMetadata2(v.C, C.unsigned(kind), node.C) +} + +// Conversion functions. +// Return the input value if it is an instance of the specified class, otherwise NULL. +// See llvm::dyn_cast_or_null<>. +func (v Value) IsAArgument() (rv Value) { rv.C = C.LLVMIsAArgument(v.C); return } +func (v Value) IsABasicBlock() (rv Value) { rv.C = C.LLVMIsABasicBlock(v.C); return } +func (v Value) IsAInlineAsm() (rv Value) { rv.C = C.LLVMIsAInlineAsm(v.C); return } +func (v Value) IsAUser() (rv Value) { rv.C = C.LLVMIsAUser(v.C); return } +func (v Value) IsAConstant() (rv Value) { rv.C = C.LLVMIsAConstant(v.C); return } +func (v Value) IsAConstantAggregateZero() (rv Value) { + rv.C = C.LLVMIsAConstantAggregateZero(v.C) + return +} +func (v Value) IsAConstantArray() (rv Value) { rv.C = C.LLVMIsAConstantArray(v.C); return } +func (v Value) IsAConstantExpr() (rv Value) { rv.C = C.LLVMIsAConstantExpr(v.C); return } +func (v Value) IsAConstantFP() (rv Value) { rv.C = C.LLVMIsAConstantFP(v.C); return } +func (v Value) IsAConstantInt() (rv Value) { rv.C = C.LLVMIsAConstantInt(v.C); return } +func (v Value) IsAConstantPointerNull() (rv Value) { rv.C = C.LLVMIsAConstantPointerNull(v.C); return } +func (v Value) IsAConstantStruct() (rv Value) { rv.C = C.LLVMIsAConstantStruct(v.C); return } +func (v Value) IsAConstantVector() (rv Value) { rv.C = C.LLVMIsAConstantVector(v.C); return } +func (v Value) IsAGlobalValue() (rv Value) { rv.C = C.LLVMIsAGlobalValue(v.C); return } +func (v Value) IsAFunction() (rv Value) { rv.C = C.LLVMIsAFunction(v.C); return } +func (v Value) IsAGlobalAlias() (rv Value) { rv.C = C.LLVMIsAGlobalAlias(v.C); return } +func (v Value) IsAGlobalVariable() (rv Value) { rv.C = C.LLVMIsAGlobalVariable(v.C); return } +func (v Value) IsAUndefValue() (rv Value) { rv.C = C.LLVMIsAUndefValue(v.C); return } +func (v Value) IsAInstruction() (rv Value) { rv.C = C.LLVMIsAInstruction(v.C); return } +func (v Value) IsABinaryOperator() (rv Value) { rv.C = C.LLVMIsABinaryOperator(v.C); return } +func (v Value) IsACallInst() (rv Value) { rv.C = C.LLVMIsACallInst(v.C); return } +func (v Value) IsAIntrinsicInst() (rv Value) { rv.C = C.LLVMIsAIntrinsicInst(v.C); return } +func (v Value) IsADbgInfoIntrinsic() (rv Value) { rv.C = C.LLVMIsADbgInfoIntrinsic(v.C); return } +func (v Value) IsADbgDeclareInst() (rv Value) { rv.C = C.LLVMIsADbgDeclareInst(v.C); return } +func (v Value) IsAMemIntrinsic() (rv Value) { rv.C = C.LLVMIsAMemIntrinsic(v.C); return } +func (v Value) IsAMemCpyInst() (rv Value) { rv.C = C.LLVMIsAMemCpyInst(v.C); return } +func (v Value) IsAMemMoveInst() (rv Value) { rv.C = C.LLVMIsAMemMoveInst(v.C); return } +func (v Value) IsAMemSetInst() (rv Value) { rv.C = C.LLVMIsAMemSetInst(v.C); return } +func (v Value) IsACmpInst() (rv Value) { rv.C = C.LLVMIsACmpInst(v.C); return } +func (v Value) IsAFCmpInst() (rv Value) { rv.C = C.LLVMIsAFCmpInst(v.C); return } +func (v Value) IsAICmpInst() (rv Value) { rv.C = C.LLVMIsAICmpInst(v.C); return } +func (v Value) IsAExtractElementInst() (rv Value) { rv.C = C.LLVMIsAExtractElementInst(v.C); return } +func (v Value) IsAGetElementPtrInst() (rv Value) { rv.C = C.LLVMIsAGetElementPtrInst(v.C); return } +func (v Value) IsAInsertElementInst() (rv Value) { rv.C = C.LLVMIsAInsertElementInst(v.C); return } +func (v Value) IsAInsertValueInst() (rv Value) { rv.C = C.LLVMIsAInsertValueInst(v.C); return } +func (v Value) IsAPHINode() (rv Value) { rv.C = C.LLVMIsAPHINode(v.C); return } +func (v Value) IsASelectInst() (rv Value) { rv.C = C.LLVMIsASelectInst(v.C); return } +func (v Value) IsAShuffleVectorInst() (rv Value) { rv.C = C.LLVMIsAShuffleVectorInst(v.C); return } +func (v Value) IsAStoreInst() (rv Value) { rv.C = C.LLVMIsAStoreInst(v.C); return } +func (v Value) IsABranchInst() (rv Value) { rv.C = C.LLVMIsABranchInst(v.C); return } +func (v Value) IsAInvokeInst() (rv Value) { rv.C = C.LLVMIsAInvokeInst(v.C); return } +func (v Value) IsAReturnInst() (rv Value) { rv.C = C.LLVMIsAReturnInst(v.C); return } +func (v Value) IsASwitchInst() (rv Value) { rv.C = C.LLVMIsASwitchInst(v.C); return } +func (v Value) IsAUnreachableInst() (rv Value) { rv.C = C.LLVMIsAUnreachableInst(v.C); return } +func (v Value) IsAUnaryInstruction() (rv Value) { rv.C = C.LLVMIsAUnaryInstruction(v.C); return } +func (v Value) IsAAllocaInst() (rv Value) { rv.C = C.LLVMIsAAllocaInst(v.C); return } +func (v Value) IsACastInst() (rv Value) { rv.C = C.LLVMIsACastInst(v.C); return } +func (v Value) IsABitCastInst() (rv Value) { rv.C = C.LLVMIsABitCastInst(v.C); return } +func (v Value) IsAFPExtInst() (rv Value) { rv.C = C.LLVMIsAFPExtInst(v.C); return } +func (v Value) IsAFPToSIInst() (rv Value) { rv.C = C.LLVMIsAFPToSIInst(v.C); return } +func (v Value) IsAFPToUIInst() (rv Value) { rv.C = C.LLVMIsAFPToUIInst(v.C); return } +func (v Value) IsAFPTruncInst() (rv Value) { rv.C = C.LLVMIsAFPTruncInst(v.C); return } +func (v Value) IsAIntToPtrInst() (rv Value) { rv.C = C.LLVMIsAIntToPtrInst(v.C); return } +func (v Value) IsAPtrToIntInst() (rv Value) { rv.C = C.LLVMIsAPtrToIntInst(v.C); return } +func (v Value) IsASExtInst() (rv Value) { rv.C = C.LLVMIsASExtInst(v.C); return } +func (v Value) IsASIToFPInst() (rv Value) { rv.C = C.LLVMIsASIToFPInst(v.C); return } +func (v Value) IsATruncInst() (rv Value) { rv.C = C.LLVMIsATruncInst(v.C); return } +func (v Value) IsAUIToFPInst() (rv Value) { rv.C = C.LLVMIsAUIToFPInst(v.C); return } +func (v Value) IsAZExtInst() (rv Value) { rv.C = C.LLVMIsAZExtInst(v.C); return } +func (v Value) IsAExtractValueInst() (rv Value) { rv.C = C.LLVMIsAExtractValueInst(v.C); return } +func (v Value) IsALoadInst() (rv Value) { rv.C = C.LLVMIsALoadInst(v.C); return } +func (v Value) IsAVAArgInst() (rv Value) { rv.C = C.LLVMIsAVAArgInst(v.C); return } + +// Operations on Uses +func (v Value) FirstUse() (u Use) { u.C = C.LLVMGetFirstUse(v.C); return } +func (u Use) NextUse() (ru Use) { ru.C = C.LLVMGetNextUse(u.C); return } +func (u Use) User() (v Value) { v.C = C.LLVMGetUser(u.C); return } +func (u Use) UsedValue() (v Value) { v.C = C.LLVMGetUsedValue(u.C); return } + +// Operations on Users +func (v Value) Operand(i int) (rv Value) { rv.C = C.LLVMGetOperand(v.C, C.unsigned(i)); return } +func (v Value) SetOperand(i int, op Value) { C.LLVMSetOperand(v.C, C.unsigned(i), op.C) } +func (v Value) OperandsCount() int { return int(C.LLVMGetNumOperands(v.C)) } + +// Operations on constants of any type +func ConstNull(t Type) (v Value) { v.C = C.LLVMConstNull(t.C); return } +func ConstAllOnes(t Type) (v Value) { v.C = C.LLVMConstAllOnes(t.C); return } +func Undef(t Type) (v Value) { v.C = C.LLVMGetUndef(t.C); return } +func (v Value) IsConstant() bool { return C.LLVMIsConstant(v.C) != 0 } +func (v Value) IsNull() bool { return C.LLVMIsNull(v.C) != 0 } +func (v Value) IsUndef() bool { return C.LLVMIsUndef(v.C) != 0 } +func ConstPointerNull(t Type) (v Value) { v.C = C.LLVMConstPointerNull(t.C); return } + +// Operations on metadata +func (c Context) MDString(str string) (md Metadata) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + md.C = C.LLVMMDString2(c.C, cstr, C.unsigned(len(str))) + return +} +func (c Context) MDNode(mds []Metadata) (md Metadata) { + ptr, nvals := llvmMetadataRefs(mds) + md.C = C.LLVMMDNode2(c.C, ptr, nvals) + return +} +func (v Value) ConstantAsMetadata() (md Metadata) { + md.C = C.LLVMConstantAsMetadata(v.C) + return +} + +// Operations on scalar constants +func ConstInt(t Type, n uint64, signExtend bool) (v Value) { + v.C = C.LLVMConstInt(t.C, + C.ulonglong(n), + boolToLLVMBool(signExtend)) + return +} +func ConstIntFromString(t Type, str string, radix int) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + v.C = C.LLVMConstIntOfString(t.C, cstr, C.uint8_t(radix)) + return +} +func ConstFloat(t Type, n float64) (v Value) { + v.C = C.LLVMConstReal(t.C, C.double(n)) + return +} +func ConstFloatFromString(t Type, str string) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + v.C = C.LLVMConstRealOfString(t.C, cstr) + return +} + +func (v Value) ZExtValue() uint64 { return uint64(C.LLVMConstIntGetZExtValue(v.C)) } +func (v Value) SExtValue() int64 { return int64(C.LLVMConstIntGetSExtValue(v.C)) } + +// Operations on composite constants +func (c Context) ConstString(str string, addnull bool) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + v.C = C.LLVMConstStringInContext(c.C, cstr, + C.unsigned(len(str)), boolToLLVMBool(!addnull)) + return +} +func (c Context) ConstStruct(constVals []Value, packed bool) (v Value) { + ptr, nvals := llvmValueRefs(constVals) + v.C = C.LLVMConstStructInContext(c.C, ptr, nvals, + boolToLLVMBool(packed)) + return +} +func ConstNamedStruct(t Type, constVals []Value) (v Value) { + ptr, nvals := llvmValueRefs(constVals) + v.C = C.LLVMConstNamedStruct(t.C, ptr, nvals) + return +} +func ConstString(str string, addnull bool) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + v.C = C.LLVMConstString(cstr, + C.unsigned(len(str)), boolToLLVMBool(!addnull)) + return +} +func ConstArray(t Type, constVals []Value) (v Value) { + ptr, nvals := llvmValueRefs(constVals) + v.C = C.LLVMConstArray(t.C, ptr, nvals) + return +} +func ConstStruct(constVals []Value, packed bool) (v Value) { + ptr, nvals := llvmValueRefs(constVals) + v.C = C.LLVMConstStruct(ptr, nvals, boolToLLVMBool(packed)) + return +} +func ConstVector(scalarConstVals []Value, packed bool) (v Value) { + ptr, nvals := llvmValueRefs(scalarConstVals) + v.C = C.LLVMConstVector(ptr, nvals) + return +} + +// Constant expressions +func (v Value) Opcode() Opcode { return Opcode(C.LLVMGetConstOpcode(v.C)) } +func (v Value) InstructionOpcode() Opcode { return Opcode(C.LLVMGetInstructionOpcode(v.C)) } +func AlignOf(t Type) (v Value) { v.C = C.LLVMAlignOf(t.C); return } +func SizeOf(t Type) (v Value) { v.C = C.LLVMSizeOf(t.C); return } +func ConstNeg(v Value) (rv Value) { rv.C = C.LLVMConstNeg(v.C); return } +func ConstNSWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNSWNeg(v.C); return } +func ConstNUWNeg(v Value) (rv Value) { rv.C = C.LLVMConstNUWNeg(v.C); return } +func ConstFNeg(v Value) (rv Value) { rv.C = C.LLVMConstFNeg(v.C); return } +func ConstNot(v Value) (rv Value) { rv.C = C.LLVMConstNot(v.C); return } +func ConstAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAdd(lhs.C, rhs.C); return } +func ConstNSWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWAdd(lhs.C, rhs.C); return } +func ConstNUWAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWAdd(lhs.C, rhs.C); return } +func ConstFAdd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFAdd(lhs.C, rhs.C); return } +func ConstSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSub(lhs.C, rhs.C); return } +func ConstNSWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWSub(lhs.C, rhs.C); return } +func ConstNUWSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWSub(lhs.C, rhs.C); return } +func ConstFSub(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFSub(lhs.C, rhs.C); return } +func ConstMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstMul(lhs.C, rhs.C); return } +func ConstNSWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNSWMul(lhs.C, rhs.C); return } +func ConstNUWMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstNUWMul(lhs.C, rhs.C); return } +func ConstFMul(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFMul(lhs.C, rhs.C); return } +func ConstUDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstUDiv(lhs.C, rhs.C); return } +func ConstSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSDiv(lhs.C, rhs.C); return } +func ConstExactSDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstExactSDiv(lhs.C, rhs.C); return } +func ConstFDiv(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFDiv(lhs.C, rhs.C); return } +func ConstURem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstURem(lhs.C, rhs.C); return } +func ConstSRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstSRem(lhs.C, rhs.C); return } +func ConstFRem(lhs, rhs Value) (v Value) { v.C = C.LLVMConstFRem(lhs.C, rhs.C); return } +func ConstAnd(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAnd(lhs.C, rhs.C); return } +func ConstOr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstOr(lhs.C, rhs.C); return } +func ConstXor(lhs, rhs Value) (v Value) { v.C = C.LLVMConstXor(lhs.C, rhs.C); return } + +func ConstICmp(pred IntPredicate, lhs, rhs Value) (v Value) { + v.C = C.LLVMConstICmp(C.LLVMIntPredicate(pred), lhs.C, rhs.C) + return +} +func ConstFCmp(pred FloatPredicate, lhs, rhs Value) (v Value) { + v.C = C.LLVMConstFCmp(C.LLVMRealPredicate(pred), lhs.C, rhs.C) + return +} + +func ConstShl(lhs, rhs Value) (v Value) { v.C = C.LLVMConstShl(lhs.C, rhs.C); return } +func ConstLShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstLShr(lhs.C, rhs.C); return } +func ConstAShr(lhs, rhs Value) (v Value) { v.C = C.LLVMConstAShr(lhs.C, rhs.C); return } + +func ConstGEP(v Value, indices []Value) (rv Value) { + ptr, nvals := llvmValueRefs(indices) + rv.C = C.LLVMConstGEP(v.C, ptr, nvals) + return +} +func ConstInBoundsGEP(v Value, indices []Value) (rv Value) { + ptr, nvals := llvmValueRefs(indices) + rv.C = C.LLVMConstInBoundsGEP(v.C, ptr, nvals) + return +} +func ConstTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstTrunc(v.C, t.C); return } +func ConstSExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExt(v.C, t.C); return } +func ConstZExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExt(v.C, t.C); return } +func ConstFPTrunc(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPTrunc(v.C, t.C); return } +func ConstFPExt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPExt(v.C, t.C); return } +func ConstUIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstUIToFP(v.C, t.C); return } +func ConstSIToFP(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSIToFP(v.C, t.C); return } +func ConstFPToUI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToUI(v.C, t.C); return } +func ConstFPToSI(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPToSI(v.C, t.C); return } +func ConstPtrToInt(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPtrToInt(v.C, t.C); return } +func ConstIntToPtr(v Value, t Type) (rv Value) { rv.C = C.LLVMConstIntToPtr(v.C, t.C); return } +func ConstBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstBitCast(v.C, t.C); return } +func ConstZExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstZExtOrBitCast(v.C, t.C); return } +func ConstSExtOrBitCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstSExtOrBitCast(v.C, t.C); return } +func ConstTruncOrBitCast(v Value, t Type) (rv Value) { + rv.C = C.LLVMConstTruncOrBitCast(v.C, t.C) + return +} +func ConstPointerCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstPointerCast(v.C, t.C); return } +func ConstIntCast(v Value, t Type, signed bool) (rv Value) { + rv.C = C.LLVMConstIntCast(v.C, t.C, boolToLLVMBool(signed)) + return +} +func ConstFPCast(v Value, t Type) (rv Value) { rv.C = C.LLVMConstFPCast(v.C, t.C); return } +func ConstSelect(cond, iftrue, iffalse Value) (rv Value) { + rv.C = C.LLVMConstSelect(cond.C, iftrue.C, iffalse.C) + return +} +func ConstExtractElement(vec, i Value) (rv Value) { + rv.C = C.LLVMConstExtractElement(vec.C, i.C) + return +} +func ConstInsertElement(vec, elem, i Value) (rv Value) { + rv.C = C.LLVMConstInsertElement(vec.C, elem.C, i.C) + return +} +func ConstShuffleVector(veca, vecb, mask Value) (rv Value) { + rv.C = C.LLVMConstShuffleVector(veca.C, vecb.C, mask.C) + return +} + +//TODO +//LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, +// unsigned NumIdx); + +func ConstExtractValue(agg Value, indices []uint32) (rv Value) { + n := len(indices) + if n == 0 { + panic("one or more indices are required") + } + ptr := (*C.unsigned)(&indices[0]) + rv.C = C.LLVMConstExtractValue(agg.C, ptr, C.unsigned(n)) + return +} + +func ConstInsertValue(agg, val Value, indices []uint32) (rv Value) { + n := len(indices) + if n == 0 { + panic("one or more indices are required") + } + ptr := (*C.unsigned)(&indices[0]) + rv.C = C.LLVMConstInsertValue(agg.C, val.C, ptr, C.unsigned(n)) + return +} + +func BlockAddress(f Value, bb BasicBlock) (v Value) { + v.C = C.LLVMBlockAddress(f.C, bb.C) + return +} + +// Operations on global variables, functions, and aliases (globals) +func (v Value) GlobalParent() (m Module) { m.C = C.LLVMGetGlobalParent(v.C); return } +func (v Value) IsDeclaration() bool { return C.LLVMIsDeclaration(v.C) != 0 } +func (v Value) Linkage() Linkage { return Linkage(C.LLVMGetLinkage(v.C)) } +func (v Value) SetLinkage(l Linkage) { C.LLVMSetLinkage(v.C, C.LLVMLinkage(l)) } +func (v Value) Section() string { return C.GoString(C.LLVMGetSection(v.C)) } +func (v Value) SetSection(str string) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + C.LLVMSetSection(v.C, cstr) +} +func (v Value) Visibility() Visibility { return Visibility(C.LLVMGetVisibility(v.C)) } +func (v Value) SetVisibility(vi Visibility) { C.LLVMSetVisibility(v.C, C.LLVMVisibility(vi)) } +func (v Value) Alignment() int { return int(C.LLVMGetAlignment(v.C)) } +func (v Value) SetAlignment(a int) { C.LLVMSetAlignment(v.C, C.unsigned(a)) } +func (v Value) SetUnnamedAddr(ua bool) { C.LLVMSetUnnamedAddr(v.C, boolToLLVMBool(ua)) } + +// Operations on global variables +func AddGlobal(m Module, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMAddGlobal(m.C, t.C, cname) + return +} +func AddGlobalInAddressSpace(m Module, t Type, name string, addressSpace int) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMAddGlobalInAddressSpace(m.C, t.C, cname, C.unsigned(addressSpace)) + return +} +func (m Module) NamedGlobal(name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMGetNamedGlobal(m.C, cname) + return +} + +func (m Module) FirstGlobal() (v Value) { v.C = C.LLVMGetFirstGlobal(m.C); return } +func (m Module) LastGlobal() (v Value) { v.C = C.LLVMGetLastGlobal(m.C); return } +func NextGlobal(v Value) (rv Value) { rv.C = C.LLVMGetNextGlobal(v.C); return } +func PrevGlobal(v Value) (rv Value) { rv.C = C.LLVMGetPreviousGlobal(v.C); return } +func (v Value) EraseFromParentAsGlobal() { C.LLVMDeleteGlobal(v.C) } +func (v Value) Initializer() (rv Value) { rv.C = C.LLVMGetInitializer(v.C); return } +func (v Value) SetInitializer(cv Value) { C.LLVMSetInitializer(v.C, cv.C) } +func (v Value) IsThreadLocal() bool { return C.LLVMIsThreadLocal(v.C) != 0 } +func (v Value) SetThreadLocal(tl bool) { C.LLVMSetThreadLocal(v.C, boolToLLVMBool(tl)) } +func (v Value) IsGlobalConstant() bool { return C.LLVMIsGlobalConstant(v.C) != 0 } +func (v Value) SetGlobalConstant(gc bool) { C.LLVMSetGlobalConstant(v.C, boolToLLVMBool(gc)) } +func (v Value) IsVolatile() bool { return C.LLVMGetVolatile(v.C) != 0 } +func (v Value) SetVolatile(volatile bool) { C.LLVMSetVolatile(v.C, boolToLLVMBool(volatile)) } +func (v Value) Ordering() AtomicOrdering { return AtomicOrdering(C.LLVMGetOrdering(v.C)) } +func (v Value) SetOrdering(ordering AtomicOrdering) { + C.LLVMSetOrdering(v.C, C.LLVMAtomicOrdering(ordering)) +} +func (v Value) IsAtomicSingleThread() bool { return C.LLVMIsAtomicSingleThread(v.C) != 0 } +func (v Value) SetAtomicSingleThread(singleThread bool) { + C.LLVMSetAtomicSingleThread(v.C, boolToLLVMBool(singleThread)) +} +func (v Value) CmpXchgSuccessOrdering() AtomicOrdering { + return AtomicOrdering(C.LLVMGetCmpXchgSuccessOrdering(v.C)) +} +func (v Value) SetCmpXchgSuccessOrdering(ordering AtomicOrdering) { + C.LLVMSetCmpXchgSuccessOrdering(v.C, C.LLVMAtomicOrdering(ordering)) +} +func (v Value) CmpXchgFailureOrdering() AtomicOrdering { + return AtomicOrdering(C.LLVMGetCmpXchgFailureOrdering(v.C)) +} +func (v Value) SetCmpXchgFailureOrdering(ordering AtomicOrdering) { + C.LLVMSetCmpXchgFailureOrdering(v.C, C.LLVMAtomicOrdering(ordering)) +} + +// Operations on aliases +func AddAlias(m Module, t Type, aliasee Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMAddAlias(m.C, t.C, aliasee.C, cname) + return +} + +// Operations on comdat +func (m Module) Comdat(name string) (c Comdat) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + c.C = C.LLVMGetOrInsertComdat(m.C, cname) + return +} + +func (v Value) Comdat() (c Comdat) { c.C = C.LLVMGetComdat(v.C); return } +func (v Value) SetComdat(c Comdat) { C.LLVMSetComdat(v.C, c.C) } + +func (c Comdat) SelectionKind() ComdatSelectionKind { + return ComdatSelectionKind(C.LLVMGetComdatSelectionKind(c.C)) +} + +func (c Comdat) SetSelectionKind(k ComdatSelectionKind) { + C.LLVMSetComdatSelectionKind(c.C, (C.LLVMComdatSelectionKind)(k)) +} + +// Operations on functions +func AddFunction(m Module, name string, ft Type) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMAddFunction(m.C, cname, ft.C) + return +} + +func (m Module) NamedFunction(name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMGetNamedFunction(m.C, cname) + return +} + +func (m Module) FirstFunction() (v Value) { v.C = C.LLVMGetFirstFunction(m.C); return } +func (m Module) LastFunction() (v Value) { v.C = C.LLVMGetLastFunction(m.C); return } +func NextFunction(v Value) (rv Value) { rv.C = C.LLVMGetNextFunction(v.C); return } +func PrevFunction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousFunction(v.C); return } +func (v Value) EraseFromParentAsFunction() { C.LLVMDeleteFunction(v.C) } +func (v Value) IntrinsicID() int { return int(C.LLVMGetIntrinsicID(v.C)) } +func (v Value) FunctionCallConv() CallConv { + return CallConv(C.LLVMCallConv(C.LLVMGetFunctionCallConv(v.C))) +} +func (v Value) SetFunctionCallConv(cc CallConv) { C.LLVMSetFunctionCallConv(v.C, C.unsigned(cc)) } +func (v Value) GC() string { return C.GoString(C.LLVMGetGC(v.C)) } +func (v Value) SetGC(name string) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + C.LLVMSetGC(v.C, cname) +} +func (v Value) AddAttributeAtIndex(i int, a Attribute) { + C.LLVMAddAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), a.C) +} +func (v Value) AddFunctionAttr(a Attribute) { + v.AddAttributeAtIndex(C.LLVMAttributeFunctionIndex, a) +} +func (v Value) GetEnumAttributeAtIndex(i int, kind uint) (a Attribute) { + a.C = C.LLVMGetEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) + return +} +func (v Value) GetEnumFunctionAttribute(kind uint) Attribute { + return v.GetEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) +} +func (v Value) GetStringAttributeAtIndex(i int, kind string) (a Attribute) { + ckind := C.CString(kind) + defer C.free(unsafe.Pointer(ckind)) + a.C = C.LLVMGetStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), + ckind, C.unsigned(len(kind))) + return +} +func (v Value) RemoveEnumAttributeAtIndex(i int, kind uint) { + C.LLVMRemoveEnumAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), C.unsigned(kind)) +} +func (v Value) RemoveEnumFunctionAttribute(kind uint) { + v.RemoveEnumAttributeAtIndex(C.LLVMAttributeFunctionIndex, kind) +} +func (v Value) RemoveStringAttributeAtIndex(i int, kind string) { + ckind := C.CString(kind) + defer C.free(unsafe.Pointer(ckind)) + C.LLVMRemoveStringAttributeAtIndex(v.C, C.LLVMAttributeIndex(i), + ckind, C.unsigned(len(kind))) +} +func (v Value) AddTargetDependentFunctionAttr(attr, value string) { + cattr := C.CString(attr) + defer C.free(unsafe.Pointer(cattr)) + cvalue := C.CString(value) + defer C.free(unsafe.Pointer(cvalue)) + C.LLVMAddTargetDependentFunctionAttr(v.C, cattr, cvalue) +} +func (v Value) SetPersonality(p Value) { + C.LLVMSetPersonalityFn(v.C, p.C) +} + +// Operations on parameters +func (v Value) ParamsCount() int { return int(C.LLVMCountParams(v.C)) } +func (v Value) Params() []Value { + out := make([]Value, v.ParamsCount()) + if len(out) > 0 { + C.LLVMGetParams(v.C, llvmValueRefPtr(&out[0])) + } + return out +} +func (v Value) Param(i int) (rv Value) { rv.C = C.LLVMGetParam(v.C, C.unsigned(i)); return } +func (v Value) ParamParent() (rv Value) { rv.C = C.LLVMGetParamParent(v.C); return } +func (v Value) FirstParam() (rv Value) { rv.C = C.LLVMGetFirstParam(v.C); return } +func (v Value) LastParam() (rv Value) { rv.C = C.LLVMGetLastParam(v.C); return } +func NextParam(v Value) (rv Value) { rv.C = C.LLVMGetNextParam(v.C); return } +func PrevParam(v Value) (rv Value) { rv.C = C.LLVMGetPreviousParam(v.C); return } +func (v Value) SetParamAlignment(align int) { C.LLVMSetParamAlignment(v.C, C.unsigned(align)) } + +// Operations on basic blocks +func (bb BasicBlock) AsValue() (v Value) { v.C = C.LLVMBasicBlockAsValue(bb.C); return } +func (v Value) IsBasicBlock() bool { return C.LLVMValueIsBasicBlock(v.C) != 0 } +func (v Value) AsBasicBlock() (bb BasicBlock) { bb.C = C.LLVMValueAsBasicBlock(v.C); return } +func (bb BasicBlock) Parent() (v Value) { v.C = C.LLVMGetBasicBlockParent(bb.C); return } +func (v Value) BasicBlocksCount() int { return int(C.LLVMCountBasicBlocks(v.C)) } +func (v Value) BasicBlocks() []BasicBlock { + out := make([]BasicBlock, v.BasicBlocksCount()) + C.LLVMGetBasicBlocks(v.C, llvmBasicBlockRefPtr(&out[0])) + return out +} +func (v Value) FirstBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetFirstBasicBlock(v.C); return } +func (v Value) LastBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetLastBasicBlock(v.C); return } +func NextBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetNextBasicBlock(bb.C); return } +func PrevBasicBlock(bb BasicBlock) (rbb BasicBlock) { rbb.C = C.LLVMGetPreviousBasicBlock(bb.C); return } +func (v Value) EntryBasicBlock() (bb BasicBlock) { bb.C = C.LLVMGetEntryBasicBlock(v.C); return } +func (c Context) AddBasicBlock(f Value, name string) (bb BasicBlock) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + bb.C = C.LLVMAppendBasicBlockInContext(c.C, f.C, cname) + return +} +func (c Context) InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + bb.C = C.LLVMInsertBasicBlockInContext(c.C, ref.C, cname) + return +} +func AddBasicBlock(f Value, name string) (bb BasicBlock) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + bb.C = C.LLVMAppendBasicBlock(f.C, cname) + return +} +func InsertBasicBlock(ref BasicBlock, name string) (bb BasicBlock) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + bb.C = C.LLVMInsertBasicBlock(ref.C, cname) + return +} +func (bb BasicBlock) EraseFromParent() { C.LLVMDeleteBasicBlock(bb.C) } +func (bb BasicBlock) MoveBefore(pos BasicBlock) { C.LLVMMoveBasicBlockBefore(bb.C, pos.C) } +func (bb BasicBlock) MoveAfter(pos BasicBlock) { C.LLVMMoveBasicBlockAfter(bb.C, pos.C) } + +// Operations on instructions +func (v Value) EraseFromParentAsInstruction() { C.LLVMInstructionEraseFromParent(v.C) } +func (v Value) InstructionParent() (bb BasicBlock) { bb.C = C.LLVMGetInstructionParent(v.C); return } +func (v Value) InstructionDebugLoc() (md Metadata) { md.C = C.LLVMInstructionGetDebugLoc(v.C); return } +func (v Value) InstructionSetDebugLoc(md Metadata) { C.LLVMInstructionSetDebugLoc(v.C, md.C) } +func (bb BasicBlock) FirstInstruction() (v Value) { v.C = C.LLVMGetFirstInstruction(bb.C); return } +func (bb BasicBlock) LastInstruction() (v Value) { v.C = C.LLVMGetLastInstruction(bb.C); return } +func NextInstruction(v Value) (rv Value) { rv.C = C.LLVMGetNextInstruction(v.C); return } +func PrevInstruction(v Value) (rv Value) { rv.C = C.LLVMGetPreviousInstruction(v.C); return } + +// Operations on call sites +func (v Value) SetInstructionCallConv(cc CallConv) { + C.LLVMSetInstructionCallConv(v.C, C.unsigned(cc)) +} +func (v Value) InstructionCallConv() CallConv { + return CallConv(C.LLVMCallConv(C.LLVMGetInstructionCallConv(v.C))) +} +func (v Value) AddCallSiteAttribute(i int, a Attribute) { + C.LLVMAddCallSiteAttribute(v.C, C.LLVMAttributeIndex(i), a.C) +} +func (v Value) SetInstrParamAlignment(i int, align int) { + C.LLVMSetInstrParamAlignment(v.C, C.unsigned(i), C.unsigned(align)) +} +func (v Value) CalledValue() (rv Value) { + rv.C = C.LLVMGetCalledValue(v.C) + return +} + +// Operations on call instructions (only) +func (v Value) IsTailCall() bool { return C.LLVMIsTailCall(v.C) != 0 } +func (v Value) SetTailCall(is bool) { C.LLVMSetTailCall(v.C, boolToLLVMBool(is)) } + +// Operations on phi nodes +func (v Value) AddIncoming(vals []Value, blocks []BasicBlock) { + ptr, nvals := llvmValueRefs(vals) + C.LLVMAddIncoming(v.C, ptr, llvmBasicBlockRefPtr(&blocks[0]), nvals) +} +func (v Value) IncomingCount() int { return int(C.LLVMCountIncoming(v.C)) } +func (v Value) IncomingValue(i int) (rv Value) { + rv.C = C.LLVMGetIncomingValue(v.C, C.unsigned(i)) + return +} +func (v Value) IncomingBlock(i int) (bb BasicBlock) { + bb.C = C.LLVMGetIncomingBlock(v.C, C.unsigned(i)) + return +} + +// Operations on inline assembly +func InlineAsm(t Type, asmString, constraints string, hasSideEffects, isAlignStack bool, dialect InlineAsmDialect) (rv Value) { + casm := C.CString(asmString) + defer C.free(unsafe.Pointer(casm)) + cconstraints := C.CString(constraints) + defer C.free(unsafe.Pointer(cconstraints)) + rv.C = C.LLVMGetInlineAsm(t.C, casm, C.size_t(len(asmString)), cconstraints, C.size_t(len(constraints)), boolToLLVMBool(hasSideEffects), boolToLLVMBool(isAlignStack), C.LLVMInlineAsmDialect(dialect)) + return +} + +// Operations on aggregates +func (v Value) Indices() []uint32 { + num := C.LLVMGetNumIndices(v.C) + indicesPtr := C.LLVMGetIndices(v.C) + // https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices + rawIndices := (*[1 << 20]C.uint)(unsafe.Pointer(indicesPtr))[:num:num] + indices := make([]uint32, num) + for i := range indices { + indices[i] = uint32(rawIndices[i]) + } + return indices +} + +// Operations on comparisons +func (v Value) IntPredicate() IntPredicate { return IntPredicate(C.LLVMGetICmpPredicate(v.C)) } +func (v Value) FloatPredicate() FloatPredicate { return FloatPredicate(C.LLVMGetFCmpPredicate(v.C)) } + +//------------------------------------------------------------------------- +// llvm.Builder +//------------------------------------------------------------------------- + +// An instruction builder represents a point within a basic block, and is the +// exclusive means of building instructions using the C interface. + +func (c Context) NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilderInContext(c.C); return } +func NewBuilder() (b Builder) { b.C = C.LLVMCreateBuilder(); return } +func (b Builder) SetInsertPoint(block BasicBlock, instr Value) { + C.LLVMPositionBuilder(b.C, block.C, instr.C) +} +func (b Builder) SetInsertPointBefore(instr Value) { C.LLVMPositionBuilderBefore(b.C, instr.C) } +func (b Builder) SetInsertPointAtEnd(block BasicBlock) { C.LLVMPositionBuilderAtEnd(b.C, block.C) } +func (b Builder) GetInsertBlock() (bb BasicBlock) { bb.C = C.LLVMGetInsertBlock(b.C); return } +func (b Builder) ClearInsertionPoint() { C.LLVMClearInsertionPosition(b.C) } +func (b Builder) Insert(instr Value) { C.LLVMInsertIntoBuilder(b.C, instr.C) } +func (b Builder) InsertWithName(instr Value, name string) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + C.LLVMInsertIntoBuilderWithName(b.C, instr.C, cname) +} +func (b Builder) Dispose() { C.LLVMDisposeBuilder(b.C) } + +// Metadata +type DebugLoc struct { + Line, Col uint + Scope Metadata + InlinedAt Metadata +} + +func (b Builder) SetCurrentDebugLocation(line, col uint, scope, inlinedAt Metadata) { + C.LLVMGoSetCurrentDebugLocation(b.C, C.unsigned(line), C.unsigned(col), scope.C, inlinedAt.C) +} + +// Get current debug location. Please do not call this function until setting debug location with SetCurrentDebugLocation() +func (b Builder) GetCurrentDebugLocation() (loc DebugLoc) { + md := C.LLVMGoGetCurrentDebugLocation(b.C) + loc.Line = uint(md.Line) + loc.Col = uint(md.Col) + loc.Scope = Metadata{C: md.Scope} + loc.InlinedAt = Metadata{C: md.InlinedAt} + return +} +func (b Builder) SetInstDebugLocation(v Value) { C.LLVMSetInstDebugLocation(b.C, v.C) } +func (b Builder) InsertDeclare(module Module, storage Value, md Value) Value { + f := module.NamedFunction("llvm.dbg.declare") + if f.IsNil() { + ftyp := FunctionType(VoidType(), []Type{storage.Type(), md.Type()}, false) + f = AddFunction(module, "llvm.dbg.declare", ftyp) + } + return b.CreateCall(f, []Value{storage, md}, "") +} + +// Terminators +func (b Builder) CreateRetVoid() (rv Value) { rv.C = C.LLVMBuildRetVoid(b.C); return } +func (b Builder) CreateRet(v Value) (rv Value) { rv.C = C.LLVMBuildRet(b.C, v.C); return } +func (b Builder) CreateAggregateRet(vs []Value) (rv Value) { + ptr, nvals := llvmValueRefs(vs) + rv.C = C.LLVMBuildAggregateRet(b.C, ptr, nvals) + return +} +func (b Builder) CreateBr(bb BasicBlock) (rv Value) { rv.C = C.LLVMBuildBr(b.C, bb.C); return } +func (b Builder) CreateCondBr(ifv Value, thenb, elseb BasicBlock) (rv Value) { + rv.C = C.LLVMBuildCondBr(b.C, ifv.C, thenb.C, elseb.C) + return +} +func (b Builder) CreateSwitch(v Value, elseb BasicBlock, numCases int) (rv Value) { + rv.C = C.LLVMBuildSwitch(b.C, v.C, elseb.C, C.unsigned(numCases)) + return +} +func (b Builder) CreateIndirectBr(addr Value, numDests int) (rv Value) { + rv.C = C.LLVMBuildIndirectBr(b.C, addr.C, C.unsigned(numDests)) + return +} +func (b Builder) CreateInvoke(fn Value, args []Value, then, catch BasicBlock, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ptr, nvals := llvmValueRefs(args) + rv.C = C.LLVMBuildInvoke(b.C, fn.C, ptr, nvals, then.C, catch.C, cname) + return +} +func (b Builder) CreateUnreachable() (rv Value) { rv.C = C.LLVMBuildUnreachable(b.C); return } + +// Add a case to the switch instruction +func (v Value) AddCase(on Value, dest BasicBlock) { C.LLVMAddCase(v.C, on.C, dest.C) } + +// Add a destination to the indirectbr instruction +func (v Value) AddDest(dest BasicBlock) { C.LLVMAddDestination(v.C, dest.C) } + +// Arithmetic +func (b Builder) CreateAdd(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildAdd(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNSWAdd(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNSWAdd(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNUWAdd(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNUWAdd(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFAdd(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFAdd(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateSub(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSub(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNSWSub(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNSWSub(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNUWSub(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNUWSub(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFSub(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + v.C = C.LLVMBuildFSub(b.C, lhs.C, rhs.C, cname) + C.free(unsafe.Pointer(cname)) + return +} +func (b Builder) CreateMul(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildMul(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNSWMul(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNSWMul(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNUWMul(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildNUWMul(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFMul(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFMul(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateUDiv(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildUDiv(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateSDiv(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSDiv(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateExactSDiv(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildExactSDiv(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFDiv(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFDiv(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateURem(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildURem(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateSRem(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSRem(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFRem(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFRem(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateShl(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildShl(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateLShr(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildLShr(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateAShr(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildAShr(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateAnd(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildAnd(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateOr(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildOr(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateXor(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildXor(b.C, lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateBinOp(op Opcode, lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildBinOp(b.C, C.LLVMOpcode(op), lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateNeg(v Value, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + rv.C = C.LLVMBuildNeg(b.C, v.C, cname) + return +} +func (b Builder) CreateNSWNeg(v Value, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + rv.C = C.LLVMBuildNSWNeg(b.C, v.C, cname) + return +} +func (b Builder) CreateNUWNeg(v Value, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + rv.C = C.LLVMBuildNUWNeg(b.C, v.C, cname) + return +} +func (b Builder) CreateFNeg(v Value, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + rv.C = C.LLVMBuildFNeg(b.C, v.C, cname) + return +} +func (b Builder) CreateNot(v Value, name string) (rv Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + rv.C = C.LLVMBuildNot(b.C, v.C, cname) + return +} + +// Memory + +func (b Builder) CreateMalloc(t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildMalloc(b.C, t.C, cname) + return +} +func (b Builder) CreateArrayMalloc(t Type, val Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildArrayMalloc(b.C, t.C, val.C, cname) + return +} +func (b Builder) CreateAlloca(t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildAlloca(b.C, t.C, cname) + return +} +func (b Builder) CreateArrayAlloca(t Type, val Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildArrayAlloca(b.C, t.C, val.C, cname) + return +} +func (b Builder) CreateFree(p Value) (v Value) { + v.C = C.LLVMBuildFree(b.C, p.C) + return +} +func (b Builder) CreateLoad(p Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildLoad(b.C, p.C, cname) + return +} +func (b Builder) CreateStore(val Value, p Value) (v Value) { + v.C = C.LLVMBuildStore(b.C, val.C, p.C) + return +} +func (b Builder) CreateGEP(p Value, indices []Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ptr, nvals := llvmValueRefs(indices) + v.C = C.LLVMBuildGEP(b.C, p.C, ptr, nvals, cname) + return +} +func (b Builder) CreateInBoundsGEP(p Value, indices []Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ptr, nvals := llvmValueRefs(indices) + v.C = C.LLVMBuildInBoundsGEP(b.C, p.C, ptr, nvals, cname) + return +} +func (b Builder) CreateStructGEP(p Value, i int, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildStructGEP(b.C, p.C, C.unsigned(i), cname) + return +} +func (b Builder) CreateGlobalString(str, name string) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildGlobalString(b.C, cstr, cname) + return +} +func (b Builder) CreateGlobalStringPtr(str, name string) (v Value) { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildGlobalStringPtr(b.C, cstr, cname) + return +} +func (b Builder) CreateAtomicRMW(op AtomicRMWBinOp, ptr, val Value, ordering AtomicOrdering, singleThread bool) (v Value) { + v.C = C.LLVMBuildAtomicRMW(b.C, C.LLVMAtomicRMWBinOp(op), ptr.C, val.C, C.LLVMAtomicOrdering(ordering), boolToLLVMBool(singleThread)) + return +} +func (b Builder) CreateAtomicCmpXchg(ptr, cmp, newVal Value, successOrdering, failureOrdering AtomicOrdering, singleThread bool) (v Value) { + v.C = C.LLVMBuildAtomicCmpXchg(b.C, ptr.C, cmp.C, newVal.C, C.LLVMAtomicOrdering(successOrdering), C.LLVMAtomicOrdering(failureOrdering), boolToLLVMBool(singleThread)) + return +} + +// Casts +func (b Builder) CreateTrunc(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildTrunc(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateZExt(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildZExt(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateSExt(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSExt(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateFPToUI(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFPToUI(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateFPToSI(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFPToSI(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateUIToFP(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildUIToFP(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateSIToFP(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSIToFP(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateFPTrunc(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFPTrunc(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateFPExt(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFPExt(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreatePtrToInt(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildPtrToInt(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateIntToPtr(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildIntToPtr(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateBitCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildBitCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateZExtOrBitCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildZExtOrBitCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateSExtOrBitCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSExtOrBitCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateTruncOrBitCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildTruncOrBitCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateCast(val Value, op Opcode, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildCast(b.C, C.LLVMOpcode(op), val.C, t.C, cname) + return +} // +func (b Builder) CreatePointerCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildPointerCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateIntCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildIntCast(b.C, val.C, t.C, cname) + return +} +func (b Builder) CreateFPCast(val Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFPCast(b.C, val.C, t.C, cname) + return +} + +// Comparisons +func (b Builder) CreateICmp(pred IntPredicate, lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildICmp(b.C, C.LLVMIntPredicate(pred), lhs.C, rhs.C, cname) + return +} +func (b Builder) CreateFCmp(pred FloatPredicate, lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildFCmp(b.C, C.LLVMRealPredicate(pred), lhs.C, rhs.C, cname) + return +} + +// Miscellaneous instructions +func (b Builder) CreatePHI(t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildPhi(b.C, t.C, cname) + return +} +func (b Builder) CreateCall(fn Value, args []Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ptr, nvals := llvmValueRefs(args) + v.C = C.LLVMBuildCall(b.C, fn.C, ptr, nvals, cname) + return +} + +func (b Builder) CreateSelect(ifv, thenv, elsev Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildSelect(b.C, ifv.C, thenv.C, elsev.C, cname) + return +} + +func (b Builder) CreateVAArg(list Value, t Type, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildVAArg(b.C, list.C, t.C, cname) + return +} +func (b Builder) CreateExtractElement(vec, i Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildExtractElement(b.C, vec.C, i.C, cname) + return +} +func (b Builder) CreateInsertElement(vec, elt, i Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildInsertElement(b.C, vec.C, elt.C, i.C, cname) + return +} +func (b Builder) CreateShuffleVector(v1, v2, mask Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildShuffleVector(b.C, v1.C, v2.C, mask.C, cname) + return +} +func (b Builder) CreateExtractValue(agg Value, i int, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildExtractValue(b.C, agg.C, C.unsigned(i), cname) + return +} +func (b Builder) CreateInsertValue(agg, elt Value, i int, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildInsertValue(b.C, agg.C, elt.C, C.unsigned(i), cname) + return +} + +func (b Builder) CreateIsNull(val Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildIsNull(b.C, val.C, cname) + return +} +func (b Builder) CreateIsNotNull(val Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildIsNotNull(b.C, val.C, cname) + return +} +func (b Builder) CreatePtrDiff(lhs, rhs Value, name string) (v Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + v.C = C.LLVMBuildPtrDiff(b.C, lhs.C, rhs.C, cname) + return +} + +func (b Builder) CreateLandingPad(t Type, nclauses int, name string) (l Value) { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + l.C = C.LLVMBuildLandingPad(b.C, t.C, nil, C.unsigned(nclauses), cname) + return l +} + +func (l Value) AddClause(v Value) { + C.LLVMAddClause(l.C, v.C) +} + +func (l Value) SetCleanup(cleanup bool) { + C.LLVMSetCleanup(l.C, boolToLLVMBool(cleanup)) +} + +func (b Builder) CreateResume(ex Value) (v Value) { + v.C = C.LLVMBuildResume(b.C, ex.C) + return +} + +//------------------------------------------------------------------------- +// llvm.ModuleProvider +//------------------------------------------------------------------------- + +// Changes the type of M so it can be passed to FunctionPassManagers and the +// JIT. They take ModuleProviders for historical reasons. +func NewModuleProviderForModule(m Module) (mp ModuleProvider) { + mp.C = C.LLVMCreateModuleProviderForExistingModule(m.C) + return +} + +// Destroys the module M. +func (mp ModuleProvider) Dispose() { C.LLVMDisposeModuleProvider(mp.C) } + +//------------------------------------------------------------------------- +// llvm.MemoryBuffer +//------------------------------------------------------------------------- + +func NewMemoryBufferFromFile(path string) (b MemoryBuffer, err error) { + var cmsg *C.char + cpath := C.CString(path) + defer C.free(unsafe.Pointer(cpath)) + fail := C.LLVMCreateMemoryBufferWithContentsOfFile(cpath, &b.C, &cmsg) + if fail != 0 { + b.C = nil + err = errors.New(C.GoString(cmsg)) + C.LLVMDisposeMessage(cmsg) + } + return +} + +func NewMemoryBufferFromStdin() (b MemoryBuffer, err error) { + var cmsg *C.char + fail := C.LLVMCreateMemoryBufferWithSTDIN(&b.C, &cmsg) + if fail != 0 { + b.C = nil + err = errors.New(C.GoString(cmsg)) + C.LLVMDisposeMessage(cmsg) + } + return +} + +func (b MemoryBuffer) Bytes() []byte { + cstart := C.LLVMGetBufferStart(b.C) + csize := C.LLVMGetBufferSize(b.C) + return C.GoBytes(unsafe.Pointer(cstart), C.int(csize)) +} + +func (b MemoryBuffer) Dispose() { C.LLVMDisposeMemoryBuffer(b.C) } + +//------------------------------------------------------------------------- +// llvm.PassManager +//------------------------------------------------------------------------- + +// Constructs a new whole-module pass pipeline. This type of pipeline is +// suitable for link-time optimization and whole-module transformations. +// See llvm::PassManager::PassManager. +func NewPassManager() (pm PassManager) { pm.C = C.LLVMCreatePassManager(); return } + +// Constructs a new function-by-function pass pipeline over the module +// provider. It does not take ownership of the module provider. This type of +// pipeline is suitable for code generation and JIT compilation tasks. +// See llvm::FunctionPassManager::FunctionPassManager. +func NewFunctionPassManagerForModule(m Module) (pm PassManager) { + pm.C = C.LLVMCreateFunctionPassManagerForModule(m.C) + return +} + +// Initializes, executes on the provided module, and finalizes all of the +// passes scheduled in the pass manager. Returns 1 if any of the passes +// modified the module, 0 otherwise. See llvm::PassManager::run(Module&). +func (pm PassManager) Run(m Module) bool { return C.LLVMRunPassManager(pm.C, m.C) != 0 } + +// Initializes all of the function passes scheduled in the function pass +// manager. Returns 1 if any of the passes modified the module, 0 otherwise. +// See llvm::FunctionPassManager::doInitialization. +func (pm PassManager) InitializeFunc() bool { return C.LLVMInitializeFunctionPassManager(pm.C) != 0 } + +// Executes all of the function passes scheduled in the function pass manager +// on the provided function. Returns 1 if any of the passes modified the +// function, false otherwise. +// See llvm::FunctionPassManager::run(Function&). +func (pm PassManager) RunFunc(f Value) bool { return C.LLVMRunFunctionPassManager(pm.C, f.C) != 0 } + +// Finalizes all of the function passes scheduled in the function pass +// manager. Returns 1 if any of the passes modified the module, 0 otherwise. +// See llvm::FunctionPassManager::doFinalization. +func (pm PassManager) FinalizeFunc() bool { return C.LLVMFinalizeFunctionPassManager(pm.C) != 0 } + +// Frees the memory of a pass pipeline. For function pipelines, does not free +// the module provider. +// See llvm::PassManagerBase::~PassManagerBase. +func (pm PassManager) Dispose() { C.LLVMDisposePassManager(pm.C) } diff --git a/llvm/bindings/go/src/llvm/ir_test.go b/llvm/bindings/go/src/llvm/ir_test.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/ir_test.go @@ -0,0 +1,165 @@ +//===- 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", + "inalloca", + "inlinehint", + "inreg", + "jumptable", + "minsize", + "naked", + "nest", + "noalias", + "nobuiltin", + "nocapture", + "noduplicate", + "noimplicitfloat", + "noinline", + "nonlazybind", + "nonnull", + "noredzone", + "noreturn", + "nounwind", + "optnone", + "optsize", + "readnone", + "readonly", + "returned", + "returns_twice", + "signext", + "safestack", + "ssp", + "sspreq", + "sspstrong", + "sret", + "sanitize_thread", + "sanitize_memory", + "uwtable", + "zeroext", + "cold", + "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") + } +} diff --git a/llvm/bindings/go/src/llvm/linker.go b/llvm/bindings/go/src/llvm/linker.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/linker.go @@ -0,0 +1,30 @@ +//===- 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 +*/ +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 +} diff --git a/llvm/bindings/go/src/llvm/llvm_config.go.in b/llvm/bindings/go/src/llvm/llvm_config.go.in new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/llvm_config.go.in @@ -0,0 +1,12 @@ +// +build !byollvm + +package llvm + +/* +#cgo CXXFLAGS: -std=c++14 +#cgo CPPFLAGS: @LLVM_CFLAGS@ +#cgo LDFLAGS: @LLVM_LDFLAGS@ +*/ +import "C" + +type (run_build_sh int) diff --git a/llvm/bindings/go/src/llvm/llvm_dep.go b/llvm/bindings/go/src/llvm/llvm_dep.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/llvm_dep.go @@ -0,0 +1,16 @@ +//===- 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 diff --git a/llvm/bindings/go/src/llvm/string.go b/llvm/bindings/go/src/llvm/string.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/string.go @@ -0,0 +1,104 @@ +//===- 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 VectorTypeKind: + return "VectorTypeKind" + case MetadataTypeKind: + return "MetadataTypeKind" + } + panic("unreachable") +} + +func (t Type) String() string { + ts := typeStringer{s: make(map[Type]string)} + return ts.typeString(t) +} + +type typeStringer struct { + s map[Type]string +} + +func (ts *typeStringer) typeString(t Type) string { + if s, ok := ts.s[t]; ok { + return s + } + + k := t.TypeKind() + s := k.String() + s = s[:len(s)-len("Kind")] + + switch k { + case ArrayTypeKind: + s += fmt.Sprintf("(%v[%v])", ts.typeString(t.ElementType()), t.ArrayLength()) + case PointerTypeKind: + s += fmt.Sprintf("(%v)", ts.typeString(t.ElementType())) + case FunctionTypeKind: + params := t.ParamTypes() + s += "(" + if len(params) > 0 { + s += fmt.Sprintf("%v", ts.typeString(params[0])) + for i := 1; i < len(params); i++ { + s += fmt.Sprintf(", %v", ts.typeString(params[i])) + } + } + s += fmt.Sprintf("):%v", ts.typeString(t.ReturnType())) + case StructTypeKind: + if name := t.StructName(); name != "" { + ts.s[t] = "%" + name + s = fmt.Sprintf("%%%s: %s", name, s) + } + etypes := t.StructElementTypes() + s += "(" + if n := len(etypes); n > 0 { + s += ts.typeString(etypes[0]) + for i := 1; i < n; i++ { + s += fmt.Sprintf(", %v", ts.typeString(etypes[i])) + } + } + s += ")" + case IntegerTypeKind: + s += fmt.Sprintf("(%d bits)", t.IntTypeWidth()) + } + + ts.s[t] = s + return s +} diff --git a/llvm/bindings/go/src/llvm/string_test.go b/llvm/bindings/go/src/llvm/string_test.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/string_test.go @@ -0,0 +1,27 @@ +//===- 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) + } +} diff --git a/llvm/bindings/go/src/llvm/support.go b/llvm/bindings/go/src/llvm/support.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/support.go @@ -0,0 +1,53 @@ +//===- 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 +*/ +import "C" + +import ( + "errors" + "unsafe" +) + +// Loads a dynamic library such that it may be used as an LLVM plugin. +// See llvm::sys::DynamicLibrary::LoadLibraryPermanently. +func LoadLibraryPermanently(lib string) error { + var errstr *C.char + libstr := C.CString(lib) + defer C.free(unsafe.Pointer(libstr)) + C.LLVMLoadLibraryPermanently2(libstr, &errstr) + if errstr != nil { + err := errors.New(C.GoString(errstr)) + C.free(unsafe.Pointer(errstr)) + return err + } + return nil +} + +// Parse the given arguments using the LLVM command line parser. +// See llvm::cl::ParseCommandLineOptions. +func ParseCommandLineOptions(args []string, overview string) { + argstrs := make([]*C.char, len(args)) + for i, arg := range args { + argstrs[i] = C.CString(arg) + defer C.free(unsafe.Pointer(argstrs[i])) + } + overviewstr := C.CString(overview) + defer C.free(unsafe.Pointer(overviewstr)) + C.LLVMParseCommandLineOptions(C.int(len(args)), &argstrs[0], overviewstr) +} diff --git a/llvm/bindings/go/src/llvm/target.go b/llvm/bindings/go/src/llvm/target.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/target.go @@ -0,0 +1,296 @@ +//===- 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 +*/ +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 +} diff --git a/llvm/bindings/go/src/llvm/transforms_coroutines.go b/llvm/bindings/go/src/llvm/transforms_coroutines.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/transforms_coroutines.go @@ -0,0 +1,23 @@ +//===- transforms_coroutines.go - Bindings for coroutines -----------------===// +// +// 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 coroutines component. +// +//===----------------------------------------------------------------------===// + +package llvm + +/* +#include "llvm-c/Transforms/Coroutines.h" +*/ +import "C" + +func (pm PassManager) AddCoroEarlyPass() { C.LLVMAddCoroEarlyPass(pm.C) } +func (pm PassManager) AddCoroSplitPass() { C.LLVMAddCoroSplitPass(pm.C) } +func (pm PassManager) AddCoroElidePass() { C.LLVMAddCoroElidePass(pm.C) } +func (pm PassManager) AddCoroCleanupPass() { C.LLVMAddCoroCleanupPass(pm.C) } diff --git a/llvm/bindings/go/src/llvm/transforms_instrumentation.go b/llvm/bindings/go/src/llvm/transforms_instrumentation.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/transforms_instrumentation.go @@ -0,0 +1,45 @@ +//===- 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 +*/ +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) AddMemorySanitizerLegacyPassPass() { + C.LLVMAddMemorySanitizerLegacyPassPass(pm.C) +} + +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]) +} diff --git a/llvm/bindings/go/src/llvm/transforms_ipo.go b/llvm/bindings/go/src/llvm/transforms_ipo.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/transforms_ipo.go @@ -0,0 +1,41 @@ +//===- 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) AddArgumentPromotionPass() { C.LLVMAddArgumentPromotionPass(pm.C) } +func (pm PassManager) AddConstantMergePass() { C.LLVMAddConstantMergePass(pm.C) } +func (pm PassManager) AddDeadArgEliminationPass() { C.LLVMAddDeadArgEliminationPass(pm.C) } +func (pm PassManager) AddFunctionAttrsPass() { C.LLVMAddFunctionAttrsPass(pm.C) } +func (pm PassManager) AddFunctionInliningPass() { C.LLVMAddFunctionInliningPass(pm.C) } +func (pm PassManager) AddGlobalDCEPass() { C.LLVMAddGlobalDCEPass(pm.C) } +func (pm PassManager) AddGlobalOptimizerPass() { C.LLVMAddGlobalOptimizerPass(pm.C) } +func (pm PassManager) AddIPConstantPropagationPass() { C.LLVMAddIPConstantPropagationPass(pm.C) } +func (pm PassManager) AddPruneEHPass() { C.LLVMAddPruneEHPass(pm.C) } +func (pm PassManager) AddIPSCCPPass() { C.LLVMAddIPSCCPPass(pm.C) } +func (pm PassManager) AddInternalizePass(allButMain bool) { + C.LLVMAddInternalizePass(pm.C, boolToUnsigned(allButMain)) +} +func (pm PassManager) AddStripDeadPrototypesPass() { C.LLVMAddStripDeadPrototypesPass(pm.C) } diff --git a/llvm/bindings/go/src/llvm/transforms_pmbuilder.go b/llvm/bindings/go/src/llvm/transforms_pmbuilder.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/transforms_pmbuilder.go @@ -0,0 +1,67 @@ +//===- 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) PopulateLTOPassManager(pm PassManager, internalize bool, runInliner bool) { + C.LLVMPassManagerBuilderPopulateLTOPassManager(pmb.C, pm.C, boolToLLVMBool(internalize), boolToLLVMBool(runInliner)) +} + +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)) +} diff --git a/llvm/bindings/go/src/llvm/transforms_scalar.go b/llvm/bindings/go/src/llvm/transforms_scalar.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/transforms_scalar.go @@ -0,0 +1,45 @@ +//===- 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) AddLoopUnswitchPass() { C.LLVMAddLoopUnswitchPass(pm.C) } +func (pm PassManager) AddMemCpyOptPass() { C.LLVMAddMemCpyOptPass(pm.C) } +func (pm PassManager) AddPromoteMemoryToRegisterPass() { C.LLVMAddPromoteMemoryToRegisterPass(pm.C) } +func (pm PassManager) AddReassociatePass() { C.LLVMAddReassociatePass(pm.C) } +func (pm PassManager) AddSCCPPass() { C.LLVMAddSCCPPass(pm.C) } +func (pm PassManager) AddScalarReplAggregatesPass() { C.LLVMAddScalarReplAggregatesPass(pm.C) } +func (pm PassManager) AddScalarReplAggregatesPassWithThreshold(threshold int) { + C.LLVMAddScalarReplAggregatesPassWithThreshold(pm.C, C.int(threshold)) +} +func (pm PassManager) AddSimplifyLibCallsPass() { C.LLVMAddSimplifyLibCallsPass(pm.C) } +func (pm PassManager) AddTailCallEliminationPass() { C.LLVMAddTailCallEliminationPass(pm.C) } +func (pm PassManager) AddConstantPropagationPass() { C.LLVMAddConstantPropagationPass(pm.C) } +func (pm PassManager) AddDemoteMemoryToRegisterPass() { C.LLVMAddDemoteMemoryToRegisterPass(pm.C) } +func (pm PassManager) AddVerifierPass() { C.LLVMAddVerifierPass(pm.C) } diff --git a/llvm/bindings/go/src/llvm/version.go b/llvm/bindings/go/src/llvm/version.go new file mode 100644 --- /dev/null +++ b/llvm/bindings/go/src/llvm/version.go @@ -0,0 +1,20 @@ +//===- 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 diff --git a/llvm/test/Bindings/Go/go.test b/llvm/test/Bindings/Go/go.test --- a/llvm/test/Bindings/Go/go.test +++ b/llvm/test/Bindings/Go/go.test @@ -1,4 +1,4 @@ -; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm +; RUN: CGO_CPPFLAGS="`llvm-config --cppflags`" CGO_CXXFLAGS=-std=c++14 CGO_LDFLAGS="`llvm-config --ldflags --libs --system-libs all`" go test llvm ; REQUIRES: shell ; UNSUPPORTED: asan, ubsan, msan diff --git a/llvm/test/Bindings/Go/lit.local.cfg b/llvm/test/Bindings/Go/lit.local.cfg --- a/llvm/test/Bindings/Go/lit.local.cfg +++ b/llvm/test/Bindings/Go/lit.local.cfg @@ -57,4 +57,5 @@ 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 +config.environment['LD_LIBRARY_PATH'] = config.llvm_shlib_dir +config.environment['GOPATH'] = os.path.join(config.llvm_src_root, 'bindings', 'go') diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py --- a/llvm/test/lit.cfg.py +++ b/llvm/test/lit.cfg.py @@ -160,7 +160,7 @@ # The following tools are optional tools.extend([ - ToolSubst('llvm-go', unresolved='ignore'), + ToolSubst('go', unresolved='ignore'), ToolSubst('llvm-mt', unresolved='ignore'), ToolSubst('Kaleidoscope-Ch3', unresolved='ignore'), ToolSubst('Kaleidoscope-Ch4', unresolved='ignore'), diff --git a/llvm/utils/lit/lit/llvm/subst.py b/llvm/utils/lit/lit/llvm/subst.py --- a/llvm/utils/lit/lit/llvm/subst.py +++ b/llvm/utils/lit/lit/llvm/subst.py @@ -23,7 +23,7 @@ if self.name == 'llc' and os.environ.get('LLVM_ENABLE_MACHINE_VERIFIER') == '1': command += ' -verify-machineinstrs' - elif self.name == 'llvm-go': + elif self.name == 'go': exe = getattr(config.config, 'go_executable', None) if exe: command += ' go=' + exe