//===-- 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://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22)
//
// This code uses code from the llvm compiler-rt project and the llvm 
// Kaleidoscope project.
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Intrinsics.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Support/IRBuilder.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/TargetSelect.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://sourcery.mentor.com/public/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://refspecs.freestandards.org/abi-eh-1.21.html
struct OurBaseException_t {
  struct OurExceptionType_t type;
  
  // Note: This is properly aligned in unwind.h
  struct _Unwind_Exception unwindException;
};


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

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

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

int64_t ourBaseFromUnwindOffset;

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


static uint64_t ourBaseExceptionClass = 0;

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

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

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

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

//
// Code Generation Utilities
//

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


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


//
// Code Generation Utilities End
//

//
// Runtime C Library functions 
//

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

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


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


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


/// Deletes the true previosly allocated exception whose address
/// is calculated from the supplied OurBaseException_t::unwindException
/// member address. Handles (ignores), NULL pointers.
/// @param expToDelete exception to delete
void deleteOurException(OurUnwindException *expToDelete) {
#ifdef DEBUG
  fprintf(stderr,
          "deleteOurException(...).\n");
#endif
  
  if (expToDelete &&
      (expToDelete->exception_class == ourBaseExceptionClass)) {
    
    free(((char*) expToDelete) + ourBaseFromUnwindOffset);
  }
}


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


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


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


/// Read a sleb128 encoded value and advance pointer 
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// @param data reference variable holding memory pointer to decode from
/// @returns decoded value
static uintptr_t readSLEB128(const uint8_t **data) {
  uintptr_t result = 0;
  uintptr_t shift = 0;
  unsigned char byte;
  const uint8_t *p = *data;
  
  do {
    byte = *p++;
    result |= (byte & 0x7f) << shift;
    shift += 7;
  } 
  while (byte & 0x80);
  
  *data = p;
  
  if ((byte & 0x40) && (shift < (sizeof(result) << 3))) {
    result |= (~0 << shift);
  }
  
  return result;
}


/// Read a pointer encoded value and advance pointer 
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// @param data reference variable holding memory pointer to decode from
/// @param encoding dwarf encoding type
/// @returns decoded value
static uintptr_t readEncodedPointer(const uint8_t **data, uint8_t encoding) {
  uintptr_t result = 0;
  const uint8_t *p = *data;
  
  if (encoding == llvm::dwarf::DW_EH_PE_omit) 
    return(result);
  
  // first get value 
  switch (encoding & 0x0F) {
    case llvm::dwarf::DW_EH_PE_absptr:
      result = *((uintptr_t*)p);
      p += sizeof(uintptr_t);
      break;
    case llvm::dwarf::DW_EH_PE_uleb128:
      result = readULEB128(&p);
      break;
      // Note: This case has not been tested
    case llvm::dwarf::DW_EH_PE_sleb128:
      result = readSLEB128(&p);
      break;
    case llvm::dwarf::DW_EH_PE_udata2:
      result = *((uint16_t*)p);
      p += sizeof(uint16_t);
      break;
    case llvm::dwarf::DW_EH_PE_udata4:
      result = *((uint32_t*)p);
      p += sizeof(uint32_t);
      break;
    case llvm::dwarf::DW_EH_PE_udata8:
      result = *((uint64_t*)p);
      p += sizeof(uint64_t);
      break;
    case llvm::dwarf::DW_EH_PE_sdata2:
      result = *((int16_t*)p);
      p += sizeof(int16_t);
      break;
    case llvm::dwarf::DW_EH_PE_sdata4:
      result = *((int32_t*)p);
      p += sizeof(int32_t);
      break;
    case llvm::dwarf::DW_EH_PE_sdata8:
      result = *((int64_t*)p);
      p += sizeof(int64_t);
      break;
    default:
      // not supported 
      abort();
      break;
  }
  
  // then add relative offset 
  switch (encoding & 0x70) {
    case llvm::dwarf::DW_EH_PE_absptr:
      // do nothing 
      break;
    case llvm::dwarf::DW_EH_PE_pcrel:
      result += (uintptr_t)(*data);
      break;
    case llvm::dwarf::DW_EH_PE_textrel:
    case llvm::dwarf::DW_EH_PE_datarel:
    case llvm::dwarf::DW_EH_PE_funcrel:
    case llvm::dwarf::DW_EH_PE_aligned:
    default:
      // not supported 
      abort();
      break;
  }
  
  // then apply indirection 
  if (encoding & llvm::dwarf::DW_EH_PE_indirect) {
    result = *((uintptr_t*)result);
  }
  
  *data = p;
  
  return result;
}


