diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp
new file mode 100644
index 0000000..b1ba001
--- /dev/null
+++ b/tools/llvm2cpp/CppWriter.cpp
@@ -0,0 +1,1884 @@
+//===-- CppWriter.cpp - Printing LLVM IR as a C++ Source File -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the writing of the LLVM IR as a set of C++ calls to the
+// LLVM IR interface. The input module is assumed to be verified.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Instruction.h"
+#include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/Module.h"
+#include "llvm/TypeSymbolTable.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Config/config.h"
+#include <algorithm>
+#include <iostream>
+#include <set>
+
+using namespace llvm;
+
+static cl::opt<std::string>
+FuncName("funcname", cl::desc("Specify the name of the generated function"),
+         cl::value_desc("function name"));
+
+enum WhatToGenerate {
+  GenProgram,
+  GenModule,
+  GenContents,
+  GenFunction,
+  GenInline,
+  GenVariable,
+  GenType
+};
+
+static cl::opt<WhatToGenerate> GenerationType(cl::Optional,
+  cl::desc("Choose what kind of output to generate"),
+  cl::init(GenProgram),
+  cl::values(
+    clEnumValN(GenProgram, "gen-program",  "Generate a complete program"),
+    clEnumValN(GenModule,  "gen-module",   "Generate a module definition"),
+    clEnumValN(GenContents,"gen-contents", "Generate contents of a module"),
+    clEnumValN(GenFunction,"gen-function", "Generate a function definition"),
+    clEnumValN(GenInline,  "gen-inline",   "Generate an inline function"),
+    clEnumValN(GenVariable,"gen-variable", "Generate a variable definition"),
+    clEnumValN(GenType,    "gen-type",     "Generate a type definition"),
+    clEnumValEnd
+  )
+);
+
+static cl::opt<std::string> NameToGenerate("for", cl::Optional,
+  cl::desc("Specify the name of the thing to generate"),
+  cl::init("!bad!"));
+
+namespace {
+typedef std::vector<const Type*> TypeList;
+typedef std::map<const Type*,std::string> TypeMap;
+typedef std::map<const Value*,std::string> ValueMap;
+typedef std::set<std::string> NameSet;
+typedef std::set<const Type*> TypeSet;
+typedef std::set<const Value*> ValueSet;
+typedef std::map<const Value*,std::string> ForwardRefMap;
+
+class CppWriter {
+  const char* progname;
+  std::ostream &Out;
+  const Module *TheModule;
+  uint64_t uniqueNum;
+  TypeMap TypeNames;
+  ValueMap ValueNames;
+  TypeMap UnresolvedTypes;
+  TypeList TypeStack;
+  NameSet UsedNames;
+  TypeSet DefinedTypes;
+  ValueSet DefinedValues;
+  ForwardRefMap ForwardRefs;
+  bool is_inline;
+
+public:
+  inline CppWriter(std::ostream &o, const Module *M, const char* pn="llvm2cpp")
+    : progname(pn), Out(o), TheModule(M), uniqueNum(0), TypeNames(),
+      ValueNames(), UnresolvedTypes(), TypeStack(), is_inline(false) { }
+
+  const Module* getModule() { return TheModule; }
+
+  void printProgram(const std::string& fname, const std::string& modName );
+  void printModule(const std::string& fname, const std::string& modName );
+  void printContents(const std::string& fname, const std::string& modName );
+  void printFunction(const std::string& fname, const std::string& funcName );
+  void printInline(const std::string& fname, const std::string& funcName );
+  void printVariable(const std::string& fname, const std::string& varName );
+  void printType(const std::string& fname, const std::string& typeName );
+
+  void error(const std::string& msg);
+
+private:
+  void printLinkageType(GlobalValue::LinkageTypes LT);
+  void printCallingConv(unsigned cc);
+  void printEscapedString(const std::string& str);
+  void printCFP(const ConstantFP* CFP);
+
+  std::string getCppName(const Type* val);
+  inline void printCppName(const Type* val);
+
+  std::string getCppName(const Value* val);
+  inline void printCppName(const Value* val);
+
+  bool printTypeInternal(const Type* Ty);
+  inline void printType(const Type* Ty);
+  void printTypes(const Module* M);
+
+  void printConstant(const Constant *CPV);
+  void printConstants(const Module* M);
+
+  void printVariableUses(const GlobalVariable *GV);
+  void printVariableHead(const GlobalVariable *GV);
+  void printVariableBody(const GlobalVariable *GV);
+
+  void printFunctionUses(const Function *F);
+  void printFunctionHead(const Function *F);
+  void printFunctionBody(const Function *F);
+  void printInstruction(const Instruction *I, const std::string& bbname);
+  std::string getOpName(Value*);
+
+  void printModuleBody();
+
+};
+
+static unsigned indent_level = 0;
+inline std::ostream& nl(std::ostream& Out, int delta = 0) {
+  Out << "\n";
+  if (delta >= 0 || indent_level >= unsigned(-delta))
+    indent_level += delta;
+  for (unsigned i = 0; i < indent_level; ++i) 
+    Out << "  ";
+  return Out;
+}
+
+inline void in() { indent_level++; }
+inline void out() { if (indent_level >0) indent_level--; }
+
+inline void
+sanitize(std::string& str) {
+  for (size_t i = 0; i < str.length(); ++i)
+    if (!isalnum(str[i]) && str[i] != '_')
+      str[i] = '_';
+}
+
+inline std::string
+getTypePrefix(const Type* Ty ) {
+  switch (Ty->getTypeID()) {
+    case Type::VoidTyID:     return "void_";
+    case Type::IntegerTyID:  
+      return std::string("int") + utostr(cast<IntegerType>(Ty)->getBitWidth()) +
+        "_";
+    case Type::FloatTyID:    return "float_"; 
+    case Type::DoubleTyID:   return "double_"; 
+    case Type::LabelTyID:    return "label_"; 
+    case Type::FunctionTyID: return "func_"; 
+    case Type::StructTyID:   return "struct_"; 
+    case Type::ArrayTyID:    return "array_"; 
+    case Type::PointerTyID:  return "ptr_"; 
+    case Type::VectorTyID:   return "packed_"; 
+    case Type::OpaqueTyID:   return "opaque_"; 
+    default:                 return "other_"; 
+  }
+  return "unknown_";
+}
+
+// Looks up the type in the symbol table and returns a pointer to its name or
+// a null pointer if it wasn't found. Note that this isn't the same as the
+// Mode::getTypeName function which will return an empty string, not a null
+// pointer if the name is not found.
+inline const std::string* 
+findTypeName(const TypeSymbolTable& ST, const Type* Ty)
+{
+  TypeSymbolTable::const_iterator TI = ST.begin();
+  TypeSymbolTable::const_iterator TE = ST.end();
+  for (;TI != TE; ++TI)
+    if (TI->second == Ty)
+      return &(TI->first);
+  return 0;
+}
+
+void
+CppWriter::error(const std::string& msg) {
+  std::cerr << progname << ": " << msg << "\n";
+  exit(2);
+}
+
+// printCFP - Print a floating point constant .. very carefully :)
+// This makes sure that conversion to/from floating yields the same binary
+// result so that we don't lose precision.
+void 
+CppWriter::printCFP(const ConstantFP *CFP) {
+  Out << "ConstantFP::get(";
+  if (CFP->getType() == Type::DoubleTy)
+    Out << "Type::DoubleTy, ";
+  else
+    Out << "Type::FloatTy, ";
+#if HAVE_PRINTF_A
+  char Buffer[100];
+  sprintf(Buffer, "%A", CFP->getValue());
+  if ((!strncmp(Buffer, "0x", 2) ||
+       !strncmp(Buffer, "-0x", 3) ||
+       !strncmp(Buffer, "+0x", 3)) &&
+      (atof(Buffer) == CFP->getValue()))
+    if (CFP->getType() == Type::DoubleTy)
+      Out << "BitsToDouble(" << Buffer << ")";
+    else
+      Out << "BitsToFloat(" << Buffer << ")";
+  else {
+#endif
+    std::string StrVal = ftostr(CFP->getValue());
+
+    while (StrVal[0] == ' ')
+      StrVal.erase(StrVal.begin());
+
+    // Check to make sure that the stringized number is not some string like 
+    // "Inf" or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
+    if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+        ((StrVal[0] == '-' || StrVal[0] == '+') &&
+         (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
+        (atof(StrVal.c_str()) == CFP->getValue()))
+      if (CFP->getType() == Type::DoubleTy)
+        Out <<  StrVal;
+      else
+        Out << StrVal;
+    else if (CFP->getType() == Type::DoubleTy)
+      Out << "BitsToDouble(0x" << std::hex << DoubleToBits(CFP->getValue()) 
+          << std::dec << "ULL) /* " << StrVal << " */";
+    else 
+      Out << "BitsToFloat(0x" << std::hex << FloatToBits(CFP->getValue()) 
+          << std::dec << "U) /* " << StrVal << " */";
+#if HAVE_PRINTF_A
+  }
+#endif
+  Out << ")";
+}
+
+void
+CppWriter::printCallingConv(unsigned cc){
+  // Print the calling convention.
+  switch (cc) {
+    case CallingConv::C:     Out << "CallingConv::C"; break;
+    case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
+    case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
+    case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
+    default:                 Out << cc; break;
+  }
+}
+
+void 
+CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
+  switch (LT) {
+    case GlobalValue::InternalLinkage:  
+      Out << "GlobalValue::InternalLinkage"; break;
+    case GlobalValue::LinkOnceLinkage:  
+      Out << "GlobalValue::LinkOnceLinkage "; break;
+    case GlobalValue::WeakLinkage:      
+      Out << "GlobalValue::WeakLinkage"; break;
+    case GlobalValue::AppendingLinkage: 
+      Out << "GlobalValue::AppendingLinkage"; break;
+    case GlobalValue::ExternalLinkage: 
+      Out << "GlobalValue::ExternalLinkage"; break;
+    case GlobalValue::DLLImportLinkage: 
+      Out << "GlobalValue::DLLImportLinkage"; break;
+    case GlobalValue::DLLExportLinkage: 
+      Out << "GlobalValue::DLLExportLinkage"; break;
+    case GlobalValue::ExternalWeakLinkage: 
+      Out << "GlobalValue::ExternalWeakLinkage"; break;
+    case GlobalValue::GhostLinkage:
+      Out << "GlobalValue::GhostLinkage"; break;
+  }
+}
+
+// printEscapedString - Print each character of the specified string, escaping
+// it if it is not printable or if it is an escape char.
+void 
+CppWriter::printEscapedString(const std::string &Str) {
+  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+    unsigned char C = Str[i];
+    if (isprint(C) && C != '"' && C != '\\') {
+      Out << C;
+    } else {
+      Out << "\\x"
+          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
+          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
+    }
+  }
+}
+
+std::string
+CppWriter::getCppName(const Type* Ty)
+{
+  // First, handle the primitive types .. easy
+  if (Ty->isPrimitiveType() || Ty->isInteger()) {
+    switch (Ty->getTypeID()) {
+      case Type::VoidTyID:   return "Type::VoidTy";
+      case Type::IntegerTyID: {
+        unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+        return "IntegerType::get(" + utostr(BitWidth) + ")";
+      }
+      case Type::FloatTyID:  return "Type::FloatTy";
+      case Type::DoubleTyID: return "Type::DoubleTy";
+      case Type::LabelTyID:  return "Type::LabelTy";
+      default:
+        error("Invalid primitive type");
+        break;
+    }
+    return "Type::VoidTy"; // shouldn't be returned, but make it sensible
+  }
+
+  // Now, see if we've seen the type before and return that
+  TypeMap::iterator I = TypeNames.find(Ty);
+  if (I != TypeNames.end())
+    return I->second;
+
+  // Okay, let's build a new name for this type. Start with a prefix
+  const char* prefix = 0;
+  switch (Ty->getTypeID()) {
+    case Type::FunctionTyID:    prefix = "FuncTy_"; break;
+    case Type::StructTyID:      prefix = "StructTy_"; break;
+    case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
+    case Type::PointerTyID:     prefix = "PointerTy_"; break;
+    case Type::OpaqueTyID:      prefix = "OpaqueTy_"; break;
+    case Type::VectorTyID:      prefix = "VectorTy_"; break;
+    default:                    prefix = "OtherTy_"; break; // prevent breakage
+  }
+
+  // See if the type has a name in the symboltable and build accordingly
+  const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty);
+  std::string name;
+  if (tName) 
+    name = std::string(prefix) + *tName;
+  else
+    name = std::string(prefix) + utostr(uniqueNum++);
+  sanitize(name);
+
+  // Save the name
+  return TypeNames[Ty] = name;
+}
+
+void
+CppWriter::printCppName(const Type* Ty)
+{
+  printEscapedString(getCppName(Ty));
+}
+
+std::string
+CppWriter::getCppName(const Value* val) {
+  std::string name;
+  ValueMap::iterator I = ValueNames.find(val);
+  if (I != ValueNames.end() && I->first == val)
+    return  I->second;
+
+  if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
+    name = std::string("gvar_") + 
+           getTypePrefix(GV->getType()->getElementType());
+  } else if (isa<Function>(val)) {
+    name = std::string("func_");
+  } else if (const Constant* C = dyn_cast<Constant>(val)) {
+    name = std::string("const_") + getTypePrefix(C->getType());
+  } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
+    if (is_inline) {
+      unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
+          Function::const_arg_iterator(Arg)) + 1;
+      name = std::string("arg_") + utostr(argNum);
+      NameSet::iterator NI = UsedNames.find(name);
+      if (NI != UsedNames.end())
+        name += std::string("_") + utostr(uniqueNum++);
+      UsedNames.insert(name);
+      return ValueNames[val] = name;
+    } else {
+      name = getTypePrefix(val->getType());
+    }
+  } else {
+    name = getTypePrefix(val->getType());
+  }
+  name += (val->hasName() ? val->getName() : utostr(uniqueNum++));
+  sanitize(name);
+  NameSet::iterator NI = UsedNames.find(name);
+  if (NI != UsedNames.end())
+    name += std::string("_") + utostr(uniqueNum++);
+  UsedNames.insert(name);
+  return ValueNames[val] = name;
+}
+
+void
+CppWriter::printCppName(const Value* val) {
+  printEscapedString(getCppName(val));
+}
+
+bool
+CppWriter::printTypeInternal(const Type* Ty) {
+  // We don't print definitions for primitive types
+  if (Ty->isPrimitiveType() || Ty->isInteger())
+    return false;
+
+  // If we already defined this type, we don't need to define it again.
+  if (DefinedTypes.find(Ty) != DefinedTypes.end())
+    return false;
+
+  // Everything below needs the name for the type so get it now.
+  std::string typeName(getCppName(Ty));
+
+  // Search the type stack for recursion. If we find it, then generate this
+  // as an OpaqueType, but make sure not to do this multiple times because
+  // the type could appear in multiple places on the stack. Once the opaque
+  // definition is issued, it must not be re-issued. Consequently we have to
+  // check the UnresolvedTypes list as well.
+  TypeList::const_iterator TI = std::find(TypeStack.begin(),TypeStack.end(),Ty);
+  if (TI != TypeStack.end()) {
+    TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
+    if (I == UnresolvedTypes.end()) {
+      Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();";
+      nl(Out);
+      UnresolvedTypes[Ty] = typeName;
+    }
+    return true;
+  }
+
+  // We're going to print a derived type which, by definition, contains other
+  // types. So, push this one we're printing onto the type stack to assist with
+  // recursive definitions.
+  TypeStack.push_back(Ty);
+
+  // Print the type definition
+  switch (Ty->getTypeID()) {
+    case Type::FunctionTyID:  {
+      const FunctionType* FT = cast<FunctionType>(Ty);
+      Out << "std::vector<const Type*>" << typeName << "_args;";
+      nl(Out);
+      FunctionType::param_iterator PI = FT->param_begin();
+      FunctionType::param_iterator PE = FT->param_end();
+      for (; PI != PE; ++PI) {
+        const Type* argTy = static_cast<const Type*>(*PI);
+        bool isForward = printTypeInternal(argTy);
+        std::string argName(getCppName(argTy));
+        Out << typeName << "_args.push_back(" << argName;
+        if (isForward)
+          Out << "_fwd";
+        Out << ");";
+        nl(Out);
+      }
+      const ParamAttrsList *PAL = FT->getParamAttrs();
+      Out << "ParamAttrsList *" << typeName << "_PAL = 0;";
+      nl(Out);
+      if (PAL) {
+        Out << '{'; in(); nl(Out);
+        Out << "ParamAttrsVector Attrs;"; nl(Out);
+        Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
+        for (unsigned i = 0; i < PAL->size(); ++i) {
+          uint16_t index = PAL->getParamIndex(i);
+          uint16_t attrs = PAL->getParamAttrs(index);
+          Out << "PAWI.index = " << index << "; PAWI.attrs = 0 ";
+          if (attrs & ParamAttr::SExt)
+            Out << " | ParamAttr::SExt";
+          if (attrs & ParamAttr::ZExt)
+            Out << " | ParamAttr::ZExt";
+          if (attrs & ParamAttr::NoAlias)
+            Out << " | ParamAttr::NoAlias";
+          if (attrs & ParamAttr::StructRet)
+            Out << " | ParamAttr::StructRet";
+          if (attrs & ParamAttr::InReg)
+            Out << " | ParamAttr::InReg";
+          if (attrs & ParamAttr::NoReturn)
+            Out << " | ParamAttr::NoReturn";
+          if (attrs & ParamAttr::NoUnwind)
+            Out << " | ParamAttr::NoUnwind";
+          Out << ";";
+          nl(Out);
+          Out << "Attrs.push_back(PAWI);";
+          nl(Out);
+        }
+        Out << typeName << "_PAL = ParamAttrsList::get(Attrs);";
+        nl(Out);
+        out(); nl(Out);
+        Out << '}'; nl(Out);
+      }
+      bool isForward = printTypeInternal(FT->getReturnType());
+      std::string retTypeName(getCppName(FT->getReturnType()));
+      Out << "FunctionType* " << typeName << " = FunctionType::get(";
+      in(); nl(Out) << "/*Result=*/" << retTypeName;
+      if (isForward)
+        Out << "_fwd";
+      Out << ",";
+      nl(Out) << "/*Params=*/" << typeName << "_args,";
+      nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true," : "false,") ;
+      nl(Out) << "/*ParamAttrs=*/" << typeName << "_PAL" << ");";
+      out(); 
+      nl(Out);
+      break;
+    }
+    case Type::StructTyID: {
+      const StructType* ST = cast<StructType>(Ty);
+      Out << "std::vector<const Type*>" << typeName << "_fields;";
+      nl(Out);
+      StructType::element_iterator EI = ST->element_begin();
+      StructType::element_iterator EE = ST->element_end();
+      for (; EI != EE; ++EI) {
+        const Type* fieldTy = static_cast<const Type*>(*EI);
+        bool isForward = printTypeInternal(fieldTy);
+        std::string fieldName(getCppName(fieldTy));
+        Out << typeName << "_fields.push_back(" << fieldName;
+        if (isForward)
+          Out << "_fwd";
+        Out << ");";
+        nl(Out);
+      }
+      Out << "StructType* " << typeName << " = StructType::get("
+          << typeName << "_fields, /*isPacked=*/"
+          << (ST->isPacked() ? "true" : "false") << ");";
+      nl(Out);
+      break;
+    }
+    case Type::ArrayTyID: {
+      const ArrayType* AT = cast<ArrayType>(Ty);
+      const Type* ET = AT->getElementType();
+      bool isForward = printTypeInternal(ET);
+      std::string elemName(getCppName(ET));
+      Out << "ArrayType* " << typeName << " = ArrayType::get("
+          << elemName << (isForward ? "_fwd" : "") 
+          << ", " << utostr(AT->getNumElements()) << ");";
+      nl(Out);
+      break;
+    }
+    case Type::PointerTyID: {
+      const PointerType* PT = cast<PointerType>(Ty);
+      const Type* ET = PT->getElementType();
+      bool isForward = printTypeInternal(ET);
+      std::string elemName(getCppName(ET));
+      Out << "PointerType* " << typeName << " = PointerType::get("
+          << elemName << (isForward ? "_fwd" : "") << ");";
+      nl(Out);
+      break;
+    }
+    case Type::VectorTyID: {
+      const VectorType* PT = cast<VectorType>(Ty);
+      const Type* ET = PT->getElementType();
+      bool isForward = printTypeInternal(ET);
+      std::string elemName(getCppName(ET));
+      Out << "VectorType* " << typeName << " = VectorType::get("
+          << elemName << (isForward ? "_fwd" : "") 
+          << ", " << utostr(PT->getNumElements()) << ");";
+      nl(Out);
+      break;
+    }
+    case Type::OpaqueTyID: {
+      Out << "OpaqueType* " << typeName << " = OpaqueType::get();";
+      nl(Out);
+      break;
+    }
+    default:
+      error("Invalid TypeID");
+  }
+
+  // If the type had a name, make sure we recreate it.
+  const std::string* progTypeName = 
+    findTypeName(TheModule->getTypeSymbolTable(),Ty);
+  if (progTypeName) {
+    Out << "mod->addTypeName(\"" << *progTypeName << "\", " 
+        << typeName << ");";
+    nl(Out);
+  }
+
+  // Pop us off the type stack
+  TypeStack.pop_back();
+
+  // Indicate that this type is now defined.
+  DefinedTypes.insert(Ty);
+
+  // Early resolve as many unresolved types as possible. Search the unresolved
+  // types map for the type we just printed. Now that its definition is complete
+  // we can resolve any previous references to it. This prevents a cascade of
+  // unresolved types.
+  TypeMap::iterator I = UnresolvedTypes.find(Ty);
+  if (I != UnresolvedTypes.end()) {
+    Out << "cast<OpaqueType>(" << I->second 
+        << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");";
+    nl(Out);
+    Out << I->second << " = cast<";
+    switch (Ty->getTypeID()) {
+      case Type::FunctionTyID: Out << "FunctionType"; break;
+      case Type::ArrayTyID:    Out << "ArrayType"; break;
+      case Type::StructTyID:   Out << "StructType"; break;
+      case Type::VectorTyID:   Out << "VectorType"; break;
+      case Type::PointerTyID:  Out << "PointerType"; break;
+      case Type::OpaqueTyID:   Out << "OpaqueType"; break;
+      default:                 Out << "NoSuchDerivedType"; break;
+    }
+    Out << ">(" << I->second << "_fwd.get());";
+    nl(Out); nl(Out);
+    UnresolvedTypes.erase(I);
+  }
+
+  // Finally, separate the type definition from other with a newline.
+  nl(Out);
+
+  // We weren't a recursive type
+  return false;
+}
+
+// Prints a type definition. Returns true if it could not resolve all the types
+// in the definition but had to use a forward reference.
+void
+CppWriter::printType(const Type* Ty) {
+  assert(TypeStack.empty());
+  TypeStack.clear();
+  printTypeInternal(Ty);
+  assert(TypeStack.empty());
+}
+
+void
+CppWriter::printTypes(const Module* M) {
+
+  // Walk the symbol table and print out all its types
+  const TypeSymbolTable& symtab = M->getTypeSymbolTable();
+  for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end(); 
+       TI != TE; ++TI) {
+
+    // For primitive types and types already defined, just add a name
+    TypeMap::const_iterator TNI = TypeNames.find(TI->second);
+    if (TI->second->isInteger() || TI->second->isPrimitiveType() || 
+        TNI != TypeNames.end()) {
+      Out << "mod->addTypeName(\"";
+      printEscapedString(TI->first);
+      Out << "\", " << getCppName(TI->second) << ");";
+      nl(Out);
+    // For everything else, define the type
+    } else {
+      printType(TI->second);
+    }
+  }
+
+  // Add all of the global variables to the value table...
+  for (Module::const_global_iterator I = TheModule->global_begin(), 
+       E = TheModule->global_end(); I != E; ++I) {
+    if (I->hasInitializer())
+      printType(I->getInitializer()->getType());
+    printType(I->getType());
+  }
+
+  // Add all the functions to the table
+  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
+       FI != FE; ++FI) {
+    printType(FI->getReturnType());
+    printType(FI->getFunctionType());
+    // Add all the function arguments
+    for(Function::const_arg_iterator AI = FI->arg_begin(),
+        AE = FI->arg_end(); AI != AE; ++AI) {
+      printType(AI->getType());
+    }
+
+    // Add all of the basic blocks and instructions
+    for (Function::const_iterator BB = FI->begin(),
+         E = FI->end(); BB != E; ++BB) {
+      printType(BB->getType());
+      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; 
+           ++I) {
+        printType(I->getType());
+        for (unsigned i = 0; i < I->getNumOperands(); ++i)
+          printType(I->getOperand(i)->getType());
+      }
+    }
+  }
+}
+
+
+// printConstant - Print out a constant pool entry...
+void CppWriter::printConstant(const Constant *CV) {
+  // First, if the constant is actually a GlobalValue (variable or function) or
+  // its already in the constant list then we've printed it already and we can
+  // just return.
+  if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
+    return;
+
+  std::string constName(getCppName(CV));
+  std::string typeName(getCppName(CV->getType()));
+  if (CV->isNullValue()) {
+    Out << "Constant* " << constName << " = Constant::getNullValue("
+        << typeName << ");";
+    nl(Out);
+    return;
+  }
+  if (isa<GlobalValue>(CV)) {
+    // Skip variables and functions, we emit them elsewhere
+    return;
+  }
+  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
+    Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt(" 
+        << cast<IntegerType>(CI->getType())->getBitWidth() << ", "
+        << " \"" << CI->getValue().toStringSigned(10)  << "\", 10));";
+  } else if (isa<ConstantAggregateZero>(CV)) {
+    Out << "ConstantAggregateZero* " << constName 
+        << " = ConstantAggregateZero::get(" << typeName << ");";
+  } else if (isa<ConstantPointerNull>(CV)) {
+    Out << "ConstantPointerNull* " << constName 
+        << " = ConstanPointerNull::get(" << typeName << ");";
+  } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
+    Out << "ConstantFP* " << constName << " = ";
+    printCFP(CFP);
+    Out << ";";
+  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
+    if (CA->isString() && CA->getType()->getElementType() == Type::Int8Ty) {
+      Out << "Constant* " << constName << " = ConstantArray::get(\"";
+      std::string tmp = CA->getAsString();
+      bool nullTerminate = false;
+      if (tmp[tmp.length()-1] == 0) {
+        tmp.erase(tmp.length()-1);
+        nullTerminate = true;
+      }
+      printEscapedString(tmp);
+      // Determine if we want null termination or not.
+      if (nullTerminate)
+        Out << "\", true"; // Indicate that the null terminator should be added.
+      else
+        Out << "\", false";// No null terminator
+      Out << ");";
+    } else { 
+      Out << "std::vector<Constant*> " << constName << "_elems;";
+      nl(Out);
+      unsigned N = CA->getNumOperands();
+      for (unsigned i = 0; i < N; ++i) {
+        printConstant(CA->getOperand(i)); // recurse to print operands
+        Out << constName << "_elems.push_back("
+            << getCppName(CA->getOperand(i)) << ");";
+        nl(Out);
+      }
+      Out << "Constant* " << constName << " = ConstantArray::get(" 
+          << typeName << ", " << constName << "_elems);";
+    }
+  } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
+    Out << "std::vector<Constant*> " << constName << "_fields;";
+    nl(Out);
+    unsigned N = CS->getNumOperands();
+    for (unsigned i = 0; i < N; i++) {
+      printConstant(CS->getOperand(i));
+      Out << constName << "_fields.push_back("
+          << getCppName(CS->getOperand(i)) << ");";
+      nl(Out);
+    }
+    Out << "Constant* " << constName << " = ConstantStruct::get(" 
+        << typeName << ", " << constName << "_fields);";
+  } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
+    Out << "std::vector<Constant*> " << constName << "_elems;";
+    nl(Out);
+    unsigned N = CP->getNumOperands();
+    for (unsigned i = 0; i < N; ++i) {
+      printConstant(CP->getOperand(i));
+      Out << constName << "_elems.push_back("
+          << getCppName(CP->getOperand(i)) << ");";
+      nl(Out);
+    }
+    Out << "Constant* " << constName << " = ConstantVector::get(" 
+        << typeName << ", " << constName << "_elems);";
+  } else if (isa<UndefValue>(CV)) {
+    Out << "UndefValue* " << constName << " = UndefValue::get(" 
+        << typeName << ");";
+  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
+    if (CE->getOpcode() == Instruction::GetElementPtr) {
+      Out << "std::vector<Constant*> " << constName << "_indices;";
+      nl(Out);
+      printConstant(CE->getOperand(0));
+      for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
+        printConstant(CE->getOperand(i));
+        Out << constName << "_indices.push_back("
+            << getCppName(CE->getOperand(i)) << ");";
+        nl(Out);
+      }
+      Out << "Constant* " << constName 
+          << " = ConstantExpr::getGetElementPtr(" 
+          << getCppName(CE->getOperand(0)) << ", " 
+          << "&" << constName << "_indices[0], " << CE->getNumOperands() - 1
+          << " );";
+    } else if (CE->isCast()) {
+      printConstant(CE->getOperand(0));
+      Out << "Constant* " << constName << " = ConstantExpr::getCast(";
+      switch (CE->getOpcode()) {
+        default: assert(0 && "Invalid cast opcode");
+        case Instruction::Trunc: Out << "Instruction::Trunc"; break;
+        case Instruction::ZExt:  Out << "Instruction::ZExt"; break;
+        case Instruction::SExt:  Out << "Instruction::SExt"; break;
+        case Instruction::FPTrunc:  Out << "Instruction::FPTrunc"; break;
+        case Instruction::FPExt:  Out << "Instruction::FPExt"; break;
+        case Instruction::FPToUI:  Out << "Instruction::FPToUI"; break;
+        case Instruction::FPToSI:  Out << "Instruction::FPToSI"; break;
+        case Instruction::UIToFP:  Out << "Instruction::UIToFP"; break;
+        case Instruction::SIToFP:  Out << "Instruction::SIToFP"; break;
+        case Instruction::PtrToInt:  Out << "Instruction::PtrToInt"; break;
+        case Instruction::IntToPtr:  Out << "Instruction::IntToPtr"; break;
+        case Instruction::BitCast:  Out << "Instruction::BitCast"; break;
+      }
+      Out << ", " << getCppName(CE->getOperand(0)) << ", " 
+          << getCppName(CE->getType()) << ");";
+    } else {
+      unsigned N = CE->getNumOperands();
+      for (unsigned i = 0; i < N; ++i ) {
+        printConstant(CE->getOperand(i));
+      }
+      Out << "Constant* " << constName << " = ConstantExpr::";
+      switch (CE->getOpcode()) {
+        case Instruction::Add:    Out << "getAdd(";  break;
+        case Instruction::Sub:    Out << "getSub("; break;
+        case Instruction::Mul:    Out << "getMul("; break;
+        case Instruction::UDiv:   Out << "getUDiv("; break;
+        case Instruction::SDiv:   Out << "getSDiv("; break;
+        case Instruction::FDiv:   Out << "getFDiv("; break;
+        case Instruction::URem:   Out << "getURem("; break;
+        case Instruction::SRem:   Out << "getSRem("; break;
+        case Instruction::FRem:   Out << "getFRem("; break;
+        case Instruction::And:    Out << "getAnd("; break;
+        case Instruction::Or:     Out << "getOr("; break;
+        case Instruction::Xor:    Out << "getXor("; break;
+        case Instruction::ICmp:   
+          Out << "getICmp(ICmpInst::ICMP_";
+          switch (CE->getPredicate()) {
+            case ICmpInst::ICMP_EQ:  Out << "EQ"; break;
+            case ICmpInst::ICMP_NE:  Out << "NE"; break;
+            case ICmpInst::ICMP_SLT: Out << "SLT"; break;
+            case ICmpInst::ICMP_ULT: Out << "ULT"; break;
+            case ICmpInst::ICMP_SGT: Out << "SGT"; break;
+            case ICmpInst::ICMP_UGT: Out << "UGT"; break;
+            case ICmpInst::ICMP_SLE: Out << "SLE"; break;
+            case ICmpInst::ICMP_ULE: Out << "ULE"; break;
+            case ICmpInst::ICMP_SGE: Out << "SGE"; break;
+            case ICmpInst::ICMP_UGE: Out << "UGE"; break;
+            default: error("Invalid ICmp Predicate");
+          }
+          break;
+        case Instruction::FCmp:
+          Out << "getFCmp(FCmpInst::FCMP_";
+          switch (CE->getPredicate()) {
+            case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
+            case FCmpInst::FCMP_ORD:   Out << "ORD"; break;
+            case FCmpInst::FCMP_UNO:   Out << "UNO"; break;
+            case FCmpInst::FCMP_OEQ:   Out << "OEQ"; break;
+            case FCmpInst::FCMP_UEQ:   Out << "UEQ"; break;
+            case FCmpInst::FCMP_ONE:   Out << "ONE"; break;
+            case FCmpInst::FCMP_UNE:   Out << "UNE"; break;
+            case FCmpInst::FCMP_OLT:   Out << "OLT"; break;
+            case FCmpInst::FCMP_ULT:   Out << "ULT"; break;
+            case FCmpInst::FCMP_OGT:   Out << "OGT"; break;
+            case FCmpInst::FCMP_UGT:   Out << "UGT"; break;
+            case FCmpInst::FCMP_OLE:   Out << "OLE"; break;
+            case FCmpInst::FCMP_ULE:   Out << "ULE"; break;
+            case FCmpInst::FCMP_OGE:   Out << "OGE"; break;
+            case FCmpInst::FCMP_UGE:   Out << "UGE"; break;
+            case FCmpInst::FCMP_TRUE:  Out << "TRUE"; break;
+            default: error("Invalid FCmp Predicate");
+          }
+          break;
+        case Instruction::Shl:     Out << "getShl("; break;
+        case Instruction::LShr:    Out << "getLShr("; break;
+        case Instruction::AShr:    Out << "getAShr("; break;
+        case Instruction::Select:  Out << "getSelect("; break;
+        case Instruction::ExtractElement: Out << "getExtractElement("; break;
+        case Instruction::InsertElement:  Out << "getInsertElement("; break;
+        case Instruction::ShuffleVector:  Out << "getShuffleVector("; break;
+        default:
+          error("Invalid constant expression");
+          break;
+      }
+      Out << getCppName(CE->getOperand(0));
+      for (unsigned i = 1; i < CE->getNumOperands(); ++i) 
+        Out << ", " << getCppName(CE->getOperand(i));
+      Out << ");";
+    }
+  } else {
+    error("Bad Constant");
+    Out << "Constant* " << constName << " = 0; ";
+  }
+  nl(Out);
+}
+
+void
+CppWriter::printConstants(const Module* M) {
+  // Traverse all the global variables looking for constant initializers
+  for (Module::const_global_iterator I = TheModule->global_begin(), 
+       E = TheModule->global_end(); I != E; ++I)
+    if (I->hasInitializer())
+      printConstant(I->getInitializer());
+
+  // Traverse the LLVM functions looking for constants
+  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
+       FI != FE; ++FI) {
+    // Add all of the basic blocks and instructions
+    for (Function::const_iterator BB = FI->begin(),
+         E = FI->end(); BB != E; ++BB) {
+      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; 
+           ++I) {
+        for (unsigned i = 0; i < I->getNumOperands(); ++i) {
+          if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
+            printConstant(C);
+          }
+        }
+      }
+    }
+  }
+}
+
+void CppWriter::printVariableUses(const GlobalVariable *GV) {
+  nl(Out) << "// Type Definitions";
+  nl(Out);
+  printType(GV->getType());
+  if (GV->hasInitializer()) {
+    Constant* Init = GV->getInitializer();
+    printType(Init->getType());
+    if (Function* F = dyn_cast<Function>(Init)) {
+      nl(Out)<< "/ Function Declarations"; nl(Out);
+      printFunctionHead(F);
+    } else if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
+      nl(Out) << "// Global Variable Declarations"; nl(Out);
+      printVariableHead(gv);
+    } else  {
+      nl(Out) << "// Constant Definitions"; nl(Out);
+      printConstant(gv);
+    }
+    if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
+      nl(Out) << "// Global Variable Definitions"; nl(Out);
+      printVariableBody(gv);
+    }
+  }
+}
+
+void CppWriter::printVariableHead(const GlobalVariable *GV) {
+  nl(Out) << "GlobalVariable* " << getCppName(GV);
+  if (is_inline) {
+     Out << " = mod->getGlobalVariable(";
+     printEscapedString(GV->getName());
+     Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
+     nl(Out) << "if (!" << getCppName(GV) << ") {";
+     in(); nl(Out) << getCppName(GV);
+  }
+  Out << " = new GlobalVariable(";
+  nl(Out) << "/*Type=*/";
+  printCppName(GV->getType()->getElementType());
+  Out << ",";
+  nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
+  Out << ",";
+  nl(Out) << "/*Linkage=*/";
+  printLinkageType(GV->getLinkage());
+  Out << ",";
+  nl(Out) << "/*Initializer=*/0, ";
+  if (GV->hasInitializer()) {
+    Out << "// has initializer, specified below";
+  }
+  nl(Out) << "/*Name=*/\"";
+  printEscapedString(GV->getName());
+  Out << "\",";
+  nl(Out) << "mod);";
+  nl(Out);
+
+  if (GV->hasSection()) {
+    printCppName(GV);
+    Out << "->setSection(\"";
+    printEscapedString(GV->getSection());
+    Out << "\");";
+    nl(Out);
+  }
+  if (GV->getAlignment()) {
+    printCppName(GV);
+    Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
+    nl(Out);
+  };
+  if (is_inline) {
+    out(); Out << "}"; nl(Out);
+  }
+}
+
+void 
+CppWriter::printVariableBody(const GlobalVariable *GV) {
+  if (GV->hasInitializer()) {
+    printCppName(GV);
+    Out << "->setInitializer(";
+    //if (!isa<GlobalValue(GV->getInitializer()))
+    //else 
+      Out << getCppName(GV->getInitializer()) << ");";
+      nl(Out);
+  }
+}
+
+std::string
+CppWriter::getOpName(Value* V) {
+  if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
+    return getCppName(V);
+
+  // See if its alread in the map of forward references, if so just return the
+  // name we already set up for it
+  ForwardRefMap::const_iterator I = ForwardRefs.find(V);
+  if (I != ForwardRefs.end())
+    return I->second;
+
+  // This is a new forward reference. Generate a unique name for it
+  std::string result(std::string("fwdref_") + utostr(uniqueNum++));
+
+  // Yes, this is a hack. An Argument is the smallest instantiable value that
+  // we can make as a placeholder for the real value. We'll replace these
+  // Argument instances later.
+  Out << "Argument* " << result << " = new Argument(" 
+      << getCppName(V->getType()) << ");";
+  nl(Out);
+  ForwardRefs[V] = result;
+  return result;
+}
+
+// printInstruction - This member is called for each Instruction in a function.
+void 
+CppWriter::printInstruction(const Instruction *I, const std::string& bbname) {
+  std::string iName(getCppName(I));
+
+  // Before we emit this instruction, we need to take care of generating any
+  // forward references. So, we get the names of all the operands in advance
+  std::string* opNames = new std::string[I->getNumOperands()];
+  for (unsigned i = 0; i < I->getNumOperands(); i++) {
+    opNames[i] = getOpName(I->getOperand(i));
+  }
+
+  switch (I->getOpcode()) {
+    case Instruction::Ret: {
+      const ReturnInst* ret =  cast<ReturnInst>(I);
+      Out << "new ReturnInst("
+          << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
+      break;
+    }
+    case Instruction::Br: {
+      const BranchInst* br = cast<BranchInst>(I);
+      Out << "new BranchInst(" ;
+      if (br->getNumOperands() == 3 ) {
+        Out << opNames[0] << ", " 
+            << opNames[1] << ", "
+            << opNames[2] << ", ";
+
+      } else if (br->getNumOperands() == 1) {
+        Out << opNames[0] << ", ";
+      } else {
+        error("Branch with 2 operands?");
+      }
+      Out << bbname << ");";
+      break;
+    }
+    case Instruction::Switch: {
+      const SwitchInst* sw = cast<SwitchInst>(I);
+      Out << "SwitchInst* " << iName << " = new SwitchInst("
+          << opNames[0] << ", "
+          << opNames[1] << ", "
+          << sw->getNumCases() << ", " << bbname << ");";
+      nl(Out);
+      for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) {
+        Out << iName << "->addCase(" 
+            << opNames[i] << ", "
+            << opNames[i+1] << ");";
+        nl(Out);
+      }
+      break;
+    }
+    case Instruction::Invoke: {
+      const InvokeInst* inv = cast<InvokeInst>(I);
+      Out << "std::vector<Value*> " << iName << "_params;";
+      nl(Out);
+      for (unsigned i = 3; i < inv->getNumOperands(); ++i) {
+        Out << iName << "_params.push_back("
+            << opNames[i] << ");";
+        nl(Out);
+      }
+      Out << "InvokeInst *" << iName << " = new InvokeInst("
+          << opNames[0] << ", "
+          << opNames[1] << ", "
+          << opNames[2] << ", "
+          << "&" << iName << "_params[0], " << inv->getNumOperands() - 3 
+          << ", \"";
+      printEscapedString(inv->getName());
+      Out << "\", " << bbname << ");";
+      nl(Out) << iName << "->setCallingConv(";
+      printCallingConv(inv->getCallingConv());
+      Out << ");";
+      break;
+    }
+    case Instruction::Unwind: {
+      Out << "new UnwindInst("
+          << bbname << ");";
+      break;
+    }
+    case Instruction::Unreachable:{
+      Out << "new UnreachableInst("
+          << bbname << ");";
+      break;
+    }
+    case Instruction::Add:
+    case Instruction::Sub:
+    case Instruction::Mul:
+    case Instruction::UDiv:
+    case Instruction::SDiv:
+    case Instruction::FDiv:
+    case Instruction::URem:
+    case Instruction::SRem:
+    case Instruction::FRem:
+    case Instruction::And:
+    case Instruction::Or:
+    case Instruction::Xor:
+    case Instruction::Shl: 
+    case Instruction::LShr: 
+    case Instruction::AShr:{
+      Out << "BinaryOperator* " << iName << " = BinaryOperator::create(";
+      switch (I->getOpcode()) {
+        case Instruction::Add: Out << "Instruction::Add"; break;
+        case Instruction::Sub: Out << "Instruction::Sub"; break;
+        case Instruction::Mul: Out << "Instruction::Mul"; break;
+        case Instruction::UDiv:Out << "Instruction::UDiv"; break;
+        case Instruction::SDiv:Out << "Instruction::SDiv"; break;
+        case Instruction::FDiv:Out << "Instruction::FDiv"; break;
+        case Instruction::URem:Out << "Instruction::URem"; break;
+        case Instruction::SRem:Out << "Instruction::SRem"; break;
+        case Instruction::FRem:Out << "Instruction::FRem"; break;
+        case Instruction::And: Out << "Instruction::And"; break;
+        case Instruction::Or:  Out << "Instruction::Or";  break;
+        case Instruction::Xor: Out << "Instruction::Xor"; break;
+        case Instruction::Shl: Out << "Instruction::Shl"; break;
+        case Instruction::LShr:Out << "Instruction::LShr"; break;
+        case Instruction::AShr:Out << "Instruction::AShr"; break;
+        default: Out << "Instruction::BadOpCode"; break;
+      }
+      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+      printEscapedString(I->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::FCmp: {
+      Out << "FCmpInst* " << iName << " = new FCmpInst(";
+      switch (cast<FCmpInst>(I)->getPredicate()) {
+        case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
+        case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
+        case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
+        case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
+        case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
+        case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
+        case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
+        case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
+        case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
+        case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
+        case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
+        case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
+        case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
+        case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
+        case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
+        case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
+        default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
+      }
+      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+      printEscapedString(I->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::ICmp: {
+      Out << "ICmpInst* " << iName << " = new ICmpInst(";
+      switch (cast<ICmpInst>(I)->getPredicate()) {
+        case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
+        case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
+        case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
+        case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
+        case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
+        case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
+        case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
+        case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
+        case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
+        case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
+        default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
+      }
+      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
+      printEscapedString(I->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::Malloc: {
+      const MallocInst* mallocI = cast<MallocInst>(I);
+      Out << "MallocInst* " << iName << " = new MallocInst("
+          << getCppName(mallocI->getAllocatedType()) << ", ";
+      if (mallocI->isArrayAllocation())
+        Out << opNames[0] << ", " ;
+      Out << "\"";
+      printEscapedString(mallocI->getName());
+      Out << "\", " << bbname << ");";
+      if (mallocI->getAlignment())
+        nl(Out) << iName << "->setAlignment(" 
+            << mallocI->getAlignment() << ");";
+      break;
+    }
+    case Instruction::Free: {
+      Out << "FreeInst* " << iName << " = new FreeInst("
+          << getCppName(I->getOperand(0)) << ", " << bbname << ");";
+      break;
+    }
+    case Instruction::Alloca: {
+      const AllocaInst* allocaI = cast<AllocaInst>(I);
+      Out << "AllocaInst* " << iName << " = new AllocaInst("
+          << getCppName(allocaI->getAllocatedType()) << ", ";
+      if (allocaI->isArrayAllocation())
+        Out << opNames[0] << ", ";
+      Out << "\"";
+      printEscapedString(allocaI->getName());
+      Out << "\", " << bbname << ");";
+      if (allocaI->getAlignment())
+        nl(Out) << iName << "->setAlignment(" 
+            << allocaI->getAlignment() << ");";
+      break;
+    }
+    case Instruction::Load:{
+      const LoadInst* load = cast<LoadInst>(I);
+      Out << "LoadInst* " << iName << " = new LoadInst(" 
+          << opNames[0] << ", \"";
+      printEscapedString(load->getName());
+      Out << "\", " << (load->isVolatile() ? "true" : "false" )
+          << ", " << bbname << ");";
+      break;
+    }
+    case Instruction::Store: {
+      const StoreInst* store = cast<StoreInst>(I);
+      Out << "StoreInst* " << iName << " = new StoreInst(" 
+          << opNames[0] << ", "
+          << opNames[1] << ", "
+          << (store->isVolatile() ? "true" : "false") 
+          << ", " << bbname << ");";
+      break;
+    }
+    case Instruction::GetElementPtr: {
+      const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
+      if (gep->getNumOperands() <= 2) {
+        Out << "GetElementPtrInst* " << iName << " = new GetElementPtrInst("
+            << opNames[0]; 
+        if (gep->getNumOperands() == 2)
+          Out << ", " << opNames[1];
+      } else {
+        Out << "std::vector<Value*> " << iName << "_indices;";
+        nl(Out);
+        for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
+          Out << iName << "_indices.push_back("
+              << opNames[i] << ");";
+          nl(Out);
+        }
+        Out << "Instruction* " << iName << " = new GetElementPtrInst(" 
+            << opNames[0] << ", &" << iName << "_indices[0], " 
+            << gep->getNumOperands() - 1;
+      }
+      Out << ", \"";
+      printEscapedString(gep->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::PHI: {
+      const PHINode* phi = cast<PHINode>(I);
+
+      Out << "PHINode* " << iName << " = new PHINode("
+          << getCppName(phi->getType()) << ", \"";
+      printEscapedString(phi->getName());
+      Out << "\", " << bbname << ");";
+      nl(Out) << iName << "->reserveOperandSpace(" 
+        << phi->getNumIncomingValues()
+          << ");";
+      nl(Out);
+      for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
+        Out << iName << "->addIncoming("
+            << opNames[i] << ", " << opNames[i+1] << ");";
+        nl(Out);
+      }
+      break;
+    }
+    case Instruction::Trunc: 
+    case Instruction::ZExt:
+    case Instruction::SExt:
+    case Instruction::FPTrunc:
+    case Instruction::FPExt:
+    case Instruction::FPToUI:
+    case Instruction::FPToSI:
+    case Instruction::UIToFP:
+    case Instruction::SIToFP:
+    case Instruction::PtrToInt:
+    case Instruction::IntToPtr:
+    case Instruction::BitCast: {
+      const CastInst* cst = cast<CastInst>(I);
+      Out << "CastInst* " << iName << " = new ";
+      switch (I->getOpcode()) {
+        case Instruction::Trunc:    Out << "TruncInst"; break;
+        case Instruction::ZExt:     Out << "ZExtInst"; break;
+        case Instruction::SExt:     Out << "SExtInst"; break;
+        case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
+        case Instruction::FPExt:    Out << "FPExtInst"; break;
+        case Instruction::FPToUI:   Out << "FPToUIInst"; break;
+        case Instruction::FPToSI:   Out << "FPToSIInst"; break;
+        case Instruction::UIToFP:   Out << "UIToFPInst"; break;
+        case Instruction::SIToFP:   Out << "SIToFPInst"; break;
+        case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
+        case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
+        case Instruction::BitCast:  Out << "BitCastInst"; break;
+        default: assert(!"Unreachable"); break;
+      }
+      Out << "(" << opNames[0] << ", "
+          << getCppName(cst->getType()) << ", \"";
+      printEscapedString(cst->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::Call:{
+      const CallInst* call = cast<CallInst>(I);
+      if (InlineAsm* ila = dyn_cast<InlineAsm>(call->getOperand(0))) {
+        Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
+            << getCppName(ila->getFunctionType()) << ", \""
+            << ila->getAsmString() << "\", \""
+            << ila->getConstraintString() << "\","
+            << (ila->hasSideEffects() ? "true" : "false") << ");";
+        nl(Out);
+      }
+      if (call->getNumOperands() > 3) {
+        Out << "std::vector<Value*> " << iName << "_params;";
+        nl(Out);
+        for (unsigned i = 1; i < call->getNumOperands(); ++i) {
+          Out << iName << "_params.push_back(" << opNames[i] << ");";
+          nl(Out);
+        }
+        Out << "CallInst* " << iName << " = new CallInst("
+            << opNames[0] << ", &" << iName << "_params[0], " 
+            << call->getNumOperands() - 1 << ", \"";
+      } else if (call->getNumOperands() == 3) {
+        Out << "CallInst* " << iName << " = new CallInst("
+            << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+      } else if (call->getNumOperands() == 2) {
+        Out << "CallInst* " << iName << " = new CallInst("
+            << opNames[0] << ", " << opNames[1] << ", \"";
+      } else {
+        Out << "CallInst* " << iName << " = new CallInst(" << opNames[0] 
+            << ", \"";
+      }
+      printEscapedString(call->getName());
+      Out << "\", " << bbname << ");";
+      nl(Out) << iName << "->setCallingConv(";
+      printCallingConv(call->getCallingConv());
+      Out << ");";
+      nl(Out) << iName << "->setTailCall(" 
+          << (call->isTailCall() ? "true":"false");
+      Out << ");";
+      break;
+    }
+    case Instruction::Select: {
+      const SelectInst* sel = cast<SelectInst>(I);
+      Out << "SelectInst* " << getCppName(sel) << " = new SelectInst(";
+      Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+      printEscapedString(sel->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::UserOp1:
+      /// FALL THROUGH
+    case Instruction::UserOp2: {
+      /// FIXME: What should be done here?
+      break;
+    }
+    case Instruction::VAArg: {
+      const VAArgInst* va = cast<VAArgInst>(I);
+      Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
+          << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
+      printEscapedString(va->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::ExtractElement: {
+      const ExtractElementInst* eei = cast<ExtractElementInst>(I);
+      Out << "ExtractElementInst* " << getCppName(eei) 
+          << " = new ExtractElementInst(" << opNames[0]
+          << ", " << opNames[1] << ", \"";
+      printEscapedString(eei->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::InsertElement: {
+      const InsertElementInst* iei = cast<InsertElementInst>(I);
+      Out << "InsertElementInst* " << getCppName(iei) 
+          << " = new InsertElementInst(" << opNames[0]
+          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+      printEscapedString(iei->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::ShuffleVector: {
+      const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
+      Out << "ShuffleVectorInst* " << getCppName(svi) 
+          << " = new ShuffleVectorInst(" << opNames[0]
+          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
+      printEscapedString(svi->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+  }
+  DefinedValues.insert(I);
+  nl(Out);
+  delete [] opNames;
+}
+
+// Print out the types, constants and declarations needed by one function
+void CppWriter::printFunctionUses(const Function* F) {
+
+  nl(Out) << "// Type Definitions"; nl(Out);
+  if (!is_inline) {
+    // Print the function's return type
+    printType(F->getReturnType());
+
+    // Print the function's function type
+    printType(F->getFunctionType());
+
+    // Print the types of each of the function's arguments
+    for(Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); 
+        AI != AE; ++AI) {
+      printType(AI->getType());
+    }
+  }
+
+  // Print type definitions for every type referenced by an instruction and
+  // make a note of any global values or constants that are referenced
+  SmallPtrSet<GlobalValue*,64> gvs;
+  SmallPtrSet<Constant*,64> consts;
+  for (Function::const_iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB){
+    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); 
+         I != E; ++I) {
+      // Print the type of the instruction itself
+      printType(I->getType());
+
+      // Print the type of each of the instruction's operands
+      for (unsigned i = 0; i < I->getNumOperands(); ++i) {
+        Value* operand = I->getOperand(i);
+        printType(operand->getType());
+
+        // If the operand references a GVal or Constant, make a note of it
+        if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
+          gvs.insert(GV);
+          if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) 
+            if (GVar->hasInitializer())
+              consts.insert(GVar->getInitializer());
+        } else if (Constant* C = dyn_cast<Constant>(operand))
+          consts.insert(C);
+      }
+    }
+  }
+
+  // Print the function declarations for any functions encountered
+  nl(Out) << "// Function Declarations"; nl(Out);
+  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+       I != E; ++I) {
+    if (Function* Fun = dyn_cast<Function>(*I)) {
+      if (!is_inline || Fun != F)
+        printFunctionHead(Fun);
+    }
+  }
+
+  // Print the global variable declarations for any variables encountered
+  nl(Out) << "// Global Variable Declarations"; nl(Out);
+  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+       I != E; ++I) {
+    if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
+      printVariableHead(F);
+  }
+
+  // Print the constants found
+  nl(Out) << "// Constant Definitions"; nl(Out);
+  for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(), E = consts.end();
+       I != E; ++I) {
+      printConstant(*I);
+  }
+
+  // Process the global variables definitions now that all the constants have
+  // been emitted. These definitions just couple the gvars with their constant
+  // initializers.
+  nl(Out) << "// Global Variable Definitions"; nl(Out);
+  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
+       I != E; ++I) {
+    if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
+      printVariableBody(GV);
+  }
+}
+
+void CppWriter::printFunctionHead(const Function* F) {
+  nl(Out) << "Function* " << getCppName(F); 
+  if (is_inline) {
+    Out << " = mod->getFunction(\"";
+    printEscapedString(F->getName());
+    Out << "\", " << getCppName(F->getFunctionType()) << ");";
+    nl(Out) << "if (!" << getCppName(F) << ") {";
+    nl(Out) << getCppName(F);
+  }
+  Out<< " = new Function(";
+  nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
+  nl(Out) << "/*Linkage=*/";
+  printLinkageType(F->getLinkage());
+  Out << ",";
+  nl(Out) << "/*Name=*/\"";
+  printEscapedString(F->getName());
+  Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
+  nl(Out,-1);
+  printCppName(F);
+  Out << "->setCallingConv(";
+  printCallingConv(F->getCallingConv());
+  Out << ");";
+  nl(Out);
+  if (F->hasSection()) {
+    printCppName(F);
+    Out << "->setSection(\"" << F->getSection() << "\");";
+    nl(Out);
+  }
+  if (F->getAlignment()) {
+    printCppName(F);
+    Out << "->setAlignment(" << F->getAlignment() << ");";
+    nl(Out);
+  }
+  if (is_inline) {
+    Out << "}";
+    nl(Out);
+  }
+}
+
+void CppWriter::printFunctionBody(const Function *F) {
+  if (F->isDeclaration())
+    return; // external functions have no bodies.
+
+  // Clear the DefinedValues and ForwardRefs maps because we can't have 
+  // cross-function forward refs
+  ForwardRefs.clear();
+  DefinedValues.clear();
+
+  // Create all the argument values
+  if (!is_inline) {
+    if (!F->arg_empty()) {
+      Out << "Function::arg_iterator args = " << getCppName(F) 
+          << "->arg_begin();";
+      nl(Out);
+    }
+    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+         AI != AE; ++AI) {
+      Out << "Value* " << getCppName(AI) << " = args++;";
+      nl(Out);
+      if (AI->hasName()) {
+        Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
+        nl(Out);
+      }
+    }
+  }
+
+  // Create all the basic blocks
+  nl(Out);
+  for (Function::const_iterator BI = F->begin(), BE = F->end(); 
+       BI != BE; ++BI) {
+    std::string bbname(getCppName(BI));
+    Out << "BasicBlock* " << bbname << " = new BasicBlock(\"";
+    if (BI->hasName())
+      printEscapedString(BI->getName());
+    Out << "\"," << getCppName(BI->getParent()) << ",0);";
+    nl(Out);
+  }
+
+  // Output all of its basic blocks... for the function
+  for (Function::const_iterator BI = F->begin(), BE = F->end(); 
+       BI != BE; ++BI) {
+    std::string bbname(getCppName(BI));
+    nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
+    nl(Out);
+
+    // Output all of the instructions in the basic block...
+    for (BasicBlock::const_iterator I = BI->begin(), E = BI->end(); 
+         I != E; ++I) {
+      printInstruction(I,bbname);
+    }
+  }
+
+  // Loop over the ForwardRefs and resolve them now that all instructions
+  // are generated.
+  if (!ForwardRefs.empty()) {
+    nl(Out) << "// Resolve Forward References";
+    nl(Out);
+  }
+  
+  while (!ForwardRefs.empty()) {
+    ForwardRefMap::iterator I = ForwardRefs.begin();
+    Out << I->second << "->replaceAllUsesWith(" 
+        << getCppName(I->first) << "); delete " << I->second << ";";
+    nl(Out);
+    ForwardRefs.erase(I);
+  }
+}
+
+void CppWriter::printInline(const std::string& fname, const std::string& func) {
+  const Function* F = TheModule->getFunction(func);
+  if (!F) {
+    error(std::string("Function '") + func + "' not found in input module");
+    return;
+  }
+  if (F->isDeclaration()) {
+    error(std::string("Function '") + func + "' is external!");
+    return;
+  }
+  nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *" 
+      << getCppName(F);
+  unsigned arg_count = 1;
+  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+       AI != AE; ++AI) {
+    Out << ", Value* arg_" << arg_count;
+  }
+  Out << ") {";
+  nl(Out);
+  is_inline = true;
+  printFunctionUses(F);
+  printFunctionBody(F);
+  is_inline = false;
+  Out << "return " << getCppName(F->begin()) << ";";
+  nl(Out) << "}";
+  nl(Out);
+}
+
+void CppWriter::printModuleBody() {
+  // Print out all the type definitions
+  nl(Out) << "// Type Definitions"; nl(Out);
+  printTypes(TheModule);
+
+  // Functions can call each other and global variables can reference them so 
+  // define all the functions first before emitting their function bodies.
+  nl(Out) << "// Function Declarations"; nl(Out);
+  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); 
+       I != E; ++I)
+    printFunctionHead(I);
+
+  // Process the global variables declarations. We can't initialze them until
+  // after the constants are printed so just print a header for each global
+  nl(Out) << "// Global Variable Declarations\n"; nl(Out);
+  for (Module::const_global_iterator I = TheModule->global_begin(), 
+       E = TheModule->global_end(); I != E; ++I) {
+    printVariableHead(I);
+  }
+
+  // Print out all the constants definitions. Constants don't recurse except
+  // through GlobalValues. All GlobalValues have been declared at this point
+  // so we can proceed to generate the constants.
+  nl(Out) << "// Constant Definitions"; nl(Out);
+  printConstants(TheModule);
+
+  // Process the global variables definitions now that all the constants have
+  // been emitted. These definitions just couple the gvars with their constant
+  // initializers.
+  nl(Out) << "// Global Variable Definitions"; nl(Out);
+  for (Module::const_global_iterator I = TheModule->global_begin(), 
+       E = TheModule->global_end(); I != E; ++I) {
+    printVariableBody(I);
+  }
+
+  // Finally, we can safely put out all of the function bodies.
+  nl(Out) << "// Function Definitions"; nl(Out);
+  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); 
+       I != E; ++I) {
+    if (!I->isDeclaration()) {
+      nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I) 
+          << ")";
+      nl(Out) << "{";
+      nl(Out,1);
+      printFunctionBody(I);
+      nl(Out,-1) << "}";
+      nl(Out);
+    }
+  }
+}
+
+void CppWriter::printProgram(
+  const std::string& fname, 
+  const std::string& mName
+) {
+  Out << "#include <llvm/Module.h>\n";
+  Out << "#include <llvm/DerivedTypes.h>\n";
+  Out << "#include <llvm/Constants.h>\n";
+  Out << "#include <llvm/GlobalVariable.h>\n";
+  Out << "#include <llvm/Function.h>\n";
+  Out << "#include <llvm/CallingConv.h>\n";
+  Out << "#include <llvm/BasicBlock.h>\n";
+  Out << "#include <llvm/Instructions.h>\n";
+  Out << "#include <llvm/InlineAsm.h>\n";
+  Out << "#include <llvm/ParameterAttributes.h>\n";
+  Out << "#include <llvm/Support/MathExtras.h>\n";
+  Out << "#include <llvm/Pass.h>\n";
+  Out << "#include <llvm/PassManager.h>\n";
+  Out << "#include <llvm/Analysis/Verifier.h>\n";
+  Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
+  Out << "#include <algorithm>\n";
+  Out << "#include <iostream>\n\n";
+  Out << "using namespace llvm;\n\n";
+  Out << "Module* " << fname << "();\n\n";
+  Out << "int main(int argc, char**argv) {\n";
+  Out << "  Module* Mod = " << fname << "();\n";
+  Out << "  verifyModule(*Mod, PrintMessageAction);\n";
+  Out << "  std::cerr.flush();\n";
+  Out << "  std::cout.flush();\n";
+  Out << "  PassManager PM;\n";
+  Out << "  PM.add(new PrintModulePass(&llvm::cout));\n";
+  Out << "  PM.run(*Mod);\n";
+  Out << "  return 0;\n";
+  Out << "}\n\n";
+  printModule(fname,mName);
+}
+
+void CppWriter::printModule(
+  const std::string& fname, 
+  const std::string& mName
+) {
+  nl(Out) << "Module* " << fname << "() {";
+  nl(Out,1) << "// Module Construction";
+  nl(Out) << "Module* mod = new Module(\"" << mName << "\");"; 
+  if (!TheModule->getTargetTriple().empty()) {
+    nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
+  }
+  if (!TheModule->getTargetTriple().empty()) {
+    nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple() 
+            << "\");";
+  }
+
+  if (!TheModule->getModuleInlineAsm().empty()) {
+    nl(Out) << "mod->setModuleInlineAsm(\"";
+    printEscapedString(TheModule->getModuleInlineAsm());
+    Out << "\");";
+  }
+  nl(Out);
+  
+  // Loop over the dependent libraries and emit them.
+  Module::lib_iterator LI = TheModule->lib_begin();
+  Module::lib_iterator LE = TheModule->lib_end();
+  while (LI != LE) {
+    Out << "mod->addLibrary(\"" << *LI << "\");";
+    nl(Out);
+    ++LI;
+  }
+  printModuleBody();
+  nl(Out) << "return mod;";
+  nl(Out,-1) << "}";
+  nl(Out);
+}
+
+void CppWriter::printContents(
+  const std::string& fname, // Name of generated function
+  const std::string& mName // Name of module generated module
+) {
+  Out << "\nModule* " << fname << "(Module *mod) {\n";
+  Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n";
+  printModuleBody();
+  Out << "\nreturn mod;\n";
+  Out << "\n}\n";
+}
+
+void CppWriter::printFunction(
+  const std::string& fname, // Name of generated function
+  const std::string& funcName // Name of function to generate
+) {
+  const Function* F = TheModule->getFunction(funcName);
+  if (!F) {
+    error(std::string("Function '") + funcName + "' not found in input module");
+    return;
+  }
+  Out << "\nFunction* " << fname << "(Module *mod) {\n";
+  printFunctionUses(F);
+  printFunctionHead(F);
+  printFunctionBody(F);
+  Out << "return " << getCppName(F) << ";\n";
+  Out << "}\n";
+}
+
+void CppWriter::printVariable(
+  const std::string& fname,  /// Name of generated function
+  const std::string& varName // Name of variable to generate
+) {
+  const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
+
+  if (!GV) {
+    error(std::string("Variable '") + varName + "' not found in input module");
+    return;
+  }
+  Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
+  printVariableUses(GV);
+  printVariableHead(GV);
+  printVariableBody(GV);
+  Out << "return " << getCppName(GV) << ";\n";
+  Out << "}\n";
+}
+
+void CppWriter::printType(
+  const std::string& fname,  /// Name of generated function
+  const std::string& typeName // Name of type to generate
+) {
+  const Type* Ty = TheModule->getTypeByName(typeName);
+  if (!Ty) {
+    error(std::string("Type '") + typeName + "' not found in input module");
+    return;
+  }
+  Out << "\nType* " << fname << "(Module *mod) {\n";
+  printType(Ty);
+  Out << "return " << getCppName(Ty) << ";\n";
+  Out << "}\n";
+}
+
+}  // end anonymous llvm
+
+namespace llvm {
+
+void WriteModuleToCppFile(Module* mod, std::ostream& o) {
+  // Initialize a CppWriter for us to use
+  CppWriter W(o, mod);
+
+  // Emit a header
+  o << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
+
+  // Get the name of the function we're supposed to generate
+  std::string fname = FuncName.getValue();
+
+  // Get the name of the thing we are to generate
+  std::string tgtname = NameToGenerate.getValue();
+  if (GenerationType == GenModule || 
+      GenerationType == GenContents || 
+      GenerationType == GenProgram) {
+    if (tgtname == "!bad!") {
+      if (mod->getModuleIdentifier() == "-")
+        tgtname = "<stdin>";
+      else
+        tgtname = mod->getModuleIdentifier();
+    }
+  } else if (tgtname == "!bad!") {
+    W.error("You must use the -for option with -gen-{function,variable,type}");
+  }
+
+  switch (WhatToGenerate(GenerationType)) {
+    case GenProgram:
+      if (fname.empty())
+        fname = "makeLLVMModule";
+      W.printProgram(fname,tgtname);
+      break;
+    case GenModule:
+      if (fname.empty())
+        fname = "makeLLVMModule";
+      W.printModule(fname,tgtname);
+      break;
+    case GenContents:
+      if (fname.empty())
+        fname = "makeLLVMModuleContents";
+      W.printContents(fname,tgtname);
+      break;
+    case GenFunction:
+      if (fname.empty())
+        fname = "makeLLVMFunction";
+      W.printFunction(fname,tgtname);
+      break;
+    case GenInline:
+      if (fname.empty())
+        fname = "makeLLVMInline";
+      W.printInline(fname,tgtname);
+      break;
+    case GenVariable:
+      if (fname.empty())
+        fname = "makeLLVMVariable";
+      W.printVariable(fname,tgtname);
+      break;
+    case GenType:
+      if (fname.empty())
+        fname = "makeLLVMType";
+      W.printType(fname,tgtname);
+      break;
+    default:
+      W.error("Invalid generation option");
+  }
+}
+
+}
