//===-- examples/ExceptionDemo/ExceptionDemo.cpp - 
//                      An example use of the llvm Exception mechanism --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===--------------------------------------------------------------------===//
//
// Demo program which implements an example LLVM exception implementation, and
// shows several test cases including the handling of foreign exceptions.
// It is run with type info types arguments to throw. A test will
// be run for each given type info type. While type info types with the value 
// of -1 will trigger a foreign C++ exception to be thrown; type info types
// <= 6 and >= 1 will cause the associated generated exceptions to be thrown 
// and caught by generated test functions; and type info types > 6
// will result in exceptions which pass through to the test harness. All other
// type info types are not supported and could cause a crash. In all cases,
// the "finally" blocks of every generated test functions will executed 
// regardless of whether or not that test function ignores or catches the
// thrown exception.
//
// examples:
//
// ExceptionDemo
//
//     causes a usage to be printed to stderr
// 
// ExceptionDemo 2 3 7 -1
//
//     results in the following cases:
//         - Value 2 causes an exception with a type info type of 2 to be 
//           thrown and caught by an inner generated test function.
//         - Value 3 causes an exception with a type info type of 3 to be 
//           thrown and caught by an outer generated test function.
//         - Value 7 causes an exception with a type info type of 7 to be 
//           thrown and NOT be caught by any generated function.
//         - Value -1 causes a foreign C++ exception to be thrown and not be
//           caught by any generated function
//
//     Cases -1 and 7 are caught by a C++ test harness where the validity of
//         of a C++ catch(...) clause catching a generated exception with a 
//         type info type of 7 is questionable.
//
// This code uses code from the llvm compiler-rt project and the llvm 
// Kaleidoscope project.
//
//===--------------------------------------------------------------------===//


#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/Dwarf.h"

#include <cstdio>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <stdexcept>


#ifndef USE_GLOBAL_STR_CONSTS
#define USE_GLOBAL_STR_CONSTS true
#endif

// System C++ ABI unwind types from: 
//     http://refspecs.freestandards.org/abi-eh-1.21.html

extern "C" {

typedef enum {
    _URC_NO_REASON = 0,
    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
    _URC_FATAL_PHASE2_ERROR = 2,
    _URC_FATAL_PHASE1_ERROR = 3,
    _URC_NORMAL_STOP = 4,
    _URC_END_OF_STACK = 5,
    _URC_HANDLER_FOUND = 6,
    _URC_INSTALL_CONTEXT = 7,
    _URC_CONTINUE_UNWIND = 8
} _Unwind_Reason_Code;

typedef enum {
    _UA_SEARCH_PHASE = 1,
    _UA_CLEANUP_PHASE = 2,
    _UA_HANDLER_FRAME = 4,
    _UA_FORCE_UNWIND = 8,
    _UA_END_OF_STACK = 16
} _Unwind_Action;

struct _Unwind_Exception;

typedef void (*_Unwind_Exception_Cleanup_Fn) (_Unwind_Reason_Code,
                                              struct _Unwind_Exception *);

struct _Unwind_Exception {
    uint64_t exception_class;
    _Unwind_Exception_Cleanup_Fn exception_cleanup;

    uintptr_t private_1;    
    uintptr_t private_2;    

    // @@@ The IA-64 ABI says that this structure must be double-word aligned.
    //  Taking that literally does not make much sense generically.  Instead 
    //  we provide the maximum alignment required by any type for the machine.
} __attribute__((__aligned__));

struct _Unwind_Context;
typedef struct _Unwind_Context* _Unwind_Context_t;

extern const uint8_t* _Unwind_GetLanguageSpecificData (_Unwind_Context_t c);
extern uintptr_t _Unwind_GetGR (_Unwind_Context_t c, int i);
extern void _Unwind_SetGR (_Unwind_Context_t c, int i, uintptr_t n);
extern void _Unwind_SetIP (_Unwind_Context_t, uintptr_t new_value);
extern uintptr_t _Unwind_GetIP (_Unwind_Context_t context);
extern uintptr_t _Unwind_GetRegionStart (_Unwind_Context_t context);

} // extern "C"

//
// Example types
//

/// This is our simplistic type info
struct OurExceptionType_t {
    /// type info type
    int type;
};


/// This is our Exception class which relies on a negative offset to calculate
/// pointers to its instances from pointers to its unwindException member.
/// 
/// Note: The above unwind.h defines struct _Unwind_Exception to be aligned
///       on a double word boundary. This is necessary to match the standard:
///       http://refspecs.freestandards.org/abi-eh-1.21.html
struct OurBaseException_t {
    struct OurExceptionType_t type;

    // Note: This is properly aligned in unwind.h
    struct _Unwind_Exception unwindException;
};


// Note: Not needed since we are C++
typedef struct OurBaseException_t OurException;
typedef struct _Unwind_Exception OurUnwindException;

//
// Various globals used to support typeinfo and generatted exceptions in 
// general
//

static std::map<std::string, llvm::Value*> namedValues;

int64_t ourBaseFromUnwindOffset;

const unsigned char ourBaseExcpClassChars[] = 
                                {'o', 'b', 'j', '\0', 'b', 'a', 's', '\0'};


static uint64_t ourBaseExceptionClass = 0;

static std::vector<std::string> ourTypeInfoNames;
static std::map<int, std::string> ourTypeInfoNamesIndex;

static llvm::StructType* ourTypeInfoType;
static llvm::StructType* ourExceptionType;
static llvm::StructType* ourUnwindExceptionType;

static llvm::ConstantInt* ourExceptionNotThrownState;
static llvm::ConstantInt* ourExceptionThrownState;
static llvm::ConstantInt* ourExceptionCaughtState;

typedef std::vector<std::string> ArgNames;
typedef std::vector<const llvm::Type*> ArgTypes;

//
// Code Generation Utilities
//

/// Utility used to create a function, both declarations and definitions
/// @param module for module instance
/// @param retType function return type
/// @param theArgTypes function's ordered argument types
/// @param theArgNames function's ordered arguments needed if use of this
///        function corresponds to a function definition. Use empty 
///        aggregate for function declarations.
/// @param functName function name
/// @param linkage function linkage
/// @param declarationOnly for function declarations
/// @param isVarArg function uses vararg arguments
/// @returns function instance
llvm::Function *createFunction(llvm::Module& module,
                               const llvm::Type* retType,
                               const ArgTypes& theArgTypes,
                               const ArgNames& theArgNames,
                               const std::string& functName,
                               llvm::GlobalValue::LinkageTypes linkage,
                               bool declarationOnly,
                               bool isVarArg) {
    llvm::FunctionType* functType = llvm::FunctionType::get(retType, 
                                                            theArgTypes, 
                                                            isVarArg);
    llvm::Function* ret = llvm::Function::Create(functType, 
                                                 linkage, 
                                                 functName, 
                                                 &module);
    if (!ret || declarationOnly)
        return(ret);

    namedValues.clear();
    unsigned i = 0; 
    for (llvm::Function::arg_iterator argIndex = ret->arg_begin();
         i != theArgNames.size();
         ++argIndex, ++i) {

        argIndex->setName(theArgNames[i]);
        namedValues[theArgNames[i]] = argIndex;
    }

    return(ret);
}