/// Deals with Dwarf actions matching our type infos 
/// (OurExceptionType_t instances). Returns whether or not a dwarf emitted 
/// action matches the supplied exception type. If such a match succeeds, 
/// the resultAction argument will be set with > 0 index value. Only 
/// corresponding llvm.eh.selector type info arguments, cleanup arguments 
/// are supported. Filters are not supported.
/// See Variable Length Data in: 
/// @link http://dwarfstd.org/Dwarf3.pdf @unlink
/// Also see @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param resultAction reference variable which will be set with result
/// @param classInfo our array of type info pointers (to globals)
/// @param actionEntry index into above type info array or 0 (clean up). 
///        We do not support filters.
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @returns whether or not a type info was found. False is returned if only
///          a cleanup was found
static bool handleActionValue(int64_t *resultAction,
                              struct OurExceptionType_t **classInfo, 
                              uintptr_t actionEntry, 
                              uint64_t exceptionClass, 
                              struct _Unwind_Exception *exceptionObject) {
  bool ret = false;
  
  if (!resultAction || 
      !exceptionObject || 
      (exceptionClass != ourBaseExceptionClass))
    return(ret);
  
  struct OurBaseException_t *excp = (struct OurBaseException_t*)
  (((char*) exceptionObject) + ourBaseFromUnwindOffset);
  struct OurExceptionType_t *excpType = &(excp->type);
  int type = excpType->type;
  
#ifdef DEBUG
  fprintf(stderr,
          "handleActionValue(...): exceptionObject = <%p>, "
          "excp = <%p>.\n",
          exceptionObject,
          excp);
#endif
  
  const uint8_t *actionPos = (uint8_t*) actionEntry,
  *tempActionPos;
  int64_t typeOffset = 0,
  actionOffset;
  
  for (int i = 0; true; ++i) {
    // Each emitted dwarf action corresponds to a 2 tuple of
    // type info address offset, and action offset to the next
    // emitted action.
    typeOffset = readSLEB128(&actionPos);
    tempActionPos = actionPos;
    actionOffset = readSLEB128(&tempActionPos);
    
#ifdef DEBUG
    fprintf(stderr,
            "handleActionValue(...):typeOffset: <%lld>, "
            "actionOffset: <%lld>.\n",
            typeOffset,
            actionOffset);
#endif
    assert((typeOffset >= 0) && 
           "handleActionValue(...):filters are not supported.");
    
    // Note: A typeOffset == 0 implies that a cleanup llvm.eh.selector
    //       argument has been matched.
    if ((typeOffset > 0) &&
        (type == (classInfo[-typeOffset])->type)) {
#ifdef DEBUG
      fprintf(stderr,
              "handleActionValue(...):actionValue <%d> found.\n",
              i);
#endif
      *resultAction = i + 1;
      ret = true;
      break;
    }
    
#ifdef DEBUG
    fprintf(stderr,
            "handleActionValue(...):actionValue not found.\n");
#endif
    if (!actionOffset)
      break;
    
    actionPos += actionOffset;
  }
  
  return(ret);
}


/// Deals with the Language specific data portion of the emitted dwarf code.
/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param lsda language specific data area
/// @param _Unwind_Action actions minimally supported unwind stage 
///        (forced specifically not supported)
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @param context unwind system context
/// @returns minimally supported unwinding control indicator 
static _Unwind_Reason_Code handleLsda(int version, 
                                      const uint8_t *lsda,
                                      _Unwind_Action actions,
                                      uint64_t exceptionClass, 
                                    struct _Unwind_Exception *exceptionObject,
                                      _Unwind_Context_t context) {
  _Unwind_Reason_Code ret = _URC_CONTINUE_UNWIND;
  
  if (!lsda)
    return(ret);
  
#ifdef DEBUG
  fprintf(stderr, 
          "handleLsda(...):lsda is non-zero.\n");
#endif
  
  // Get the current instruction pointer and offset it before next
  // instruction in the current frame which threw the exception.
  uintptr_t pc = _Unwind_GetIP(context)-1;
  
  // Get beginning current frame's code (as defined by the 
  // emitted dwarf code)
  uintptr_t funcStart = _Unwind_GetRegionStart(context);
  uintptr_t pcOffset = pc - funcStart;
  struct OurExceptionType_t **classInfo = NULL;
  
  // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
  //       dwarf emission
  
  // Parse LSDA header.
  uint8_t lpStartEncoding = *lsda++;
  
  if (lpStartEncoding != llvm::dwarf::DW_EH_PE_omit) {
    readEncodedPointer(&lsda, lpStartEncoding); 
  }
  
  uint8_t ttypeEncoding = *lsda++;
  uintptr_t classInfoOffset;
  
  if (ttypeEncoding != llvm::dwarf::DW_EH_PE_omit) {
    // Calculate type info locations in emitted dwarf code which
    // were flagged by type info arguments to llvm.eh.selector
    // intrinsic
    classInfoOffset = readULEB128(&lsda);
    classInfo = (struct OurExceptionType_t**) (lsda + classInfoOffset);
  }
  
  // Walk call-site table looking for range that 
  // includes current PC. 
  
  uint8_t         callSiteEncoding = *lsda++;
  uint32_t        callSiteTableLength = readULEB128(&lsda);
  const uint8_t   *callSiteTableStart = lsda;
  const uint8_t   *callSiteTableEnd = callSiteTableStart + 
  callSiteTableLength;
  const uint8_t   *actionTableStart = callSiteTableEnd;
  const uint8_t   *callSitePtr = callSiteTableStart;
  
  bool foreignException = false;
  
  while (callSitePtr < callSiteTableEnd) {
    uintptr_t start = readEncodedPointer(&callSitePtr, 
                                         callSiteEncoding);
    uintptr_t length = readEncodedPointer(&callSitePtr, 
                                          callSiteEncoding);
    uintptr_t landingPad = readEncodedPointer(&callSitePtr, 
                                              callSiteEncoding);
    
    // Note: Action value
    uintptr_t actionEntry = readULEB128(&callSitePtr);
    
    if (exceptionClass != ourBaseExceptionClass) {
      // We have been notified of a foreign exception being thrown,
      // and we therefore need to execute cleanup landing pads
      actionEntry = 0;
      foreignException = true;
    }
    
    if (landingPad == 0) {
#ifdef DEBUG
      fprintf(stderr,
              "handleLsda(...): No landing pad found.\n");
#endif
      
      continue; // no landing pad for this entry
    }
    
    if (actionEntry) {
      actionEntry += ((uintptr_t) actionTableStart) - 1;
    }
    else {
#ifdef DEBUG
      fprintf(stderr,
              "handleLsda(...):No action table found.\n");
#endif
    }
    
    bool exceptionMatched = false;
    
    if ((start <= pcOffset) && (pcOffset < (start + length))) {
#ifdef DEBUG
      fprintf(stderr,
              "handleLsda(...): Landing pad found.\n");
#endif
      int64_t actionValue = 0;
      
      if (actionEntry) {
        exceptionMatched = handleActionValue(&actionValue,
                                             classInfo, 
                                             actionEntry, 
                                             exceptionClass, 
                                             exceptionObject);
      }
      
      if (!(actions & _UA_SEARCH_PHASE)) {
#ifdef DEBUG
        fprintf(stderr,
                "handleLsda(...): installed landing pad "
                "context.\n");
#endif
        
        // Found landing pad for the PC.
        // Set Instruction Pointer to so we re-enter function 
        // at landing pad. The landing pad is created by the 
        // compiler to take two parameters in registers.
        _Unwind_SetGR(context, 
                      __builtin_eh_return_data_regno(0), 
                      (uintptr_t)exceptionObject);
        
        // Note: this virtual register directly corresponds
        //       to the return of the llvm.eh.selector intrinsic
        if (!actionEntry || !exceptionMatched) {
          // We indicate cleanup only
          _Unwind_SetGR(context, 
                        __builtin_eh_return_data_regno(1), 
                        0);
        }
        else {
          // Matched type info index of llvm.eh.selector intrinsic
          // passed here.
          _Unwind_SetGR(context, 
                        __builtin_eh_return_data_regno(1), 
                        actionValue);
        }
        
        // To execute landing pad set here
        _Unwind_SetIP(context, funcStart + landingPad);
        ret = _URC_INSTALL_CONTEXT;
      }
      else if (exceptionMatched) {
#ifdef DEBUG
        fprintf(stderr,
                "handleLsda(...): setting handler found.\n");
#endif
        ret = _URC_HANDLER_FOUND;
      }
      else {
        // Note: Only non-clean up handlers are marked as
        //       found. Otherwise the clean up handlers will be 
        //       re-found and executed during the clean up 
        //       phase.
#ifdef DEBUG
        fprintf(stderr,
                "handleLsda(...): cleanup handler found.\n");
#endif
      }
      
      break;
    }
  }
  
  return(ret);
}


