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

#ifdef OLD_EXC_SYSTEM
// See use of UpgradeExceptionHandling(...) below                        
#include "llvm/AutoUpgrade.h"
#endif

// 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;
#ifndef OLD_EXC_SYSTEM
static llvm::StructType *ourCaughtResultType;
#endif
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::ConstantArray::get(context, toPrint);
  
  if (useGlobal) {
    // Note: Does not work without allocation
    stringVar = 
    new llvm::GlobalVariable(module, 
                             stringConstant->getType(),
                             true, 
                             llvm::GlobalValue::LinkerPrivateLinkage, 
                             stringConstant, 
                             "");
  }
  else {
    stringVar = builder.CreateAlloca(stringConstant->getType());
    builder.CreateStore(stringConstant, stringVar);
  }
  
  llvm::Value *cast = builder.CreatePointerCast(stringVar, 
                                                builder.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::ConstantArray::get(context, format);
  llvm::Value *stringVar;
  
  if (useGlobal) {
    // Note: Does not seem to work without allocation
    stringVar = 
    new llvm::GlobalVariable(module, 
                             stringConstant->getType(),
                             true, 
                             llvm::GlobalValue::LinkerPrivateLinkage, 
                             stringConstant, 
                             "");
  }
  else {
    stringVar = builder.CreateAlloca(stringConstant->getType());
    builder.CreateStore(stringConstant, stringVar);
  }
  
  llvm::Value *cast = builder.CreateBitCast(stringVar, 
                                            builder.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
#ifndef OLD_EXC_SYSTEM
/// @param caughtResultStorage reference to landingpad result storage
#endif
/// @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
#ifndef OLD_EXC_SYSTEM
                                            ,llvm::Value **caughtResultStorage
#endif
                                            ) {
  assert(exceptionCaughtFlag && 
         "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag "
         "is NULL");
  assert(exceptionStorage && 
         "ExceptionDemo::createFinallyBlock(...):exceptionStorage "
         "is NULL");

#ifndef OLD_EXC_SYSTEM
  assert(caughtResultStorage && 
         "ExceptionDemo::createFinallyBlock(...):caughtResultStorage "
         "is NULL");
#endif
  
  *exceptionCaughtFlag = createEntryBlockAlloca(toAddTo,
                                         "exceptionCaught",
                                         ourExceptionNotThrownState->getType(),
                                         ourExceptionNotThrownState);
  
  llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy();
  *exceptionStorage = createEntryBlockAlloca(toAddTo,
                                             "exceptionStorage",
                                             exceptionStorageType,
                                             llvm::ConstantPointerNull::get(
                                               exceptionStorageType));
#ifndef OLD_EXC_SYSTEM
  *caughtResultStorage = createEntryBlockAlloca(toAddTo,
                                              "caughtResultStorage",
                                              ourCaughtResultType,
                                              llvm::ConstantAggregateZero::get(
                                                ourCaughtResultType));
#endif
  
  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;
#ifndef OLD_EXC_SYSTEM
  llvm::Value *caughtResultStorage = NULL;
#endif
  
  // 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
#ifndef OLD_EXC_SYSTEM
                                                      ,&caughtResultStorage
#endif
                                                      );
  
  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);
  
  
#ifndef OLD_EXC_SYSTEM
  builder.CreateResume(builder.CreateLoad(caughtResultStorage));
#else
  llvm::Function *resumeOurException = module.getFunction("_Unwind_Resume");
  builder.CreateCall(resumeOurException, 
                     builder.CreateLoad(exceptionStorage));
  builder.CreateUnreachable();
#endif
  
  // Exception Block
  
  builder.SetInsertPoint(exceptionBlock);
  
  llvm::Function *personality = module.getFunction("ourPersonality");
  
#ifndef OLD_EXC_SYSTEM
  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);