/// Create an alloca instruction in the entry block of
/// the parent function.  This is used for mutable variables etc.
/// @param function parent instance
/// @param varName stack variable name
/// @param type stack variable type
/// @param initWith optional constant initialization value
/// @returns AllocaInst instance
static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function& function,
                                            const std::string &varName,
                                            const llvm::Type* type,
                                            llvm::Constant* initWith = NULL) {
    llvm::BasicBlock& block = function.getEntryBlock(); 
    llvm::IRBuilder<> tmp(&block, block.begin());
    llvm::AllocaInst* ret = tmp.CreateAlloca(type, 0, varName.c_str());

    if (initWith) 
        tmp.CreateStore(initWith, ret);

    return(ret);
}


//
// Code Generation Utilities End
//

//
// Runtime C Library functions 
//

// Note: using an extern "C" block so that static functions can be used
extern "C" {

// Note: Better ways to decide on bit width
//
/// Prints a 32 bit number, according to the format, to stderr.
/// @param intToPrint integer to print 
/// @param format printf like format to use when printing
void print32Int(int intToPrint, const char* format) {
    if (format) {
        // Note: No NULL check
        fprintf(stderr, format, intToPrint);
    }
    else {
        // Note: No NULL check
        fprintf(stderr, "::print32Int(...):NULL arg.\n");
    }
}


// Note: Better ways to decide on bit width
//
/// Prints a 64 bit number, according to the format, to stderr.
/// @param intToPrint integer to print 
/// @param format printf like format to use when printing
void print64Int(long int intToPrint, const char* format) {
    if (format) {
        // Note: No NULL check
        fprintf(stderr, format, intToPrint);
    }
    else {
        // Note: No NULL check
        fprintf(stderr, "::print64Int(...):NULL arg.\n");
    }
}


/// Prints a C string to stderr
/// @param toPrint string to print
void printStr(char* toPrint) {
    if (toPrint) {
        fprintf(stderr, "%s", toPrint);
    }
    else {
        fprintf(stderr, "::printStr(...):NULL arg.\n");
    }
}


/// Deletes the true previosly allocated exception whose address
/// is calculated from the supplied OurBaseException_t::unwindException
/// member address. Handles (ignores), NULL pointers.
/// @param expToDelete exception to delete
void deleteOurException(OurUnwindException* expToDelete) {
#ifdef DEBUG
    fprintf(stderr,
            "deleteOurException(...).\n");
#endif

    if (expToDelete &&
        (expToDelete->exception_class == ourBaseExceptionClass)) {

        free(((char*) expToDelete) + ourBaseFromUnwindOffset);
    }
}


/// This function is the struct _Unwind_Exception API mandated delete function 
/// used by foreign exception handlers when deleting our exception 
/// (OurException), instances.
/// @param reason @link http://refspecs.freestandards.org/abi-eh-1.21.html 
/// @unlink
/// @param expToDelete exception instance to delete
void deleteFromUnwindOurException(_Unwind_Reason_Code reason,
                                  OurUnwindException* expToDelete) {
#ifdef DEBUG
    fprintf(stderr,
            "deleteFromUnwindOurException(...).\n");
#endif

    deleteOurException(expToDelete);
}


/// Creates (allocates on the heap), an exception (OurException instance),
/// of the supplied type info type.
/// @param type type info type
OurUnwindException* createOurException(int type) {
    size_t size = sizeof(OurException);
    OurException* ret = (OurException*) memset(malloc(size), 0, size);
    (ret->type).type = type;
    (ret->unwindException).exception_class = ourBaseExceptionClass;
    (ret->unwindException).exception_cleanup = deleteFromUnwindOurException;

    return(&(ret->unwindException));
}


/// Read a uleb128 encoded value and advance pointer 
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// @param data reference variable holding memory pointer to decode from
/// @returns decoded value
static uintptr_t readULEB128(const uint8_t** data) {
    uintptr_t result = 0;
    uintptr_t shift = 0;
    unsigned char byte;
    const uint8_t* p = *data;

    do {
        byte = *p++;
        result |= (byte & 0x7f) << shift;
        shift += 7;
    } 
    while (byte & 0x80);

    *data = p;

    return result;
}


/// Read a sleb128 encoded value and advance pointer 
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// @param data reference variable holding memory pointer to decode from
/// @returns decoded value
static uintptr_t readSLEB128(const uint8_t** data) {
    uintptr_t result = 0;
    uintptr_t shift = 0;
    unsigned char byte;
    const uint8_t* p = *data;

    do {
        byte = *p++;
        result |= (byte & 0x7f) << shift;
        shift += 7;
    } 
    while (byte & 0x80);

    *data = p;

    if ((byte & 0x40) && (shift < (sizeof(result) << 3))) {
        result |= (~0 << shift);
    }

    return result;
}


/// Read a pointer encoded value and advance pointer 
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// @param data reference variable holding memory pointer to decode from
/// @param encoding dwarf encoding type
/// @returns decoded value
static uintptr_t readEncodedPointer(const uint8_t** data, uint8_t encoding) {
    uintptr_t result = 0;
    const uint8_t* p = *data;

    if (encoding == llvm::dwarf::DW_EH_PE_omit) 
        return(result);

    // first get value 
    switch (encoding & 0x0F) {
        case llvm::dwarf::DW_EH_PE_absptr:
            result = *((uintptr_t*)p);
            p += sizeof(uintptr_t);
            break;
        case llvm::dwarf::DW_EH_PE_uleb128:
            result = readULEB128(&p);
            break;
        // Note: This case has not been tested
        case llvm::dwarf::DW_EH_PE_sleb128:
            result = readSLEB128(&p);
            break;
        case llvm::dwarf::DW_EH_PE_udata2:
            result = *((uint16_t*)p);
            p += sizeof(uint16_t);
            break;
        case llvm::dwarf::DW_EH_PE_udata4:
            result = *((uint32_t*)p);
            p += sizeof(uint32_t);
            break;
        case llvm::dwarf::DW_EH_PE_udata8:
            result = *((uint64_t*)p);
            p += sizeof(uint64_t);
            break;
        case llvm::dwarf::DW_EH_PE_sdata2:
            result = *((int16_t*)p);
            p += sizeof(int16_t);
            break;
        case llvm::dwarf::DW_EH_PE_sdata4:
            result = *((int32_t*)p);
            p += sizeof(int32_t);
            break;
        case llvm::dwarf::DW_EH_PE_sdata8:
            result = *((int64_t*)p);
            p += sizeof(int64_t);
            break;
        default:
            // not supported 
            abort();
            break;
    }

    // then add relative offset 
    switch (encoding & 0x70) {
        case llvm::dwarf::DW_EH_PE_absptr:
            // do nothing 
            break;
        case llvm::dwarf::DW_EH_PE_pcrel:
            result += (uintptr_t)(*data);
            break;
        case llvm::dwarf::DW_EH_PE_textrel:
        case llvm::dwarf::DW_EH_PE_datarel:
        case llvm::dwarf::DW_EH_PE_funcrel:
        case llvm::dwarf::DW_EH_PE_aligned:
        default:
            // not supported 
            abort();
            break;
    }

    // then apply indirection 
    if (encoding & llvm::dwarf::DW_EH_PE_indirect) {
        result = *((uintptr_t*)result);
    }

    *data = p;

    return result;
}


/// Deals with Dwarf actions matching our type infos 
/// (OurExceptionType_t instances). Returns whether or not a dwarf emitted 
/// action matches the supplied exception type. If such a match succeeds, 
/// the resultAction argument will be set with > 0 index value. Only 
/// corresponding llvm.eh.selector type info arguments, cleanup arguments 
/// are supported. Filters are not supported.
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// Also see @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param resultAction reference variable which will be set with result
/// @param classInfo our array of type info pointers (to globals)
/// @param actionEntry index into above type info array or 0 (clean up). 
///        We do not support filters.
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @returns whether or not a type info was found. False is returned if only
///          a cleanup was found
static bool handleActionValue(int64_t *resultAction,
                              struct OurExceptionType_t **classInfo, 
                              uintptr_t actionEntry, 
                              uint64_t exceptionClass, 
                              struct _Unwind_Exception *exceptionObject) {
    bool ret = false;

    if (!resultAction || 
        !exceptionObject || 
        (exceptionClass != ourBaseExceptionClass))
        return(ret);

    struct OurBaseException_t* excp = (struct OurBaseException_t*)
                        (((char*) exceptionObject) + ourBaseFromUnwindOffset);
    struct OurExceptionType_t *excpType = &(excp->type);
    int type = excpType->type;

#ifdef DEBUG
    fprintf(stderr,
            "handleActionValue(...): exceptionObject = <%p>, "
                "excp = <%p>.\n",
            exceptionObject,
            excp);
#endif

    const uint8_t *actionPos = (uint8_t*) actionEntry,
                  *tempActionPos;
    int64_t typeOffset = 0,
            actionOffset;

    for (int i = 0; true; ++i) {
        // Each emitted dwarf action corresponds to a 2 tuple of
        // type info address offset, and action offset to the next
        // emitted action.
        typeOffset = readSLEB128(&actionPos);
        tempActionPos = actionPos;
        actionOffset = readSLEB128(&tempActionPos);

#ifdef DEBUG
        fprintf(stderr,
                "handleActionValue(...):typeOffset: <%lld>, "
                    "actionOffset: <%lld>.\n",
                typeOffset,
                actionOffset);
#endif
        assert((typeOffset >= 0) && 
               "handleActionValue(...):filters are not supported.");

        // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector
        //       argument has been matched.
        if ((typeOffset > 0) &&
            (type == (classInfo[-typeOffset])->type)) {
#ifdef DEBUG
            fprintf(stderr,
                    "handleActionValue(...):actionValue <%d> found.\n",
                    i);
#endif
            *resultAction = i + 1;
            ret = true;
            break;
        }

#ifdef DEBUG
        fprintf(stderr,
                "handleActionValue(...):actionValue not found.\n");
#endif
        if (!actionOffset)
            break;

        actionPos += actionOffset;
    }

    return(ret);
}


/// Deals with the Language specific data portion of the emitted dwarf code.
/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param lsda language specific data area
/// @param _Unwind_Action actions minimally supported unwind stage 
///        (forced specifically not supported)
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @param context unwind system context
/// @returns minimally supported unwinding control indicator 
static _Unwind_Reason_Code handleLsda(int version, 
                                  const uint8_t* lsda,
                                  _Unwind_Action actions,
                                  uint64_t exceptionClass, 
                                  struct _Unwind_Exception* exceptionObject,
                                  _Unwind_Context_t context) {
    _Unwind_Reason_Code ret = _URC_CONTINUE_UNWIND;

    if (!lsda)
        return(ret);

#ifdef DEBUG
    fprintf(stderr, 
            "handleLsda(...):lsda is non-zero.\n");
#endif

    // Get the current instruction pointer and offset it before next
    // instruction in the current frame which threw the exception.
    uintptr_t pc = _Unwind_GetIP(context)-1;

    // Get beginning current frame's code (as defined by the 
    // emitted dwarf code)
    uintptr_t funcStart = _Unwind_GetRegionStart(context);
    uintptr_t pcOffset = pc - funcStart;
    struct OurExceptionType_t** classInfo = NULL;

    // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
    //       dwarf emission

    // Parse LSDA header.
    uint8_t lpStartEncoding = *lsda++;

    if (lpStartEncoding != llvm::dwarf::DW_EH_PE_omit) {
        readEncodedPointer(&lsda, lpStartEncoding); 
    }

    uint8_t ttypeEncoding = *lsda++;
    uintptr_t classInfoOffset;

    if (ttypeEncoding != llvm::dwarf::DW_EH_PE_omit) {
        // Calculate type info locations in emitted dwarf code which
        // were flagged by type info arguments to llvm.eh.selector
        // intrinsic
        classInfoOffset = readULEB128(&lsda);
        classInfo = (struct OurExceptionType_t**) (lsda + classInfoOffset);
    }

    // Walk call-site table looking for range that 
    // includes current PC. 

    uint8_t         callSiteEncoding = *lsda++;
    uint32_t        callSiteTableLength = readULEB128(&lsda);
    const uint8_t*  callSiteTableStart = lsda;
    const uint8_t*  callSiteTableEnd = callSiteTableStart + 
                                                    callSiteTableLength;
    const uint8_t*  actionTableStart = callSiteTableEnd;
    const uint8_t*  callSitePtr = callSiteTableStart;

    bool foreignException = false;

    while (callSitePtr < callSiteTableEnd) {
        uintptr_t start = readEncodedPointer(&callSitePtr, 
                                             callSiteEncoding);
        uintptr_t length = readEncodedPointer(&callSitePtr, 
                                              callSiteEncoding);
        uintptr_t landingPad = readEncodedPointer(&callSitePtr, 
                                                  callSiteEncoding);

        // Note: Action value
        uintptr_t actionEntry = readULEB128(&callSitePtr);

        if (exceptionClass != ourBaseExceptionClass) {
            // We have been notified of a foreign exception being thrown,
            // and we therefore need to execute cleanup landing pads
            actionEntry = 0;
            foreignException = true;
        }

        if (landingPad == 0) {
#ifdef DEBUG
            fprintf(stderr,
                    "handleLsda(...): No landing pad found.\n");
#endif

            continue; // no landing pad for this entry
        }

        if (actionEntry) {
            actionEntry += ((uintptr_t) actionTableStart) - 1;
        }
        else {
#ifdef DEBUG
            fprintf(stderr,
                    "handleLsda(...):No action table found.\n");
#endif
        }

        bool exceptionMatched = false;

        if ((start <= pcOffset) && (pcOffset < (start + length))) {
#ifdef DEBUG
            fprintf(stderr,
                    "handleLsda(...): Landing pad found.\n");
#endif
            int64_t actionValue = 0;

            if (actionEntry) {
                exceptionMatched = handleActionValue
                                   (
                                       &actionValue,
                                       classInfo, 
                                       actionEntry, 
                                       exceptionClass, 
                                       exceptionObject
                                   );
            }

            if (!(actions & _UA_SEARCH_PHASE)) {
#ifdef DEBUG
                fprintf(stderr,
                        "handleLsda(...): installed landing pad "
                            "context.\n");
#endif

                // Found landing pad for the PC.
                // Set Instruction Pointer to so we re-enter function 
                // at landing pad. The landing pad is created by the 
                // compiler to take two parameters in registers.
                _Unwind_SetGR(context, 
                              __builtin_eh_return_data_regno(0), 
                              (uintptr_t)exceptionObject);

                // Note: this virtual register directly corresponds
                //       to the return of the llvm.eh.selector intrinsic
                if (!actionEntry || !exceptionMatched) {
                    // We indicate cleanup only
                    _Unwind_SetGR(context, 
                                  __builtin_eh_return_data_regno(1), 
                                  0);
                }
                else {
                    // Matched type info index of llvm.eh.selector intrinsic
                    // passed here.
                    _Unwind_SetGR(context, 
                                  __builtin_eh_return_data_regno(1), 
                                  actionValue);
                }

                // To execute landing pad set here
                _Unwind_SetIP(context, funcStart + landingPad);
                ret = _URC_INSTALL_CONTEXT;
            }
            else if (exceptionMatched) {
#ifdef DEBUG
                fprintf(stderr,
                        "handleLsda(...): setting handler found.\n");
#endif
                ret = _URC_HANDLER_FOUND;
            }
            else {
                // Note: Only non-clean up handlers are marked as
                //       found. Otherwise the clean up handlers will be 
                //       re-found and executed during the clean up 
                //       phase.
#ifdef DEBUG
                fprintf(stderr,
                        "handleLsda(...): cleanup handler found.\n");
#endif
            }

            break;
        }
    }

    return(ret);
}


/// This is the personality function which is embedded (dwarf emitted), in the
/// dwarf unwind info block. Again see: JITDwarfEmitter.cpp.
/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param _Unwind_Action actions minimally supported unwind stage 
///        (forced specifically not supported)
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @param context unwind system context
/// @returns minimally supported unwinding control indicator 
_Unwind_Reason_Code ourPersonality(int version, 
                               _Unwind_Action actions,
                               uint64_t exceptionClass, 
                               struct _Unwind_Exception* exceptionObject,
                               _Unwind_Context_t context) {
#ifdef DEBUG
    fprintf(stderr, 
            "We are in ourPersonality(...):actions is <%d>.\n",
            actions);

    if (actions & _UA_SEARCH_PHASE) {
        fprintf(stderr, "ourPersonality(...):In search phase.\n");
    }
    else {
        fprintf(stderr, "ourPersonality(...):In non-search phase.\n");
    }
#endif

    const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context);

#ifdef DEBUG
    fprintf(stderr, 
            "ourPersonality(...):lsda = <%p>.\n",
            lsda);
#endif

    // The real work of the personality function is captured here
    return(handleLsda(version,
                      lsda,
                      actions,
                      exceptionClass,
                      exceptionObject,
                      context));
}


