//===-- ExceptionDemo.cpp - An example using llvm Exceptions --------------===//
//
//                     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 explained by: example in rules 1.6.4 in
//         http://mentorembedded.github.com/cxx-abi/abi-eh.html (v1.22)
//
// This code uses code from the llvm compiler-rt project and the llvm
// Kaleidoscope project.
//
//===----------------------------------------------------------------------===//

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

// FIXME: Although all systems tested with (Linux, OS X), do not need this
//        header file included. A user on ubuntu reported, undefined symbols
//        for stderr, and fprintf, and the addition of this include fixed the
//        issue for them. Given that LLVM's best practices include the goal
//        of reducing the number of redundant header files included, the
//        correct solution would be to find out why these symbols are not
//        defined for the system in question, and fix the issue by finding out
//        which LLVM header file, if any, would include these symbols.
#include <cstdio>

#include <sstream>
#include <stdexcept>


#ifndef USE_GLOBAL_STR_CONSTS
#define USE_GLOBAL_STR_CONSTS true
#endif

// System C++ ABI unwind types from:
//     http://mentorembedded.github.com/cxx-abi/abi-eh.html (v1.22)

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://mentorembedded.github.com/cxx-abi/abi-eh.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 *ourCaughtResultType;
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<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,
                               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,
                                                llvm::Type *type,
                                                llvm::Constant *initWith = 0) {
  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://mentorembedded.github.com/cxx-abi/abi-eh.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://mentorembedded.github.com/cxx-abi/abi-eh.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://mentorembedded.github.com/cxx-abi/abi-eh.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;

  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;
    }

    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://mentorembedded.github.com/cxx-abi/abi-eh.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://mentorembedded.github.com/cxx-abi/abi-eh.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::ConstantDataArray::getString(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.getInt8PtrTy());
  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::ConstantDataArray::getString(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.getInt8PtrTy());
  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
/// @param caughtResultStorage reference to landingpad result 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,
                                            llvm::Value **caughtResultStorage) {
  assert(exceptionCaughtFlag &&
         "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
         "is NULL");
  assert(exceptionStorage &&
         "ExceptionDemo::createFinallyBlock(...):exceptionStorage "
         "is NULL");
  assert(caughtResultStorage &&
         "ExceptionDemo::createFinallyBlock(...):caughtResultStorage "
         "is NULL");

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

  llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy();
  *exceptionStorage = createEntryBlockAlloca(toAddTo,
                                             "exceptionStorage",
                                             exceptionStorageType,
                                             llvm::ConstantPointerNull::get(
                                               exceptionStorageType));
  *caughtResultStorage = createEntryBlockAlloca(toAddTo,
                                              "caughtResultStorage",
                                              ourCaughtResultType,
                                              llvm::ConstantAggregateZero::get(
                                                ourCaughtResultType));

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

  builder.SetInsertPoint(ret);

  std::ostringstream bufferToPrint;
  bufferToPrint << "Gen: Executing finally block "
    << blockName << " in " << functionId << "\n";
  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;
  llvm::Value *caughtResultStorage = 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,
                                                      &caughtResultStorage
                                                      );

  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);

  // 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);

  builder.CreateResume(builder.CreateLoad(caughtResultStorage));

  // Exception Block

  builder.SetInsertPoint(exceptionBlock);

  llvm::Function *personality = module.getFunction("ourPersonality");

  llvm::LandingPadInst *caughtResult =
    builder.CreateLandingPad(ourCaughtResultType,
                             personality,
                             numExceptionsToCatch,
                             "landingPad");

  caughtResult->setCleanup(true);

  for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
    // Set up type infos to be caught
    caughtResult->addClause(module.getGlobalVariable(
                             ourTypeInfoNames[exceptionTypesToCatch[i]]));
  }

  llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0);
  llvm::Value *retTypeInfoIndex = builder.CreateExtractValue(caughtResult, 1);

  // FIXME: Redundant storage which, beyond utilizing value of
  //        caughtResultStore for unwindException storage, may be alleviated
  //        altogether with a block rearrangement
  builder.CreateStore(caughtResult, caughtResultStorage);
  builder.CreateStore(unwindException, exceptionStorage);
  builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);

  // 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 execution
/// 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. This latter
    // functionality works according to the example in rules 1.6.4 of
    // http://mentorembedded.github.com/cxx-abi/abi-eh.html (v1.22),
    // given that these will be exceptions foreign to C++
    // (the _Unwind_Exception::exception_class should be different from
    // the one used by C++).
    fprintf(stderr,
            "\nrunExceptionThrow(...):In C++ catch all.\n");
  }
}

//
// End test functions
//

typedef llvm::ArrayRef<llvm::Type*> TypeArray;

/// 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,
                                          TypeArray(builder.getInt32Ty()));

  llvm::Type *caughtResultFieldTypes[] = {
    builder.getInt8PtrTy(),
    builder.getInt32Ty()
  };

  // Create our landingpad result type
  ourCaughtResultType = llvm::StructType::get(context,
                                            TypeArray(caughtResultFieldTypes));

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

  // 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,
                    TypeArray(builder.getInt64Ty()));

  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;

  // 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
    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

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

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

  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.getInt8PtrTy());

  argNames.clear();

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

  // printStr

  retType = builder.getVoidTy();

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

  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.getInt8PtrTy());

  argNames.clear();

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

  // createOurException

  retType = builder.getInt8PtrTy();

  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.getInt8PtrTy());

  argNames.clear();

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

  funct->setDoesNotReturn();

  // _Unwind_Resume

  retType = builder.getInt32Ty();

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

  argNames.clear();

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

  funct->setDoesNotReturn();

  // 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.getInt8PtrTy());
  argTypes.push_back(builder.getInt8PtrTy());

  argNames.clear();

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

  // 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::TargetOptions Opts;
  Opts.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);
  factory.setTargetOptions(Opts);
  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::DataLayout(*executionEngine->getDataLayout()));

    // Optimizations turned on
#ifdef ADD_OPT_PASSES

    // Basic AliasAnslysis support for GVN.
    fpm.add(llvm::createBasicAliasAnalysisPass());

    // 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;
}
