diff --git a/CHANGELOG b/CHANGELOG index d6ff008..3fd8c03 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ 0.4, in progress: + * Code cleanup, added license headers. * Added llvm.core.load_library_permanently() (Issue #12). * Fix comparison using != (Issue #11). * Instruction.is_terminator added. diff --git a/llvm/__init__.py b/llvm/__init__.py index cb09aaa..2a95cef 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -1,3 +1,33 @@ +# +# Copyright (c) 2008, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + """Common classes related to LLVM. """ diff --git a/llvm/_core.c b/llvm/_core.c index 415df68..ea1ee70 100644 --- a/llvm/_core.c +++ b/llvm/_core.c @@ -1,3 +1,32 @@ +/* + * Copyright (c) 2008, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /* our includes */ #include "wrap.h" @@ -427,13 +456,11 @@ _wrap_obj2none(LLVMViewFunctionCFGOnly, LLVMValueRef) static PyObject * _wLLVMVerifyFunction(PyObject *self, PyObject *args) { - PyObject *obj; LLVMValueRef fn; - if (!PyArg_ParseTuple(args, "O", &obj)) + if (!(fn = (LLVMValueRef)get_object_arg(args))) return NULL; - fn = (LLVMValueRef) PyCObject_AsVoidPtr(obj); return ctor_int(LLVMVerifyFunction(fn, LLVMReturnStatusAction)); } @@ -473,8 +500,8 @@ _wrap_obj2obj(LLVMInstIsArithmeticShift, LLVMValueRef, int) _wrap_obj2obj(LLVMInstIsAssociative, LLVMValueRef, int) _wrap_obj2obj(LLVMInstIsCommutative, LLVMValueRef, int) _wrap_obj2obj(LLVMInstIsTrapping, LLVMValueRef, int) -_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) -_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) +_wrap_obj2obj(LLVMInstGetOpcode, LLVMValueRef, int) +_wrap_obj2str(LLVMInstGetOpcodeName, LLVMValueRef) /*===-- Call Sites (Call or Invoke) --------------------------------------===*/ @@ -493,7 +520,7 @@ static void LLVMAddIncoming1(LLVMValueRef PhiNode, LLVMValueRef IncomingValue, L } _wrap_objobjobj2none(LLVMAddIncoming1, LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef) -_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int) +_wrap_obj2obj(LLVMCountIncoming, LLVMValueRef, int) _wrap_objint2obj(LLVMGetIncomingValue, LLVMValueRef, LLVMValueRef) _wrap_objint2obj(LLVMGetIncomingBlock, LLVMValueRef, LLVMBasicBlockRef) @@ -766,15 +793,13 @@ _wrap_obj2none(LLVMDisposeTargetData, LLVMTargetDataRef) static PyObject * _wLLVMTargetDataAsString(PyObject *self, PyObject *args) { - PyObject *obj; LLVMTargetDataRef td; char *tdrep = 0; PyObject *ret; - if (!PyArg_ParseTuple(args, "O", &obj)) + if (!(td = (LLVMTargetDataRef)get_object_arg(args))) return NULL; - td = (LLVMTargetDataRef) PyCObject_AsVoidPtr(obj); tdrep = LLVMCopyStringRepOfTargetData(td); ret = PyString_FromString(tdrep); LLVMDisposeMessage(tdrep); diff --git a/llvm/_util.py b/llvm/_util.py index 9ea2ecb..090ee5d 100644 --- a/llvm/_util.py +++ b/llvm/_util.py @@ -1,3 +1,33 @@ +# +# Copyright (c) 2008, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + """Utility functions and classes. Used only in other modules, not for public use.""" diff --git a/llvm/core.py b/llvm/core.py index bbc1676..7780ee7 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -1,3 +1,33 @@ +# +# Copyright (c) 2008, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + """Core classes of LLVM. The llvm.core module contains classes and constants required to build the @@ -880,6 +910,8 @@ class Module(llvm.Ownable): return Function.get(self, name) def get_or_insert_function(self, ty, name): + """Like get_function_named(), but does add_function() first, if + function is not present.""" return Function.get_or_insert(self, ty, name) @property @@ -1143,6 +1175,7 @@ class FunctionType(Type): class StructType(Type): + """Represents a structure type.""" def __init__(self, ptr, kind): """DO NOT CALL DIRECTLY. @@ -1152,19 +1185,26 @@ class StructType(Type): @property def element_count(self): + """Number of elements (members) in the structure. + + Same as len(obj.elements), but faster.""" return _core.LLVMCountStructElementTypes(self.ptr) @property def elements(self): + """An iterable that yieldsd Type objects, representing the types of the + elements (members) of the structure, in order.""" pp = _core.LLVMGetStructElementTypes(self.ptr) return [ _make_type(p, _core.LLVMGetTypeKind(p)) for p in pp ] @property def packed(self): + """True if the structure is packed, False otherwise.""" return _core.LLVMIsPackedStruct(self.ptr) != 0 class ArrayType(Type): + """Represents an array type.""" def __init__(self, ptr, kind): """DO NOT CALL DIRECTLY. diff --git a/llvm/ee.py b/llvm/ee.py index 40e63aa..adcc2a7 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -1,3 +1,33 @@ +# +# Copyright (c) 2008, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + """Execution Engine and related classes. """ diff --git a/llvm/extra.cpp b/llvm/extra.cpp index cf5729f..65058bf 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -1,14 +1,46 @@ +/* + * Copyright (c) 2008, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /** * These are some "extra" functions not available in the standard LLVM-C * bindings, but are required / good-to-have inorder to implement the * Python bindings. */ +// standard includes #include #include #include #include +// LLVM includes #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Constants.h" @@ -22,202 +54,271 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/Parser.h" #include "llvm/System/DynamicLibrary.h" -// +includes for passes #include "llvm/PassManager.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" #include "llvm/Transforms/Instrumentation.h" -// -includes for passes +// LLVM-C includes #include "llvm-c/Core.h" +// our includes #include "extra.h" -using namespace llvm; +//using namespace llvm; -char *LLVMDumpModuleToString(LLVMModuleRef M) { - std::ostringstream buf; - unwrap(M)->print(buf); - return strdup(buf.str().c_str()); -} - -char *LLVMDumpTypeToString(LLVMTypeRef Ty) { - std::ostringstream buf; - unwrap(Ty)->print(buf); - return strdup(buf.str().c_str()); -} - -char *LLVMDumpValueToString(LLVMValueRef Val) { - std::ostringstream buf; - unwrap(Val)->print(buf); - return strdup(buf.str().c_str()); -} - -#if 0 /* after LLVM 2.3! */ -LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate, - LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getVICmp(Predicate, - unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate, - LLVMValueRef LHSConstant, LLVMValueRef RHSConstant) { - return wrap(ConstantExpr::getVFCmp(Predicate, - unwrap(LHSConstant), - unwrap(RHSConstant))); -} - -LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef B, LLVMIntPredicate Op, - LLVMValueRef LHS, LLVMValueRef RHS, - const char *Name) { - return wrap(unwrap(B)->CreateVICmp(static_cast(Op), - unwrap(LHS), unwrap(RHS), Name)); -} - -LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef B, LLVMRealPredicate Op, - LLVMValueRef LHS, LLVMValueRef RHS, - const char *Name) { - return wrap(unwrap(B)->CreateVFCmp(static_cast(Op), - unwrap(LHS), unwrap(RHS), Name)); -} -#endif - -unsigned LLVMModuleGetPointerSize(LLVMModuleRef M) +/* Helper method for LLVMDumpXXXToString() methods. */ +template +char *do_print(W obj) { - Module::PointerSize p = unwrap(M)->getPointerSize(); - if (p == Module::Pointer32) + std::ostringstream buf; + UW *p = llvm::unwrap(obj); + assert(p); + p->print(buf); + return strdup(buf.str().c_str()); +} + +char *LLVMDumpModuleToString(LLVMModuleRef module) +{ + return do_print(module); +} + +char *LLVMDumpTypeToString(LLVMTypeRef type) +{ + return do_print(type); +} + +char *LLVMDumpValueToString(LLVMValueRef value) +{ + return do_print(value); +} + +unsigned LLVMModuleGetPointerSize(LLVMModuleRef module) +{ + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + llvm::Module::PointerSize p = modulep->getPointerSize(); + if (p == llvm::Module::Pointer32) return 32; - else if (p == Module::Pointer64) + else if (p == llvm::Module::Pointer64) return 64; return 0; } -LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef M, - const char *Name, LLVMTypeRef FunctionTy) +LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, + const char *name, LLVMTypeRef function_type) { - FunctionType *ft = unwrap(FunctionTy); - Constant *f = unwrap(M)->getOrInsertFunction(Name, ft); + assert(name); + + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + llvm::FunctionType *ftp = llvm::unwrap(function_type); + assert(ftp); + + llvm::Constant *f = modulep->getOrInsertFunction(name, ftp); return wrap(f); } -#define inst_checkfn(ourfn, llvmfn) \ - unsigned ourfn (LLVMValueRef I) { \ - return unwrap(I)-> llvmfn () ? 1 : 0; \ +#define inst_checkfn(ourfn, llvmfn) \ +unsigned ourfn (LLVMValueRef v) { \ + llvm::Instruction *ip = llvm::unwrap(v); \ + assert(ip); \ + return ip-> llvmfn () ? 1 : 0; \ +} + +inst_checkfn(LLVMInstIsTerminator, isTerminator) +inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp) +inst_checkfn(LLVMInstIsShift, isShift) +inst_checkfn(LLVMInstIsCast, isCast) +inst_checkfn(LLVMInstIsLogicalShift, isLogicalShift) +inst_checkfn(LLVMInstIsArithmeticShift, isArithmeticShift) +inst_checkfn(LLVMInstIsAssociative, isAssociative) +inst_checkfn(LLVMInstIsCommutative, isCommutative) +inst_checkfn(LLVMInstIsTrapping, isTrapping) + +const char *LLVMInstGetOpcodeName(LLVMValueRef inst) +{ + llvm::Instruction *instp = llvm::unwrap(inst); + assert(instp); + return instp->getOpcodeName(); +} + +unsigned LLVMInstGetOpcode(LLVMValueRef inst) +{ + llvm::Instruction *instp = llvm::unwrap(inst); + assert(instp); + return instp->getOpcode(); +} + +/* llvm::unwrap a set of `n' wrapped objects starting at `values', + * into a vector of pointers to llvm::unwrapped objects `out'. */ +template +void unwrap_vec(W *values, unsigned n, std::vector& out) +{ + out.clear(); + + while (n--) { + UW *p = llvm::unwrap(*values); + assert(p); + out.push_back(p); + ++values; } +} -inst_checkfn(LLVMInstIsTerminator, isTerminator) -inst_checkfn(LLVMInstIsBinaryOp, isBinaryOp) -inst_checkfn(LLVMInstIsShift, isShift) -inst_checkfn(LLVMInstIsCast, isCast) -inst_checkfn(LLVMInstIsLogicalShift,isLogicalShift) -inst_checkfn(LLVMInstIsArithmeticShift,isArithmeticShift) -inst_checkfn(LLVMInstIsAssociative, isAssociative) -inst_checkfn(LLVMInstIsCommutative, isCommutative) -inst_checkfn(LLVMInstIsTrapping, isTrapping) - -const char *LLVMInstGetOpcodeName(LLVMValueRef I) +/* Same as llvm::unwrap_vec, but use a vector of const pointers. */ +template +void unwrap_cvec(W *values, unsigned n, std::vector& out) { - return unwrap(I)->getOpcodeName(); + out.clear(); + + while (n--) { + UW *p = llvm::unwrap(*values); + assert(p); + out.push_back(p); + ++values; + } } -unsigned LLVMInstGetOpcode(LLVMValueRef I) +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef builder, + LLVMValueRef *values, unsigned n_values) { - return unwrap(I)->getOpcode(); + assert(values); + + std::vector values_vec; + unwrap_vec(values, n_values, values_vec); + + llvm::IRBuilder *builderp = llvm::unwrap(builder); + assert(builderp); + + return wrap(builderp->CreateRet(&values_vec[0], values_vec.size())); } -LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef B, LLVMValueRef *Values, - unsigned NumValues) { - std::vector Vs; - for (LLVMValueRef *I = Values, *E = Values + NumValues; I != E; ++I) - Vs.push_back(unwrap(*I)); - - return wrap(unwrap(B)->CreateRet(&Vs[0], NumValues)); -} - -LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef B, LLVMValueRef V, - unsigned Index, const char *Name) { - return wrap(unwrap(B)->CreateGetResult(unwrap(V), Index, Name)); -} - -LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef M, int ID, - LLVMTypeRef *Types, unsigned Count) +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, + LLVMValueRef value, unsigned index, const char *name) { - std::vector Tys; - for (LLVMTypeRef *I = Types, *E = Types + Count; I != E; ++I) - Tys.push_back(unwrap(*I)); - - Function *intfunc = Intrinsic::getDeclaration(unwrap(M), - Intrinsic::ID(ID), &Tys[0], Count); + assert(name); + + llvm::IRBuilder *builderp = llvm::unwrap(builder); + assert(builderp); + + return wrap(builderp->CreateGetResult(llvm::unwrap(value), index, name)); +} + +LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id, + LLVMTypeRef *types, unsigned n_types) +{ + assert(types); + + std::vector types_vec; + unwrap_cvec(types, n_types, types_vec); + + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + llvm::Function *intfunc = llvm::Intrinsic::getDeclaration(modulep, + llvm::Intrinsic::ID(id), &types_vec[0], types_vec.size()); return wrap(intfunc); } -LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len, - char **OutMessage) +LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtext, unsigned txtlen, + char **out) { - ParseError e; + assert(asmtext); + assert(out); - Module *MP = ParseAssemblyString(A, NULL /*unused within!*/, &e); - if (!MP) { - *OutMessage = strdup(e.getMessage().c_str()); + llvm::Module *modulep; + llvm::ParseError error; + if (!(modulep = llvm::ParseAssemblyString(asmtext, NULL /*unused within!*/, + &error))) { + *out = strdup(error.getMessage().c_str()); return NULL; } - return wrap(MP); + return wrap(modulep); } -LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len, - char **OutMessage) +LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen, + char **out) { - MemoryBuffer *mb = MemoryBuffer::getMemBufferCopy(BC, BC+Len); - if (!mb) + assert(bitcode); + assert(out); + + llvm::MemoryBuffer *mbp; + if (!(mbp = llvm::MemoryBuffer::getMemBufferCopy(bitcode, bitcode+bclen))) return NULL; std::string msg; - LLVMModuleRef mr = wrap(ParseBitcodeFile(mb, &msg)); - if (!mr) - *OutMessage = strdup(msg.c_str()); + llvm::Module *modulep; + if (!(modulep = llvm::ParseBitcodeFile(mbp, &msg))) + *out = strdup(msg.c_str()); - delete mb; - return mr; + delete mbp; + return wrap(modulep); } -unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len) +unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *lenp) { + assert(lenp); + + llvm::Module *modulep = llvm::unwrap(module); + assert(modulep); + + /* get bc into a string */ std::ostringstream buf; - WriteBitcodeToFile(unwrap(M), buf); - const std::string& s = buf.str(); - size_t len = s.size(); - unsigned char *bytes = (unsigned char *)malloc(len); + llvm::WriteBitcodeToFile(modulep, buf); + const std::string& bc = buf.str(); + + /* and then into a malloc()-ed block */ + size_t bclen = bc.size(); + unsigned char *bytes = (unsigned char *)malloc(bclen); if (!bytes) return NULL; - memcpy(bytes, s.data(), len); - *Len = len; + memcpy(bytes, bc.data(), bclen); + + /* return */ + *lenp = bclen; return bytes; } -/* Return 0 on failure (with ErrMsg filled in), 1 on success. */ -unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg) +/* Return 0 on failure (with errmsg filled in), 1 on success. */ +unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg) { - std::string msg; - + assert(filename); + assert(errmsg); + /* Note: the LLVM API returns true on failure. Don't ask why. */ - if (sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) { - *ErrMsg = strdup(msg.c_str()); + std::string msg; + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) { + *errmsg = strdup(msg.c_str()); return 0; } return 1; } -/* passes */ -#define define_pass(P) \ -void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM) { \ - unwrap(PM)->add( create ## P ## Pass ()); \ +/* Passes. A few passes (listed below) are used directly from LLVM-C, + * rest are defined here. + * + * ConstantPropagation + * GVN + * InstructionCombining + * PromoteMemoryToRegister + * Reassociate + * CFGSimplification + */ + +#define define_pass(P) \ +void LLVMAdd ## P ## Pass (LLVMPassManagerRef passmgr) { \ + using namespace llvm; \ + llvm::PassManagerBase *pmp = llvm::unwrap(passmgr); \ + assert(pmp); \ + pmp->add( create ## P ## Pass ()); \ } define_pass( AggressiveDCE ) @@ -227,7 +328,6 @@ define_pass( BreakCriticalEdges ) define_pass( CodeGenPrepare ) define_pass( CondPropagation ) define_pass( ConstantMerge ) -//LLVM-C define_pass( ConstantPropagation ) define_pass( DeadCodeElimination ) define_pass( DeadArgElimination ) define_pass( DeadTypeElimination ) @@ -236,7 +336,6 @@ define_pass( DeadStoreElimination ) define_pass( GCSE ) define_pass( GlobalDCE ) define_pass( GlobalOptimizer ) -//LLVM-C define_pass( GVN ) define_pass( GVNPRE ) define_pass( IndMemRem ) define_pass( IndVarSimplify ) @@ -246,9 +345,8 @@ define_pass( EdgeProfiler ) define_pass( FunctionProfiler ) define_pass( NullProfilerRS ) define_pass( RSProfiling ) -//LLVM-C define_pass( InstructionCombining ) /* we support only internalize(true) */ -ModulePass *createInternalizePass() { return llvm::createInternalizePass(true); } +llvm::ModulePass *createInternalizePass() { return llvm::createInternalizePass(true); } define_pass( Internalize ) define_pass( IPConstantPropagation ) define_pass( IPSCCP ) @@ -268,18 +366,15 @@ define_pass( LowerAllocations ) define_pass( LowerInvoke ) define_pass( LowerSetJmp ) define_pass( LowerSwitch ) -//LLVM-C define_pass( PromoteMemoryToRegister ) define_pass( MemCpyOpt ) define_pass( UnifyFunctionExitNodes ) define_pass( PredicateSimplifier ) define_pass( PruneEH ) define_pass( RaiseAllocations ) -//LLVM-C define_pass( Reassociate ) define_pass( DemoteRegisterToMemory ) define_pass( ScalarReplAggregates ) define_pass( SCCP ) define_pass( SimplifyLibCalls ) -//LLVM-C define_pass( CFGSimplification ) define_pass( StripSymbols ) define_pass( StripDeadPrototypes ) define_pass( StructRetPromotion ) diff --git a/llvm/extra.h b/llvm/extra.h index 5f10582..f592edd 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -1,3 +1,33 @@ +/* + * Copyright (c) 2008, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /** * These are some "extra" functions not available in the standard LLVM-C * bindings, but are required / good-to-have inorder to implement the @@ -11,81 +41,92 @@ extern "C" { #endif -/** Dumps module contents to a string. See Module::print. Free the - returned string with LLVMDisposeMessage, after use. */ -char *LLVMDumpModuleToString(LLVMModuleRef M); +/* Notes: + * - Some returned strings must be disposed of by LLVMDisposeMessage. These are + * indicated in the comments. Where it is not indicated, DO NOT call dispose. + */ -/** Dumps type to a string. See Type::print. Free the returned string with - LLVMDisposeMessage, after use. */ -char *LLVMDumpTypeToString(LLVMTypeRef Ty); +/* Wraps llvm::Module::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ +char *LLVMDumpModuleToString(LLVMModuleRef module); -/** Dumps value to a string. See Value::print. Free the returned string with - LLVMDisposeMessage, after use. */ +/* Wraps llvm::Type::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ +char *LLVMDumpTypeToString(LLVMTypeRef type); + +/* Wraps llvm::Value::print(). Dispose the returned string after use, via + * LLVMDisposeMessage(). */ char *LLVMDumpValueToString(LLVMValueRef Val); -/* missing constant expressions */ +/* Wraps llvm::IRBuilder::CreateRet(). */ +LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values, + unsigned n_values); -#if 0 /* after LLVM 2.3! */ -LLVMValueRef LLVMConstVICmp(LLVMIntPredicate Predicate, - LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); -LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate Predicate, - LLVMValueRef LHSConstant, LLVMValueRef RHSConstant); +/* Wraps llvm::IRBuilder::CreateGetResult(). */ +LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value, + unsigned index, const char *name); -/* missing instructions */ +/* Wraps llvm::Intrinsic::getDeclaration(). */ +LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id, + LLVMTypeRef *types, unsigned n_types); -LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef, LLVMIntPredicate Op, - LLVMValueRef LHS, LLVMValueRef RHS, - const char *Name); -LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef, LLVMRealPredicate Op, - LLVMValueRef LHS, LLVMValueRef RHS, - const char *Name); -#endif +/* Wraps llvm::Module::getPointerSize(). */ +unsigned LLVMModuleGetPointerSize(LLVMModuleRef module); -LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef, LLVMValueRef *Values, - unsigned NumValues); -LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef, LLVMValueRef V, - unsigned Index, const char *Name); +/* Wraps llvm::Module::getOrInsertFunction(). */ +LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, + const char *name, LLVMTypeRef function_type); -/* intrinsics */ +/* The following functions wrap various llvm::Instruction::isXXX() functions. + * All of them take an instruction and return 0 (isXXX returned false) or 1 + * (isXXX returned false). */ +unsigned LLVMInstIsTerminator (LLVMValueRef inst); +unsigned LLVMInstIsBinaryOp (LLVMValueRef inst); +unsigned LLVMInstIsShift (LLVMValueRef inst); +unsigned LLVMInstIsCast (LLVMValueRef inst); +unsigned LLVMInstIsLogicalShift (LLVMValueRef inst); +unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst); +unsigned LLVMInstIsAssociative (LLVMValueRef inst); +unsigned LLVMInstIsCommutative (LLVMValueRef inst); +unsigned LLVMInstIsTrapping (LLVMValueRef inst); -LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef B, int ID, - LLVMTypeRef *Types, unsigned Count); +/* Wraps llvm::Instruction::getOpcodeName(). */ +const char *LLVMInstGetOpcodeName(LLVMValueRef inst); -/* module */ +/* Wraps llvm::Instruction::getOpcode(). */ +unsigned LLVMInstGetOpcode(LLVMValueRef inst); -unsigned LLVMModuleGetPointerSize(LLVMModuleRef M); -LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef M, - const char *Name, LLVMTypeRef FunctionTy); +/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with + * `out' pointing to an error message). Dispose error message after use, via + * LLVMDisposeMessage(). */ +LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, unsigned txten, + char **out); -/* instruction */ +/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with + * `out' pointing to an error message). Dispose error message after use, via + * LLVMDisposeMessage(). */ +LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen, + char **out); -unsigned LLVMInstIsTerminator(LLVMValueRef I); -unsigned LLVMInstIsBinaryOp(LLVMValueRef I); -unsigned LLVMInstIsShift(LLVMValueRef I); -unsigned LLVMInstIsCast(LLVMValueRef I); -unsigned LLVMInstIsLogicalShift(LLVMValueRef I); -unsigned LLVMInstIsArithmeticShift(LLVMValueRef I); -unsigned LLVMInstIsAssociative(LLVMValueRef I); -unsigned LLVMInstIsCommutative(LLVMValueRef I); -unsigned LLVMInstIsTrapping(LLVMValueRef I); +/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code + * for the given module. NULL on error. */ +unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *len); -const char *LLVMInstGetOpcodeName(LLVMValueRef I); -unsigned LLVMInstGetOpcode(LLVMValueRef I); +/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on + * failure (with errmsg filled in) and 1 on success. Dispose error message after + * use, via LLVMDisposeMessage(). */ +unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg); -/* reading llvm "assembly" */ - -LLVMModuleRef LLVMGetModuleFromAssembly(const char *A, unsigned Len, - char **OutMessage); - -/* bitcode related */ - -LLVMModuleRef LLVMGetModuleFromBitcode(const char *BC, unsigned Len, - char **OutMessage); -unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef M, unsigned *Len); - -unsigned LLVMLoadLibraryPermanently(const char* filename, char **ErrMsg); - -/* passes */ +/* Passes. A few passes (listed below) are used directly from LLVM-C, + * rest are declared here. + * + * ConstantPropagation + * GVN + * InstructionCombining + * PromoteMemoryToRegister + * Reassociate + * CFGSimplification + */ #define declare_pass(P) \ void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM); @@ -97,7 +138,6 @@ declare_pass( BreakCriticalEdges ) declare_pass( CodeGenPrepare ) declare_pass( CondPropagation ) declare_pass( ConstantMerge ) -//LLVM-C declare_pass( ConstantPropagation ) declare_pass( DeadCodeElimination ) declare_pass( DeadArgElimination ) declare_pass( DeadTypeElimination ) @@ -106,7 +146,6 @@ declare_pass( DeadStoreElimination ) declare_pass( GCSE ) declare_pass( GlobalDCE ) declare_pass( GlobalOptimizer ) -//LLVM-C declare_pass( GVN ) declare_pass( GVNPRE ) declare_pass( IndMemRem ) declare_pass( IndVarSimplify ) @@ -116,7 +155,6 @@ declare_pass( EdgeProfiler ) declare_pass( FunctionProfiler ) declare_pass( NullProfilerRS ) declare_pass( RSProfiling ) -//LLVM-C declare_pass( InstructionCombining ) declare_pass( Internalize ) declare_pass( IPConstantPropagation ) declare_pass( IPSCCP ) @@ -136,18 +174,15 @@ declare_pass( LowerAllocations ) declare_pass( LowerInvoke ) declare_pass( LowerSetJmp ) declare_pass( LowerSwitch ) -//LLVM-C declare_pass( PromoteMemoryToRegister ) declare_pass( MemCpyOpt ) declare_pass( UnifyFunctionExitNodes ) declare_pass( PredicateSimplifier ) declare_pass( PruneEH ) declare_pass( RaiseAllocations ) -//LLVM-C declare_pass( Reassociate ) declare_pass( DemoteRegisterToMemory ) declare_pass( ScalarReplAggregates ) declare_pass( SCCP ) declare_pass( SimplifyLibCalls ) -//LLVM-C declare_pass( CFGSimplification ) declare_pass( StripSymbols ) declare_pass( StripDeadPrototypes ) declare_pass( StructRetPromotion ) diff --git a/llvm/passes.py b/llvm/passes.py index e2309dd..c9e99b5 100644 --- a/llvm/passes.py +++ b/llvm/passes.py @@ -1,3 +1,33 @@ +# +# Copyright (c) 2008, Mahadevan R All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of this software, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + """Pass managers and passes. This module provides the LLVM pass managers and the passes themselves. diff --git a/llvm/wrap.c b/llvm/wrap.c index 2279ac2..776573b 100644 --- a/llvm/wrap.c +++ b/llvm/wrap.c @@ -1,3 +1,33 @@ +/* + * Copyright (c) 2008, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include "wrap.h" diff --git a/llvm/wrap.h b/llvm/wrap.h index 6ec6b35..5844619 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -1,3 +1,33 @@ +/* + * Copyright (c) 2008, Mahadevan R All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of this software, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + /** * Functions and macros to aid in wrapping. */