/// Generates our _Unwind_Exception class from a given character array.
/// thereby handling arbitrary lengths (not in standard), and handling
/// embedded \0s.
/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param classChars char array to encode. NULL values not checkedf
/// @param classCharsSize number of chars in classChars. Value is not checked.
/// @returns class value
uint64_t genClass(const unsigned char classChars[], size_t classCharsSize)
{
    uint64_t ret = classChars[0];

    for (unsigned i = 1; i < classCharsSize; ++i) {
        ret <<= 8;
        ret += classChars[i];
    }

    return(ret);
}

} // extern "C"

//
// Runtime C Library functions End
//

//
// Code generation functions
//

/// Generates code to print given constant string
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param toPrint string to print
/// @param useGlobal A value of true (default) indicates a GlobalValue is 
///        generated, and is used to hold the constant string. A value of 
///        false indicates that the constant string will be stored on the 
///        stack.
void generateStringPrint(llvm::LLVMContext& context, 
                         llvm::Module& module,
                         llvm::IRBuilder<>& builder, 
                         std::string toPrint,
                         bool useGlobal = true) {
    llvm::Function *printFunct = module.getFunction("printStr");

    llvm::Value *stringVar;
    llvm::Constant* stringConstant = 
        llvm::ConstantArray::get(context, toPrint);

    if (useGlobal) {
        // Note: Does not work without allocation
        stringVar = 
            new llvm::GlobalVariable(module, 
                                     stringConstant->getType(),
                                     true, 
                                     llvm::GlobalValue::LinkerPrivateLinkage, 
                                     stringConstant, 
                                     "");
    }
    else {
        stringVar = builder.CreateAlloca(stringConstant->getType());
        builder.CreateStore(stringConstant, stringVar);
    }

    llvm::Value* cast = 
        builder.CreatePointerCast(stringVar, 
                                  builder.getInt8Ty()->getPointerTo());
    builder.CreateCall(printFunct, cast);
}