#else
  llvm::Function *ehException = module.getFunction("llvm.eh.exception");

  // Retrieve thrown exception
  llvm::Value *unwindException = builder.CreateCall(ehException);
  
  // Store exception and flag
  builder.CreateStore(unwindException, exceptionStorage);
  builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag);
  llvm::Value *functPtr = builder.CreatePointerCast(personality, 
                                                    builder.getInt8PtrTy());
  
  args.clear();
  args.push_back(unwindException);
  args.push_back(functPtr);
  
  // Note: Skipping index 0
  for (unsigned i = 0; i < numExceptionsToCatch; ++i) {
    // Set up type infos to be caught
    args.push_back(module.getGlobalVariable(
                                  ourTypeInfoNames[exceptionTypesToCatch[i]]));
  }
  
  args.push_back(llvm::ConstantInt::get(builder.getInt32Ty(), 0));
  
  llvm::Function *ehSelector = module.getFunction("llvm.eh.selector");
  
  // Set up this exeption block as the landing pad which will handle
  // given type infos. See case Intrinsic::eh_selector in 
  // SelectionDAGBuilder::visitIntrinsicCall(...) and AddCatchInfo(...)
  // implemented in FunctionLoweringInfo.cpp to see how the implementation
  // handles this call. This landing pad (this exception block), will be 
  // called either because it nees to cleanup (call finally) or a type 
  // info was found which matched the thrown exception.
  llvm::Value *retTypeInfoIndex = builder.CreateCall(ehSelector, args);
#endif
  
  // 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]);
  }

#ifdef OLD_EXC_SYSTEM
  // Must be run before verifier                                                
  UpgradeExceptionHandling(&module);
#endif

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

#ifndef OLD_EXC_SYSTEM

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

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

#endif

  // 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.selector intrinsic
  
  getDeclaration(&module, llvm::Intrinsic::eh_selector);
  
  // llvm.eh.exception intrinsic
  
  getDeclaration(&module, llvm::Intrinsic::eh_exception);
  
  // llvm.eh.typeid.for intrinsic
  
  getDeclaration(&module, llvm::Intrinsic::eh_typeid_for);
}


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

/// Demo main routine which takes the type info types to throw. A test will
/// be run for each given type info type. While type info types with the value 
/// of -1 will trigger a foreign C++ exception to be thrown; type info types
/// <= 6 and >= 1 will be caught by test functions; and type info types > 6
/// will result in exceptions which pass through to the test harness. All other
/// type info types are not supported and could cause a crash.
int main(int argc, char *argv[]) {
  if (argc == 1) {
    fprintf(stderr,
            "\nUsage: ExceptionDemo <exception type to throw> "
            "[<type 2>...<type n>].\n"
            "   Each type must have the value of 1 - 6 for "
            "generated exceptions to be caught;\n"
            "   the value -1 for foreign C++ exceptions to be "
            "generated and thrown;\n"
            "   or the values > 6 for exceptions to be ignored.\n"
            "\nTry: ExceptionDemo 2 3 7 -1\n"
            "   for a full test.\n\n");
    return(0);
  }
  
  // If not set, exception handling will not be turned on
  llvm::JITExceptionHandling = true;
  
  llvm::InitializeNativeTarget();
  llvm::LLVMContext &context = llvm::getGlobalContext();
  llvm::IRBuilder<> theBuilder(context);
  
  // Make the module, which holds all the code.
  llvm::Module *module = new llvm::Module("my cool jit", context);
  
  // Build engine with JIT
  llvm::EngineBuilder factory(module);
  factory.setEngineKind(llvm::EngineKind::JIT);
  factory.setAllocateGVsWithCode(false);
  llvm::ExecutionEngine *executionEngine = factory.create();
  
  {
    llvm::FunctionPassManager fpm(module);
    
    // Set up the optimizer pipeline.  
    // Start with registering info about how the
    // target lays out data structures.
    fpm.add(new llvm::TargetData(*executionEngine->getTargetData()));
    
    // Optimizations turned on
#ifdef ADD_OPT_PASSES
    
    // 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;
}