/// This is the personality function which is embedded (dwarf emitted), in the
/// dwarf unwind info block. Again see: JITDwarfEmitter.cpp.
/// See @link http://refspecs.freestandards.org/abi-eh-1.21.html @unlink
/// @param version unsupported (ignored), unwind version
/// @param _Unwind_Action actions minimally supported unwind stage 
///        (forced specifically not supported)
/// @param exceptionClass exception class (_Unwind_Exception::exception_class)
///        of thrown exception.
/// @param exceptionObject thrown _Unwind_Exception instance.
/// @param context unwind system context
/// @returns minimally supported unwinding control indicator 
_Unwind_Reason_Code ourPersonality(int version, 
                                   _Unwind_Action actions,
                                   uint64_t exceptionClass, 
                                   struct _Unwind_Exception *exceptionObject,
                                   _Unwind_Context_t context) {
#ifdef DEBUG
  fprintf(stderr, 
          "We are in ourPersonality(...):actions is <%d>.\n",
          actions);
  
  if (actions & _UA_SEARCH_PHASE) {
    fprintf(stderr, "ourPersonality(...):In search phase.\n");
  }
  else {
    fprintf(stderr, "ourPersonality(...):In non-search phase.\n");
  }
#endif
  
  const uint8_t *lsda = _Unwind_GetLanguageSpecificData(context);
  
#ifdef DEBUG
  fprintf(stderr, 
          "ourPersonality(...):lsda = <%p>.\n",
          lsda);
#endif
  
  // The real work of the personality function is captured here
  return(handleLsda(version,
                    lsda,
                    actions,
                    exceptionClass,
                    exceptionObject,
                    context));
}


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

} // extern "C"

//
// Runtime C Library functions End
//

//
// Code generation functions
//

/// Generates code to print given constant string
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param toPrint string to print
/// @param useGlobal A value of true (default) indicates a GlobalValue is 
///        generated, and is used to hold the constant string. A value of 
///        false indicates that the constant string will be stored on the 
///        stack.
void generateStringPrint(llvm::LLVMContext &context, 
                         llvm::Module &module,
                         llvm::IRBuilder<> &builder, 
                         std::string toPrint,
                         bool useGlobal = true) {
  llvm::Function *printFunct = module.getFunction("printStr");
  
  llvm::Value *stringVar;
  llvm::Constant *stringConstant = 
  llvm::ConstantDataArray::getString(context, toPrint);
  
  if (useGlobal) {
    // Note: Does not work without allocation
    stringVar = 
    new llvm::GlobalVariable(module, 
                             stringConstant->getType(),
                             true, 
                             llvm::GlobalValue::LinkerPrivateLinkage, 
                             stringConstant, 
                             "");
  }
  else {
    stringVar = builder.CreateAlloca(stringConstant->getType());
    builder.CreateStore(stringConstant, stringVar);
  }
  
  llvm::Value *cast = builder.CreatePointerCast(stringVar, 
                                                builder.getInt8PtrTy());
  builder.CreateCall(printFunct, cast);
}