/// Generates code to print given runtime integer according to constant
/// string format, and a given print function.
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param printFunct function used to "print" integer
/// @param toPrint string to print
/// @param format printf like formating string for print
/// @param useGlobal A value of true (default) indicates a GlobalValue is 
///        generated, and is used to hold the constant string. A value of 
///        false indicates that the constant string will be stored on the 
///        stack.
void generateIntegerPrint(llvm::LLVMContext& context, 
                          llvm::Module& module,
                          llvm::IRBuilder<>& builder, 
                          llvm::Function& printFunct,
                          llvm::Value& toPrint,
                          std::string format, 
                          bool useGlobal = true) {
    llvm::Constant *stringConstant = llvm::ConstantArray::get(context, format);
    llvm::Value *stringVar;

    if (useGlobal) {
        // Note: Does not seem to work without allocation
        stringVar = 
            new llvm::GlobalVariable(module, 
                                     stringConstant->getType(),
                                    true, 
                                     llvm::GlobalValue::LinkerPrivateLinkage, 
                                     stringConstant, 
                                     "");
    }
    else {
        stringVar = builder.CreateAlloca(stringConstant->getType());
        builder.CreateStore(stringConstant, stringVar);
    }

    llvm::Value* cast = 
        builder.CreateBitCast(stringVar, 
                              builder.getInt8Ty()->getPointerTo());
    builder.CreateCall2(&printFunct, &toPrint, cast);
}


/// Generates code to handle finally block type semantics: always runs 
/// regardless of whether a thrown exception is passing through or the 
/// parent function is simply exiting. In addition to printing some state 
/// to stderr, this code will resume the exception handling--runs the 
/// unwind resume block, if the exception has not been previously caught 
/// by a catch clause, and will otherwise execute the end block (terminator 
/// block). In addition this function creates the corresponding function's 
/// stack storage for the exception pointer and catch flag status.
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param toAddTo parent function to add block to
/// @param blockName block name of new "finally" block.
/// @param functionId output id used for printing
/// @param terminatorBlock terminator "end" block
/// @param unwindResumeBlock unwind resume block
/// @param exceptionCaughtFlag reference exception caught/thrown status storage
/// @param exceptionStorage reference to exception pointer storage
/// @returns newly created block
static llvm::BasicBlock* createFinallyBlock(llvm::LLVMContext& context, 
                             llvm::Module& module, 
                             llvm::IRBuilder<>& builder, 
                             llvm::Function& toAddTo,
                             std::string& blockName,
                             std::string& functionId,
                             llvm::BasicBlock& terminatorBlock,
                             llvm::BasicBlock& unwindResumeBlock,
                             llvm::Value** exceptionCaughtFlag,
                             llvm::Value** exceptionStorage) {
    assert(exceptionCaughtFlag && 
           "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
               "is NULL");
    assert(exceptionStorage && 
           "ExceptionDemo::createFinallyBlock(...):exceptionStorage "
               "is NULL");

    *exceptionCaughtFlag = 
        createEntryBlockAlloca(toAddTo,
                               "exceptionCaught",
                               ourExceptionNotThrownState->getType(),
                               ourExceptionNotThrownState);

    const llvm::PointerType* exceptionStorageType = 
                                builder.getInt8Ty()->getPointerTo();
    *exceptionStorage = 
        createEntryBlockAlloca(toAddTo,
                               "exceptionStorage",
                               exceptionStorageType,
                               llvm::ConstantPointerNull::get(
                                   exceptionStorageType));

    llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
                                                     blockName,
                                                     &toAddTo);

    builder.SetInsertPoint(ret);
   
    std::ostringstream bufferToPrint;
    bufferToPrint << "Gen: Executing finally block "
                  << blockName
                  << " in "
                  << functionId
                  << std::endl;
    generateStringPrint(context, 
                        module, 
                        builder, 
                        bufferToPrint.str(),
                        USE_GLOBAL_STR_CONSTS);

    llvm::SwitchInst* theSwitch = 
        builder.CreateSwitch(builder.CreateLoad(*exceptionCaughtFlag), 
                             &terminatorBlock,
                             2);
    theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock);
    theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock);

    return(ret);
}


