//===-- ExceptionDemo.cpp - An example using llvm Exceptions --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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://itanium-cxx-abi.github.io/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/BinaryFormat/Dwarf.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/IR/Verifier.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>

#include <inttypes.h>

#include <unwind.h>

#ifndef USE_GLOBAL_STR_CONSTS
#define USE_GLOBAL_STR_CONSTS true
#endif

//
// 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://itanium-cxx-abi.github.io/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);

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

  return(ret);
}


//
// Code Generation Utilities End
//

//
// Runtime C Library functions
//

namespace {
template <typename Type_>
uintptr_t ReadType(const uint8_t *&p) {
  Type_ value;
  memcpy(&value, p, sizeof(Type_));
  p += sizeof(Type_);
  return static_cast<uintptr_t>(value);
}
}

// 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 previously 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://itanium-cxx-abi.github.io/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 = ReadType<uintptr_t>(p);
      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 = ReadType<uint16_t>(p);
      break;
    case llvm::dwarf::DW_EH_PE_udata4:
      result = ReadType<uint32_t>(p);
      break;
    case llvm::dwarf::DW_EH_PE_udata8:
      result = ReadType<uint64_t>(p);
      break;
    case llvm::dwarf::DW_EH_PE_sdata2:
      result = ReadType<int16_t>(p);
      break;
    case llvm::dwarf::DW_EH_PE_sdata4:
      result = ReadType<int32_t>(p);
      break;
    case llvm::dwarf::DW_EH_PE_sdata8:
      result = ReadType<int64_t>(p);
      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://itanium-cxx-abi.github.io/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",
          (void*)exceptionObject,
          (void*)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: <%" PRIi64 ">, "
            "actionOffset: <%" PRIi64 ">.\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://itanium-cxx-abi.github.io/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,
                                      _Unwind_Exception_Class exceptionClass,
                                      struct _Unwind_Exception *exceptionObject,
                                      struct _Unwind_Context *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://itanium-cxx-abi.github.io/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,
                                   _Unwind_Exception_Class exceptionClass,
                                   struct _Unwind_Exception *exceptionObject,
                                   struct _Unwind_Context *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 = (const uint8_t *)_Unwind_GetLanguageSpecificData(context);

#ifdef DEBUG
  fprintf(stderr,
          "ourPersonality(...):lsda = <%p>.\n",
          (void*)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://itanium-cxx-abi.github.io/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.CreateCall(&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");
  ret->setPersonalityFn(personality);

  llvm::LandingPadInst *caughtResult =
    builder.CreateLandingPad(ourCaughtResultType,
                             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://itanium-cxx-abi.github.io/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 "
          "= %" PRIi64 ", 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::IRBuilder<> theBuilder(Context);

  // Make the module, which holds all the code.
  std::unique_ptr<llvm::Module> Owner =
      std::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();

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

    module->dump();

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

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