/// Generates code to print given runtime integer according to constant
/// string format, and a given print function.
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param printFunct function used to "print" integer
/// @param toPrint string to print
/// @param format printf like formating string for print
/// @param useGlobal A value of true (default) indicates a GlobalValue is 
///        generated, and is used to hold the constant string. A value of 
///        false indicates that the constant string will be stored on the 
///        stack.
void generateIntegerPrint(llvm::LLVMContext &context, 
                          llvm::Module &module,
                          llvm::IRBuilder<> &builder, 
                          llvm::Function &printFunct,
                          llvm::Value &toPrint,
                          std::string format, 
                          bool useGlobal = true) {
  llvm::Constant *stringConstant =
    llvm::ConstantDataArray::getString(context, format);
  llvm::Value *stringVar;
  
  if (useGlobal) {
    // Note: Does not seem to work without allocation
    stringVar = 
    new llvm::GlobalVariable(module, 
                             stringConstant->getType(),
                             true, 
                             llvm::GlobalValue::LinkerPrivateLinkage, 
                             stringConstant, 
                             "");
  }
  else {
    stringVar = builder.CreateAlloca(stringConstant->getType());
    builder.CreateStore(stringConstant, stringVar);
  }
  
  llvm::Value *cast = builder.CreateBitCast(stringVar, 
                                            builder.getInt8PtrTy());
  builder.CreateCall2(&printFunct, &toPrint, cast);
}


/// Generates code to handle finally block type semantics: always runs 
/// regardless of whether a thrown exception is passing through or the 
/// parent function is simply exiting. In addition to printing some state 
/// to stderr, this code will resume the exception handling--runs the 
/// unwind resume block, if the exception has not been previously caught 
/// by a catch clause, and will otherwise execute the end block (terminator 
/// block). In addition this function creates the corresponding function's 
/// stack storage for the exception pointer and catch flag status.
/// @param context llvm context
/// @param module code for module instance
/// @param builder builder instance
/// @param toAddTo parent function to add block to
/// @param blockName block name of new "finally" block.
/// @param functionId output id used for printing
/// @param terminatorBlock terminator "end" block
/// @param unwindResumeBlock unwind resume block
/// @param exceptionCaughtFlag reference exception caught/thrown status storage
/// @param exceptionStorage reference to exception pointer storage
/// @param caughtResultStorage reference to landingpad result storage
/// @returns newly created block
static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, 
                                            llvm::Module &module, 
                                            llvm::IRBuilder<> &builder, 
                                            llvm::Function &toAddTo,
                                            std::string &blockName,
                                            std::string &functionId,
                                            llvm::BasicBlock &terminatorBlock,
                                            llvm::BasicBlock &unwindResumeBlock,
                                            llvm::Value **exceptionCaughtFlag,
                                            llvm::Value **exceptionStorage,
                                            llvm::Value **caughtResultStorage) {
  assert(exceptionCaughtFlag && 
         "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
         "is NULL");
  assert(exceptionStorage && 
         "ExceptionDemo::createFinallyBlock(...):exceptionStorage "
         "is NULL");
  assert(caughtResultStorage && 
         "ExceptionDemo::createFinallyBlock(...):caughtResultStorage "
         "is NULL");
  
  *exceptionCaughtFlag = createEntryBlockAlloca(toAddTo,
                                         "exceptionCaught",
                                         ourExceptionNotThrownState->getType(),
                                         ourExceptionNotThrownState);
  
  llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy();
  *exceptionStorage = createEntryBlockAlloca(toAddTo,
                                             "exceptionStorage",
                                             exceptionStorageType,
                                             llvm::ConstantPointerNull::get(
                                               exceptionStorageType));
  *caughtResultStorage = createEntryBlockAlloca(toAddTo,
                                              "caughtResultStorage",
                                              ourCaughtResultType,
                                              llvm::ConstantAggregateZero::get(
                                                ourCaughtResultType));
  
  llvm::BasicBlock *ret = llvm::BasicBlock::Create(context,
                                                   blockName,
                                                   &toAddTo);
  
  builder.SetInsertPoint(ret);
  
  std::ostringstream bufferToPrint;
  bufferToPrint << "Gen: Executing finally block "
    << blockName << " in " << functionId << "\n";
  generateStringPrint(context, 
                      module, 
                      builder, 
                      bufferToPrint.str(),
                      USE_GLOBAL_STR_CONSTS);
  
  llvm::SwitchInst *theSwitch = builder.CreateSwitch(builder.CreateLoad(
                                                       *exceptionCaughtFlag), 
                                                     &terminatorBlock,
                                                     2);
  theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock);
  theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock);
  
  return(ret);
}


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