/// Generates catch block semantics which print a string to indicate type of
/// catch executed, sets an exception caught flag, and executes passed in 
/// end block (terminator block).
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param toAddTo parent function to add block to
/// @param blockName block name of new "catch" block.
/// @param functionId output id used for printing
/// @param terminatorBlock terminator "end" block
/// @param exceptionCaughtFlag exception caught/thrown status
/// @returns newly created block
static llvm::BasicBlock* createCatchBlock(llvm::LLVMContext& context, 
                                          llvm::Module& module, 
                                          llvm::IRBuilder<>& builder, 
                                          llvm::Function& toAddTo,
                                          std::string& blockName,
                                          std::string& functionId,
                                          llvm::BasicBlock& terminatorBlock,
                                          llvm::Value& exceptionCaughtFlag) {

    llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
                                                     blockName,
                                                     &toAddTo);

    builder.SetInsertPoint(ret);

    std::ostringstream bufferToPrint;
    bufferToPrint << "Gen: Executing catch block "
                  << blockName
                  << " in "
                  << functionId
                  << std::endl;
    generateStringPrint(context, 
                        module, 
                        builder, 
                        bufferToPrint.str(),
                        USE_GLOBAL_STR_CONSTS);
    builder.CreateStore(ourExceptionCaughtState, &exceptionCaughtFlag);
    builder.CreateBr(&terminatorBlock);

    return(ret);
}


/// Generates a function which invokes a function (toInvoke) and, whose 
/// unwind block will "catch" the type info types correspondingly held in the 
/// exceptionTypesToCatch argument. If the toInvoke function throws an 
/// exception which does not match any type info types contained in 
/// exceptionTypesToCatch, the generated code will call _Unwind_Resume 
/// with the raised exception. On the other hand the generated code will 
/// normally exit if the toInvoke function does not throw an exception.
/// The generated "finally" block is always run regardless of the cause of 
/// the generated function exit.
/// The generated function is returned after being verified.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param toInvoke inner function to invoke
/// @param ourId id used to printing purposes
/// @param numExceptionsToCatch length of exceptionTypesToCatch array
/// @param exceptionTypesToCatch array of type info types to "catch"
/// @returns generated function
static
llvm::Function* createCatchWrappedInvokeFunction(llvm::Module& module, 
                    llvm::IRBuilder<>& builder, 
                    llvm::FunctionPassManager& fpm,
                    llvm::Function& toInvoke,
                    std::string ourId,
                    unsigned numExceptionsToCatch,
                    unsigned exceptionTypesToCatch[]) {

    llvm::LLVMContext& context = module.getContext();
    llvm::Function *toPrint32Int = module.getFunction("print32Int");

    ArgTypes argTypes;
    argTypes.push_back(builder.getInt32Ty());

    ArgNames argNames;
    argNames.push_back("exceptTypeToThrow");

    llvm::Function* ret = createFunction(module, 
                                         builder.getVoidTy(),
                                         argTypes, 
                                         argNames, 
                                         ourId,
                                         llvm::Function::ExternalLinkage, 
                                         false, 
                                         false);

    // Block which calls invoke
    llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
                                                            "entry", 
                                                            ret);
    // Normal block for invoke
    llvm::BasicBlock *normalBlock = llvm::BasicBlock::Create(context, 
                                                             "normal", 
                                                             ret);
    // Unwind block for invoke
    llvm::BasicBlock *exceptionBlock = 
        llvm::BasicBlock::Create(context, "exception", ret);

    // Block which routes exception to correct catch handler block
    llvm::BasicBlock *exceptionRouteBlock = 
        llvm::BasicBlock::Create(context, "exceptionRoute", ret);

    // Foreign exception handler
    llvm::BasicBlock *externalExceptionBlock = 
        llvm::BasicBlock::Create(context, "externalException", ret);

    // Block which calls _Unwind_Resume
    llvm::BasicBlock *unwindResumeBlock = 
        llvm::BasicBlock::Create(context, "unwindResume", ret);

    // Clean up block which delete exception if needed
    llvm::BasicBlock *endBlock = 
        llvm::BasicBlock::Create(context, "end", ret);

    std::string nextName;
    std::vector<llvm::BasicBlock*> catchBlocks(numExceptionsToCatch);
    llvm::Value* exceptionCaughtFlag = NULL;
    llvm::Value* exceptionStorage = NULL;

    // Finally block which will branch to unwindResumeBlock if 
    // exception is not caught. Initializes/allocates stack locations.
    llvm::BasicBlock* finallyBlock = createFinallyBlock(context, 
                                                        module, 
                                                        builder, 
                                                        *ret, 
                                                        nextName = "finally", 
                                                        ourId,
                                                        *endBlock,
                                                        *unwindResumeBlock,
                                                        &exceptionCaughtFlag,
                                                        &exceptionStorage);

    for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
        nextName = ourTypeInfoNames[exceptionTypesToCatch[i]];

        // One catch block per type info to be caught
        catchBlocks[i] = createCatchBlock(context, 
                                          module, 
                                          builder, 
                                          *ret,
                                          nextName, 
                                          ourId,
                                          *finallyBlock,
                                          *exceptionCaughtFlag);
    }

    // Entry Block

    builder.SetInsertPoint(entryBlock);

    std::vector<llvm::Value*> args;
    args.push_back(namedValues["exceptTypeToThrow"]);
    builder.CreateInvoke(&toInvoke, 
                         normalBlock, 
                         exceptionBlock, 
                         args.begin(), 
                         args.end());

    // End Block

    builder.SetInsertPoint(endBlock);

    generateStringPrint(context, 
                        module,
                        builder, 
                        "Gen: In end block: exiting in " + ourId + ".\n",
                        USE_GLOBAL_STR_CONSTS);
    llvm::Function *deleteOurException = 
                                    module.getFunction("deleteOurException");

    // Note: function handles NULL exceptions
    builder.CreateCall(deleteOurException, 
                       builder.CreateLoad(exceptionStorage));
    builder.CreateRetVoid();

    // Normal Block

    builder.SetInsertPoint(normalBlock);

    generateStringPrint(context, 
                        module,
                        builder, 
                        "Gen: No exception in " + ourId + "!\n",
                        USE_GLOBAL_STR_CONSTS);

    // Finally block is always called
    builder.CreateBr(finallyBlock);

    // Unwind Resume Block

    builder.SetInsertPoint(unwindResumeBlock);

    llvm::Function *resumeOurException = 
                module.getFunction("_Unwind_Resume");
    builder.CreateCall(resumeOurException, 
                       builder.CreateLoad(exceptionStorage));
    builder.CreateUnreachable();

    // Exception Block

    builder.SetInsertPoint(exceptionBlock);

    llvm::Function *ehException = module.getFunction("llvm.eh.exception");

    // Retrieve thrown exception
    llvm::Value* unwindException = builder.CreateCall(ehException);

    // Store exception and flag
    builder.CreateStore(unwindException, exceptionStorage);
    builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
    llvm::Function *personality = module.getFunction("ourPersonality");
    llvm::Value* functPtr = 
        builder.CreatePointerCast(personality, 
                              builder.getInt8Ty()->getPointerTo());

    args.clear();
    args.push_back(unwindException);
    args.push_back(functPtr);

    // Note: Skipping index 0
    for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
        // Set up type infos to be caught
        args.push_back(
            module.getGlobalVariable(
                ourTypeInfoNames[exceptionTypesToCatch[i]]));
    }

    args.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), 0));

    llvm::Function *ehSelector = module.getFunction("llvm.eh.selector");

    // Set up this exeption block as the landing pad which will handle
    // given type infos. See case Intrinsic::eh_selector in 
    // SelectionDAGBuilder::visitIntrinsicCall(...) and AddCatchInfo(...)
    // implemented in FunctionLoweringInfo.cpp to see how the implementation
    // handles this call. This landing pad (this exception block), will be 
    // called either because it nees to cleanup (call finally) or a type 
    // info was found which matched the thrown exception.
    llvm::Value* retTypeInfoIndex = builder.CreateCall(ehSelector, 
                                                       args.begin(), 
                                                       args.end());

    // Retrieve exception_class member from thrown exception 
    // (_Unwind_Exception instance). This member tells us whether or not
    // the exception is foreign.
    llvm::Value* unwindExceptionClass = 
        builder.CreateLoad(
            builder.CreateStructGEP(
                builder.CreatePointerCast(
                    unwindException, 
                    ourUnwindExceptionType->getPointerTo()), 
                0));

    // Branch to the externalExceptionBlock if the exception is foreign or
    // to a catch router if not. Either way the finally block will be run.
    builder.CreateCondBr(
        builder.CreateICmpEQ(unwindExceptionClass,
                             llvm::ConstantInt::get(builder.getInt64Ty(), 
                                                    ourBaseExceptionClass)),
        exceptionRouteBlock,
        externalExceptionBlock);

    // External Exception Block

    builder.SetInsertPoint(externalExceptionBlock);

    generateStringPrint(context, 
                        module,
                        builder, 
                        "Gen: Foreign exception received.\n",
                        USE_GLOBAL_STR_CONSTS);

    // Branch to the finally block
    builder.CreateBr(finallyBlock);

    // Exception Route Block

    builder.SetInsertPoint(exceptionRouteBlock);

    // Casts exception pointer (_Unwind_Exception instance) to parent 
    // (OurException instance).
    //
    // Note: ourBaseFromUnwindOffset is usually negative
    llvm::Value* typeInfoThrown = 
        builder.CreatePointerCast(
            builder.CreateConstGEP1_64(unwindException,
                                       ourBaseFromUnwindOffset),
            ourExceptionType->getPointerTo());

    // Retrieve thrown exception type info type
    //
    // Note: Index is not relative to pointer but instead to structure
    //       unlike a true getelementptr (GEP) instruction
    typeInfoThrown = builder.CreateStructGEP(typeInfoThrown, 0);

    llvm::Value* typeInfoThrownType = 
                     builder.CreateStructGEP(typeInfoThrown, 0);

    generateIntegerPrint(context, 
                         module,
                         builder, 
                         *toPrint32Int, 
                         *(builder.CreateLoad(typeInfoThrownType)),
                         "Gen: Exception type <%d> received (stack unwound) " 
                                 " in " + 
                             ourId + 
                             ".\n",
                         USE_GLOBAL_STR_CONSTS);

    // Route to matched type info catch block or run cleanup finally block
    llvm::SwitchInst* switchToCatchBlock = 
        builder.CreateSwitch(retTypeInfoIndex, 
                             finallyBlock, 
                             numExceptionsToCatch);

    unsigned nextTypeToCatch;

    for (unsigned i = 1; i <= numExceptionsToCatch; ++i) {
        nextTypeToCatch = i - 1;
        switchToCatchBlock->addCase(llvm::ConstantInt::get(
                                        llvm::Type::getInt32Ty(context), 
                                        i),
                                    catchBlocks[nextTypeToCatch]);
    }

    llvm::verifyFunction(*ret);
    fpm.run(*ret);

    return(ret);
}


