diff options
Diffstat (limited to 'gnu/llvm/lib/IR/Core.cpp')
| -rw-r--r-- | gnu/llvm/lib/IR/Core.cpp | 2952 |
1 files changed, 2952 insertions, 0 deletions
diff --git a/gnu/llvm/lib/IR/Core.cpp b/gnu/llvm/lib/IR/Core.cpp new file mode 100644 index 00000000000..591dafa22a4 --- /dev/null +++ b/gnu/llvm/lib/IR/Core.cpp @@ -0,0 +1,2952 @@ +//===-- Core.cpp ----------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the common infrastructure (including the C bindings) +// for libLLVMCore.a, which implements the LLVM intermediate representation. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/Core.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/GlobalAlias.h" +#include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Threading.h" +#include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstdlib> +#include <cstring> +#include <system_error> + +using namespace llvm; + +#define DEBUG_TYPE "ir" + +void llvm::initializeCore(PassRegistry &Registry) { + initializeDominatorTreeWrapperPassPass(Registry); + initializePrintModulePassWrapperPass(Registry); + initializePrintFunctionPassWrapperPass(Registry); + initializePrintBasicBlockPassPass(Registry); + initializeVerifierLegacyPassPass(Registry); +} + +void LLVMInitializeCore(LLVMPassRegistryRef R) { + initializeCore(*unwrap(R)); +} + +void LLVMShutdown() { + llvm_shutdown(); +} + +/*===-- Error handling ----------------------------------------------------===*/ + +char *LLVMCreateMessage(const char *Message) { + return strdup(Message); +} + +void LLVMDisposeMessage(char *Message) { + free(Message); +} + + +/*===-- Operations on contexts --------------------------------------------===*/ + +LLVMContextRef LLVMContextCreate() { + return wrap(new LLVMContext()); +} + +LLVMContextRef LLVMGetGlobalContext() { + return wrap(&getGlobalContext()); +} + +void LLVMContextSetDiagnosticHandler(LLVMContextRef C, + LLVMDiagnosticHandler Handler, + void *DiagnosticContext) { + unwrap(C)->setDiagnosticHandler( + LLVM_EXTENSION reinterpret_cast<LLVMContext::DiagnosticHandlerTy>(Handler), + DiagnosticContext); +} + +void LLVMContextSetYieldCallback(LLVMContextRef C, LLVMYieldCallback Callback, + void *OpaqueHandle) { + auto YieldCallback = + LLVM_EXTENSION reinterpret_cast<LLVMContext::YieldCallbackTy>(Callback); + unwrap(C)->setYieldCallback(YieldCallback, OpaqueHandle); +} + +void LLVMContextDispose(LLVMContextRef C) { + delete unwrap(C); +} + +unsigned LLVMGetMDKindIDInContext(LLVMContextRef C, const char* Name, + unsigned SLen) { + return unwrap(C)->getMDKindID(StringRef(Name, SLen)); +} + +unsigned LLVMGetMDKindID(const char* Name, unsigned SLen) { + return LLVMGetMDKindIDInContext(LLVMGetGlobalContext(), Name, SLen); +} + +char *LLVMGetDiagInfoDescription(LLVMDiagnosticInfoRef DI) { + std::string MsgStorage; + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + + unwrap(DI)->print(DP); + Stream.flush(); + + return LLVMCreateMessage(MsgStorage.c_str()); +} + +LLVMDiagnosticSeverity LLVMGetDiagInfoSeverity(LLVMDiagnosticInfoRef DI){ + LLVMDiagnosticSeverity severity; + + switch(unwrap(DI)->getSeverity()) { + default: + severity = LLVMDSError; + break; + case DS_Warning: + severity = LLVMDSWarning; + break; + case DS_Remark: + severity = LLVMDSRemark; + break; + case DS_Note: + severity = LLVMDSNote; + break; + } + + return severity; +} + + + + +/*===-- Operations on modules ---------------------------------------------===*/ + +LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { + return wrap(new Module(ModuleID, getGlobalContext())); +} + +LLVMModuleRef LLVMModuleCreateWithNameInContext(const char *ModuleID, + LLVMContextRef C) { + return wrap(new Module(ModuleID, *unwrap(C))); +} + +void LLVMDisposeModule(LLVMModuleRef M) { + delete unwrap(M); +} + +/*--.. Data layout .........................................................--*/ +const char * LLVMGetDataLayout(LLVMModuleRef M) { + return unwrap(M)->getDataLayoutStr().c_str(); +} + +void LLVMSetDataLayout(LLVMModuleRef M, const char *Triple) { + unwrap(M)->setDataLayout(Triple); +} + +/*--.. Target triple .......................................................--*/ +const char * LLVMGetTarget(LLVMModuleRef M) { + return unwrap(M)->getTargetTriple().c_str(); +} + +void LLVMSetTarget(LLVMModuleRef M, const char *Triple) { + unwrap(M)->setTargetTriple(Triple); +} + +void LLVMDumpModule(LLVMModuleRef M) { + unwrap(M)->dump(); +} + +LLVMBool LLVMPrintModuleToFile(LLVMModuleRef M, const char *Filename, + char **ErrorMessage) { + std::error_code EC; + raw_fd_ostream dest(Filename, EC, sys::fs::F_Text); + if (EC) { + *ErrorMessage = strdup(EC.message().c_str()); + return true; + } + + unwrap(M)->print(dest, nullptr); + + dest.close(); + + if (dest.has_error()) { + *ErrorMessage = strdup("Error printing to file"); + return true; + } + + return false; +} + +char *LLVMPrintModuleToString(LLVMModuleRef M) { + std::string buf; + raw_string_ostream os(buf); + + unwrap(M)->print(os, nullptr); + os.flush(); + + return strdup(buf.c_str()); +} + +/*--.. Operations on inline assembler ......................................--*/ +void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm) { + unwrap(M)->setModuleInlineAsm(StringRef(Asm)); +} + + +/*--.. Operations on module contexts ......................................--*/ +LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M) { + return wrap(&unwrap(M)->getContext()); +} + + +/*===-- Operations on types -----------------------------------------------===*/ + +/*--.. Operations on all types (mostly) ....................................--*/ + +LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { + switch (unwrap(Ty)->getTypeID()) { + case Type::VoidTyID: + return LLVMVoidTypeKind; + case Type::HalfTyID: + return LLVMHalfTypeKind; + case Type::FloatTyID: + return LLVMFloatTypeKind; + case Type::DoubleTyID: + return LLVMDoubleTypeKind; + case Type::X86_FP80TyID: + return LLVMX86_FP80TypeKind; + case Type::FP128TyID: + return LLVMFP128TypeKind; + case Type::PPC_FP128TyID: + return LLVMPPC_FP128TypeKind; + case Type::LabelTyID: + return LLVMLabelTypeKind; + case Type::MetadataTyID: + return LLVMMetadataTypeKind; + case Type::IntegerTyID: + return LLVMIntegerTypeKind; + case Type::FunctionTyID: + return LLVMFunctionTypeKind; + case Type::StructTyID: + return LLVMStructTypeKind; + case Type::ArrayTyID: + return LLVMArrayTypeKind; + case Type::PointerTyID: + return LLVMPointerTypeKind; + case Type::VectorTyID: + return LLVMVectorTypeKind; + case Type::X86_MMXTyID: + return LLVMX86_MMXTypeKind; + case Type::TokenTyID: + return LLVMTokenTypeKind; + } + llvm_unreachable("Unhandled TypeID."); +} + +LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty) +{ + return unwrap(Ty)->isSized(); +} + +LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty) { + return wrap(&unwrap(Ty)->getContext()); +} + +void LLVMDumpType(LLVMTypeRef Ty) { + return unwrap(Ty)->dump(); +} + +char *LLVMPrintTypeToString(LLVMTypeRef Ty) { + std::string buf; + raw_string_ostream os(buf); + + if (unwrap(Ty)) + unwrap(Ty)->print(os); + else + os << "Printing <null> Type"; + + os.flush(); + + return strdup(buf.c_str()); +} + +/*--.. Operations on integer types .........................................--*/ + +LLVMTypeRef LLVMInt1TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt1Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt8TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt8Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt16TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt16Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt32TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt32Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt64TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt64Ty(*unwrap(C)); +} +LLVMTypeRef LLVMInt128TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getInt128Ty(*unwrap(C)); +} +LLVMTypeRef LLVMIntTypeInContext(LLVMContextRef C, unsigned NumBits) { + return wrap(IntegerType::get(*unwrap(C), NumBits)); +} + +LLVMTypeRef LLVMInt1Type(void) { + return LLVMInt1TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt8Type(void) { + return LLVMInt8TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt16Type(void) { + return LLVMInt16TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt32Type(void) { + return LLVMInt32TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt64Type(void) { + return LLVMInt64TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMInt128Type(void) { + return LLVMInt128TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMIntType(unsigned NumBits) { + return LLVMIntTypeInContext(LLVMGetGlobalContext(), NumBits); +} + +unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy) { + return unwrap<IntegerType>(IntegerTy)->getBitWidth(); +} + +/*--.. Operations on real types ............................................--*/ + +LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getHalfTy(*unwrap(C)); +} +LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getFloatTy(*unwrap(C)); +} +LLVMTypeRef LLVMDoubleTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getDoubleTy(*unwrap(C)); +} +LLVMTypeRef LLVMX86FP80TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getX86_FP80Ty(*unwrap(C)); +} +LLVMTypeRef LLVMFP128TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getFP128Ty(*unwrap(C)); +} +LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getPPC_FP128Ty(*unwrap(C)); +} +LLVMTypeRef LLVMX86MMXTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getX86_MMXTy(*unwrap(C)); +} +LLVMTypeRef LLVMTokenTypeInContext(LLVMContextRef C) { + return (LLVMTypeRef) Type::getTokenTy(*unwrap(C)); +} + +LLVMTypeRef LLVMHalfType(void) { + return LLVMHalfTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMFloatType(void) { + return LLVMFloatTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMDoubleType(void) { + return LLVMDoubleTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMX86FP80Type(void) { + return LLVMX86FP80TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMFP128Type(void) { + return LLVMFP128TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMPPCFP128Type(void) { + return LLVMPPCFP128TypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMX86MMXType(void) { + return LLVMX86MMXTypeInContext(LLVMGetGlobalContext()); +} + +/*--.. Operations on function types ........................................--*/ + +LLVMTypeRef LLVMFunctionType(LLVMTypeRef ReturnType, + LLVMTypeRef *ParamTypes, unsigned ParamCount, + LLVMBool IsVarArg) { + ArrayRef<Type*> Tys(unwrap(ParamTypes), ParamCount); + return wrap(FunctionType::get(unwrap(ReturnType), Tys, IsVarArg != 0)); +} + +LLVMBool LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) { + return unwrap<FunctionType>(FunctionTy)->isVarArg(); +} + +LLVMTypeRef LLVMGetReturnType(LLVMTypeRef FunctionTy) { + return wrap(unwrap<FunctionType>(FunctionTy)->getReturnType()); +} + +unsigned LLVMCountParamTypes(LLVMTypeRef FunctionTy) { + return unwrap<FunctionType>(FunctionTy)->getNumParams(); +} + +void LLVMGetParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { + FunctionType *Ty = unwrap<FunctionType>(FunctionTy); + for (FunctionType::param_iterator I = Ty->param_begin(), + E = Ty->param_end(); I != E; ++I) + *Dest++ = wrap(*I); +} + +/*--.. Operations on struct types ..........................................--*/ + +LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, + unsigned ElementCount, LLVMBool Packed) { + ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount); + return wrap(StructType::get(*unwrap(C), Tys, Packed != 0)); +} + +LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, + unsigned ElementCount, LLVMBool Packed) { + return LLVMStructTypeInContext(LLVMGetGlobalContext(), ElementTypes, + ElementCount, Packed); +} + +LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name) +{ + return wrap(StructType::create(*unwrap(C), Name)); +} + +const char *LLVMGetStructName(LLVMTypeRef Ty) +{ + StructType *Type = unwrap<StructType>(Ty); + if (!Type->hasName()) + return nullptr; + return Type->getName().data(); +} + +void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, + unsigned ElementCount, LLVMBool Packed) { + ArrayRef<Type*> Tys(unwrap(ElementTypes), ElementCount); + unwrap<StructType>(StructTy)->setBody(Tys, Packed != 0); +} + +unsigned LLVMCountStructElementTypes(LLVMTypeRef StructTy) { + return unwrap<StructType>(StructTy)->getNumElements(); +} + +void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest) { + StructType *Ty = unwrap<StructType>(StructTy); + for (StructType::element_iterator I = Ty->element_begin(), + E = Ty->element_end(); I != E; ++I) + *Dest++ = wrap(*I); +} + +LLVMTypeRef LLVMStructGetTypeAtIndex(LLVMTypeRef StructTy, unsigned i) { + StructType *Ty = unwrap<StructType>(StructTy); + return wrap(Ty->getTypeAtIndex(i)); +} + +LLVMBool LLVMIsPackedStruct(LLVMTypeRef StructTy) { + return unwrap<StructType>(StructTy)->isPacked(); +} + +LLVMBool LLVMIsOpaqueStruct(LLVMTypeRef StructTy) { + return unwrap<StructType>(StructTy)->isOpaque(); +} + +LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name) { + return wrap(unwrap(M)->getTypeByName(Name)); +} + +/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/ + +LLVMTypeRef LLVMArrayType(LLVMTypeRef ElementType, unsigned ElementCount) { + return wrap(ArrayType::get(unwrap(ElementType), ElementCount)); +} + +LLVMTypeRef LLVMPointerType(LLVMTypeRef ElementType, unsigned AddressSpace) { + return wrap(PointerType::get(unwrap(ElementType), AddressSpace)); +} + +LLVMTypeRef LLVMVectorType(LLVMTypeRef ElementType, unsigned ElementCount) { + return wrap(VectorType::get(unwrap(ElementType), ElementCount)); +} + +LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty) { + return wrap(unwrap<SequentialType>(Ty)->getElementType()); +} + +unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) { + return unwrap<ArrayType>(ArrayTy)->getNumElements(); +} + +unsigned LLVMGetPointerAddressSpace(LLVMTypeRef PointerTy) { + return unwrap<PointerType>(PointerTy)->getAddressSpace(); +} + +unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) { + return unwrap<VectorType>(VectorTy)->getNumElements(); +} + +/*--.. Operations on other types ...........................................--*/ + +LLVMTypeRef LLVMVoidTypeInContext(LLVMContextRef C) { + return wrap(Type::getVoidTy(*unwrap(C))); +} +LLVMTypeRef LLVMLabelTypeInContext(LLVMContextRef C) { + return wrap(Type::getLabelTy(*unwrap(C))); +} + +LLVMTypeRef LLVMVoidType(void) { + return LLVMVoidTypeInContext(LLVMGetGlobalContext()); +} +LLVMTypeRef LLVMLabelType(void) { + return LLVMLabelTypeInContext(LLVMGetGlobalContext()); +} + +/*===-- Operations on values ----------------------------------------------===*/ + +/*--.. Operations on all values ............................................--*/ + +LLVMTypeRef LLVMTypeOf(LLVMValueRef Val) { + return wrap(unwrap(Val)->getType()); +} + +const char *LLVMGetValueName(LLVMValueRef Val) { + return unwrap(Val)->getName().data(); +} + +void LLVMSetValueName(LLVMValueRef Val, const char *Name) { + unwrap(Val)->setName(Name); +} + +void LLVMDumpValue(LLVMValueRef Val) { + unwrap(Val)->dump(); +} + +char* LLVMPrintValueToString(LLVMValueRef Val) { + std::string buf; + raw_string_ostream os(buf); + + if (unwrap(Val)) + unwrap(Val)->print(os); + else + os << "Printing <null> Value"; + + os.flush(); + + return strdup(buf.c_str()); +} + +void LLVMReplaceAllUsesWith(LLVMValueRef OldVal, LLVMValueRef NewVal) { + unwrap(OldVal)->replaceAllUsesWith(unwrap(NewVal)); +} + +int LLVMHasMetadata(LLVMValueRef Inst) { + return unwrap<Instruction>(Inst)->hasMetadata(); +} + +LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { + auto *I = unwrap<Instruction>(Inst); + assert(I && "Expected instruction"); + if (auto *MD = I->getMetadata(KindID)) + return wrap(MetadataAsValue::get(I->getContext(), MD)); + return nullptr; +} + +// MetadataAsValue uses a canonical format which strips the actual MDNode for +// MDNode with just a single constant value, storing just a ConstantAsMetadata +// This undoes this canonicalization, reconstructing the MDNode. +static MDNode *extractMDNode(MetadataAsValue *MAV) { + Metadata *MD = MAV->getMetadata(); + assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) && + "Expected a metadata node or a canonicalized constant"); + + if (MDNode *N = dyn_cast<MDNode>(MD)) + return N; + + return MDNode::get(MAV->getContext(), MD); +} + +void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { + MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr; + + unwrap<Instruction>(Inst)->setMetadata(KindID, N); +} + +/*--.. Conversion functions ................................................--*/ + +#define LLVM_DEFINE_VALUE_CAST(name) \ + LLVMValueRef LLVMIsA##name(LLVMValueRef Val) { \ + return wrap(static_cast<Value*>(dyn_cast_or_null<name>(unwrap(Val)))); \ + } + +LLVM_FOR_EACH_VALUE_SUBCLASS(LLVM_DEFINE_VALUE_CAST) + +LLVMValueRef LLVMIsAMDNode(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val))) + if (isa<MDNode>(MD->getMetadata()) || + isa<ValueAsMetadata>(MD->getMetadata())) + return Val; + return nullptr; +} + +LLVMValueRef LLVMIsAMDString(LLVMValueRef Val) { + if (auto *MD = dyn_cast_or_null<MetadataAsValue>(unwrap(Val))) + if (isa<MDString>(MD->getMetadata())) + return Val; + return nullptr; +} + +/*--.. Operations on Uses ..................................................--*/ +LLVMUseRef LLVMGetFirstUse(LLVMValueRef Val) { + Value *V = unwrap(Val); + Value::use_iterator I = V->use_begin(); + if (I == V->use_end()) + return nullptr; + return wrap(&*I); +} + +LLVMUseRef LLVMGetNextUse(LLVMUseRef U) { + Use *Next = unwrap(U)->getNext(); + if (Next) + return wrap(Next); + return nullptr; +} + +LLVMValueRef LLVMGetUser(LLVMUseRef U) { + return wrap(unwrap(U)->getUser()); +} + +LLVMValueRef LLVMGetUsedValue(LLVMUseRef U) { + return wrap(unwrap(U)->get()); +} + +/*--.. Operations on Users .................................................--*/ + +static LLVMValueRef getMDNodeOperandImpl(LLVMContext &Context, const MDNode *N, + unsigned Index) { + Metadata *Op = N->getOperand(Index); + if (!Op) + return nullptr; + if (auto *C = dyn_cast<ConstantAsMetadata>(Op)) + return wrap(C->getValue()); + return wrap(MetadataAsValue::get(Context, Op)); +} + +LLVMValueRef LLVMGetOperand(LLVMValueRef Val, unsigned Index) { + Value *V = unwrap(Val); + if (auto *MD = dyn_cast<MetadataAsValue>(V)) { + if (auto *L = dyn_cast<ValueAsMetadata>(MD->getMetadata())) { + assert(Index == 0 && "Function-local metadata can only have one operand"); + return wrap(L->getValue()); + } + return getMDNodeOperandImpl(V->getContext(), + cast<MDNode>(MD->getMetadata()), Index); + } + + return wrap(cast<User>(V)->getOperand(Index)); +} + +LLVMUseRef LLVMGetOperandUse(LLVMValueRef Val, unsigned Index) { + Value *V = unwrap(Val); + return wrap(&cast<User>(V)->getOperandUse(Index)); +} + +void LLVMSetOperand(LLVMValueRef Val, unsigned Index, LLVMValueRef Op) { + unwrap<User>(Val)->setOperand(Index, unwrap(Op)); +} + +int LLVMGetNumOperands(LLVMValueRef Val) { + Value *V = unwrap(Val); + if (isa<MetadataAsValue>(V)) + return LLVMGetMDNodeNumOperands(Val); + + return cast<User>(V)->getNumOperands(); +} + +/*--.. Operations on constants of any type .................................--*/ + +LLVMValueRef LLVMConstNull(LLVMTypeRef Ty) { + return wrap(Constant::getNullValue(unwrap(Ty))); +} + +LLVMValueRef LLVMConstAllOnes(LLVMTypeRef Ty) { + return wrap(Constant::getAllOnesValue(unwrap(Ty))); +} + +LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty) { + return wrap(UndefValue::get(unwrap(Ty))); +} + +LLVMBool LLVMIsConstant(LLVMValueRef Ty) { + return isa<Constant>(unwrap(Ty)); +} + +LLVMBool LLVMIsNull(LLVMValueRef Val) { + if (Constant *C = dyn_cast<Constant>(unwrap(Val))) + return C->isNullValue(); + return false; +} + +LLVMBool LLVMIsUndef(LLVMValueRef Val) { + return isa<UndefValue>(unwrap(Val)); +} + +LLVMValueRef LLVMConstPointerNull(LLVMTypeRef Ty) { + return + wrap(ConstantPointerNull::get(unwrap<PointerType>(Ty))); +} + +/*--.. Operations on metadata nodes ........................................--*/ + +LLVMValueRef LLVMMDStringInContext(LLVMContextRef C, const char *Str, + unsigned SLen) { + LLVMContext &Context = *unwrap(C); + return wrap(MetadataAsValue::get( + Context, MDString::get(Context, StringRef(Str, SLen)))); +} + +LLVMValueRef LLVMMDString(const char *Str, unsigned SLen) { + return LLVMMDStringInContext(LLVMGetGlobalContext(), Str, SLen); +} + +LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, + unsigned Count) { + LLVMContext &Context = *unwrap(C); + SmallVector<Metadata *, 8> MDs; + for (auto *OV : makeArrayRef(Vals, Count)) { + Value *V = unwrap(OV); + Metadata *MD; + if (!V) + MD = nullptr; + else if (auto *C = dyn_cast<Constant>(V)) + MD = ConstantAsMetadata::get(C); + else if (auto *MDV = dyn_cast<MetadataAsValue>(V)) { + MD = MDV->getMetadata(); + assert(!isa<LocalAsMetadata>(MD) && "Unexpected function-local metadata " + "outside of direct argument to call"); + } else { + // This is function-local metadata. Pretend to make an MDNode. + assert(Count == 1 && + "Expected only one operand to function-local metadata"); + return wrap(MetadataAsValue::get(Context, LocalAsMetadata::get(V))); + } + + MDs.push_back(MD); + } + return wrap(MetadataAsValue::get(Context, MDNode::get(Context, MDs))); +} + +LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count) { + return LLVMMDNodeInContext(LLVMGetGlobalContext(), Vals, Count); +} + +const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len) { + if (const auto *MD = dyn_cast<MetadataAsValue>(unwrap(V))) + if (const MDString *S = dyn_cast<MDString>(MD->getMetadata())) { + *Len = S->getString().size(); + return S->getString().data(); + } + *Len = 0; + return nullptr; +} + +unsigned LLVMGetMDNodeNumOperands(LLVMValueRef V) +{ + auto *MD = cast<MetadataAsValue>(unwrap(V)); + if (isa<ValueAsMetadata>(MD->getMetadata())) + return 1; + return cast<MDNode>(MD->getMetadata())->getNumOperands(); +} + +void LLVMGetMDNodeOperands(LLVMValueRef V, LLVMValueRef *Dest) +{ + auto *MD = cast<MetadataAsValue>(unwrap(V)); + if (auto *MDV = dyn_cast<ValueAsMetadata>(MD->getMetadata())) { + *Dest = wrap(MDV->getValue()); + return; + } + const auto *N = cast<MDNode>(MD->getMetadata()); + const unsigned numOperands = N->getNumOperands(); + LLVMContext &Context = unwrap(V)->getContext(); + for (unsigned i = 0; i < numOperands; i++) + Dest[i] = getMDNodeOperandImpl(Context, N, i); +} + +unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name) +{ + if (NamedMDNode *N = unwrap(M)->getNamedMetadata(name)) { + return N->getNumOperands(); + } + return 0; +} + +void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest) +{ + NamedMDNode *N = unwrap(M)->getNamedMetadata(name); + if (!N) + return; + LLVMContext &Context = unwrap(M)->getContext(); + for (unsigned i=0;i<N->getNumOperands();i++) + Dest[i] = wrap(MetadataAsValue::get(Context, N->getOperand(i))); +} + +void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, + LLVMValueRef Val) +{ + NamedMDNode *N = unwrap(M)->getOrInsertNamedMetadata(name); + if (!N) + return; + if (!Val) + return; + N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val))); +} + +/*--.. Operations on scalar constants ......................................--*/ + +LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, + LLVMBool SignExtend) { + return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), N, SignExtend != 0)); +} + +LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, + unsigned NumWords, + const uint64_t Words[]) { + IntegerType *Ty = unwrap<IntegerType>(IntTy); + return wrap(ConstantInt::get(Ty->getContext(), + APInt(Ty->getBitWidth(), + makeArrayRef(Words, NumWords)))); +} + +LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[], + uint8_t Radix) { + return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str), + Radix)); +} + +LLVMValueRef LLVMConstIntOfStringAndSize(LLVMTypeRef IntTy, const char Str[], + unsigned SLen, uint8_t Radix) { + return wrap(ConstantInt::get(unwrap<IntegerType>(IntTy), StringRef(Str, SLen), + Radix)); +} + +LLVMValueRef LLVMConstReal(LLVMTypeRef RealTy, double N) { + return wrap(ConstantFP::get(unwrap(RealTy), N)); +} + +LLVMValueRef LLVMConstRealOfString(LLVMTypeRef RealTy, const char *Text) { + return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Text))); +} + +LLVMValueRef LLVMConstRealOfStringAndSize(LLVMTypeRef RealTy, const char Str[], + unsigned SLen) { + return wrap(ConstantFP::get(unwrap(RealTy), StringRef(Str, SLen))); +} + +unsigned long long LLVMConstIntGetZExtValue(LLVMValueRef ConstantVal) { + return unwrap<ConstantInt>(ConstantVal)->getZExtValue(); +} + +long long LLVMConstIntGetSExtValue(LLVMValueRef ConstantVal) { + return unwrap<ConstantInt>(ConstantVal)->getSExtValue(); +} + +double LLVMConstRealGetDouble(LLVMValueRef ConstantVal, LLVMBool *LosesInfo) { + ConstantFP *cFP = unwrap<ConstantFP>(ConstantVal) ; + Type *Ty = cFP->getType(); + + if (Ty->isFloatTy()) { + *LosesInfo = false; + return cFP->getValueAPF().convertToFloat(); + } + + if (Ty->isDoubleTy()) { + *LosesInfo = false; + return cFP->getValueAPF().convertToDouble(); + } + + bool APFLosesInfo; + APFloat APF = cFP->getValueAPF(); + APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &APFLosesInfo); + *LosesInfo = APFLosesInfo; + return APF.convertToDouble(); +} + +/*--.. Operations on composite constants ...................................--*/ + +LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, + unsigned Length, + LLVMBool DontNullTerminate) { + /* Inverted the sense of AddNull because ', 0)' is a + better mnemonic for null termination than ', 1)'. */ + return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), + DontNullTerminate == 0)); +} +LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, + LLVMValueRef *ConstantVals, + unsigned Count, LLVMBool Packed) { + Constant **Elements = unwrap<Constant>(ConstantVals, Count); + return wrap(ConstantStruct::getAnon(*unwrap(C), makeArrayRef(Elements, Count), + Packed != 0)); +} + +LLVMValueRef LLVMConstString(const char *Str, unsigned Length, + LLVMBool DontNullTerminate) { + return LLVMConstStringInContext(LLVMGetGlobalContext(), Str, Length, + DontNullTerminate); +} + +LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef c, unsigned idx) { + return wrap(static_cast<ConstantDataSequential*>(unwrap(c))->getElementAsConstant(idx)); +} + +LLVMBool LLVMIsConstantString(LLVMValueRef c) { + return static_cast<ConstantDataSequential*>(unwrap(c))->isString(); +} + +const char *LLVMGetAsString(LLVMValueRef c, size_t* Length) { + StringRef str = static_cast<ConstantDataSequential*>(unwrap(c))->getAsString(); + *Length = str.size(); + return str.data(); +} + +LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, + LLVMValueRef *ConstantVals, unsigned Length) { + ArrayRef<Constant*> V(unwrap<Constant>(ConstantVals, Length), Length); + return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), V)); +} + +LLVMValueRef LLVMConstStruct(LLVMValueRef *ConstantVals, unsigned Count, + LLVMBool Packed) { + return LLVMConstStructInContext(LLVMGetGlobalContext(), ConstantVals, Count, + Packed); +} + +LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, + LLVMValueRef *ConstantVals, + unsigned Count) { + Constant **Elements = unwrap<Constant>(ConstantVals, Count); + StructType *Ty = cast<StructType>(unwrap(StructTy)); + + return wrap(ConstantStruct::get(Ty, makeArrayRef(Elements, Count))); +} + +LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { + return wrap(ConstantVector::get(makeArrayRef( + unwrap<Constant>(ScalarConstantVals, Size), Size))); +} + +/*-- Opcode mapping */ + +static LLVMOpcode map_to_llvmopcode(int opcode) +{ + switch (opcode) { + default: llvm_unreachable("Unhandled Opcode."); +#define HANDLE_INST(num, opc, clas) case num: return LLVM##opc; +#include "llvm/IR/Instruction.def" +#undef HANDLE_INST + } +} + +static int map_from_llvmopcode(LLVMOpcode code) +{ + switch (code) { +#define HANDLE_INST(num, opc, clas) case LLVM##opc: return num; +#include "llvm/IR/Instruction.def" +#undef HANDLE_INST + } + llvm_unreachable("Unhandled Opcode."); +} + +/*--.. Constant expressions ................................................--*/ + +LLVMOpcode LLVMGetConstOpcode(LLVMValueRef ConstantVal) { + return map_to_llvmopcode(unwrap<ConstantExpr>(ConstantVal)->getOpcode()); +} + +LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty) { + return wrap(ConstantExpr::getAlignOf(unwrap(Ty))); +} + +LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) { + return wrap(ConstantExpr::getSizeOf(unwrap(Ty))); +} + +LLVMValueRef LLVMConstNeg(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getNeg(unwrap<Constant>(ConstantVal))); +} + +LLVMValueRef LLVMConstNSWNeg(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getNSWNeg(unwrap<Constant>(ConstantVal))); +} + +LLVMValueRef LLVMConstNUWNeg(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getNUWNeg(unwrap<Constant>(ConstantVal))); +} + + +LLVMValueRef LLVMConstFNeg(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getFNeg(unwrap<Constant>(ConstantVal))); +} + +LLVMValueRef LLVMConstNot(LLVMValueRef ConstantVal) { + return wrap(ConstantExpr::getNot(unwrap<Constant>(ConstantVal))); +} + +LLVMValueRef LLVMConstAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getAdd(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNSWAdd(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNSWAdd(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNUWAdd(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNUWAdd(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFAdd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFAdd(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getSub(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNSWSub(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNSWSub(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNUWSub(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNUWSub(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFSub(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFSub(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getMul(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNSWMul(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNSWMul(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstNUWMul(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getNUWMul(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFMul(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFMul(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstUDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getUDiv(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstSDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getSDiv(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstExactSDiv(LLVMValueRef LHSConstant, + LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getExactSDiv(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFDiv(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFDiv(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstURem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getURem(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstSRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getSRem(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFRem(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFRem(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstAnd(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getAnd(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstOr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getOr(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstXor(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getXor(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstICmp(LLVMIntPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getICmp(Predicate, + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstFCmp(LLVMRealPredicate Predicate, + LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getFCmp(Predicate, + unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstShl(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getShl(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstLShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getLShr(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstAShr(LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { + return wrap(ConstantExpr::getAShr(unwrap<Constant>(LHSConstant), + unwrap<Constant>(RHSConstant))); +} + +LLVMValueRef LLVMConstGEP(LLVMValueRef ConstantVal, + LLVMValueRef *ConstantIndices, unsigned NumIndices) { + ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices), + NumIndices); + return wrap(ConstantExpr::getGetElementPtr( + nullptr, unwrap<Constant>(ConstantVal), IdxList)); +} + +LLVMValueRef LLVMConstInBoundsGEP(LLVMValueRef ConstantVal, + LLVMValueRef *ConstantIndices, + unsigned NumIndices) { + Constant* Val = unwrap<Constant>(ConstantVal); + ArrayRef<Constant *> IdxList(unwrap<Constant>(ConstantIndices, NumIndices), + NumIndices); + return wrap(ConstantExpr::getInBoundsGetElementPtr(nullptr, Val, IdxList)); +} + +LLVMValueRef LLVMConstTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getTrunc(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstSExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getSExt(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstZExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getZExt(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstFPTrunc(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPTrunc(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstFPExt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPExtend(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstUIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getUIToFP(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstSIToFP(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getSIToFP(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstFPToUI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPToUI(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstFPToSI(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPToSI(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstPtrToInt(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getPtrToInt(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstIntToPtr(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getIntToPtr(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstBitCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getBitCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstAddrSpaceCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getAddrSpaceCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstZExtOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getZExtOrBitCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstSExtOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getSExtOrBitCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstTruncOrBitCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getTruncOrBitCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstPointerCast(LLVMValueRef ConstantVal, + LLVMTypeRef ToType) { + return wrap(ConstantExpr::getPointerCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstIntCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType, + LLVMBool isSigned) { + return wrap(ConstantExpr::getIntegerCast(unwrap<Constant>(ConstantVal), + unwrap(ToType), isSigned)); +} + +LLVMValueRef LLVMConstFPCast(LLVMValueRef ConstantVal, LLVMTypeRef ToType) { + return wrap(ConstantExpr::getFPCast(unwrap<Constant>(ConstantVal), + unwrap(ToType))); +} + +LLVMValueRef LLVMConstSelect(LLVMValueRef ConstantCondition, + LLVMValueRef ConstantIfTrue, + LLVMValueRef ConstantIfFalse) { + return wrap(ConstantExpr::getSelect(unwrap<Constant>(ConstantCondition), + unwrap<Constant>(ConstantIfTrue), + unwrap<Constant>(ConstantIfFalse))); +} + +LLVMValueRef LLVMConstExtractElement(LLVMValueRef VectorConstant, + LLVMValueRef IndexConstant) { + return wrap(ConstantExpr::getExtractElement(unwrap<Constant>(VectorConstant), + unwrap<Constant>(IndexConstant))); +} + +LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, + LLVMValueRef ElementValueConstant, + LLVMValueRef IndexConstant) { + return wrap(ConstantExpr::getInsertElement(unwrap<Constant>(VectorConstant), + unwrap<Constant>(ElementValueConstant), + unwrap<Constant>(IndexConstant))); +} + +LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, + LLVMValueRef VectorBConstant, + LLVMValueRef MaskConstant) { + return wrap(ConstantExpr::getShuffleVector(unwrap<Constant>(VectorAConstant), + unwrap<Constant>(VectorBConstant), + unwrap<Constant>(MaskConstant))); +} + +LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, + unsigned NumIdx) { + return wrap(ConstantExpr::getExtractValue(unwrap<Constant>(AggConstant), + makeArrayRef(IdxList, NumIdx))); +} + +LLVMValueRef LLVMConstInsertValue(LLVMValueRef AggConstant, + LLVMValueRef ElementValueConstant, + unsigned *IdxList, unsigned NumIdx) { + return wrap(ConstantExpr::getInsertValue(unwrap<Constant>(AggConstant), + unwrap<Constant>(ElementValueConstant), + makeArrayRef(IdxList, NumIdx))); +} + +LLVMValueRef LLVMConstInlineAsm(LLVMTypeRef Ty, const char *AsmString, + const char *Constraints, + LLVMBool HasSideEffects, + LLVMBool IsAlignStack) { + return wrap(InlineAsm::get(dyn_cast<FunctionType>(unwrap(Ty)), AsmString, + Constraints, HasSideEffects, IsAlignStack)); +} + +LLVMValueRef LLVMBlockAddress(LLVMValueRef F, LLVMBasicBlockRef BB) { + return wrap(BlockAddress::get(unwrap<Function>(F), unwrap(BB))); +} + +/*--.. Operations on global variables, functions, and aliases (globals) ....--*/ + +LLVMModuleRef LLVMGetGlobalParent(LLVMValueRef Global) { + return wrap(unwrap<GlobalValue>(Global)->getParent()); +} + +LLVMBool LLVMIsDeclaration(LLVMValueRef Global) { + return unwrap<GlobalValue>(Global)->isDeclaration(); +} + +LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { + switch (unwrap<GlobalValue>(Global)->getLinkage()) { + case GlobalValue::ExternalLinkage: + return LLVMExternalLinkage; + case GlobalValue::AvailableExternallyLinkage: + return LLVMAvailableExternallyLinkage; + case GlobalValue::LinkOnceAnyLinkage: + return LLVMLinkOnceAnyLinkage; + case GlobalValue::LinkOnceODRLinkage: + return LLVMLinkOnceODRLinkage; + case GlobalValue::WeakAnyLinkage: + return LLVMWeakAnyLinkage; + case GlobalValue::WeakODRLinkage: + return LLVMWeakODRLinkage; + case GlobalValue::AppendingLinkage: + return LLVMAppendingLinkage; + case GlobalValue::InternalLinkage: + return LLVMInternalLinkage; + case GlobalValue::PrivateLinkage: + return LLVMPrivateLinkage; + case GlobalValue::ExternalWeakLinkage: + return LLVMExternalWeakLinkage; + case GlobalValue::CommonLinkage: + return LLVMCommonLinkage; + } + + llvm_unreachable("Invalid GlobalValue linkage!"); +} + +void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { + GlobalValue *GV = unwrap<GlobalValue>(Global); + + switch (Linkage) { + case LLVMExternalLinkage: + GV->setLinkage(GlobalValue::ExternalLinkage); + break; + case LLVMAvailableExternallyLinkage: + GV->setLinkage(GlobalValue::AvailableExternallyLinkage); + break; + case LLVMLinkOnceAnyLinkage: + GV->setLinkage(GlobalValue::LinkOnceAnyLinkage); + break; + case LLVMLinkOnceODRLinkage: + GV->setLinkage(GlobalValue::LinkOnceODRLinkage); + break; + case LLVMLinkOnceODRAutoHideLinkage: + DEBUG(errs() << "LLVMSetLinkage(): LLVMLinkOnceODRAutoHideLinkage is no " + "longer supported."); + break; + case LLVMWeakAnyLinkage: + GV->setLinkage(GlobalValue::WeakAnyLinkage); + break; + case LLVMWeakODRLinkage: + GV->setLinkage(GlobalValue::WeakODRLinkage); + break; + case LLVMAppendingLinkage: + GV->setLinkage(GlobalValue::AppendingLinkage); + break; + case LLVMInternalLinkage: + GV->setLinkage(GlobalValue::InternalLinkage); + break; + case LLVMPrivateLinkage: + GV->setLinkage(GlobalValue::PrivateLinkage); + break; + case LLVMLinkerPrivateLinkage: + GV->setLinkage(GlobalValue::PrivateLinkage); + break; + case LLVMLinkerPrivateWeakLinkage: + GV->setLinkage(GlobalValue::PrivateLinkage); + break; + case LLVMDLLImportLinkage: + DEBUG(errs() + << "LLVMSetLinkage(): LLVMDLLImportLinkage is no longer supported."); + break; + case LLVMDLLExportLinkage: + DEBUG(errs() + << "LLVMSetLinkage(): LLVMDLLExportLinkage is no longer supported."); + break; + case LLVMExternalWeakLinkage: + GV->setLinkage(GlobalValue::ExternalWeakLinkage); + break; + case LLVMGhostLinkage: + DEBUG(errs() + << "LLVMSetLinkage(): LLVMGhostLinkage is no longer supported."); + break; + case LLVMCommonLinkage: + GV->setLinkage(GlobalValue::CommonLinkage); + break; + } +} + +const char *LLVMGetSection(LLVMValueRef Global) { + return unwrap<GlobalValue>(Global)->getSection(); +} + +void LLVMSetSection(LLVMValueRef Global, const char *Section) { + unwrap<GlobalObject>(Global)->setSection(Section); +} + +LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { + return static_cast<LLVMVisibility>( + unwrap<GlobalValue>(Global)->getVisibility()); +} + +void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { + unwrap<GlobalValue>(Global) + ->setVisibility(static_cast<GlobalValue::VisibilityTypes>(Viz)); +} + +LLVMDLLStorageClass LLVMGetDLLStorageClass(LLVMValueRef Global) { + return static_cast<LLVMDLLStorageClass>( + unwrap<GlobalValue>(Global)->getDLLStorageClass()); +} + +void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) { + unwrap<GlobalValue>(Global)->setDLLStorageClass( + static_cast<GlobalValue::DLLStorageClassTypes>(Class)); +} + +LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) { + return unwrap<GlobalValue>(Global)->hasUnnamedAddr(); +} + +void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) { + unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr); +} + +/*--.. Operations on global variables, load and store instructions .........--*/ + +unsigned LLVMGetAlignment(LLVMValueRef V) { + Value *P = unwrap<Value>(V); + if (GlobalValue *GV = dyn_cast<GlobalValue>(P)) + return GV->getAlignment(); + if (AllocaInst *AI = dyn_cast<AllocaInst>(P)) + return AI->getAlignment(); + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->getAlignment(); + if (StoreInst *SI = dyn_cast<StoreInst>(P)) + return SI->getAlignment(); + + llvm_unreachable( + "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); +} + +void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes) { + Value *P = unwrap<Value>(V); + if (GlobalObject *GV = dyn_cast<GlobalObject>(P)) + GV->setAlignment(Bytes); + else if (AllocaInst *AI = dyn_cast<AllocaInst>(P)) + AI->setAlignment(Bytes); + else if (LoadInst *LI = dyn_cast<LoadInst>(P)) + LI->setAlignment(Bytes); + else if (StoreInst *SI = dyn_cast<StoreInst>(P)) + SI->setAlignment(Bytes); + else + llvm_unreachable( + "only GlobalValue, AllocaInst, LoadInst and StoreInst have alignment"); +} + +/*--.. Operations on global variables ......................................--*/ + +LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { + return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, + GlobalValue::ExternalLinkage, nullptr, Name)); +} + +LLVMValueRef LLVMAddGlobalInAddressSpace(LLVMModuleRef M, LLVMTypeRef Ty, + const char *Name, + unsigned AddressSpace) { + return wrap(new GlobalVariable(*unwrap(M), unwrap(Ty), false, + GlobalValue::ExternalLinkage, nullptr, Name, + nullptr, GlobalVariable::NotThreadLocal, + AddressSpace)); +} + +LLVMValueRef LLVMGetNamedGlobal(LLVMModuleRef M, const char *Name) { + return wrap(unwrap(M)->getNamedGlobal(Name)); +} + +LLVMValueRef LLVMGetFirstGlobal(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::global_iterator I = Mod->global_begin(); + if (I == Mod->global_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetLastGlobal(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::global_iterator I = Mod->global_end(); + if (I == Mod->global_begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMGetNextGlobal(LLVMValueRef GlobalVar) { + GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar); + Module::global_iterator I(GV); + if (++I == GV->getParent()->global_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetPreviousGlobal(LLVMValueRef GlobalVar) { + GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar); + Module::global_iterator I(GV); + if (I == GV->getParent()->global_begin()) + return nullptr; + return wrap(&*--I); +} + +void LLVMDeleteGlobal(LLVMValueRef GlobalVar) { + unwrap<GlobalVariable>(GlobalVar)->eraseFromParent(); +} + +LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) { + GlobalVariable* GV = unwrap<GlobalVariable>(GlobalVar); + if ( !GV->hasInitializer() ) + return nullptr; + return wrap(GV->getInitializer()); +} + +void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) { + unwrap<GlobalVariable>(GlobalVar) + ->setInitializer(unwrap<Constant>(ConstantVal)); +} + +LLVMBool LLVMIsThreadLocal(LLVMValueRef GlobalVar) { + return unwrap<GlobalVariable>(GlobalVar)->isThreadLocal(); +} + +void LLVMSetThreadLocal(LLVMValueRef GlobalVar, LLVMBool IsThreadLocal) { + unwrap<GlobalVariable>(GlobalVar)->setThreadLocal(IsThreadLocal != 0); +} + +LLVMBool LLVMIsGlobalConstant(LLVMValueRef GlobalVar) { + return unwrap<GlobalVariable>(GlobalVar)->isConstant(); +} + +void LLVMSetGlobalConstant(LLVMValueRef GlobalVar, LLVMBool IsConstant) { + unwrap<GlobalVariable>(GlobalVar)->setConstant(IsConstant != 0); +} + +LLVMThreadLocalMode LLVMGetThreadLocalMode(LLVMValueRef GlobalVar) { + switch (unwrap<GlobalVariable>(GlobalVar)->getThreadLocalMode()) { + case GlobalVariable::NotThreadLocal: + return LLVMNotThreadLocal; + case GlobalVariable::GeneralDynamicTLSModel: + return LLVMGeneralDynamicTLSModel; + case GlobalVariable::LocalDynamicTLSModel: + return LLVMLocalDynamicTLSModel; + case GlobalVariable::InitialExecTLSModel: + return LLVMInitialExecTLSModel; + case GlobalVariable::LocalExecTLSModel: + return LLVMLocalExecTLSModel; + } + + llvm_unreachable("Invalid GlobalVariable thread local mode"); +} + +void LLVMSetThreadLocalMode(LLVMValueRef GlobalVar, LLVMThreadLocalMode Mode) { + GlobalVariable *GV = unwrap<GlobalVariable>(GlobalVar); + + switch (Mode) { + case LLVMNotThreadLocal: + GV->setThreadLocalMode(GlobalVariable::NotThreadLocal); + break; + case LLVMGeneralDynamicTLSModel: + GV->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel); + break; + case LLVMLocalDynamicTLSModel: + GV->setThreadLocalMode(GlobalVariable::LocalDynamicTLSModel); + break; + case LLVMInitialExecTLSModel: + GV->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); + break; + case LLVMLocalExecTLSModel: + GV->setThreadLocalMode(GlobalVariable::LocalExecTLSModel); + break; + } +} + +LLVMBool LLVMIsExternallyInitialized(LLVMValueRef GlobalVar) { + return unwrap<GlobalVariable>(GlobalVar)->isExternallyInitialized(); +} + +void LLVMSetExternallyInitialized(LLVMValueRef GlobalVar, LLVMBool IsExtInit) { + unwrap<GlobalVariable>(GlobalVar)->setExternallyInitialized(IsExtInit); +} + +/*--.. Operations on aliases ......................................--*/ + +LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, + const char *Name) { + auto *PTy = cast<PointerType>(unwrap(Ty)); + return wrap(GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), + GlobalValue::ExternalLinkage, Name, + unwrap<Constant>(Aliasee), unwrap(M))); +} + +/*--.. Operations on functions .............................................--*/ + +LLVMValueRef LLVMAddFunction(LLVMModuleRef M, const char *Name, + LLVMTypeRef FunctionTy) { + return wrap(Function::Create(unwrap<FunctionType>(FunctionTy), + GlobalValue::ExternalLinkage, Name, unwrap(M))); +} + +LLVMValueRef LLVMGetNamedFunction(LLVMModuleRef M, const char *Name) { + return wrap(unwrap(M)->getFunction(Name)); +} + +LLVMValueRef LLVMGetFirstFunction(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::iterator I = Mod->begin(); + if (I == Mod->end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetLastFunction(LLVMModuleRef M) { + Module *Mod = unwrap(M); + Module::iterator I = Mod->end(); + if (I == Mod->begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMGetNextFunction(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Module::iterator I(Func); + if (++I == Func->getParent()->end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetPreviousFunction(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Module::iterator I(Func); + if (I == Func->getParent()->begin()) + return nullptr; + return wrap(&*--I); +} + +void LLVMDeleteFunction(LLVMValueRef Fn) { + unwrap<Function>(Fn)->eraseFromParent(); +} + +LLVMValueRef LLVMGetPersonalityFn(LLVMValueRef Fn) { + return wrap(unwrap<Function>(Fn)->getPersonalityFn()); +} + +void LLVMSetPersonalityFn(LLVMValueRef Fn, LLVMValueRef PersonalityFn) { + unwrap<Function>(Fn)->setPersonalityFn(unwrap<Constant>(PersonalityFn)); +} + +unsigned LLVMGetIntrinsicID(LLVMValueRef Fn) { + if (Function *F = dyn_cast<Function>(unwrap(Fn))) + return F->getIntrinsicID(); + return 0; +} + +unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) { + return unwrap<Function>(Fn)->getCallingConv(); +} + +void LLVMSetFunctionCallConv(LLVMValueRef Fn, unsigned CC) { + return unwrap<Function>(Fn)->setCallingConv( + static_cast<CallingConv::ID>(CC)); +} + +const char *LLVMGetGC(LLVMValueRef Fn) { + Function *F = unwrap<Function>(Fn); + return F->hasGC()? F->getGC().c_str() : nullptr; +} + +void LLVMSetGC(LLVMValueRef Fn, const char *GC) { + Function *F = unwrap<Function>(Fn); + if (GC) + F->setGC(GC); + else + F->clearGC(); +} + +void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { + Function *Func = unwrap<Function>(Fn); + const AttributeSet PAL = Func->getAttributes(); + AttrBuilder B(PA); + const AttributeSet PALnew = + PAL.addAttributes(Func->getContext(), AttributeSet::FunctionIndex, + AttributeSet::get(Func->getContext(), + AttributeSet::FunctionIndex, B)); + Func->setAttributes(PALnew); +} + +void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, + const char *V) { + Function *Func = unwrap<Function>(Fn); + AttributeSet::AttrIndex Idx = + AttributeSet::AttrIndex(AttributeSet::FunctionIndex); + AttrBuilder B; + + B.addAttribute(A, V); + AttributeSet Set = AttributeSet::get(Func->getContext(), Idx, B); + Func->addAttributes(Idx, Set); +} + +void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) { + Function *Func = unwrap<Function>(Fn); + const AttributeSet PAL = Func->getAttributes(); + AttrBuilder B(PA); + const AttributeSet PALnew = + PAL.removeAttributes(Func->getContext(), AttributeSet::FunctionIndex, + AttributeSet::get(Func->getContext(), + AttributeSet::FunctionIndex, B)); + Func->setAttributes(PALnew); +} + +LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + const AttributeSet PAL = Func->getAttributes(); + return (LLVMAttribute)PAL.Raw(AttributeSet::FunctionIndex); +} + +/*--.. Operations on parameters ............................................--*/ + +unsigned LLVMCountParams(LLVMValueRef FnRef) { + // This function is strictly redundant to + // LLVMCountParamTypes(LLVMGetElementType(LLVMTypeOf(FnRef))) + return unwrap<Function>(FnRef)->arg_size(); +} + +void LLVMGetParams(LLVMValueRef FnRef, LLVMValueRef *ParamRefs) { + Function *Fn = unwrap<Function>(FnRef); + for (Function::arg_iterator I = Fn->arg_begin(), + E = Fn->arg_end(); I != E; I++) + *ParamRefs++ = wrap(&*I); +} + +LLVMValueRef LLVMGetParam(LLVMValueRef FnRef, unsigned index) { + Function::arg_iterator AI = unwrap<Function>(FnRef)->arg_begin(); + while (index --> 0) + AI++; + return wrap(&*AI); +} + +LLVMValueRef LLVMGetParamParent(LLVMValueRef V) { + return wrap(unwrap<Argument>(V)->getParent()); +} + +LLVMValueRef LLVMGetFirstParam(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Function::arg_iterator I = Func->arg_begin(); + if (I == Func->arg_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetLastParam(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Function::arg_iterator I = Func->arg_end(); + if (I == Func->arg_begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMGetNextParam(LLVMValueRef Arg) { + Argument *A = unwrap<Argument>(Arg); + Function::arg_iterator I(A); + if (++I == A->getParent()->arg_end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) { + Argument *A = unwrap<Argument>(Arg); + Function::arg_iterator I(A); + if (I == A->getParent()->arg_begin()) + return nullptr; + return wrap(&*--I); +} + +void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) { + Argument *A = unwrap<Argument>(Arg); + AttrBuilder B(PA); + A->addAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B)); +} + +void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) { + Argument *A = unwrap<Argument>(Arg); + AttrBuilder B(PA); + A->removeAttr(AttributeSet::get(A->getContext(), A->getArgNo() + 1, B)); +} + +LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) { + Argument *A = unwrap<Argument>(Arg); + return (LLVMAttribute)A->getParent()->getAttributes(). + Raw(A->getArgNo()+1); +} + + +void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align) { + Argument *A = unwrap<Argument>(Arg); + AttrBuilder B; + B.addAlignmentAttr(align); + A->addAttr(AttributeSet::get(A->getContext(),A->getArgNo() + 1, B)); +} + +/*--.. Operations on basic blocks ..........................................--*/ + +LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB) { + return wrap(static_cast<Value*>(unwrap(BB))); +} + +LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val) { + return isa<BasicBlock>(unwrap(Val)); +} + +LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val) { + return wrap(unwrap<BasicBlock>(Val)); +} + +LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB) { + return wrap(unwrap(BB)->getParent()); +} + +LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB) { + return wrap(unwrap(BB)->getTerminator()); +} + +unsigned LLVMCountBasicBlocks(LLVMValueRef FnRef) { + return unwrap<Function>(FnRef)->size(); +} + +void LLVMGetBasicBlocks(LLVMValueRef FnRef, LLVMBasicBlockRef *BasicBlocksRefs){ + Function *Fn = unwrap<Function>(FnRef); + for (Function::iterator I = Fn->begin(), E = Fn->end(); I != E; I++) + *BasicBlocksRefs++ = wrap(&*I); +} + +LLVMBasicBlockRef LLVMGetEntryBasicBlock(LLVMValueRef Fn) { + return wrap(&unwrap<Function>(Fn)->getEntryBlock()); +} + +LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Function::iterator I = Func->begin(); + if (I == Func->end()) + return nullptr; + return wrap(&*I); +} + +LLVMBasicBlockRef LLVMGetLastBasicBlock(LLVMValueRef Fn) { + Function *Func = unwrap<Function>(Fn); + Function::iterator I = Func->end(); + if (I == Func->begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMBasicBlockRef LLVMGetNextBasicBlock(LLVMBasicBlockRef BB) { + BasicBlock *Block = unwrap(BB); + Function::iterator I(Block); + if (++I == Block->getParent()->end()) + return nullptr; + return wrap(&*I); +} + +LLVMBasicBlockRef LLVMGetPreviousBasicBlock(LLVMBasicBlockRef BB) { + BasicBlock *Block = unwrap(BB); + Function::iterator I(Block); + if (I == Block->getParent()->begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMBasicBlockRef LLVMAppendBasicBlockInContext(LLVMContextRef C, + LLVMValueRef FnRef, + const char *Name) { + return wrap(BasicBlock::Create(*unwrap(C), Name, unwrap<Function>(FnRef))); +} + +LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef FnRef, const char *Name) { + return LLVMAppendBasicBlockInContext(LLVMGetGlobalContext(), FnRef, Name); +} + +LLVMBasicBlockRef LLVMInsertBasicBlockInContext(LLVMContextRef C, + LLVMBasicBlockRef BBRef, + const char *Name) { + BasicBlock *BB = unwrap(BBRef); + return wrap(BasicBlock::Create(*unwrap(C), Name, BB->getParent(), BB)); +} + +LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef BBRef, + const char *Name) { + return LLVMInsertBasicBlockInContext(LLVMGetGlobalContext(), BBRef, Name); +} + +void LLVMDeleteBasicBlock(LLVMBasicBlockRef BBRef) { + unwrap(BBRef)->eraseFromParent(); +} + +void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BBRef) { + unwrap(BBRef)->removeFromParent(); +} + +void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) { + unwrap(BB)->moveBefore(unwrap(MovePos)); +} + +void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos) { + unwrap(BB)->moveAfter(unwrap(MovePos)); +} + +/*--.. Operations on instructions ..........................................--*/ + +LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst) { + return wrap(unwrap<Instruction>(Inst)->getParent()); +} + +LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB) { + BasicBlock *Block = unwrap(BB); + BasicBlock::iterator I = Block->begin(); + if (I == Block->end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB) { + BasicBlock *Block = unwrap(BB); + BasicBlock::iterator I = Block->end(); + if (I == Block->begin()) + return nullptr; + return wrap(&*--I); +} + +LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst) { + Instruction *Instr = unwrap<Instruction>(Inst); + BasicBlock::iterator I(Instr); + if (++I == Instr->getParent()->end()) + return nullptr; + return wrap(&*I); +} + +LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst) { + Instruction *Instr = unwrap<Instruction>(Inst); + BasicBlock::iterator I(Instr); + if (I == Instr->getParent()->begin()) + return nullptr; + return wrap(&*--I); +} + +void LLVMInstructionEraseFromParent(LLVMValueRef Inst) { + unwrap<Instruction>(Inst)->eraseFromParent(); +} + +LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst) { + if (ICmpInst *I = dyn_cast<ICmpInst>(unwrap(Inst))) + return (LLVMIntPredicate)I->getPredicate(); + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst))) + if (CE->getOpcode() == Instruction::ICmp) + return (LLVMIntPredicate)CE->getPredicate(); + return (LLVMIntPredicate)0; +} + +LLVMRealPredicate LLVMGetFCmpPredicate(LLVMValueRef Inst) { + if (FCmpInst *I = dyn_cast<FCmpInst>(unwrap(Inst))) + return (LLVMRealPredicate)I->getPredicate(); + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(unwrap(Inst))) + if (CE->getOpcode() == Instruction::FCmp) + return (LLVMRealPredicate)CE->getPredicate(); + return (LLVMRealPredicate)0; +} + +LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst) { + if (Instruction *C = dyn_cast<Instruction>(unwrap(Inst))) + return map_to_llvmopcode(C->getOpcode()); + return (LLVMOpcode)0; +} + +LLVMValueRef LLVMInstructionClone(LLVMValueRef Inst) { + if (Instruction *C = dyn_cast<Instruction>(unwrap(Inst))) + return wrap(C->clone()); + return nullptr; +} + +/*--.. Call and invoke instructions ........................................--*/ + +unsigned LLVMGetInstructionCallConv(LLVMValueRef Instr) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast<CallInst>(V)) + return CI->getCallingConv(); + if (InvokeInst *II = dyn_cast<InvokeInst>(V)) + return II->getCallingConv(); + llvm_unreachable("LLVMGetInstructionCallConv applies only to call and invoke!"); +} + +void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC) { + Value *V = unwrap(Instr); + if (CallInst *CI = dyn_cast<CallInst>(V)) + return CI->setCallingConv(static_cast<CallingConv::ID>(CC)); + else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) + return II->setCallingConv(static_cast<CallingConv::ID>(CC)); + llvm_unreachable("LLVMSetInstructionCallConv applies only to call and invoke!"); +} + +void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index, + LLVMAttribute PA) { + CallSite Call = CallSite(unwrap<Instruction>(Instr)); + AttrBuilder B(PA); + Call.setAttributes( + Call.getAttributes().addAttributes(Call->getContext(), index, + AttributeSet::get(Call->getContext(), + index, B))); +} + +void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index, + LLVMAttribute PA) { + CallSite Call = CallSite(unwrap<Instruction>(Instr)); + AttrBuilder B(PA); + Call.setAttributes(Call.getAttributes() + .removeAttributes(Call->getContext(), index, + AttributeSet::get(Call->getContext(), + index, B))); +} + +void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, + unsigned align) { + CallSite Call = CallSite(unwrap<Instruction>(Instr)); + AttrBuilder B; + B.addAlignmentAttr(align); + Call.setAttributes(Call.getAttributes() + .addAttributes(Call->getContext(), index, + AttributeSet::get(Call->getContext(), + index, B))); +} + +/*--.. Operations on call instructions (only) ..............................--*/ + +LLVMBool LLVMIsTailCall(LLVMValueRef Call) { + return unwrap<CallInst>(Call)->isTailCall(); +} + +void LLVMSetTailCall(LLVMValueRef Call, LLVMBool isTailCall) { + unwrap<CallInst>(Call)->setTailCall(isTailCall); +} + +/*--.. Operations on terminators ...........................................--*/ + +unsigned LLVMGetNumSuccessors(LLVMValueRef Term) { + return unwrap<TerminatorInst>(Term)->getNumSuccessors(); +} + +LLVMBasicBlockRef LLVMGetSuccessor(LLVMValueRef Term, unsigned i) { + return wrap(unwrap<TerminatorInst>(Term)->getSuccessor(i)); +} + +void LLVMSetSuccessor(LLVMValueRef Term, unsigned i, LLVMBasicBlockRef block) { + return unwrap<TerminatorInst>(Term)->setSuccessor(i,unwrap(block)); +} + +/*--.. Operations on branch instructions (only) ............................--*/ + +LLVMBool LLVMIsConditional(LLVMValueRef Branch) { + return unwrap<BranchInst>(Branch)->isConditional(); +} + +LLVMValueRef LLVMGetCondition(LLVMValueRef Branch) { + return wrap(unwrap<BranchInst>(Branch)->getCondition()); +} + +void LLVMSetCondition(LLVMValueRef Branch, LLVMValueRef Cond) { + return unwrap<BranchInst>(Branch)->setCondition(unwrap(Cond)); +} + +/*--.. Operations on switch instructions (only) ............................--*/ + +LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef Switch) { + return wrap(unwrap<SwitchInst>(Switch)->getDefaultDest()); +} + +/*--.. Operations on phi nodes .............................................--*/ + +void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, + LLVMBasicBlockRef *IncomingBlocks, unsigned Count) { + PHINode *PhiVal = unwrap<PHINode>(PhiNode); + for (unsigned I = 0; I != Count; ++I) + PhiVal->addIncoming(unwrap(IncomingValues[I]), unwrap(IncomingBlocks[I])); +} + +unsigned LLVMCountIncoming(LLVMValueRef PhiNode) { + return unwrap<PHINode>(PhiNode)->getNumIncomingValues(); +} + +LLVMValueRef LLVMGetIncomingValue(LLVMValueRef PhiNode, unsigned Index) { + return wrap(unwrap<PHINode>(PhiNode)->getIncomingValue(Index)); +} + +LLVMBasicBlockRef LLVMGetIncomingBlock(LLVMValueRef PhiNode, unsigned Index) { + return wrap(unwrap<PHINode>(PhiNode)->getIncomingBlock(Index)); +} + + +/*===-- Instruction builders ----------------------------------------------===*/ + +LLVMBuilderRef LLVMCreateBuilderInContext(LLVMContextRef C) { + return wrap(new IRBuilder<>(*unwrap(C))); +} + +LLVMBuilderRef LLVMCreateBuilder(void) { + return LLVMCreateBuilderInContext(LLVMGetGlobalContext()); +} + +void LLVMPositionBuilder(LLVMBuilderRef Builder, LLVMBasicBlockRef Block, + LLVMValueRef Instr) { + BasicBlock *BB = unwrap(Block); + Instruction *I = Instr? unwrap<Instruction>(Instr) : (Instruction*) BB->end(); + unwrap(Builder)->SetInsertPoint(BB, I->getIterator()); +} + +void LLVMPositionBuilderBefore(LLVMBuilderRef Builder, LLVMValueRef Instr) { + Instruction *I = unwrap<Instruction>(Instr); + unwrap(Builder)->SetInsertPoint(I->getParent(), I->getIterator()); +} + +void LLVMPositionBuilderAtEnd(LLVMBuilderRef Builder, LLVMBasicBlockRef Block) { + BasicBlock *BB = unwrap(Block); + unwrap(Builder)->SetInsertPoint(BB); +} + +LLVMBasicBlockRef LLVMGetInsertBlock(LLVMBuilderRef Builder) { + return wrap(unwrap(Builder)->GetInsertBlock()); +} + +void LLVMClearInsertionPosition(LLVMBuilderRef Builder) { + unwrap(Builder)->ClearInsertionPoint(); +} + +void LLVMInsertIntoBuilder(LLVMBuilderRef Builder, LLVMValueRef Instr) { + unwrap(Builder)->Insert(unwrap<Instruction>(Instr)); +} + +void LLVMInsertIntoBuilderWithName(LLVMBuilderRef Builder, LLVMValueRef Instr, + const char *Name) { + unwrap(Builder)->Insert(unwrap<Instruction>(Instr), Name); +} + +void LLVMDisposeBuilder(LLVMBuilderRef Builder) { + delete unwrap(Builder); +} + +/*--.. Metadata builders ...................................................--*/ + +void LLVMSetCurrentDebugLocation(LLVMBuilderRef Builder, LLVMValueRef L) { + MDNode *Loc = + L ? cast<MDNode>(unwrap<MetadataAsValue>(L)->getMetadata()) : nullptr; + unwrap(Builder)->SetCurrentDebugLocation(DebugLoc(Loc)); +} + +LLVMValueRef LLVMGetCurrentDebugLocation(LLVMBuilderRef Builder) { + LLVMContext &Context = unwrap(Builder)->getContext(); + return wrap(MetadataAsValue::get( + Context, unwrap(Builder)->getCurrentDebugLocation().getAsMDNode())); +} + +void LLVMSetInstDebugLocation(LLVMBuilderRef Builder, LLVMValueRef Inst) { + unwrap(Builder)->SetInstDebugLocation(unwrap<Instruction>(Inst)); +} + + +/*--.. Instruction builders ................................................--*/ + +LLVMValueRef LLVMBuildRetVoid(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateRetVoid()); +} + +LLVMValueRef LLVMBuildRet(LLVMBuilderRef B, LLVMValueRef V) { + return wrap(unwrap(B)->CreateRet(unwrap(V))); +} + +LLVMValueRef LLVMBuildAggregateRet(LLVMBuilderRef B, LLVMValueRef *RetVals, + unsigned N) { + return wrap(unwrap(B)->CreateAggregateRet(unwrap(RetVals), N)); +} + +LLVMValueRef LLVMBuildBr(LLVMBuilderRef B, LLVMBasicBlockRef Dest) { + return wrap(unwrap(B)->CreateBr(unwrap(Dest))); +} + +LLVMValueRef LLVMBuildCondBr(LLVMBuilderRef B, LLVMValueRef If, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Else) { + return wrap(unwrap(B)->CreateCondBr(unwrap(If), unwrap(Then), unwrap(Else))); +} + +LLVMValueRef LLVMBuildSwitch(LLVMBuilderRef B, LLVMValueRef V, + LLVMBasicBlockRef Else, unsigned NumCases) { + return wrap(unwrap(B)->CreateSwitch(unwrap(V), unwrap(Else), NumCases)); +} + +LLVMValueRef LLVMBuildIndirectBr(LLVMBuilderRef B, LLVMValueRef Addr, + unsigned NumDests) { + return wrap(unwrap(B)->CreateIndirectBr(unwrap(Addr), NumDests)); +} + +LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, + const char *Name) { + return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch), + makeArrayRef(unwrap(Args), NumArgs), + Name)); +} + +LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef PersFn, unsigned NumClauses, + const char *Name) { + // The personality used to live on the landingpad instruction, but now it + // lives on the parent function. For compatibility, take the provided + // personality and put it on the parent function. + if (PersFn) + unwrap(B)->GetInsertBlock()->getParent()->setPersonalityFn( + cast<Function>(unwrap(PersFn))); + return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), NumClauses, Name)); +} + +LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) { + return wrap(unwrap(B)->CreateResume(unwrap(Exn))); +} + +LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) { + return wrap(unwrap(B)->CreateUnreachable()); +} + +void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, + LLVMBasicBlockRef Dest) { + unwrap<SwitchInst>(Switch)->addCase(unwrap<ConstantInt>(OnVal), unwrap(Dest)); +} + +void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) { + unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest)); +} + +void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal) { + unwrap<LandingPadInst>(LandingPad)-> + addClause(cast<Constant>(unwrap(ClauseVal))); +} + +void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) { + unwrap<LandingPadInst>(LandingPad)->setCleanup(Val); +} + +/*--.. Arithmetic ..........................................................--*/ + +LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNSWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNSWAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNUWAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNUWAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFAdd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNSWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNSWSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNUWSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNUWSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFSub(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFSub(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNSWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNSWMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNUWMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateNUWMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFMul(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFMul(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildUDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateUDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildExactSDiv(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreateExactSDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFDiv(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFDiv(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildURem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateURem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildSRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateSRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFRem(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFRem(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildShl(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateShl(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildLShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateLShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAShr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAShr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAnd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateAnd(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildOr(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateOr(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildXor(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateXor(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildBinOp(LLVMBuilderRef B, LLVMOpcode Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateBinOp(Instruction::BinaryOps(map_from_llvmopcode(Op)), unwrap(LHS), + unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildNSWNeg(LLVMBuilderRef B, LLVMValueRef V, + const char *Name) { + return wrap(unwrap(B)->CreateNSWNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V, + const char *Name) { + return wrap(unwrap(B)->CreateNUWNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateFNeg(unwrap(V), Name)); +} + +LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) { + return wrap(unwrap(B)->CreateNot(unwrap(V), Name)); +} + +/*--.. Memory ..............................................................--*/ + +LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); + Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, + nullptr, nullptr, ""); + return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); +} + +LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext()); + Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty)); + AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy); + Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(), + ITy, unwrap(Ty), AllocSize, + unwrap(Val), nullptr, ""); + return wrap(unwrap(B)->Insert(Malloc, Twine(Name))); +} + +LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), nullptr, Name)); +} + +LLVMValueRef LLVMBuildArrayAlloca(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef Val, const char *Name) { + return wrap(unwrap(B)->CreateAlloca(unwrap(Ty), unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildFree(LLVMBuilderRef B, LLVMValueRef PointerVal) { + return wrap(unwrap(B)->Insert( + CallInst::CreateFree(unwrap(PointerVal), unwrap(B)->GetInsertBlock()))); +} + +LLVMValueRef LLVMBuildLoad(LLVMBuilderRef B, LLVMValueRef PointerVal, + const char *Name) { + return wrap(unwrap(B)->CreateLoad(unwrap(PointerVal), Name)); +} + +LLVMValueRef LLVMBuildStore(LLVMBuilderRef B, LLVMValueRef Val, + LLVMValueRef PointerVal) { + return wrap(unwrap(B)->CreateStore(unwrap(Val), unwrap(PointerVal))); +} + +static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) { + switch (Ordering) { + case LLVMAtomicOrderingNotAtomic: return NotAtomic; + case LLVMAtomicOrderingUnordered: return Unordered; + case LLVMAtomicOrderingMonotonic: return Monotonic; + case LLVMAtomicOrderingAcquire: return Acquire; + case LLVMAtomicOrderingRelease: return Release; + case LLVMAtomicOrderingAcquireRelease: return AcquireRelease; + case LLVMAtomicOrderingSequentiallyConsistent: + return SequentiallyConsistent; + } + + llvm_unreachable("Invalid LLVMAtomicOrdering value!"); +} + +static LLVMAtomicOrdering mapToLLVMOrdering(AtomicOrdering Ordering) { + switch (Ordering) { + case NotAtomic: return LLVMAtomicOrderingNotAtomic; + case Unordered: return LLVMAtomicOrderingUnordered; + case Monotonic: return LLVMAtomicOrderingMonotonic; + case Acquire: return LLVMAtomicOrderingAcquire; + case Release: return LLVMAtomicOrderingRelease; + case AcquireRelease: return LLVMAtomicOrderingAcquireRelease; + case SequentiallyConsistent: + return LLVMAtomicOrderingSequentiallyConsistent; + } + + llvm_unreachable("Invalid AtomicOrdering value!"); +} + +LLVMValueRef LLVMBuildFence(LLVMBuilderRef B, LLVMAtomicOrdering Ordering, + LLVMBool isSingleThread, const char *Name) { + return wrap( + unwrap(B)->CreateFence(mapFromLLVMOrdering(Ordering), + isSingleThread ? SingleThread : CrossThread, + Name)); +} + +LLVMValueRef LLVMBuildGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name) { + ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices); + return wrap(unwrap(B)->CreateGEP(nullptr, unwrap(Pointer), IdxList, Name)); +} + +LLVMValueRef LLVMBuildInBoundsGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + LLVMValueRef *Indices, unsigned NumIndices, + const char *Name) { + ArrayRef<Value *> IdxList(unwrap(Indices), NumIndices); + return wrap( + unwrap(B)->CreateInBoundsGEP(nullptr, unwrap(Pointer), IdxList, Name)); +} + +LLVMValueRef LLVMBuildStructGEP(LLVMBuilderRef B, LLVMValueRef Pointer, + unsigned Idx, const char *Name) { + return wrap(unwrap(B)->CreateStructGEP(nullptr, unwrap(Pointer), Idx, Name)); +} + +LLVMValueRef LLVMBuildGlobalString(LLVMBuilderRef B, const char *Str, + const char *Name) { + return wrap(unwrap(B)->CreateGlobalString(Str, Name)); +} + +LLVMValueRef LLVMBuildGlobalStringPtr(LLVMBuilderRef B, const char *Str, + const char *Name) { + return wrap(unwrap(B)->CreateGlobalStringPtr(Str, Name)); +} + +LLVMBool LLVMGetVolatile(LLVMValueRef MemAccessInst) { + Value *P = unwrap<Value>(MemAccessInst); + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->isVolatile(); + return cast<StoreInst>(P)->isVolatile(); +} + +void LLVMSetVolatile(LLVMValueRef MemAccessInst, LLVMBool isVolatile) { + Value *P = unwrap<Value>(MemAccessInst); + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->setVolatile(isVolatile); + return cast<StoreInst>(P)->setVolatile(isVolatile); +} + +LLVMAtomicOrdering LLVMGetOrdering(LLVMValueRef MemAccessInst) { + Value *P = unwrap<Value>(MemAccessInst); + AtomicOrdering O; + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + O = LI->getOrdering(); + else + O = cast<StoreInst>(P)->getOrdering(); + return mapToLLVMOrdering(O); +} + +void LLVMSetOrdering(LLVMValueRef MemAccessInst, LLVMAtomicOrdering Ordering) { + Value *P = unwrap<Value>(MemAccessInst); + AtomicOrdering O = mapFromLLVMOrdering(Ordering); + + if (LoadInst *LI = dyn_cast<LoadInst>(P)) + return LI->setOrdering(O); + return cast<StoreInst>(P)->setOrdering(O); +} + +/*--.. Casts ...............................................................--*/ + +LLVMValueRef LLVMBuildTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildZExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateZExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToUI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToUI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPToSI(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPToSI(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildUIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateUIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildSIToFP(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSIToFP(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPTrunc(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPTrunc(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildFPExt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPExt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildPtrToInt(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreatePtrToInt(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildIntToPtr(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateIntToPtr(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateBitCast(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildAddrSpaceCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateAddrSpaceCast(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildZExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateZExtOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildSExtOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateSExtOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildTruncOrBitCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateTruncOrBitCast(unwrap(Val), unwrap(DestTy), + Name)); +} + +LLVMValueRef LLVMBuildCast(LLVMBuilderRef B, LLVMOpcode Op, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateCast(Instruction::CastOps(map_from_llvmopcode(Op)), unwrap(Val), + unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildPointerCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreatePointerCast(unwrap(Val), unwrap(DestTy), Name)); +} + +LLVMValueRef LLVMBuildIntCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateIntCast(unwrap(Val), unwrap(DestTy), + /*isSigned*/true, Name)); +} + +LLVMValueRef LLVMBuildFPCast(LLVMBuilderRef B, LLVMValueRef Val, + LLVMTypeRef DestTy, const char *Name) { + return wrap(unwrap(B)->CreateFPCast(unwrap(Val), unwrap(DestTy), Name)); +} + +/*--.. Comparisons .........................................................--*/ + +LLVMValueRef LLVMBuildICmp(LLVMBuilderRef B, LLVMIntPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateICmp(static_cast<ICmpInst::Predicate>(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, + LLVMValueRef LHS, LLVMValueRef RHS, + const char *Name) { + return wrap(unwrap(B)->CreateFCmp(static_cast<FCmpInst::Predicate>(Op), + unwrap(LHS), unwrap(RHS), Name)); +} + +/*--.. Miscellaneous instructions ..........................................--*/ + +LLVMValueRef LLVMBuildPhi(LLVMBuilderRef B, LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreatePHI(unwrap(Ty), 0, Name)); +} + +LLVMValueRef LLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, + LLVMValueRef *Args, unsigned NumArgs, + const char *Name) { + return wrap(unwrap(B)->CreateCall(unwrap(Fn), + makeArrayRef(unwrap(Args), NumArgs), + Name)); +} + +LLVMValueRef LLVMBuildSelect(LLVMBuilderRef B, LLVMValueRef If, + LLVMValueRef Then, LLVMValueRef Else, + const char *Name) { + return wrap(unwrap(B)->CreateSelect(unwrap(If), unwrap(Then), unwrap(Else), + Name)); +} + +LLVMValueRef LLVMBuildVAArg(LLVMBuilderRef B, LLVMValueRef List, + LLVMTypeRef Ty, const char *Name) { + return wrap(unwrap(B)->CreateVAArg(unwrap(List), unwrap(Ty), Name)); +} + +LLVMValueRef LLVMBuildExtractElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef Index, const char *Name) { + return wrap(unwrap(B)->CreateExtractElement(unwrap(VecVal), unwrap(Index), + Name)); +} + +LLVMValueRef LLVMBuildInsertElement(LLVMBuilderRef B, LLVMValueRef VecVal, + LLVMValueRef EltVal, LLVMValueRef Index, + const char *Name) { + return wrap(unwrap(B)->CreateInsertElement(unwrap(VecVal), unwrap(EltVal), + unwrap(Index), Name)); +} + +LLVMValueRef LLVMBuildShuffleVector(LLVMBuilderRef B, LLVMValueRef V1, + LLVMValueRef V2, LLVMValueRef Mask, + const char *Name) { + return wrap(unwrap(B)->CreateShuffleVector(unwrap(V1), unwrap(V2), + unwrap(Mask), Name)); +} + +LLVMValueRef LLVMBuildExtractValue(LLVMBuilderRef B, LLVMValueRef AggVal, + unsigned Index, const char *Name) { + return wrap(unwrap(B)->CreateExtractValue(unwrap(AggVal), Index, Name)); +} + +LLVMValueRef LLVMBuildInsertValue(LLVMBuilderRef B, LLVMValueRef AggVal, + LLVMValueRef EltVal, unsigned Index, + const char *Name) { + return wrap(unwrap(B)->CreateInsertValue(unwrap(AggVal), unwrap(EltVal), + Index, Name)); +} + +LLVMValueRef LLVMBuildIsNull(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateIsNull(unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildIsNotNull(LLVMBuilderRef B, LLVMValueRef Val, + const char *Name) { + return wrap(unwrap(B)->CreateIsNotNull(unwrap(Val), Name)); +} + +LLVMValueRef LLVMBuildPtrDiff(LLVMBuilderRef B, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name) { + return wrap(unwrap(B)->CreatePtrDiff(unwrap(LHS), unwrap(RHS), Name)); +} + +LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,LLVMAtomicRMWBinOp op, + LLVMValueRef PTR, LLVMValueRef Val, + LLVMAtomicOrdering ordering, + LLVMBool singleThread) { + AtomicRMWInst::BinOp intop; + switch (op) { + case LLVMAtomicRMWBinOpXchg: intop = AtomicRMWInst::Xchg; break; + case LLVMAtomicRMWBinOpAdd: intop = AtomicRMWInst::Add; break; + case LLVMAtomicRMWBinOpSub: intop = AtomicRMWInst::Sub; break; + case LLVMAtomicRMWBinOpAnd: intop = AtomicRMWInst::And; break; + case LLVMAtomicRMWBinOpNand: intop = AtomicRMWInst::Nand; break; + case LLVMAtomicRMWBinOpOr: intop = AtomicRMWInst::Or; break; + case LLVMAtomicRMWBinOpXor: intop = AtomicRMWInst::Xor; break; + case LLVMAtomicRMWBinOpMax: intop = AtomicRMWInst::Max; break; + case LLVMAtomicRMWBinOpMin: intop = AtomicRMWInst::Min; break; + case LLVMAtomicRMWBinOpUMax: intop = AtomicRMWInst::UMax; break; + case LLVMAtomicRMWBinOpUMin: intop = AtomicRMWInst::UMin; break; + } + return wrap(unwrap(B)->CreateAtomicRMW(intop, unwrap(PTR), unwrap(Val), + mapFromLLVMOrdering(ordering), singleThread ? SingleThread : CrossThread)); +} + + +/*===-- Module providers --------------------------------------------------===*/ + +LLVMModuleProviderRef +LLVMCreateModuleProviderForExistingModule(LLVMModuleRef M) { + return reinterpret_cast<LLVMModuleProviderRef>(M); +} + +void LLVMDisposeModuleProvider(LLVMModuleProviderRef MP) { + delete unwrap(MP); +} + + +/*===-- Memory buffers ----------------------------------------------------===*/ + +LLVMBool LLVMCreateMemoryBufferWithContentsOfFile( + const char *Path, + LLVMMemoryBufferRef *OutMemBuf, + char **OutMessage) { + + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path); + if (std::error_code EC = MBOrErr.getError()) { + *OutMessage = strdup(EC.message().c_str()); + return 1; + } + *OutMemBuf = wrap(MBOrErr.get().release()); + return 0; +} + +LLVMBool LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf, + char **OutMessage) { + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getSTDIN(); + if (std::error_code EC = MBOrErr.getError()) { + *OutMessage = strdup(EC.message().c_str()); + return 1; + } + *OutMemBuf = wrap(MBOrErr.get().release()); + return 0; +} + +LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRange( + const char *InputData, + size_t InputDataLength, + const char *BufferName, + LLVMBool RequiresNullTerminator) { + + return wrap(MemoryBuffer::getMemBuffer(StringRef(InputData, InputDataLength), + StringRef(BufferName), + RequiresNullTerminator).release()); +} + +LLVMMemoryBufferRef LLVMCreateMemoryBufferWithMemoryRangeCopy( + const char *InputData, + size_t InputDataLength, + const char *BufferName) { + + return wrap( + MemoryBuffer::getMemBufferCopy(StringRef(InputData, InputDataLength), + StringRef(BufferName)).release()); +} + +const char *LLVMGetBufferStart(LLVMMemoryBufferRef MemBuf) { + return unwrap(MemBuf)->getBufferStart(); +} + +size_t LLVMGetBufferSize(LLVMMemoryBufferRef MemBuf) { + return unwrap(MemBuf)->getBufferSize(); +} + +void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf) { + delete unwrap(MemBuf); +} + +/*===-- Pass Registry -----------------------------------------------------===*/ + +LLVMPassRegistryRef LLVMGetGlobalPassRegistry(void) { + return wrap(PassRegistry::getPassRegistry()); +} + +/*===-- Pass Manager ------------------------------------------------------===*/ + +LLVMPassManagerRef LLVMCreatePassManager() { + return wrap(new legacy::PassManager()); +} + +LLVMPassManagerRef LLVMCreateFunctionPassManagerForModule(LLVMModuleRef M) { + return wrap(new legacy::FunctionPassManager(unwrap(M))); +} + +LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) { + return LLVMCreateFunctionPassManagerForModule( + reinterpret_cast<LLVMModuleRef>(P)); +} + +LLVMBool LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { + return unwrap<legacy::PassManager>(PM)->run(*unwrap(M)); +} + +LLVMBool LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) { + return unwrap<legacy::FunctionPassManager>(FPM)->doInitialization(); +} + +LLVMBool LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) { + return unwrap<legacy::FunctionPassManager>(FPM)->run(*unwrap<Function>(F)); +} + +LLVMBool LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) { + return unwrap<legacy::FunctionPassManager>(FPM)->doFinalization(); +} + +void LLVMDisposePassManager(LLVMPassManagerRef PM) { + delete unwrap(PM); +} + +/*===-- Threading ------------------------------------------------------===*/ + +LLVMBool LLVMStartMultithreaded() { + return LLVMIsMultithreaded(); +} + +void LLVMStopMultithreaded() { +} + +LLVMBool LLVMIsMultithreaded() { + return llvm_is_multithreaded(); +} |