/// Generates a function which invokes a function (toInvoke) and, whose 
/// unwind block will "catch" the type info types correspondingly held in the 
/// exceptionTypesToCatch argument. If the toInvoke function throws an 
/// exception which does not match any type info types contained in 
/// exceptionTypesToCatch, the generated code will call _Unwind_Resume 
/// with the raised exception. On the other hand the generated code will 
/// normally exit if the toInvoke function does not throw an exception.
/// The generated "finally" block is always run regardless of the cause of 
/// the generated function exit.
/// The generated function is returned after being verified.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param toInvoke inner function to invoke
/// @param ourId id used to printing purposes
/// @param numExceptionsToCatch length of exceptionTypesToCatch array
/// @param exceptionTypesToCatch array of type info types to "catch"
/// @returns generated function
static
llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, 
                                             llvm::IRBuilder<> &builder, 
                                             llvm::FunctionPassManager &fpm,
                                             llvm::Function &toInvoke,
                                             std::string ourId,
                                             unsigned numExceptionsToCatch,
                                             unsigned exceptionTypesToCatch[]) {
  
  llvm::LLVMContext &context = module.getContext();
  llvm::Function *toPrint32Int = module.getFunction("print32Int");
  
  ArgTypes argTypes;
  argTypes.push_back(builder.getInt32Ty());
  
  ArgNames argNames;
  argNames.push_back("exceptTypeToThrow");
  
  llvm::Function *ret = createFunction(module, 
                                       builder.getVoidTy(),
                                       argTypes, 
                                       argNames, 
                                       ourId,
                                       llvm::Function::ExternalLinkage, 
                                       false, 
                                       false);
  
  // Block which calls invoke
  llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
                                                          "entry", 
                                                          ret);
  // Normal block for invoke
  llvm::BasicBlock *normalBlock = llvm::BasicBlock::Create(context, 
                                                           "normal", 
                                                           ret);
  // Unwind block for invoke
  llvm::BasicBlock *exceptionBlock = llvm::BasicBlock::Create(context, 
                                                              "exception", 
                                                              ret);
  
  // Block which routes exception to correct catch handler block
  llvm::BasicBlock *exceptionRouteBlock = llvm::BasicBlock::Create(context, 
                                                             "exceptionRoute", 
                                                             ret);
  
  // Foreign exception handler
  llvm::BasicBlock *externalExceptionBlock = llvm::BasicBlock::Create(context, 
                                                          "externalException", 
                                                          ret);
  
  // Block which calls _Unwind_Resume
  llvm::BasicBlock *unwindResumeBlock = llvm::BasicBlock::Create(context, 
                                                               "unwindResume", 
                                                               ret);
  
  // Clean up block which delete exception if needed
  llvm::BasicBlock *endBlock = llvm::BasicBlock::Create(context, "end", ret);
  
  std::string nextName;
  std::vector<llvm::BasicBlock*> catchBlocks(numExceptionsToCatch);
  llvm::Value *exceptionCaughtFlag = NULL;
  llvm::Value *exceptionStorage = NULL;
  llvm::Value *caughtResultStorage = NULL;
  
  // Finally block which will branch to unwindResumeBlock if 
  // exception is not caught. Initializes/allocates stack locations.
  llvm::BasicBlock *finallyBlock = createFinallyBlock(context, 
                                                      module, 
                                                      builder, 
                                                      *ret, 
                                                      nextName = "finally", 
                                                      ourId,
                                                      *endBlock,
                                                      *unwindResumeBlock,
                                                      &exceptionCaughtFlag,
                                                      &exceptionStorage,
                                                      &caughtResultStorage
                                                      );
  
  for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
    nextName = ourTypeInfoNames[exceptionTypesToCatch[i]];
    
    // One catch block per type info to be caught
    catchBlocks[i] = createCatchBlock(context, 
                                      module, 
                                      builder, 
                                      *ret,
                                      nextName, 
                                      ourId,
                                      *finallyBlock,
                                      *exceptionCaughtFlag);
  }
  
  // Entry Block
  
  builder.SetInsertPoint(entryBlock);
  
  std::vector<llvm::Value*> args;
  args.push_back(namedValues["exceptTypeToThrow"]);
  builder.CreateInvoke(&toInvoke, 
                       normalBlock, 
                       exceptionBlock, 
                       args);
  
  // End Block
  
  builder.SetInsertPoint(endBlock);
  
  generateStringPrint(context, 
                      module,
                      builder, 
                      "Gen: In end block: exiting in " + ourId + ".\n",
                      USE_GLOBAL_STR_CONSTS);
  llvm::Function *deleteOurException = module.getFunction("deleteOurException");
  
  // Note: function handles NULL exceptions
  builder.CreateCall(deleteOurException, 
                     builder.CreateLoad(exceptionStorage));
  builder.CreateRetVoid();
  
  // Normal Block
  
  builder.SetInsertPoint(normalBlock);
  
  generateStringPrint(context, 
                      module,
                      builder, 
                      "Gen: No exception in " + ourId + "!\n",
                      USE_GLOBAL_STR_CONSTS);
  
  // Finally block is always called
  builder.CreateBr(finallyBlock);
  
  // Unwind Resume Block
  
  builder.SetInsertPoint(unwindResumeBlock);
  
  builder.CreateResume(builder.CreateLoad(caughtResultStorage));
  
  // Exception Block
  
  builder.SetInsertPoint(exceptionBlock);
  
  llvm::Function *personality = module.getFunction("ourPersonality");
  
  llvm::LandingPadInst *caughtResult = 
    builder.CreateLandingPad(ourCaughtResultType,
                             personality,
                             numExceptionsToCatch,
                             "landingPad");

  caughtResult->setCleanup(true);

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

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

  // FIXME: Redundant storage which, beyond utilizing value of 
  //        caughtResultStore for unwindException storage, may be alleviated 
  //        alltogether with a block rearrangement
  builder.CreateStore(caughtResult, caughtResultStorage);
  builder.CreateStore(unwindException, exceptionStorage);
  builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
  
  // Retrieve exception_class member from thrown exception 
  // (_Unwind_Exception instance). This member tells us whether or not
  // the exception is foreign.
  llvm::Value *unwindExceptionClass = 
    builder.CreateLoad(builder.CreateStructGEP(
             builder.CreatePointerCast(unwindException, 
                                       ourUnwindExceptionType->getPointerTo()), 
                                               0));
  
  // Branch to the externalExceptionBlock if the exception is foreign or
  // to a catch router if not. Either way the finally block will be run.
  builder.CreateCondBr(builder.CreateICmpEQ(unwindExceptionClass,
                            llvm::ConstantInt::get(builder.getInt64Ty(), 
                                                   ourBaseExceptionClass)),
                       exceptionRouteBlock,
                       externalExceptionBlock);
  
  // External Exception Block
  
  builder.SetInsertPoint(externalExceptionBlock);
  
  generateStringPrint(context, 
                      module,
                      builder, 
                      "Gen: Foreign exception received.\n",
                      USE_GLOBAL_STR_CONSTS);
  
  // Branch to the finally block
  builder.CreateBr(finallyBlock);
  
  // Exception Route Block
  
  builder.SetInsertPoint(exceptionRouteBlock);
  
  // Casts exception pointer (_Unwind_Exception instance) to parent 
  // (OurException instance).
  //
  // Note: ourBaseFromUnwindOffset is usually negative
  llvm::Value *typeInfoThrown = builder.CreatePointerCast(
                                  builder.CreateConstGEP1_64(unwindException,
                                                       ourBaseFromUnwindOffset),
                                  ourExceptionType->getPointerTo());
  
  // Retrieve thrown exception type info type
  //
  // Note: Index is not relative to pointer but instead to structure
  //       unlike a true getelementptr (GEP) instruction
  typeInfoThrown = builder.CreateStructGEP(typeInfoThrown, 0);
  
  llvm::Value *typeInfoThrownType = 
  builder.CreateStructGEP(typeInfoThrown, 0);
  
  generateIntegerPrint(context, 
                       module,
                       builder, 
                       *toPrint32Int, 
                       *(builder.CreateLoad(typeInfoThrownType)),
                       "Gen: Exception type <%d> received (stack unwound) " 
                       " in " + 
                       ourId + 
                       ".\n",
                       USE_GLOBAL_STR_CONSTS);
  
  // Route to matched type info catch block or run cleanup finally block
  llvm::SwitchInst *switchToCatchBlock = builder.CreateSwitch(retTypeInfoIndex, 
                                                          finallyBlock, 
                                                          numExceptionsToCatch);
  
  unsigned nextTypeToCatch;
  
  for (unsigned i = 1; i <= numExceptionsToCatch; ++i) {
    nextTypeToCatch = i - 1;
    switchToCatchBlock->addCase(llvm::ConstantInt::get(
                                   llvm::Type::getInt32Ty(context), i),
                                catchBlocks[nextTypeToCatch]);
  }

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