/// Generates function which throws either an exception matched to a runtime
/// determined type info type (argument to generated function), or if this 
/// runtime value matches nativeThrowType, throws a foreign exception by 
/// calling nativeThrowFunct.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param ourId id used to printing purposes
/// @param nativeThrowType a runtime argument of this value results in
///        nativeThrowFunct being called to generate/throw exception.
/// @param nativeThrowFunct function which will throw a foreign exception
///        if the above nativeThrowType matches generated function's arg.
/// @returns generated function
static
llvm::Function* createThrowExceptionFunction(llvm::Module& module, 
                                         llvm::IRBuilder<>& builder, 
                                         llvm::FunctionPassManager& fpm,
                                         std::string ourId,
                                         int32_t nativeThrowType,
                                         llvm::Function& nativeThrowFunct) {
    llvm::LLVMContext& context = module.getContext();
    namedValues.clear();
    ArgTypes unwindArgTypes;
    unwindArgTypes.push_back(builder.getInt32Ty());
    ArgNames unwindArgNames;
    unwindArgNames.push_back("exceptTypeToThrow");

    llvm::Function *ret = createFunction(module,
                                         builder.getVoidTy(),
                                         unwindArgTypes,
                                         unwindArgNames,
                                         ourId,
                                         llvm::Function::ExternalLinkage,
                                         false,
                                         false);

    // Throws either one of our exception or a native C++ exception depending
    // on a runtime argument value containing a type info type.
    llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
                                                            "entry", 
                                                            ret);
    // Throws a foreign exception
    llvm::BasicBlock *nativeThrowBlock = 
                                llvm::BasicBlock::Create(context,
                                                         "nativeThrow", 
                                                         ret);
    // Throws one of our Exceptions
    llvm::BasicBlock *generatedThrowBlock = 
                                llvm::BasicBlock::Create(context,
                                                         "generatedThrow", 
                                                         ret);
    // Retrieved runtime type info type to throw
    llvm::Value* exceptionType = namedValues["exceptTypeToThrow"];

    // nativeThrowBlock block

    builder.SetInsertPoint(nativeThrowBlock);

    // Throws foreign exception
    builder.CreateCall(&nativeThrowFunct, exceptionType);
    builder.CreateUnreachable();

    // entry block

    builder.SetInsertPoint(entryBlock);

    llvm::Function *toPrint32Int = module.getFunction("print32Int");
    generateIntegerPrint(context, 
                         module,
                         builder, 
                         *toPrint32Int, 
                         *exceptionType, 
                         "\nGen: About to throw exception type <%d> in " + 
                             ourId + 
                             ".\n",
                         USE_GLOBAL_STR_CONSTS);

    // Switches on runtime type info type value to determine whether or not
    // a foreign exception is thrown. Defaults to throwing one of our 
    // generated exceptions.
    llvm::SwitchInst* theSwitch = builder.CreateSwitch(exceptionType,
                                                       generatedThrowBlock,
                                                       1);

    theSwitch->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 
                                              nativeThrowType),
                       nativeThrowBlock);

    // generatedThrow block

    builder.SetInsertPoint(generatedThrowBlock);

    llvm::Function *createOurException = 
                module.getFunction("createOurException");
    llvm::Function *raiseOurException = 
                module.getFunction("_Unwind_RaiseException");

    // Creates exception to throw with runtime type info type.
    llvm::Value* exception = 
        builder.CreateCall(createOurException, 
                           namedValues["exceptTypeToThrow"]);

    // Throw generated Exception
    builder.CreateCall(raiseOurException, exception);
    builder.CreateUnreachable();

    llvm::verifyFunction(*ret);
    fpm.run(*ret);

    return(ret);
}

