From 8b94a14a782867b1da1f272b6f502562d0c2a1aa Mon Sep 17 00:00:00 2001 From: Gordon Henriksen Date: Tue, 18 Sep 2007 03:18:57 +0000 Subject: [PATCH] C bindings for libLLVMCore.a and libLLVMBitWriter.a. - The naming prefix is LLVM. - All types are represented using opaque references. - Functions are not named LLVM{Type}{Method}; the names became unreadable goop. Instead, they are named LLVM{ImperativeSentence}. - Where an attribute only appears once in the class hierarchy (e.g., linkage only applies to values; parameter types only apply to function types), the class is omitted from identifiers for brevity. Tastes like methods. - Strings are C strings or string/length tuples on a case-by-case basis. - APIs which give the caller ownership of an object are not mapped (removeFromParent, certain constructor overloads). This keeps keep memory management as simple as possible. For each library with bindings: llvm-c/.h - Declares the bindings. lib//.cpp - Implements the bindings. So just link with the library of your choice and use the C header instead of the C++ one. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42077 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm-c/BitWriter.h | 42 ++++ include/llvm-c/Core.h | 221 +++++++++++++++++++++ include/llvm/CHelpers.h | 94 +++++++++ lib/Bitcode/Writer/BitWriter.cpp | 51 +++++ lib/VMCore/Core.cpp | 322 +++++++++++++++++++++++++++++++ 5 files changed, 730 insertions(+) create mode 100644 include/llvm-c/BitWriter.h create mode 100644 include/llvm-c/Core.h create mode 100644 include/llvm/CHelpers.h create mode 100644 lib/Bitcode/Writer/BitWriter.cpp create mode 100644 lib/VMCore/Core.cpp diff --git a/include/llvm-c/BitWriter.h b/include/llvm-c/BitWriter.h new file mode 100644 index 00000000000..2f7b466daec --- /dev/null +++ b/include/llvm-c/BitWriter.h @@ -0,0 +1,42 @@ +/*===-- llvm-c/BitWriter.h - BitWriter Library C Interface ------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file was developed by Gordon Henriksen and is distributed under the *| +|* University of Illinois Open Source License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header declares the C interface to libLLVMBitWriter.a, which *| +|* implements output of the LLVM bitcode format. *| +|* *| +|* Many exotic languages can interoperate with C code but have a harder time *| +|* with C++ due to name mangling. So in addition to C, this interface enables *| +|* tools written in such languages. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_BITCODEWRITER_H +#define LLVM_C_BITCODEWRITER_H + +#include "llvm-c/Core.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*===-- Operations on modules ---------------------------------------------===*/ + +/* Writes a module to an open file descriptor. Returns 0 on success. */ +int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int Handle); + +/* Writes a module to the specified path. Returns 0 on success. */ +int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h new file mode 100644 index 00000000000..1442a237d99 --- /dev/null +++ b/include/llvm-c/Core.h @@ -0,0 +1,221 @@ +/*===-- llvm-c/Core.h - Core Library C Interface ------------------*- C -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file was developed by Gordon Henriksen and is distributed under the *| +|* University of Illinois Open Source License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This header declares the C interface to libLLVMCore.a, which implements *| +|* the LLVM intermediate representation. *| +|* *| +|* LLVM uses a polymorphic type hierarchy which C cannot represent, therefore *| +|* parameters must be passed as base types. Despite the declared types, most *| +|* of the functions provided operate only on branches of the type hierarchy. *| +|* The declared parameter names are descriptive and specify which type is *| +|* required. Additionally, each type hierarchy is documented along with the *| +|* functions that operate upon it. For more detail, refer to LLVM's C++ code. *| +|* If in doubt, refer to Core.cpp, which performs paramter downcasts in the *| +|* form unwrap(Param). *| +|* *| +|* Many exotic languages can interoperate with C code but have a harder time *| +|* with C++ due to name mangling. So in addition to C, this interface enables *| +|* tools written in such languages. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_CORE_H +#define LLVM_C_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Opaque types. */ +typedef struct LLVMOpaqueModule *LLVMModuleRef; +typedef struct LLVMOpaqueType *LLVMTypeRef; +typedef struct LLVMOpaqueValue *LLVMValueRef; + +typedef enum { + LLVMVoidTypeKind = 0, /* type with no size */ + LLVMFloatTypeKind, /* 32 bit floating point type */ + LLVMDoubleTypeKind, /* 64 bit floating point type */ + LLVMX86_FP80TypeKind, /* 80 bit floating point type (X87) */ + LLVMFP128TypeKind, /* 128 bit floating point type (112-bit mantissa) */ + LLVMPPC_FP128TypeKind, /* 128 bit floating point type (two 64-bits) */ + LLVMLabelTypeKind, /* Labels */ + LLVMIntegerTypeKind, /* Arbitrary bit width integers */ + LLVMFunctionTypeKind, /* Functions */ + LLVMStructTypeKind, /* Structures */ + LLVMArrayTypeKind, /* Arrays */ + LLVMPointerTypeKind, /* Pointers */ + LLVMOpaqueTypeKind, /* Opaque: type with unknown structure */ + LLVMVectorTypeKind /* SIMD 'packed' format, or other vector type */ +} LLVMTypeKind; + +typedef enum { + LLVMExternalLinkage = 0,/* Externally visible function */ + LLVMLinkOnceLinkage, /* Keep one copy of function when linking (inline) */ + LLVMWeakLinkage, /* Keep one copy of function when linking (weak) */ + LLVMAppendingLinkage, /* Special purpose, only applies to global arrays */ + LLVMInternalLinkage, /* Rename collisions when linking (static functions)*/ + LLVMDLLImportLinkage, /* Function to be imported from DLL */ + LLVMDLLExportLinkage, /* Function to be accessible from DLL */ + LLVMExternalWeakLinkage,/* ExternalWeak linkage description */ + LLVMGhostLinkage /* Stand-in functions for streaming fns from bitcode*/ +} LLVMLinkage; + +typedef enum { + LLVMDefaultVisibility = 0, /* The GV is visible */ + LLVMHiddenVisibility, /* The GV is hidden */ + LLVMProtectedVisibility /* The GV is protected */ +} LLVMVisibility; + + +/*===-- Modules -----------------------------------------------------------===*/ + +/* Create and destroy modules. */ +LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID); +void LLVMDisposeModule(LLVMModuleRef M); + +/* Same as Module::addTypeName. */ +int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty); +int LLVMDeleteTypeName(LLVMModuleRef M, const char *Name); + + +/*===-- Types --------------------------------------------------------------===*/ + +/* LLVM types conform to the following hierarchy: + * + * types: + * integer type + * real type + * function type + * sequence types: + * array type + * pointer type + * vector type + * void type + * label type + * opaque type + */ + +LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty); +void LLVMRefineAbstractType(LLVMTypeRef AbstractType, LLVMTypeRef ConcreteType); + +/* Operations on integer types */ +LLVMTypeRef LLVMInt1Type(); +LLVMTypeRef LLVMInt8Type(); +LLVMTypeRef LLVMInt16Type(); +LLVMTypeRef LLVMInt32Type(); +LLVMTypeRef LLVMInt64Type(); +LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits); +unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy); + +/* Operations on real types */ +LLVMTypeRef LLVMFloatType(); +LLVMTypeRef LLVMDoubleType(); +LLVMTypeRef LLVMX86FP80Type(); +LLVMTypeRef LLVMFP128Type(); +LLVMTypeRef LLVMPPCFP128Type(); + +/* Operations on function types */ +LLVMTypeRef LLVMCreateFunctionType(LLVMTypeRef ReturnType, + LLVMTypeRef *ParamTypes, unsigned ParamCount, + int IsVarArg); +int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy); +LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy); +unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy); +void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest); + +/* Operations on struct types */ +LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes, + unsigned ElementCount, int Packed); +unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy); +void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest); +int LLVMIsPackedStruct(LLVMTypeRef StructTy); + +/* Operations on array, pointer, and vector types (sequence types) */ +LLVMTypeRef LLVMCreateArrayType(LLVMTypeRef ElementType, unsigned ElementCount); +LLVMTypeRef LLVMCreatePointerType(LLVMTypeRef ElementType); +LLVMTypeRef LLVMCreateVectorType(LLVMTypeRef ElementType,unsigned ElementCount); + +LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty); +unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy); +unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy); + +/* Operations on other types */ +LLVMTypeRef LLVMVoidType(); +LLVMTypeRef LLVMLabelType(); +LLVMTypeRef LLVMCreateOpaqueType(); + + +/*===-- Values ------------------------------------------------------------===*/ + +/* The bulk of LLVM's object model consists of values, which comprise a very + * rich type hierarchy. + * + * values: + * constants: + * scalar constants + * composite contants + * globals: + * global variable + * function + * alias + */ + +/* Operations on all values */ +LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val); +const char *LLVMGetValueName(LLVMValueRef Val); +void LLVMSetValueName(LLVMValueRef Val, const char *Name); + +/* Operations on constants of any type */ +LLVMValueRef LLVMGetNull(LLVMTypeRef Ty); /* all zeroes */ +LLVMValueRef LLVMGetAllOnes(LLVMTypeRef Ty); /* only for int/vector */ +LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty); +int LLVMIsNull(LLVMValueRef Val); + +/* Operations on scalar constants */ +LLVMValueRef LLVMGetIntConstant(LLVMTypeRef IntTy, unsigned long long N, + int SignExtend); +LLVMValueRef LLVMGetRealConstant(LLVMTypeRef RealTy, double N); + +/* Operations on composite constants */ +LLVMValueRef LLVMGetStringConstant(const char *Str, unsigned Length, + int DontNullTerminate); +LLVMValueRef LLVMGetArrayConstant(LLVMTypeRef ArrayTy, + LLVMValueRef *ConstantVals, unsigned Length); +LLVMValueRef LLVMGetStructConstant(LLVMValueRef *ConstantVals, unsigned Count, + int packed); +LLVMValueRef LLVMGetVectorConstant(LLVMValueRef *ScalarConstantVals, + unsigned Size); + +/* Operations on global variables, functions, and aliases (globals) */ +int LLVMIsDeclaration(LLVMValueRef Global); +LLVMLinkage LLVMGetLinkage(LLVMValueRef Global); +void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage); +const char *LLVMGetSection(LLVMValueRef Global); +void LLVMSetSection(LLVMValueRef Global, const char *Section); +LLVMVisibility LLVMGetVisibility(LLVMValueRef Global); +void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz); +unsigned LLVMGetAlignment(LLVMValueRef Global); +void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes); + +/* Operations on global variables */ +LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name); +void LLVMDeleteGlobal(LLVMValueRef GlobalVar); +int LLVMHasInitializer(LLVMValueRef GlobalVar); +LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar); +void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal); +int LLVMIsThreadLocal(LLVMValueRef GlobalVar); +void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/llvm/CHelpers.h b/include/llvm/CHelpers.h new file mode 100644 index 00000000000..d00aba383f9 --- /dev/null +++ b/include/llvm/CHelpers.h @@ -0,0 +1,94 @@ +//===-- Support/CHelpers.h - Utilities for writing C bindings -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// These opaque reference<-->pointer conversions are shorter and more tightly +// typed than writing the casts by hand in C bindings. In assert builds, they +// will do type checking. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CHELPERS_H +#define LLVM_SUPPORT_CHELPERS_H + +#include "llvm/Module.h" +#include "llvm/Type.h" +#include "llvm/Value.h" + +typedef struct LLVMOpaqueModule *LLVMModuleRef; +typedef struct LLVMOpaqueType *LLVMTypeRef; +typedef struct LLVMOpaqueValue *LLVMValueRef; + +namespace llvm { + /// Opaque module conversions + /// + inline Module *unwrap(LLVMModuleRef M) { + return reinterpret_cast(M); + } + + inline LLVMModuleRef wrap(Module *M) { + return reinterpret_cast(M); + } + + /// Opaque type conversions + /// + inline Type *unwrap(LLVMTypeRef Ty) { + return reinterpret_cast(Ty); + } + + template + inline T *unwrap(LLVMTypeRef Ty) { + return cast(unwrap(Ty)); + } + + inline Type **unwrap(LLVMTypeRef* Tys) { + return reinterpret_cast(Tys); + } + + inline LLVMTypeRef wrap(const Type *Ty) { + return reinterpret_cast(const_cast(Ty)); + } + + inline LLVMTypeRef *wrap(const Type **Tys) { + return reinterpret_cast(const_cast(Tys)); + } + + /// Opaque value conversions + /// + inline Value *unwrap(LLVMValueRef Val) { + return reinterpret_cast(Val); + } + + template + inline T *unwrap(LLVMValueRef Val) { + return cast(unwrap(Val)); + } + + inline Value **unwrap(LLVMValueRef *Vals) { + return reinterpret_cast(Vals); + } + + template + inline T **unwrap(LLVMValueRef *Vals, unsigned Length) { + #if DEBUG + for (LLVMValueRef *I = Vals, E = Vals + Length; I != E; ++I) + cast(*I); + #endif + return reinterpret_cast(Vals); + } + + inline LLVMValueRef wrap(const Value *Val) { + return reinterpret_cast(const_cast(Val)); + } + + inline LLVMValueRef *wrap(const Value **Vals) { + return reinterpret_cast(const_cast(Vals)); + } +} + +#endif diff --git a/lib/Bitcode/Writer/BitWriter.cpp b/lib/Bitcode/Writer/BitWriter.cpp new file mode 100644 index 00000000000..7b90586fd70 --- /dev/null +++ b/lib/Bitcode/Writer/BitWriter.cpp @@ -0,0 +1,51 @@ +//===-- BitWriter.cpp -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/BitWriter.h" +#include "llvm/CHelpers.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include + +using namespace llvm; + + +/*===-- Operations on modules ---------------------------------------------===*/ + +int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) { + std::ofstream OS(Path); + + if (!OS.fail()) + WriteBitcodeToFile(unwrap(M), OS); + + if (OS.fail()) + return -1; + + return 0; +} + +#ifdef __GNUC__ +#include + +// FIXME: Control this with configure? Provide some portable abstraction in +// libSystem? As is, the user will just get a linker error if they use this on +// non-GCC. Some C++ stdlibs even have ofstream::ofstream(int fd). +int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) { + __gnu_cxx::stdio_filebuf Buffer(FileHandle, std::ios_base::out); + std::ostream OS(&Buffer); + + if (!OS.fail()) + WriteBitcodeToFile(unwrap(M), OS); + + if (OS.fail()) + return -1; + + return 0; +} + +#endif diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp new file mode 100644 index 00000000000..297027fd314 --- /dev/null +++ b/lib/VMCore/Core.cpp @@ -0,0 +1,322 @@ +//===-- Core.cpp ----------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Gordon Henriksen and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the C bindings for libLLVMCore.a, which implements +// the LLVM intermediate representation. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/Core.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/CHelpers.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include +#include +#include + +using namespace llvm; + + +/*===-- Operations on modules ---------------------------------------------===*/ + +LLVMModuleRef LLVMModuleCreateWithName(const char *ModuleID) { + return wrap(new Module(ModuleID)); +} + +void LLVMDisposeModule(LLVMModuleRef M) { + delete unwrap(M); +} + +int LLVMAddTypeName(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) { + return unwrap(M)->addTypeName(Name, unwrap(Ty)); +} + + +/*===-- Operations on types -----------------------------------------------===*/ + +/*--.. Operations on all types (mostly) ....................................--*/ + +LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { + return static_cast(unwrap(Ty)->getTypeID()); +} + +void LLVMRefineAbstractType(LLVMTypeRef AbstractType, LLVMTypeRef ConcreteType){ + DerivedType *Ty = unwrap(AbstractType); + Ty->refineAbstractTypeTo(unwrap(ConcreteType)); +} + +/*--.. Operations on integer types .........................................--*/ + +LLVMTypeRef LLVMInt1Type() { return (LLVMTypeRef) Type::Int1Ty; } +LLVMTypeRef LLVMInt8Type() { return (LLVMTypeRef) Type::Int8Ty; } +LLVMTypeRef LLVMInt16Type() { return (LLVMTypeRef) Type::Int16Ty; } +LLVMTypeRef LLVMInt32Type() { return (LLVMTypeRef) Type::Int32Ty; } +LLVMTypeRef LLVMInt64Type() { return (LLVMTypeRef) Type::Int64Ty; } + +LLVMTypeRef LLVMCreateIntegerType(unsigned NumBits) { + return wrap(IntegerType::get(NumBits)); +} + +unsigned LLVMGetIntegerTypeWidth(LLVMTypeRef IntegerTy) { + return unwrap(IntegerTy)->getBitWidth(); +} + +/*--.. Operations on real types ............................................--*/ + +LLVMTypeRef LLVMFloatType() { return (LLVMTypeRef) Type::FloatTy; } +LLVMTypeRef LLVMDoubleType() { return (LLVMTypeRef) Type::DoubleTy; } +LLVMTypeRef LLVMX86FP80Type() { return (LLVMTypeRef) Type::X86_FP80Ty; } +LLVMTypeRef LLVMFP128Type() { return (LLVMTypeRef) Type::FP128Ty; } +LLVMTypeRef LLVMPPCFP128Type() { return (LLVMTypeRef) Type::PPC_FP128Ty; } + +/*--.. Operations on function types ........................................--*/ + +LLVMTypeRef LLVMCreateFunctionType(LLVMTypeRef ReturnType, + LLVMTypeRef *ParamTypes, unsigned ParamCount, + int IsVarArg) { + std::vector Tys; + for (LLVMTypeRef *I = ParamTypes, *E = ParamTypes + ParamCount; I != E; ++I) + Tys.push_back(unwrap(*I)); + + return wrap(FunctionType::get(unwrap(ReturnType), Tys, IsVarArg != 0)); +} + +int LLVMIsFunctionVarArg(LLVMTypeRef FunctionTy) { + return unwrap(FunctionTy)->isVarArg(); +} + +LLVMTypeRef LLVMGetFunctionReturnType(LLVMTypeRef FunctionTy) { + return wrap(unwrap(FunctionTy)->getReturnType()); +} + +unsigned LLVMGetFunctionParamCount(LLVMTypeRef FunctionTy) { + return unwrap(FunctionTy)->getNumParams(); +} + +void LLVMGetFunctionParamTypes(LLVMTypeRef FunctionTy, LLVMTypeRef *Dest) { + FunctionType *Ty = unwrap(FunctionTy); + for (FunctionType::param_iterator I = Ty->param_begin(), + E = Ty->param_end(); I != E; ++I) + *Dest++ = wrap(*I); +} + +/*--.. Operations on struct types ..........................................--*/ + +LLVMTypeRef LLVMCreateStructType(LLVMTypeRef *ElementTypes, + unsigned ElementCount, int Packed) { + std::vector Tys; + for (LLVMTypeRef *I = ElementTypes, + *E = ElementTypes + ElementCount; I != E; ++I) + Tys.push_back(unwrap(*I)); + + return wrap(StructType::get(Tys, Packed != 0)); +} + +unsigned LLVMGetStructElementCount(LLVMTypeRef StructTy) { + return unwrap(StructTy)->getNumElements(); +} + +void LLVMGetStructElementTypes(LLVMTypeRef StructTy, LLVMTypeRef *Dest) { + StructType *Ty = unwrap(StructTy); + for (FunctionType::param_iterator I = Ty->element_begin(), + E = Ty->element_end(); I != E; ++I) + *Dest++ = wrap(*I); +} + +int LLVMIsPackedStruct(LLVMTypeRef StructTy) { + return unwrap(StructTy)->isPacked(); +} + +/*--.. Operations on array, pointer, and vector types (sequence types) .....--*/ + +LLVMTypeRef LLVMCreateArrayType(LLVMTypeRef ElementType, unsigned ElementCount){ + return wrap(ArrayType::get(unwrap(ElementType), ElementCount)); +} + +LLVMTypeRef LLVMCreatePointerType(LLVMTypeRef ElementType) { + return wrap(PointerType::get(unwrap(ElementType))); +} + +LLVMTypeRef LLVMCreateVectorType(LLVMTypeRef ElementType,unsigned ElementCount){ + return wrap(VectorType::get(unwrap(ElementType), ElementCount)); +} + +LLVMTypeRef LLVMGetElementType(LLVMTypeRef Ty) { + return wrap(unwrap(Ty)->getElementType()); +} + +unsigned LLVMGetArrayLength(LLVMTypeRef ArrayTy) { + return unwrap(ArrayTy)->getNumElements(); +} + +unsigned LLVMGetVectorSize(LLVMTypeRef VectorTy) { + return unwrap(VectorTy)->getNumElements(); +} + +/*--.. Operations on other types ...........................................--*/ + +LLVMTypeRef LLVMVoidType() { return (LLVMTypeRef) Type::VoidTy; } +LLVMTypeRef LLVMLabelType() { return (LLVMTypeRef) Type::LabelTy; } + +LLVMTypeRef LLVMCreateOpaqueType() { + return wrap(llvm::OpaqueType::get()); +} + + +/*===-- Operations on values ----------------------------------------------===*/ + +/*--.. Operations on all values ............................................--*/ + +LLVMTypeRef LLVMGetTypeOfValue(LLVMValueRef Val) { + return wrap(unwrap(Val)->getType()); +} + +const char *LLVMGetValueName(LLVMValueRef Val) { + return unwrap(Val)->getNameStart(); +} + +void LLVMSetValueName(LLVMValueRef Val, const char *Name) { + unwrap(Val)->setName(Name); +} + +/*--.. Operations on constants of any type .................................--*/ + +LLVMValueRef LLVMGetNull(LLVMTypeRef Ty) { + return wrap(Constant::getNullValue(unwrap(Ty))); +} + +LLVMValueRef LLVMGetAllOnes(LLVMTypeRef Ty) { + return wrap(Constant::getAllOnesValue(unwrap(Ty))); +} + +LLVMValueRef LLVMGetUndef(LLVMTypeRef Ty) { + return wrap(UndefValue::get(unwrap(Ty))); +} + +int LLVMIsNull(LLVMValueRef Val) { + if (Constant *C = dyn_cast(unwrap(Val))) + return C->isNullValue(); + return false; +} + +/*--.. Operations on scalar constants ......................................--*/ + +LLVMValueRef LLVMGetIntConstant(LLVMTypeRef IntTy, unsigned long long N, + int SignExtend) { + return wrap(ConstantInt::get(unwrap(IntTy), N, SignExtend != 0)); +} + +LLVMValueRef LLVMGetRealConstant(LLVMTypeRef RealTy, double N) { + return wrap(ConstantFP::get(unwrap(RealTy), APFloat(N))); +} + +/*--.. Operations on composite constants ...................................--*/ + +LLVMValueRef LLVMGetStringConstant(const char *Str, unsigned Length, + int DontNullTerminate) { + /* Inverted the sense of AddNull because ', 0)' is a + better mnemonic for null termination than ', 1)'. */ + return wrap(ConstantArray::get(std::string(Str, Length), + DontNullTerminate == 0)); +} + +LLVMValueRef LLVMGetArrayConstant(LLVMTypeRef ElementTy, + LLVMValueRef *ConstantVals, unsigned Length) { + return wrap(ConstantArray::get(ArrayType::get(unwrap(ElementTy), Length), + unwrap(ConstantVals, Length), + Length)); +} + +LLVMValueRef LLVMGetStructConstant(LLVMValueRef *ConstantVals, unsigned Count, + int Packed) { + return wrap(ConstantStruct::get(unwrap(ConstantVals, Count), + Count, Packed != 0)); +} + +LLVMValueRef LLVMGetVectorConstant(LLVMValueRef *ScalarConstantVals, + unsigned Size) { + return wrap(ConstantVector::get(unwrap(ScalarConstantVals, Size), + Size)); +} + +/*--.. Operations on global variables, functions, and aliases (globals) ....--*/ + +int LLVMIsDeclaration(LLVMValueRef Global) { + return unwrap(Global)->isDeclaration(); +} + +LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { + return static_cast(unwrap(Global)->getLinkage()); +} + +void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { + unwrap(Global) + ->setLinkage(static_cast(Linkage)); +} + +const char *LLVMGetSection(LLVMValueRef Global) { + return unwrap(Global)->getSection().c_str(); +} + +void LLVMSetSection(LLVMValueRef Global, const char *Section) { + unwrap(Global)->setSection(Section); +} + +LLVMVisibility LLVMGetVisibility(LLVMValueRef Global) { + return static_cast( + unwrap(Global)->getVisibility()); +} + +void LLVMSetVisibility(LLVMValueRef Global, LLVMVisibility Viz) { + unwrap(Global) + ->setVisibility(static_cast(Viz)); +} + +unsigned LLVMGetAlignment(LLVMValueRef Global) { + return unwrap(Global)->getAlignment(); +} + +void LLVMSetAlignment(LLVMValueRef Global, unsigned Bytes) { + unwrap(Global)->setAlignment(Bytes); +} + +/*--.. Operations on global variables ......................................--*/ + +LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { + return wrap(new GlobalVariable(unwrap(Ty), false, + GlobalValue::ExternalLinkage, 0, Name, unwrap(M))); +} + +void LLVMDeleteGlobal(LLVMValueRef GlobalVar) { + unwrap(GlobalVar)->eraseFromParent(); +} + +int LLVMHasInitializer(LLVMValueRef GlobalVar) { + return unwrap(GlobalVar)->hasInitializer(); +} + +LLVMValueRef LLVMGetInitializer(LLVMValueRef GlobalVar) { + return wrap(unwrap(GlobalVar)->getInitializer()); +} + +void LLVMSetInitializer(LLVMValueRef GlobalVar, LLVMValueRef ConstantVal) { + unwrap(GlobalVar) + ->setInitializer(unwrap(ConstantVal)); +} + +int LLVMIsThreadLocal(LLVMValueRef GlobalVar) { + return unwrap(GlobalVar)->isThreadLocal(); +} + +void LLVMSetThreadLocal(LLVMValueRef GlobalVar, int IsThreadLocal) { + unwrap(GlobalVar)->setThreadLocal(IsThreadLocal != 0); +} + -- 2.34.1