/// Generates function which throws either an exception matched to a runtime
/// determined type info type (argument to generated function), or if this 
/// runtime value matches nativeThrowType, throws a foreign exception by 
/// calling nativeThrowFunct.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param ourId id used to printing purposes
/// @param nativeThrowType a runtime argument of this value results in
///        nativeThrowFunct being called to generate/throw exception.
/// @param nativeThrowFunct function which will throw a foreign exception
///        if the above nativeThrowType matches generated function's arg.
/// @returns generated function
static
llvm::Function *createThrowExceptionFunction(llvm::Module &module, 
                                             llvm::IRBuilder<> &builder, 
                                             llvm::FunctionPassManager &fpm,
                                             std::string ourId,
                                             int32_t nativeThrowType,
                                             llvm::Function &nativeThrowFunct) {
  llvm::LLVMContext &context = module.getContext();
  namedValues.clear();
  ArgTypes unwindArgTypes;
  unwindArgTypes.push_back(builder.getInt32Ty());
  ArgNames unwindArgNames;
  unwindArgNames.push_back("exceptTypeToThrow");
  
  llvm::Function *ret = createFunction(module,
                                       builder.getVoidTy(),
                                       unwindArgTypes,
                                       unwindArgNames,
                                       ourId,
                                       llvm::Function::ExternalLinkage,
                                       false,
                                       false);
  
  // Throws either one of our exception or a native C++ exception depending
  // on a runtime argument value containing a type info type.
  llvm::BasicBlock *entryBlock = llvm::BasicBlock::Create(context,
                                                          "entry", 
                                                          ret);
  // Throws a foreign exception
  llvm::BasicBlock *nativeThrowBlock = llvm::BasicBlock::Create(context,
                                                                "nativeThrow", 
                                                                ret);
  // Throws one of our Exceptions
  llvm::BasicBlock *generatedThrowBlock = llvm::BasicBlock::Create(context,
                                                             "generatedThrow", 
                                                             ret);
  // Retrieved runtime type info type to throw
  llvm::Value *exceptionType = namedValues["exceptTypeToThrow"];
  
  // nativeThrowBlock block
  
  builder.SetInsertPoint(nativeThrowBlock);
  
  // Throws foreign exception
  builder.CreateCall(&nativeThrowFunct, exceptionType);
  builder.CreateUnreachable();
  
  // entry block
  
  builder.SetInsertPoint(entryBlock);
  
  llvm::Function *toPrint32Int = module.getFunction("print32Int");
  generateIntegerPrint(context, 
                       module,
                       builder, 
                       *toPrint32Int, 
                       *exceptionType, 
                       "\nGen: About to throw exception type <%d> in " + 
                       ourId + 
                       ".\n",
                       USE_GLOBAL_STR_CONSTS);
  
  // Switches on runtime type info type value to determine whether or not
  // a foreign exception is thrown. Defaults to throwing one of our 
  // generated exceptions.
  llvm::SwitchInst *theSwitch = builder.CreateSwitch(exceptionType,
                                                     generatedThrowBlock,
                                                     1);
  
  theSwitch->addCase(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), 
                                            nativeThrowType),
                     nativeThrowBlock);
  
  // generatedThrow block
  
  builder.SetInsertPoint(generatedThrowBlock);
  
  llvm::Function *createOurException = module.getFunction("createOurException");
  llvm::Function *raiseOurException = module.getFunction(
                                        "_Unwind_RaiseException");
  
  // Creates exception to throw with runtime type info type.
  llvm::Value *exception = builder.CreateCall(createOurException, 
                                              namedValues["exceptTypeToThrow"]);
  
  // Throw generated Exception
  builder.CreateCall(raiseOurException, exception);
  builder.CreateUnreachable();
  
  llvm::verifyFunction(*ret);
  fpm.run(*ret);
  
  return(ret);
}

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

