//===-- 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/ADT/STLExtras.h"
#include "llvm/IR/Verifier.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.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/LegacyPassManager.h"
#include "llvm/IR/Module.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 See @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;
}

unsigned getEncodingSize(uint8_t Encoding) {
  if (Encoding == llvm::dwarf::DW_EH_PE_omit)
    return 0;

  switch (Encoding & 0x0F) {
  case llvm::dwarf::DW_EH_PE_absptr:
    return sizeof(uintptr_t);
  case llvm::dwarf::DW_EH_PE_udata2:
    return sizeof(uint16_t);
  case llvm::dwarf::DW_EH_PE_udata4:
    return sizeof(uint32_t);
  case llvm::dwarf::DW_EH_PE_udata8:
    return sizeof(uint64_t);
  case llvm::dwarf::DW_EH_PE_sdata2:
    return sizeof(int16_t);
  case llvm::dwarf::DW_EH_PE_sdata4:
    return sizeof(int32_t);
  case llvm::dwarf::DW_EH_PE_sdata8:
    return sizeof(int64_t);
  default:
    // not supported
    abort();
  }
}

/// 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,
                              uint8_t TTypeEncoding,
                              const uint8_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) {
#ifdef DEBUG
      fprintf(stderr,
              "handleActionValue(...):actionValue <%d> found.\n",
              i);
#endif
      unsigned EncSize = getEncodingSize(TTypeEncoding);
      const uint8_t *EntryP = ClassInfo - typeOffset * EncSize;
      uintptr_t P = readEncodedPointer(&EntryP, TTypeEncoding);
      struct OurExceptionType_t *ThisClassInfo =
        reinterpret_cast<struct OurExceptionType_t *>(P);
      if (ThisClassInfo->type == type) {
        *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;
  const uint8_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 = 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,
                                             ttypeEncoding,
                                             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::PrivateLinkage,
                             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::PrivateLinkage,
                             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::legacy::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(
          ourUnwindExceptionType,
          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(ourExceptionType, typeInfoThrown, 0);

  llvm::Value *typeInfoThrownType =
      builder.CreateStructGEP(builder.getInt8PtrTy(), 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::legacy::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::legacy::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);
}

namespace {
/// 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() override {}
};
} // end anonymous namespace

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

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

  // Make the module, which holds all the code.
  std::unique_ptr<llvm::Module> Owner =
      llvm::make_unique<llvm::Module>("my cool jit", context);
  llvm::Module *module = Owner.get();

  std::unique_ptr<llvm::RTDyldMemoryManager> MemMgr(new llvm::SectionMemoryManager());

  // Build engine with JIT
  llvm::EngineBuilder factory(std::move(Owner));
  factory.setEngineKind(llvm::EngineKind::JIT);
  factory.setTargetOptions(Opts);
  factory.setMCJITMemoryManager(std::move(MemMgr));
  llvm::ExecutionEngine *executionEngine = factory.create();

  {
    llvm::legacy::FunctionPassManager fpm(module);

    // Set up the optimizer pipeline.
    // Start with registering info about how the
    // target lays out data structures.
    module->setDataLayout(*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");

    executionEngine->finalizeObject();

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