static void createStandardUtilityFunctions(unsigned numTypeInfos,
                                           llvm::Module& module, 
                                           llvm::IRBuilder<>& builder);

/// Creates test code by generating and organizing these functions into the 
/// test case. The test case consists of an outer function setup to invoke
/// an inner function within an environment having multiple catch and single 
/// finally blocks. This inner function is also setup to invoke a throw
/// function within an evironment similar in nature to the outer function's 
/// catch and finally blocks. Each of these two functions catch mutually
/// exclusive subsets (even or odd) of the type info types configured
/// for this this. All generated functions have a runtime argument which
/// holds a type info type to throw that each function takes and passes it
/// to the inner one if such a inner function exists. This type info type is
/// looked at by the generated throw function to see whether or not it should
/// throw a generated exception with the same type info type, or instead call
/// a supplied a function which in turn will throw a foreign exception.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param nativeThrowFunctName name of external function which will throw
///        a foreign exception
/// @returns outermost generated test function.
llvm::Function* createUnwindExceptionTest(llvm::Module& module, 
                                          llvm::IRBuilder<>& builder, 
                                          llvm::FunctionPassManager& fpm,
                                          std::string nativeThrowFunctName) {
    // Number of type infos to generate
    unsigned numTypeInfos = 6;

    // Initialze intrisics and external functions to use along with exception
    // and type info globals.
    createStandardUtilityFunctions(numTypeInfos,
                                   module,
                                   builder);
    llvm::Function *nativeThrowFunct = 
        module.getFunction(nativeThrowFunctName);

    // Create exception throw function using the value ~0 to cause 
    // foreign exceptions to be thrown.
    llvm::Function* throwFunct = 
                            createThrowExceptionFunction(module,
                                                         builder,
                                                         fpm,
                                                         "throwFunct",
                                                         ~0,
                                                         *nativeThrowFunct);
    // Inner function will catch even type infos
    unsigned innerExceptionTypesToCatch[] = {6, 2, 4};
    size_t numExceptionTypesToCatch = sizeof(innerExceptionTypesToCatch) / 
                                          sizeof(unsigned);

    // Generate inner function.
    llvm::Function* innerCatchFunct = 
        createCatchWrappedInvokeFunction(module,
                                         builder,
                                         fpm,
                                         *throwFunct,
                                         "innerCatchFunct",
                                         numExceptionTypesToCatch,
                                         innerExceptionTypesToCatch);

    // Outer function will catch odd type infos
    unsigned outerExceptionTypesToCatch[] = {3, 1, 5};
    numExceptionTypesToCatch = sizeof(outerExceptionTypesToCatch) / 
                                   sizeof(unsigned);

    // Generate outer function
    llvm::Function* outerCatchFunct = 
        createCatchWrappedInvokeFunction(module,
                                         builder,
                                         fpm,
                                         *innerCatchFunct,
                                         "outerCatchFunct",
                                         numExceptionTypesToCatch,
                                         outerExceptionTypesToCatch);

    // Return outer function to run
    return(outerCatchFunct);
}


/// Represents our foreign exceptions
class OurCppRunException : public std::runtime_error {
public:
    OurCppRunException(const std::string reason) :
        std::runtime_error(reason) {}

    OurCppRunException (const OurCppRunException& toCopy) :
        std::runtime_error(toCopy) {}

    OurCppRunException& operator = (const OurCppRunException& toCopy) {
        return(reinterpret_cast<OurCppRunException&>(
                   std::runtime_error::operator = (toCopy)
               ));
    }

    ~OurCppRunException (void) throw () {}
};


/// Throws foreign C++ exception.
/// @param ignoreIt unused parameter that allows function to match implied
///        generated function contract.
extern "C"
void throwCppException (int32_t ignoreIt) {
    throw(OurCppRunException("thrown by throwCppException(...)"));
}

typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);

/// This is a test harness which runs test by executing generated 
/// function with a type info type to throw. Harness wraps the excecution 
/// of generated function in a C++ try catch clause.
/// @param engine execution engine to use for executing generated function.
///        This demo program expects this to be a JIT instance for demo
///        purposes.
/// @param function generated test function to run
/// @param typeToThrow type info type of generated exception to throw, or
///        indicator to cause foreign exception to be thrown.
static
void runExceptionThrow(llvm::ExecutionEngine* engine, 
                       llvm::Function* function, 
                       int32_t typeToThrow) {

    // Find test's function pointer
    OurExceptionThrowFunctType functPtr = 
          reinterpret_cast<OurExceptionThrowFunctType>(
              reinterpret_cast<intptr_t>(
                  engine->getPointerToFunction(function)
              )
          );

    try {
        // Run test
        (*functPtr)(typeToThrow);
    }
    catch (OurCppRunException exc) {
        // Catch foreign C++ exception
        fprintf(stderr,
                "\nrunExceptionThrow(...):In C++ catch OurCppRunException "
                    "with reason: %s.\n", 
                exc.what());
    }
    catch (...) {
        // Catch all exceptions including our generated ones. I'm not sure
        // why this latter functionality should work, as it seems that
        // our exceptions should be foreign to C++ (the _Unwind_Exception::
        // exception_class should be different from the one used by C++), and
        // therefore C++ should ignore the generated exceptions. 

        fprintf(stderr,
                "\nrunExceptionThrow(...):In C++ catch all.\n");
    }
}

//
// End test functions
//

/// This initialization routine creates type info globals and 
/// adds external function declarations to module.
/// @param numTypeInfos number of linear type info associated type info types
///        to create as GlobalVariable instances, starting with the value 1.
/// @param module code for module instance
/// @param builder builder instance
static void createStandardUtilityFunctions(unsigned numTypeInfos,
                                           llvm::Module& module, 
                                           llvm::IRBuilder<>& builder) {

    llvm::LLVMContext& context = module.getContext();

    // Exception initializations

    // Setup exception catch state
    ourExceptionNotThrownState = 
                    llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0),
    ourExceptionThrownState = 
                    llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1),
    ourExceptionCaughtState = 
                    llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2),


    // Create our type info type
    ourTypeInfoType = llvm::StructType::get(context, 
                                            builder.getInt32Ty(), 
                                            NULL);

    // Create OurException type
    ourExceptionType = llvm::StructType::get(context, 
                                             ourTypeInfoType,
                                             NULL);

    // Create portion of _Unwind_Exception type
    //
    // Note: Declaring only a portion of the _Unwind_Exception struct.
    //       Does this cause problems?
    ourUnwindExceptionType = llvm::StructType::get(context, 
                                                   builder.getInt64Ty(),
                                                   NULL);
    struct OurBaseException_t dummyException;

    // Calculate offset of OurException::unwindException member.
    ourBaseFromUnwindOffset = ((uintptr_t) &dummyException) - 
                           ((uintptr_t) &(dummyException.unwindException));

#ifdef DEBUG
    fprintf(stderr,
            "createStandardUtilityFunctions(...):ourBaseFromUnwindOffset "
                "= %lld, sizeof(struct OurBaseException_t) - "
                "sizeof(struct _Unwind_Exception) = %lu.\n",
            ourBaseFromUnwindOffset,
            sizeof(struct OurBaseException_t) - 
                sizeof(struct _Unwind_Exception));