/// Creates test code by generating and organizing these functions into the 
/// test case. The test case consists of an outer function setup to invoke
/// an inner function within an environment having multiple catch and single 
/// finally blocks. This inner function is also setup to invoke a throw
/// function within an evironment similar in nature to the outer function's 
/// catch and finally blocks. Each of these two functions catch mutually
/// exclusive subsets (even or odd) of the type info types configured
/// for this this. All generated functions have a runtime argument which
/// holds a type info type to throw that each function takes and passes it
/// to the inner one if such a inner function exists. This type info type is
/// looked at by the generated throw function to see whether or not it should
/// throw a generated exception with the same type info type, or instead call
/// a supplied a function which in turn will throw a foreign exception.
/// @param module code for module instance
/// @param builder builder instance
/// @param fpm a function pass manager holding optional IR to IR 
///        transformations
/// @param nativeThrowFunctName name of external function which will throw
///        a foreign exception
/// @returns outermost generated test function.
llvm::Function *createUnwindExceptionTest(llvm::Module &module, 
                                          llvm::IRBuilder<> &builder, 
                                          llvm::FunctionPassManager &fpm,
                                          std::string nativeThrowFunctName) {
  // Number of type infos to generate
  unsigned numTypeInfos = 6;
  
  // Initialze intrisics and external functions to use along with exception
  // and type info globals.
  createStandardUtilityFunctions(numTypeInfos,
                                 module,
                                 builder);
  llvm::Function *nativeThrowFunct = module.getFunction(nativeThrowFunctName);
  
  // Create exception throw function using the value ~0 to cause 
  // foreign exceptions to be thrown.
  llvm::Function *throwFunct = createThrowExceptionFunction(module,
                                                            builder,
                                                            fpm,
                                                            "throwFunct",
                                                            ~0,
                                                            *nativeThrowFunct);
  // Inner function will catch even type infos
  unsigned innerExceptionTypesToCatch[] = {6, 2, 4};
  size_t numExceptionTypesToCatch = sizeof(innerExceptionTypesToCatch) / 
                                    sizeof(unsigned);
  
  // Generate inner function.
  llvm::Function *innerCatchFunct = createCatchWrappedInvokeFunction(module,
                                                    builder,
                                                    fpm,
                                                    *throwFunct,
                                                    "innerCatchFunct",
                                                    numExceptionTypesToCatch,
                                                    innerExceptionTypesToCatch);
  
  // Outer function will catch odd type infos
  unsigned outerExceptionTypesToCatch[] = {3, 1, 5};
  numExceptionTypesToCatch = sizeof(outerExceptionTypesToCatch) / 
  sizeof(unsigned);
  
  // Generate outer function
  llvm::Function *outerCatchFunct = createCatchWrappedInvokeFunction(module,
                                                    builder,
                                                    fpm,
                                                    *innerCatchFunct,
                                                    "outerCatchFunct",
                                                    numExceptionTypesToCatch,
                                                    outerExceptionTypesToCatch);
  
  // Return outer function to run
  return(outerCatchFunct);
}


/// Represents our foreign exceptions
class OurCppRunException : public std::runtime_error {
public:
  OurCppRunException(const std::string reason) :
  std::runtime_error(reason) {}
  
  OurCppRunException (const OurCppRunException &toCopy) :
  std::runtime_error(toCopy) {}
  
  OurCppRunException &operator = (const OurCppRunException &toCopy) {
    return(reinterpret_cast<OurCppRunException&>(
                                 std::runtime_error::operator=(toCopy)));
  }
  
  ~OurCppRunException (void) throw () {}
};


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

typedef void (*OurExceptionThrowFunctType) (int32_t typeToThrow);

/// This is a test harness which runs test by executing generated 
/// function with a type info type to throw. Harness wraps the execution
/// of generated function in a C++ try catch clause.
/// @param engine execution engine to use for executing generated function.
///        This demo program expects this to be a JIT instance for demo
///        purposes.
/// @param function generated test function to run
/// @param typeToThrow type info type of generated exception to throw, or
///        indicator to cause foreign exception to be thrown.
static
void runExceptionThrow(llvm::ExecutionEngine *engine, 
                       llvm::Function *function, 
                       int32_t typeToThrow) {
  
  // Find test's function pointer
  OurExceptionThrowFunctType functPtr = 
    reinterpret_cast<OurExceptionThrowFunctType>(
       reinterpret_cast<intptr_t>(engine->getPointerToFunction(function)));
  
  try {
    // Run test
    (*functPtr)(typeToThrow);
  }
  catch (OurCppRunException exc) {
    // Catch foreign C++ exception
    fprintf(stderr,
            "\nrunExceptionThrow(...):In C++ catch OurCppRunException "
            "with reason: %s.\n", 
            exc.what());
  }
  catch (...) {
    // Catch all exceptions including our generated ones. This latter 
    // functionality works according to the example in rules 1.6.4 of
    // http://sourcery.mentor.com/public/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;
  llvm::GlobalVariable *nextGlobal = NULL;
  
  // Generate each type info
  //
  // Note: First type info is not used.
  for (unsigned i = 0; i <= numTypeInfos; ++i) {
    structVals.clear();
    structVals.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), i));
    nextStruct = llvm::ConstantStruct::get(ourTypeInfoType, structVals);
    
    typeInfoNameBuilder.str("");
    typeInfoNameBuilder << baseStr << i;
    typeInfoName = typeInfoNameBuilder.str();
    
    // Note: Does not seem to work without allocation
    nextGlobal = 
    new llvm::GlobalVariable(module, 
                             ourTypeInfoType, 
                             true, 
                             llvm::GlobalValue::ExternalLinkage, 
                             nextStruct, 
                             typeInfoName);
    
    ourTypeInfoNames.push_back(typeInfoName);
    ourTypeInfoNamesIndex[i] = typeInfoName;
  }
  
  ArgNames argNames;
  ArgTypes argTypes;
  llvm::Function *funct = NULL;
  
  // print32Int
  
  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->addFnAttr(llvm::Attribute::NoReturn);
  
  // _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->addFnAttr(llvm::Attribute::NoReturn);
  
  // ourPersonality
  
  retType = builder.getInt32Ty();
  
  argTypes.clear();
  argTypes.push_back(builder.getInt32Ty());
  argTypes.push_back(builder.getInt32Ty());
  argTypes.push_back(builder.getInt64Ty());
  argTypes.push_back(builder.getInt8PtrTy());
  argTypes.push_back(builder.getInt8PtrTy());
  
  argNames.clear();
  
  createFunction(module, 
                 retType, 
                 argTypes, 
                 argNames, 
                 "ourPersonality", 
                 llvm::Function::ExternalLinkage, 
                 true, 
                 false);
  
  // llvm.eh.typeid.for intrinsic
  
  getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
}


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

/// Demo main routine which takes the type info types to throw. A test will
/// be run for each given type info type. While type info types with the value 
/// of -1 will trigger a foreign C++ exception to be thrown; type info types
/// <= 6 and >= 1 will be caught by test functions; and type info types > 6
/// will result in exceptions which pass through to the test harness. All other
/// type info types are not supported and could cause a crash.
int main(int argc, char *argv[]) {
  if (argc == 1) {
    fprintf(stderr,
            "\nUsage: ExceptionDemo <exception type to throw> "
            "[<type 2>...<type n>].\n"
            "   Each type must have the value of 1 - 6 for "
            "generated exceptions to be caught;\n"
            "   the value -1 for foreign C++ exceptions to be "
            "generated and thrown;\n"
            "   or the values > 6 for exceptions to be ignored.\n"
            "\nTry: ExceptionDemo 2 3 7 -1\n"
            "   for a full test.\n\n");
    return(0);
  }
  
  // If not set, exception handling will not be turned on
  llvm::TargetOptions Opts;
  Opts.JITExceptionHandling = true;
  
  llvm::InitializeNativeTarget();
  llvm::LLVMContext &context = llvm::getGlobalContext();
  llvm::IRBuilder<> theBuilder(context);
  
  // Make the module, which holds all the code.
  llvm::Module *module = new llvm::Module("my cool jit", context);
  
  // Build engine with JIT
  llvm::EngineBuilder factory(module);
  factory.setEngineKind(llvm::EngineKind::JIT);
  factory.setAllocateGVsWithCode(false);
  factory.setTargetOptions(Opts);
  llvm::ExecutionEngine *executionEngine = factory.create();
  
  {
    llvm::FunctionPassManager fpm(module);
    
    // Set up the optimizer pipeline.  
    // Start with registering info about how the
    // target lays out data structures.
    fpm.add(new llvm::TargetData(*executionEngine->getTargetData()));
    
    // Optimizations turned on
#ifdef ADD_OPT_PASSES
    
    // Basic AliasAnslysis support for GVN.
    fpm.add(llvm::createBasicAliasAnalysisPass());
    
    // Promote allocas to registers.
    fpm.add(llvm::createPromoteMemoryToRegisterPass());
    
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    fpm.add(llvm::createInstructionCombiningPass());
    
    // Reassociate expressions.
    fpm.add(llvm::createReassociatePass());
    
    // Eliminate Common SubExpressions.
    fpm.add(llvm::createGVNPass());
    
    // Simplify the control flow graph (deleting unreachable 
    // blocks, etc).
    fpm.add(llvm::createCFGSimplificationPass());
#endif  // ADD_OPT_PASSES
    
    fpm.doInitialization();
    
    // Generate test code using function throwCppException(...) as
    // the function which throws foreign exceptions.
    llvm::Function *toRun = 
    createUnwindExceptionTest(*module, 
                              theBuilder, 
                              fpm,
                              "throwCppException");
    
    fprintf(stderr, "\nBegin module dump:\n\n");
    
    module->dump();
    
    fprintf(stderr, "\nEnd module dump:\n");
    
    fprintf(stderr, "\n\nBegin Test:\n");
    
    for (int i = 1; i < argc; ++i) {
      // Run test for each argument whose value is the exception
      // type to throw.
      runExceptionThrow(executionEngine, 
                        toRun, 
                        (unsigned) strtoul(argv[i], NULL, 10));
    }
    
    fprintf(stderr, "\nEnd Test:\n\n");
  } 
  
  delete executionEngine;
  
  return 0;
}