#endif

    size_t numChars = sizeof(ourBaseExcpClassChars) / sizeof(char);

    // Create our _Unwind_Exception::exception_class value
    ourBaseExceptionClass = genClass(ourBaseExcpClassChars, numChars);

    // Type infos

    std::string baseStr = "typeInfo", typeInfoName;
    std::ostringstream typeInfoNameBuilder;
    std::vector<llvm::Constant*> structVals;
    
    llvm::Constant *nextStruct;
    llvm::GlobalVariable* nextGlobal = NULL;

    // Generate each type info
    //
    // Note: First type info is not used.
    for (unsigned i = 0; i <= numTypeInfos; ++i) {
        structVals.clear();
        structVals.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), i));
        nextStruct = llvm::ConstantStruct::get(ourTypeInfoType, structVals);

        typeInfoNameBuilder.str("");
        typeInfoNameBuilder << baseStr << i;
        typeInfoName = typeInfoNameBuilder.str();

        // Note: Does not seem to work without allocation
        nextGlobal = 
            new llvm::GlobalVariable(module, 
                                     ourTypeInfoType, 
                                     true, 
                                     llvm::GlobalValue::ExternalLinkage, 
                                     nextStruct, 
                                     typeInfoName);

        ourTypeInfoNames.push_back(typeInfoName);
        ourTypeInfoNamesIndex[i] = typeInfoName;
    }

    ArgNames argNames;
    ArgTypes argTypes;
    llvm::Function* funct = NULL;

    // print32Int

    const llvm::Type* retType = builder.getVoidTy();

    argTypes.clear();
    argTypes.push_back(builder.getInt32Ty());
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "print32Int", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // print64Int

    retType = builder.getVoidTy();

    argTypes.clear();
    argTypes.push_back(builder.getInt64Ty());
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "print64Int", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // printStr

    retType = builder.getVoidTy();

    argTypes.clear();
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "printStr", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // throwCppException

    retType = builder.getVoidTy();

    argTypes.clear();
    argTypes.push_back(builder.getInt32Ty());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "throwCppException", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // deleteOurException

    retType = builder.getVoidTy();

    argTypes.clear();
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "deleteOurException", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // createOurException

    retType = builder.getInt8Ty()->getPointerTo();

    argTypes.clear();
    argTypes.push_back(builder.getInt32Ty());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "createOurException", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // _Unwind_RaiseException

    retType = builder.getInt32Ty();

    argTypes.clear();
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    funct = createFunction(module, 
                           retType, 
                           argTypes, 
                           argNames, 
                           "_Unwind_RaiseException", 
                           llvm::Function::ExternalLinkage, 
                           true, 
                           false);

    funct->addFnAttr(llvm::Attribute::NoReturn);

    // _Unwind_Resume

    retType = builder.getInt32Ty();

    argTypes.clear();
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    funct = createFunction(module, 
                           retType, 
                           argTypes, 
                           argNames, 
                           "_Unwind_Resume", 
                           llvm::Function::ExternalLinkage, 
                           true, 
                           false);

    funct->addFnAttr(llvm::Attribute::NoReturn);

    // ourPersonality

    retType = builder.getInt32Ty();

    argTypes.clear();
    argTypes.push_back(builder.getInt32Ty());
    argTypes.push_back(builder.getInt32Ty());
    argTypes.push_back(builder.getInt64Ty());
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());
    argTypes.push_back(builder.getInt8Ty()->getPointerTo());

    argNames.clear();

    createFunction(module, 
                   retType, 
                   argTypes, 
                   argNames, 
                   "ourPersonality", 
                   llvm::Function::ExternalLinkage, 
                   true, 
                   false);

    // llvm.eh.selector intrinsic

    getDeclaration(&module, llvm::Intrinsic::eh_selector);

    // llvm.eh.exception intrinsic

    getDeclaration(&module, llvm::Intrinsic::eh_exception);

    // llvm.eh.typeid.for intrinsic

    getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
}


//===---------------------------------------------------------------------===//
// Main test driver code.
//===---------------------------------------------------------------------===//

/// Demo main routine which takes the type info types to throw. A test will
/// be run for each given type info type. While type info types with the value 
/// of -1 will trigger a foreign C++ exception to be thrown; type info types
/// <= 6 and >= 1 will be caught by test functions; and type info types > 6
/// will result in exceptions which pass through to the test harness. All other
/// type info types are not supported and could cause a crash.
int main(int argc, char* argv[]) {
    if (argc == 1) {
        fprintf(stderr,
                "\nUsage: ExceptionDemo <exception type to throw> "
                    "[<type 2>...<type n>].\n"
                    "   Each type must have the value of 1 - 6 for "
                    "generated exceptions to be caught;\n"
                    "   the value -1 for foreign C++ exceptions to be "
                    "generated and thrown;\n"
                    "   or the values > 6 for exceptions to be ignored.\n"
                    "\nTry: ExceptionDemo 2 3 7 -1\n"
                    "   for a full test.\n\n");
        return(0);
    }

    // If not set, exception handling will not be turned on
    llvm::JITExceptionHandling = true;

    llvm::InitializeNativeTarget();
    llvm::LLVMContext& context = llvm::getGlobalContext();
    llvm::IRBuilder<> theBuilder(context);

    // Make the module, which holds all the code.
    llvm::Module* module = new llvm::Module("my cool jit", context);

    // Build engine with JIT
    llvm::EngineBuilder factory(module);
    factory.setEngineKind(llvm::EngineKind::JIT);
    factory.setAllocateGVsWithCode(false);
    llvm::ExecutionEngine* executionEngine = factory.create();

    {
        llvm::FunctionPassManager fpm(module);

        // Set up the optimizer pipeline.  
        // Start with registering info about how the
        // target lays out data structures.
        fpm.add(new llvm::TargetData(*executionEngine->getTargetData()));

        // Optimizations turned on
#ifdef ADD_OPT_PASSES

        // Promote allocas to registers.
        fpm.add(llvm::createPromoteMemoryToRegisterPass());

        // Do simple "peephole" optimizations and bit-twiddling optzns.
        fpm.add(llvm::createInstructionCombiningPass());

        // Reassociate expressions.
        fpm.add(llvm::createReassociatePass());

        // Eliminate Common SubExpressions.
        fpm.add(llvm::createGVNPass());

        // Simplify the control flow graph (deleting unreachable 
        // blocks, etc).
        fpm.add(llvm::createCFGSimplificationPass());
#endif  // ADD_OPT_PASSES

        fpm.doInitialization();

        // Generate test code using function throwCppException(...) as
        // the function which throws foreign exceptions.
        llvm::Function* toRun = 
                          createUnwindExceptionTest(*module, 
                                                    theBuilder, 
                                                    fpm,
                                                    "throwCppException");

        fprintf(stderr, "\nBegin module dump:\n\n");

        module->dump();

        fprintf(stderr, "\nEnd module dump:\n");

        fprintf(stderr, "\n\nBegin Test:\n");

        for (int i = 1; i < argc; ++i) {
            // Run test for each argument whose value is the exception
            // type to throw.
            runExceptionThrow(executionEngine, 
                              toRun, 
                              (unsigned) strtoul(argv[i], NULL, 10));
        }

        fprintf(stderr, "\nEnd Test:\n\n");
    } 

    delete executionEngine;
  
    return 0;
}

