Implement part of review feedback for address spaces.
[oota-llvm.git] / tools / llvm2cpp / CppWriter.cpp
index 54a28e9f83314614f4e7d333959ca8e034d738da..18bdc1b6668dd43b98ef9342f7fc7bd2d8572cae 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/InlineAsm.h"
 #include "llvm/Instruction.h"
 #include "llvm/Instructions.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/Module.h"
-#include "llvm/SymbolTable.h"
-#include "llvm/Support/CFG.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;
 
-namespace {
-/// This class provides computation of slot numbers for LLVM Assembly writing.
-/// @brief LLVM Assembly Writing Slot Computation.
-class SlotMachine {
-
-/// @name Types
-/// @{
-public:
-
-  /// @brief A mapping of Values to slot numbers
-  typedef std::map<const Value*, unsigned> ValueMap;
-  typedef std::map<const Type*, unsigned> TypeMap;
+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,
+  GenFunctions,
+  GenInline,
+  GenVariable,
+  GenType
+};
 
-  /// @brief A plane with next slot number and ValueMap
-  struct ValuePlane {
-    unsigned next_slot;        ///< The next slot number to use
-    ValueMap map;              ///< The map of Value* -> unsigned
-    ValuePlane() { next_slot = 0; } ///< Make sure we start at 0
-  };
+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(GenFunctions,"gen-functions", "Generate all function definitions"),
+    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!"));
 
-  struct TypePlane {
-    unsigned next_slot;
-    TypeMap map;
-    TypePlane() { next_slot = 0; }
-    void clear() { map.clear(); next_slot = 0; }
-  };
+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;
 
-  /// @brief The map of planes by Type
-  typedef std::map<const Type*, ValuePlane> TypedPlanes;
+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;
 
-/// @}
-/// @name Constructors
-/// @{
 public:
-  /// @brief Construct from a module
-  SlotMachine(const Module *M );
+  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) { }
 
-/// @}
-/// @name Accessors
-/// @{
-public:
-  /// Return the slot number of the specified value in it's type
-  /// plane.  Its an error to ask for something not in the SlotMachine.
-  /// Its an error to ask for a Type*
-  int getSlot(const Value *V);
-  int getSlot(const Type*Ty);
-
-  /// Determine if a Value has a slot or not
-  bool hasSlot(const Value* V);
-  bool hasSlot(const Type* Ty);
-
-/// @}
-/// @name Mutators
-/// @{
-public:
-  /// If you'd like to deal with a function instead of just a module, use
-  /// this method to get its data into the SlotMachine.
-  void incorporateFunction(const Function *F) {
-    TheFunction = F;
-    FunctionProcessed = false;
-  }
+  const Module* getModule() { return TheModule; }
 
-  /// After calling incorporateFunction, use this method to remove the
-  /// most recently incorporated function from the SlotMachine. This
-  /// will reset the state of the machine back to just the module contents.
-  void purgeFunction();
+  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 printFunctions();
+  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);
 
-/// @}
-/// @name Implementation Details
-/// @{
 private:
-  /// Values can be crammed into here at will. If they haven't
-  /// been inserted already, they get inserted, otherwise they are ignored.
-  /// Either way, the slot number for the Value* is returned.
-  unsigned createSlot(const Value *V);
-  unsigned createSlot(const Type* Ty);
-
-  /// Insert a value into the value table. Return the slot number
-  /// that it now occupies.  BadThings(TM) will happen if you insert a
-  /// Value that's already been inserted.
-  unsigned insertValue( const Value *V );
-  unsigned insertValue( const Type* Ty);
-
-  /// Add all of the module level global variables (and their initializers)
-  /// and function declarations, but not the contents of those functions.
-  void processModule();
-
-  /// Add all of the functions arguments, basic blocks, and instructions
-  void processFunction();
-
-  SlotMachine(const SlotMachine &);  // DO NOT IMPLEMENT
-  void operator=(const SlotMachine &);  // DO NOT IMPLEMENT
-
-/// @}
-/// @name Data
-/// @{
-public:
+  void printLinkageType(GlobalValue::LinkageTypes LT);
+  void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
+  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);
 
-  /// @brief The module for which we are holding slot numbers
-  const Module* TheModule;
+  void printParamAttrs(const ParamAttrsList* PAL, const std::string &name);
+  bool printTypeInternal(const Type* Ty);
+  inline void printType(const Type* Ty);
+  void printTypes(const Module* M);
 
-  /// @brief The function for which we are holding slot numbers
-  const Function* TheFunction;
-  bool FunctionProcessed;
+  void printConstant(const Constant *CPV);
+  void printConstants(const Module* M);
 
-  /// @brief The TypePlanes map for the module level data
-  TypedPlanes mMap;
-  TypePlane mTypes;
+  void printVariableUses(const GlobalVariable *GV);
+  void printVariableHead(const GlobalVariable *GV);
+  void printVariableBody(const GlobalVariable *GV);
 
-  /// @brief The TypePlanes map for the function level data
-  TypedPlanes fMap;
-  TypePlane fTypes;
+  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();
 
 };
 
-typedef std::vector<const Type*> TypeList;
-typedef std::map<const Type*,std::string> TypeMap;
-typedef std::map<const Value*,std::string> ValueMap;
-
-void WriteAsOperandInternal(std::ostream &Out, const Value *V,
-                                   bool PrintName, TypeMap &TypeTable,
-                                   SlotMachine *Machine);
-
-void WriteAsOperandInternal(std::ostream &Out, const Type *T,
-                                   bool PrintName, TypeMap& TypeTable,
-                                   SlotMachine *Machine);
-
-const Module *getModuleFromVal(const Value *V) {
-  if (const Argument *MA = dyn_cast<Argument>(V))
-    return MA->getParent() ? MA->getParent()->getParent() : 0;
-  else if (const BasicBlock *BB = dyn_cast<BasicBlock>(V))
-    return BB->getParent() ? BB->getParent()->getParent() : 0;
-  else if (const Instruction *I = dyn_cast<Instruction>(V)) {
-    const Function *M = I->getParent() ? I->getParent()->getParent() : 0;
-    return M ? M->getParent() : 0;
-  } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
-    return GV->getParent();
-  return 0;
+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;
 }
 
-// getLLVMName - Turn the specified string into an 'LLVM name', which is either
-// prefixed with % (if the string only contains simple characters) or is
-// surrounded with ""'s (if it has special chars in it).
-std::string getLLVMName(const std::string &Name,
-                               bool prefixName = true) {
-  assert(!Name.empty() && "Cannot get empty name!");
-
-  // First character cannot start with a number...
-  if (Name[0] >= '0' && Name[0] <= '9')
-    return "\"" + Name + "\"";
-
-  // Scan to see if we have any characters that are not on the "white list"
-  for (unsigned i = 0, e = Name.size(); i != e; ++i) {
-    char C = Name[i];
-    assert(C != '"' && "Illegal character in LLVM value name!");
-    if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') &&
-        C != '-' && C != '.' && C != '_')
-      return "\"" + Name + "\"";
-  }
+inline void in() { indent_level++; }
+inline void out() { if (indent_level >0) indent_level--; }
 
-  // If we get here, then the identifier is legal to use as a "VarID".
-  if (prefixName)
-    return "%"+Name;
-  else
-    return Name;
+inline void
+sanitize(std::string& str) {
+  for (size_t i = 0; i < str.length(); ++i)
+    if (!isalnum(str[i]) && str[i] != '_')
+      str[i] = '_';
 }
 
-
-/// fillTypeNameTable - If the module has a symbol table, take all global types
-/// and stuff their names into the TypeNames map.
-///
-void fillTypeNameTable(const Module *M, TypeMap& TypeNames) {
-  if (!M) return;
-  const SymbolTable &ST = M->getSymbolTable();
-  SymbolTable::type_const_iterator TI = ST.type_begin();
-  for (; TI != ST.type_end(); ++TI ) {
-    // As a heuristic, don't insert pointer to primitive types, because
-    // they are used too often to have a single useful name.
-    //
-    const Type *Ty = cast<Type>(TI->second);
-    if (!isa<PointerType>(Ty) ||
-        !cast<PointerType>(Ty)->getElementType()->isPrimitiveType() ||
-        isa<OpaqueType>(cast<PointerType>(Ty)->getElementType()))
-      TypeNames.insert(std::make_pair(Ty, getLLVMName(TI->first)));
+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_";
 }
 
-void calcTypeName(const Type *Ty,
-                         std::vector<const Type *> &TypeStack,
-                         TypeMap& TypeNames,
-                         std::string & Result){
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty)) {
-    Result += Ty->getDescription();  // Base case
-    return;
-  }
+// 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;
+}
 
-  // Check to see if the type is named.
-  TypeMap::iterator I = TypeNames.find(Ty);
-  if (I != TypeNames.end()) {
-    Result += I->second;
-    return;
-  }
+void
+CppWriter::error(const std::string& msg) {
+  std::cerr << progname << ": " << msg << "\n";
+  exit(2);
+}
 
-  if (isa<OpaqueType>(Ty)) {
-    Result += "opaque";
-    return;
-  }
+// 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) {
+  APFloat APF = APFloat(CFP->getValueAPF());  // copy
+  if (CFP->getType() == Type::FloatTy)
+    APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
+  Out << "ConstantFP::get(";
+  if (CFP->getType() == Type::DoubleTy)
+    Out << "Type::DoubleTy, ";
+  else
+    Out << "Type::FloatTy, ";
+  Out << "APFloat(";
+#if HAVE_PRINTF_A
+  char Buffer[100];
+  sprintf(Buffer, "%A", APF.convertToDouble());
+  if ((!strncmp(Buffer, "0x", 2) ||
+       !strncmp(Buffer, "-0x", 3) ||
+       !strncmp(Buffer, "+0x", 3)) &&
+      APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
+    if (CFP->getType() == Type::DoubleTy)
+      Out << "BitsToDouble(" << Buffer << ")";
+    else
+      Out << "BitsToFloat((float)" << Buffer << ")";
+    Out << ")";
+  } else {
+#endif
+    std::string StrVal = ftostr(CFP->getValueAPF());
 
-  // Check to see if the Type is already on the stack...
-  unsigned Slot = 0, CurSize = TypeStack.size();
-  while (Slot < CurSize && TypeStack[Slot] != Ty) ++Slot; // Scan for type
+    while (StrVal[0] == ' ')
+      StrVal.erase(StrVal.begin());
 
-  // This is another base case for the recursion.  In this case, we know
-  // that we have looped back to a type that we have previously visited.
-  // Generate the appropriate upreference to handle this.
-  if (Slot < CurSize) {
-    Result += "\\" + utostr(CurSize-Slot);     // Here's the upreference
-    return;
+    // 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'))) &&
+        (CFP->isExactlyValue(atof(StrVal.c_str())))) {
+      if (CFP->getType() == Type::DoubleTy)
+        Out <<  StrVal;
+      else
+        Out << StrVal << "f";
+      }
+    else if (CFP->getType() == Type::DoubleTy)
+      Out << "BitsToDouble(0x" << std::hex 
+          << CFP->getValueAPF().convertToAPInt().getZExtValue()
+          << std::dec << "ULL) /* " << StrVal << " */";
+    else 
+      Out << "BitsToFloat(0x" << std::hex 
+          << (uint32_t)CFP->getValueAPF().convertToAPInt().getZExtValue()
+          << std::dec << "U) /* " << StrVal << " */";
+    Out << ")";
+#if HAVE_PRINTF_A
   }
+#endif
+  Out << ")";
+}
 
-  TypeStack.push_back(Ty);    // Recursive case: Add us to the stack..
-
-  switch (Ty->getTypeID()) {
-  case Type::FunctionTyID: {
-    const FunctionType *FTy = cast<FunctionType>(Ty);
-    calcTypeName(FTy->getReturnType(), TypeStack, TypeNames, Result);
-    Result += " (";
-    for (FunctionType::param_iterator I = FTy->param_begin(),
-           E = FTy->param_end(); I != E; ++I) {
-      if (I != FTy->param_begin())
-        Result += ", ";
-      calcTypeName(*I, TypeStack, TypeNames, Result);
-    }
-    if (FTy->isVarArg()) {
-      if (FTy->getNumParams()) Result += ", ";
-      Result += "...";
-    }
-    Result += ")";
-    break;
-  }
-  case Type::StructTyID: {
-    const StructType *STy = cast<StructType>(Ty);
-    Result += "{ ";
-    for (StructType::element_iterator I = STy->element_begin(),
-           E = STy->element_end(); I != E; ++I) {
-      if (I != STy->element_begin())
-        Result += ", ";
-      calcTypeName(*I, TypeStack, TypeNames, Result);
-    }
-    Result += " }";
-    break;
-  }
-  case Type::PointerTyID:
-    calcTypeName(cast<PointerType>(Ty)->getElementType(),
-                          TypeStack, TypeNames, Result);
-    Result += "*";
-    break;
-  case Type::ArrayTyID: {
-    const ArrayType *ATy = cast<ArrayType>(Ty);
-    Result += "[" + utostr(ATy->getNumElements()) + " x ";
-    calcTypeName(ATy->getElementType(), TypeStack, TypeNames, Result);
-    Result += "]";
-    break;
-  }
-  case Type::PackedTyID: {
-    const PackedType *PTy = cast<PackedType>(Ty);
-    Result += "<" + utostr(PTy->getNumElements()) + " x ";
-    calcTypeName(PTy->getElementType(), TypeStack, TypeNames, Result);
-    Result += ">";
-    break;
-  }
-  case Type::OpaqueTyID:
-    Result += "opaque";
-    break;
-  default:
-    Result += "<unrecognized-type>";
+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;
   }
-
-  TypeStack.pop_back();       // Remove self from stack...
-  return;
 }
 
-
-/// printTypeInt - The internal guts of printing out a type that has a
-/// potentially named portion.
-///
-std::ostream &printTypeInt(std::ostream &Out, const Type *Ty,TypeMap&TypeNames){
-  // Primitive types always print out their description, regardless of whether
-  // they have been named or not.
-  //
-  if (Ty->isPrimitiveType() && !isa<OpaqueType>(Ty))
-    return Out << Ty->getDescription();
-
-  // Check to see if the type is named.
-  TypeMap::iterator I = TypeNames.find(Ty);
-  if (I != TypeNames.end()) return Out << I->second;
-
-  // Otherwise we have a type that has not been named but is a derived type.
-  // Carefully recurse the type hierarchy to print out any contained symbolic
-  // names.
-  //
-  std::vector<const Type *> TypeStack;
-  std::string TypeName;
-  calcTypeName(Ty, TypeStack, TypeNames, TypeName);
-  TypeNames.insert(std::make_pair(Ty, TypeName));//Cache type name for later use
-  return (Out << TypeName);
+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;
+  }
 }
 
-
-/// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
-/// type, iff there is an entry in the modules symbol table for the specified
-/// type or one of it's component types. This is slower than a simple x << Type
-///
-std::ostream &WriteTypeSymbolic(std::ostream &Out, const Type *Ty,
-                                      const Module *M) {
-  Out << ' ';
-
-  // If they want us to print out a type, attempt to make it symbolic if there
-  // is a symbol table in the module...
-  if (M) {
-    TypeMap TypeNames;
-    fillTypeNameTable(M, TypeNames);
-
-    return printTypeInt(Out, Ty, TypeNames);
-  } else {
-    return Out << Ty->getDescription();
+void
+CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
+  switch (VisType) {
+    default: assert(0 && "Unknown GVar visibility");
+    case GlobalValue::DefaultVisibility:
+      Out << "GlobalValue::DefaultVisibility";
+      break;
+    case GlobalValue::HiddenVisibility:
+      Out << "GlobalValue::HiddenVisibility";
+      break;
+    case GlobalValue::ProtectedVisibility:
+      Out << "GlobalValue::ProtectedVisibility";
+      break;
   }
 }
 
-// PrintEscapedString - Print each character of the specified string, escaping
+// printEscapedString - Print each character of the specified string, escaping
 // it if it is not printable or if it is an escape char.
-void PrintEscapedString(const std::string &Str, std::ostream &Out) {
+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 << '\\'
+      Out << "\\x"
           << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
           << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
     }
   }
 }
 
-/// @brief Internal constant writer.
-void WriteConstantInternal(std::ostream &Out, const Constant *CV,
-                             bool PrintName,
-                             TypeMap& TypeTable,
-                             SlotMachine *Machine) {
-  const int IndentSize = 4;
-  static std::string Indent = "\n";
-  if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
-    Out << (CB == ConstantBool::True ? "true" : "false");
-  } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
-    Out << CI->getValue();
-  } else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) {
-    Out << CI->getValue();
-  } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
-    // We would like to output the FP constant value in exponential notation,
-    // but we cannot do this if doing so will lose precision.  Check here to
-    // make sure that we only output it in exponential format if we can parse
-    // the value back and get the same value.
-    //
-    std::string StrVal = ftostr(CFP->getValue());
-
-    // Check to make sure that the stringized number is not some string like
-    // "Inf" or NaN, that atof will accept, but the lexer will not.  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')))
-      // Reparse stringized version!
-      if (atof(StrVal.c_str()) == CFP->getValue()) {
-        Out << StrVal;
-        return;
-      }
-
-    // Otherwise we could not reparse it to exactly the same value, so we must
-    // output the string in hexadecimal format!
-    assert(sizeof(double) == sizeof(uint64_t) &&
-           "assuming that double is 64 bits!");
-    Out << "0x" << utohexstr(DoubleToBits(CFP->getValue()));
-
-  } else if (isa<ConstantAggregateZero>(CV)) {
-    Out << "zeroinitializer";
-  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
-    // As a special case, print the array as a string if it is an array of
-    // ubytes or an array of sbytes with positive values.
-    //
-    const Type *ETy = CA->getType()->getElementType();
-    if (CA->isString()) {
-      Out << "c\"";
-      PrintEscapedString(CA->getAsString(), Out);
-      Out << "\"";
-
-    } else {                // Cannot output in string format...
-      Out << '[';
-      if (CA->getNumOperands()) {
-        Out << ' ';
-        printTypeInt(Out, ETy, TypeTable);
-        WriteAsOperandInternal(Out, CA->getOperand(0),
-                               PrintName, TypeTable, Machine);
-        for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
-          Out << ", ";
-          printTypeInt(Out, ETy, TypeTable);
-          WriteAsOperandInternal(Out, CA->getOperand(i), PrintName,
-                                 TypeTable, Machine);
-        }
-      }
-      Out << " ]";
-    }
-  } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
-    Out << '{';
-    unsigned N = CS->getNumOperands();
-    if (N) {
-      if (N > 2) {
-        Indent += std::string(IndentSize, ' ');
-        Out << Indent;
-      } else {
-        Out << ' ';
-      }
-      printTypeInt(Out, CS->getOperand(0)->getType(), TypeTable);
-
-      WriteAsOperandInternal(Out, CS->getOperand(0),
-                             PrintName, TypeTable, Machine);
-
-      for (unsigned i = 1; i < N; i++) {
-        Out << ", ";
-        if (N > 2) Out << Indent;
-        printTypeInt(Out, CS->getOperand(i)->getType(), TypeTable);
-
-        WriteAsOperandInternal(Out, CS->getOperand(i),
-                               PrintName, TypeTable, Machine);
-      }
-      if (N > 2) Indent.resize(Indent.size() - IndentSize);
-    }
-    Out << " }";
-  } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
-      const Type *ETy = CP->getType()->getElementType();
-      assert(CP->getNumOperands() > 0 &&
-             "Number of operands for a PackedConst must be > 0");
-      Out << '<';
-      Out << ' ';
-      printTypeInt(Out, ETy, TypeTable);
-      WriteAsOperandInternal(Out, CP->getOperand(0),
-                             PrintName, TypeTable, Machine);
-      for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) {
-          Out << ", ";
-          printTypeInt(Out, ETy, TypeTable);
-          WriteAsOperandInternal(Out, CP->getOperand(i), PrintName,
-                                 TypeTable, Machine);
-      }
-      Out << " >";
-  } else if (isa<ConstantPointerNull>(CV)) {
-    Out << "null";
-
-  } else if (isa<UndefValue>(CV)) {
-    Out << "undef";
-
-  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
-    Out << CE->getOpcodeName() << " (";
-
-    for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
-      printTypeInt(Out, (*OI)->getType(), TypeTable);
-      WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Machine);
-      if (OI+1 != CE->op_end())
-        Out << ", ";
-    }
-
-    if (CE->getOpcode() == Instruction::Cast) {
-      Out << " to ";
-      printTypeInt(Out, CE->getType(), TypeTable);
-    }
-    Out << ')';
-
-  } else {
-    Out << "<placeholder or erroneous Constant>";
-  }
-}
-
-
-/// WriteAsOperand - Write the name of the specified value out to the specified
-/// ostream.  This can be useful when you just want to print int %reg126, not
-/// the whole instruction that generated it.
-///
-void WriteAsOperandInternal(std::ostream &Out, const Value *V,
-                                   bool PrintName, TypeMap& TypeTable,
-                                   SlotMachine *Machine) {
-  Out << ' ';
-  if ((PrintName || isa<GlobalValue>(V)) && V->hasName())
-    Out << getLLVMName(V->getName());
-  else {
-    const Constant *CV = dyn_cast<Constant>(V);
-    if (CV && !isa<GlobalValue>(CV)) {
-      WriteConstantInternal(Out, CV, PrintName, TypeTable, Machine);
-    } else if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
-      Out << "asm ";
-      if (IA->hasSideEffects())
-        Out << "sideeffect ";
-      Out << '"';
-      PrintEscapedString(IA->getAsmString(), Out);
-      Out << "\", \"";
-      PrintEscapedString(IA->getConstraintString(), Out);
-      Out << '"';
-    } else {
-      int Slot = Machine->getSlot(V);
-      if (Slot != -1)
-        Out << '%' << Slot;
-      else
-        Out << "<badref>";
-    }
-  }
-}
-
-/// WriteAsOperand - Write the name of the specified value out to the specified
-/// ostream.  This can be useful when you just want to print int %reg126, not
-/// the whole instruction that generated it.
-///
-std::ostream &WriteAsOperand(std::ostream &Out, const Value *V,
-                                   bool PrintType, bool PrintName,
-                                   const Module *Context) {
-  TypeMap TypeNames;
-  if (Context == 0) Context = getModuleFromVal(V);
-
-  if (Context)
-    fillTypeNameTable(Context, TypeNames);
-
-  if (PrintType)
-    printTypeInt(Out, V->getType(), TypeNames);
-
-  WriteAsOperandInternal(Out, V, PrintName, TypeNames, 0);
-  return Out;
-}
-
-/// WriteAsOperandInternal - Write the name of the specified value out to
-/// the specified ostream.  This can be useful when you just want to print
-/// int %reg126, not the whole instruction that generated it.
-///
-void WriteAsOperandInternal(std::ostream &Out, const Type *T,
-                                   bool PrintName, TypeMap& TypeTable,
-                                   SlotMachine *Machine) {
-  Out << ' ';
-  int Slot = Machine->getSlot(T);
-  if (Slot != -1)
-    Out << '%' << Slot;
-  else
-    Out << "<badref>";
-}
-
-/// WriteAsOperand - Write the name of the specified value out to the specified
-/// ostream.  This can be useful when you just want to print int %reg126, not
-/// the whole instruction that generated it.
-///
-std::ostream &WriteAsOperand(std::ostream &Out, const Type *Ty,
-                                   bool PrintType, bool PrintName,
-                                   const Module *Context) {
-  TypeMap TypeNames;
-  assert(Context != 0 && "Can't write types as operand without module context");
-
-  fillTypeNameTable(Context, TypeNames);
-
-  // if (PrintType)
-    // printTypeInt(Out, V->getType(), TypeNames);
-
-  printTypeInt(Out, Ty, TypeNames);
-
-  WriteAsOperandInternal(Out, Ty, PrintName, TypeNames, 0);
-  return Out;
-}
-
-class CppWriter {
-  std::ostream &Out;
-  SlotMachine &Machine;
-  const Module *TheModule;
-  unsigned long uniqueNum;
-  TypeMap TypeNames;
-  ValueMap ValueNames;
-  TypeMap UnresolvedTypes;
-  TypeList TypeStack;
-
-public:
-  inline CppWriter(std::ostream &o, SlotMachine &Mac, const Module *M)
-    : Out(o), Machine(Mac), TheModule(M), uniqueNum(0), TypeNames(),
-      ValueNames(), UnresolvedTypes(), TypeStack() { }
-
-  inline void write(const Module *M)         { printModule(M);      }
-  inline void write(const GlobalVariable *G) { printGlobal(G);      }
-  inline void write(const Function *F)       { printFunction(F);    }
-  inline void write(const BasicBlock *BB)    { printBasicBlock(BB); }
-  inline void write(const Instruction *I)    { printInstruction(*I); }
-  inline void write(const Constant *CPV)     { printConstant(CPV);  }
-  inline void write(const Type *Ty)          { printType(Ty);       }
-
-  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
-
-  const Module* getModule() { return TheModule; }
-
-private:
-  void printModule(const Module *M);
-  void printTypes(const Module* M);
-  void printConstants(const Module* M);
-  void printConstant(const Constant *CPV);
-  void printGlobal(const GlobalVariable *GV);
-  void printFunction(const Function *F);
-  void printArgument(const Argument *FA);
-  void printBasicBlock(const BasicBlock *BB);
-  void printInstruction(const Instruction &I);
-  void printSymbolTable(const SymbolTable &ST);
-  void printLinkageType(GlobalValue::LinkageTypes LT);
-  void printCallingConv(unsigned cc);
-
-
-  // printType - Go to extreme measures to attempt to print out a short,
-  // symbolic version of a type name.
-  //
-  std::ostream &printType(const Type *Ty) {
-    return printTypeInt(Out, Ty, TypeNames);
-  }
-
-  // printTypeAtLeastOneLevel - Print out one level of the possibly complex type
-  // without considering any symbolic types that we may have equal to it.
-  //
-  std::ostream &printTypeAtLeastOneLevel(const Type *Ty);
-
-  // printInfoComment - Print a little comment after the instruction indicating
-  // which slot it occupies.
-  void printInfoComment(const Value &V);
-
-  std::string getCppName(const Type* val);
-  std::string getCppName(const Value* val);
-  inline void printCppName(const Value* val);
-  inline void printCppName(const Type* val);
-  bool isOnStack(const Type*) const;
-  inline void printTypeDef(const Type* Ty);
-  bool printTypeDefInternal(const Type* Ty);
-};
-
-std::string
-CppWriter::getCppName(const Value* val) {
-  std::string name;
-  ValueMap::iterator I = ValueNames.find(val);
-  if (I != ValueNames.end()) {
-    name = I->second;
-  } else {
-    const char* prefix;
-    switch (val->getType()->getTypeID()) {
-      case Type::VoidTyID:     prefix = "void_"; break;
-      case Type::BoolTyID:     prefix = "bool_"; break; 
-      case Type::UByteTyID:    prefix = "ubyte_"; break;
-      case Type::SByteTyID:    prefix = "sbyte_"; break;
-      case Type::UShortTyID:   prefix = "ushort_"; break;
-      case Type::ShortTyID:    prefix = "short_"; break;
-      case Type::UIntTyID:     prefix = "uint_"; break;
-      case Type::IntTyID:      prefix = "int_"; break;
-      case Type::ULongTyID:    prefix = "ulong_"; break;
-      case Type::LongTyID:     prefix = "long_"; break;
-      case Type::FloatTyID:    prefix = "float_"; break;
-      case Type::DoubleTyID:   prefix = "double_"; break;
-      case Type::LabelTyID:    prefix = "label_"; break;
-      case Type::FunctionTyID: prefix = "func_"; break;
-      case Type::StructTyID:   prefix = "struct_"; break;
-      case Type::ArrayTyID:    prefix = "array_"; break;
-      case Type::PointerTyID:  prefix = "ptr_"; break;
-      case Type::PackedTyID:   prefix = "packed_"; break;
-      default:                 prefix = "other_"; break;
-    }
-    name = ValueNames[val] = std::string(prefix) +
-        (val->hasName() ? val->getName() : utostr(uniqueNum++));
-  }
-  return name;
-}
-
-void
-CppWriter::printCppName(const Value* val) {
-  PrintEscapedString(getCppName(val),Out);
-}
-
-void
-CppWriter::printCppName(const Type* Ty)
-{
-  PrintEscapedString(getCppName(Ty),Out);
-}
-
-// Gets the C++ name for a type. Returns true if we already saw the type,
-// false otherwise.
-//
-inline const std::string* 
-findTypeName(const SymbolTable& ST, const Type* Ty)
-{
-  SymbolTable::type_const_iterator TI = ST.type_begin();
-  SymbolTable::type_const_iterator TE = ST.type_end();
-  for (;TI != TE; ++TI)
-    if (TI->second == Ty)
-      return &(TI->first);
-  return 0;
-}
-
 std::string
 CppWriter::getCppName(const Type* Ty)
 {
   // First, handle the primitive types .. easy
-  if (Ty->isPrimitiveType()) {
+  if (Ty->isPrimitiveType() || Ty->isInteger()) {
     switch (Ty->getTypeID()) {
-      case Type::VoidTyID:     return "Type::VoidTy";
-      case Type::BoolTyID:     return "Type::BoolTy"; 
-      case Type::UByteTyID:    return "Type::UByteTy";
-      case Type::SByteTyID:    return "Type::SByteTy";
-      case Type::UShortTyID:   return "Type::UShortTy";
-      case Type::ShortTyID:    return "Type::ShortTy";
-      case Type::UIntTyID:     return "Type::UIntTy";
-      case Type::IntTyID:      return "Type::IntTy";
-      case Type::ULongTyID:    return "Type::ULongTy";
-      case Type::LongTyID:     return "Type::LongTy";
-      case Type::FloatTyID:    return "Type::FloatTy";
-      case Type::DoubleTyID:   return "Type::DoubleTy";
-      case Type::LabelTyID:    return "Type::LabelTy";
+      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:
-        assert(!"Can't get here");
+        error("Invalid primitive type");
         break;
     }
     return "Type::VoidTy"; // shouldn't be returned, but make it sensible
@@ -769,1191 +370,1511 @@ CppWriter::getCppName(const Type* Ty)
     case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
     case Type::PointerTyID:     prefix = "PointerTy_"; break;
     case Type::OpaqueTyID:      prefix = "OpaqueTy_"; break;
-    case Type::PackedTyID:      prefix = "PackedTy_"; 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->getSymbolTable(), Ty);
+  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;
 }
 
-/// printTypeAtLeastOneLevel - Print out one level of the possibly complex type
-/// without considering any symbolic types that we may have equal to it.
-///
-std::ostream &CppWriter::printTypeAtLeastOneLevel(const Type *Ty) {
-  if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
-    printType(FTy->getReturnType()) << " (";
-    for (FunctionType::param_iterator I = FTy->param_begin(),
-           E = FTy->param_end(); I != E; ++I) {
-      if (I != FTy->param_begin())
-        Out << ", ";
-      printType(*I);
-    }
-    if (FTy->isVarArg()) {
-      if (FTy->getNumParams()) Out << ", ";
-      Out << "...";
-    }
-    Out << ')';
-  } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
-    Out << "{ ";
-    for (StructType::element_iterator I = STy->element_begin(),
-           E = STy->element_end(); I != E; ++I) {
-      if (I != STy->element_begin())
-        Out << ", ";
-      printType(*I);
+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());
     }
-    Out << " }";
-  } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
-    printType(PTy->getElementType()) << '*';
-  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
-    Out << '[' << ATy->getNumElements() << " x ";
-    printType(ATy->getElementType()) << ']';
-  } else if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
-    Out << '<' << PTy->getNumElements() << " x ";
-    printType(PTy->getElementType()) << '>';
-  }
-  else if (const OpaqueType *OTy = dyn_cast<OpaqueType>(Ty)) {
-    Out << "opaque";
   } else {
-    if (!Ty->isPrimitiveType())
-      Out << "<unknown derived type>";
-    printType(Ty);
+    name = getTypePrefix(val->getType());
   }
-  return Out;
-}
-
-
-void CppWriter::writeOperand(const Value *Operand, bool PrintType,
-                                  bool PrintName) {
-  if (Operand != 0) {
-    if (PrintType) { Out << ' '; printType(Operand->getType()); }
-    WriteAsOperandInternal(Out, Operand, PrintName, TypeNames, &Machine);
-  } else {
-    Out << "<null operand!>";
-  }
-}
-
-
-void CppWriter::printModule(const Module *M) {
-  Out << "\n// Module Construction\n";
-  Out << "Module* mod = new Module(\"";
-  PrintEscapedString(M->getModuleIdentifier(),Out);
-  Out << "\");\n";
-  Out << "mod->setEndianness(";
-  switch (M->getEndianness()) {
-    case Module::LittleEndian: Out << "Module::LittleEndian);\n"; break;
-    case Module::BigEndian:    Out << "Module::BigEndian);\n";    break;
-    case Module::AnyEndianness:Out << "Module::AnyEndianness);\n";  break;
-  }
-  Out << "mod->setPointerSize(";
-  switch (M->getPointerSize()) {
-    case Module::Pointer32:      Out << "Module::Pointer32);\n"; break;
-    case Module::Pointer64:      Out << "Module::Pointer64);\n"; break;
-    case Module::AnyPointerSize: Out << "Module::AnyPointerSize);\n"; break;
-  }
-  if (!M->getTargetTriple().empty())
-    Out << "mod->setTargetTriple(\"" << M->getTargetTriple() << "\");\n";
-
-  if (!M->getModuleInlineAsm().empty()) {
-    Out << "mod->setModuleInlineAsm(\"";
-    PrintEscapedString(M->getModuleInlineAsm(),Out);
-    Out << "\");\n";
-  }
-  
-  // Loop over the dependent libraries and emit them.
-  Module::lib_iterator LI = M->lib_begin();
-  Module::lib_iterator LE = M->lib_end();
-  while (LI != LE) {
-    Out << "mod->addLibrary(\"" << *LI << "\");\n";
-    ++LI;
-  }
-
-  // Print out all the type definitions
-  Out << "\n// Type Definitions\n";
-  printTypes(M);
-
-  // Print out all the constants declarations
-  Out << "\n// Constants Construction\n";
-  printConstants(M);
-
-  // Process the global variables
-  Out << "\n// Global Variable Construction\n";
-  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
-       I != E; ++I) {
-    printGlobal(I);
-  }
-
-  // Output all of the functions.
-  Out << "\n// Function Construction\n";
-  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
-    printFunction(I);
+  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::printCallingConv(unsigned cc){
-  // Print the calling convention.
-  switch (cc) {
-    default:
-    case CallingConv::C:     Out << "CallingConv::C"; break;
-    case CallingConv::CSRet: Out << "CallingConv::CSRet"; break;
-    case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
-    case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
-    case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; 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::GhostLinkage:
-      Out << "GlobalValue::GhostLinkage"; break;
-  }
-}
-void CppWriter::printGlobal(const GlobalVariable *GV) {
-  Out << "\n";
-  Out << "GlobalVariable* ";
-  printCppName(GV);
-  Out << " = new GlobalVariable(\n";
-  Out << "  /*Type=*/";
-  printCppName(GV->getType()->getElementType());
-  Out << ",\n";
-  Out << "  /*isConstant=*/" << (GV->isConstant()?"true":"false") 
-      << ",\n  /*Linkage=*/";
-  printLinkageType(GV->getLinkage());
-  Out << ",\n  /*Initializer=*/";
-  if (GV->hasInitializer()) {
-    printCppName(GV->getInitializer());
-  } else {
-    Out << "0";
-  }
-  Out << ",\n  /*Name=*/\"";
-  PrintEscapedString(GV->getName(),Out);
-  Out << "\",\n  mod);\n";
-
-  if (GV->hasSection()) {
-    printCppName(GV);
-    Out << "->setSection(\"";
-    PrintEscapedString(GV->getSection(),Out);
-    Out << "\");\n";
-  }
-  if (GV->getAlignment()) {
-    printCppName(GV);
-    Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");\n";
-  };
-}
-
-bool
-CppWriter::isOnStack(const Type* Ty) const {
-  TypeList::const_iterator TI = 
-    std::find(TypeStack.begin(),TypeStack.end(),Ty);
-  return TI != TypeStack.end();
+CppWriter::printCppName(const Value* val) {
+  printEscapedString(getCppName(val));
 }
 
-// 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::printTypeDef(const Type* Ty) {
-  assert(TypeStack.empty());
-  TypeStack.clear();
-  printTypeDefInternal(Ty);
-  assert(TypeStack.empty());
-  // 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 preview 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 << ");\n";
-    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::PackedTyID:   Out << "PackedType"; break;
-      case Type::PointerTyID:  Out << "PointerType"; break;
-      case Type::OpaqueTyID:   Out << "OpaqueType"; break;
-      default:                 Out << "NoSuchDerivedType"; break;
+CppWriter::printParamAttrs(const ParamAttrsList* PAL, const std::string &name) {
+  Out << "ParamAttrsList *" << name << "_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::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 << ">(" << I->second << "_fwd.get());\n";
-    UnresolvedTypes.erase(I);
+    Out << name << "_PAL = ParamAttrsList::get(Attrs);";
+    nl(Out);
+    out(); nl(Out);
+    Out << '}'; nl(Out);
   }
-  Out << "\n";
 }
 
 bool
-CppWriter::printTypeDefInternal(const Type* Ty) {
+CppWriter::printTypeInternal(const Type* Ty) {
   // We don't print definitions for primitive types
-  if (Ty->isPrimitiveType())
+  if (Ty->isPrimitiveType() || Ty->isInteger())
     return false;
 
-  // Determine if the name is in the name list before we modify that list.
-  TypeMap::const_iterator TNI = TypeNames.find(Ty);
+  // 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
+  // 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 issues, it must not be re-issued. Consequently we have to
+  // definition is issued, it must not be re-issued. Consequently we have to
   // check the UnresolvedTypes list as well.
-  if (isOnStack(Ty)) {
+  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();\n";
+      Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();";
+      nl(Out);
       UnresolvedTypes[Ty] = typeName;
-      return true;
     }
+    return true;
   }
 
-  // Avoid printing things we have already printed. Since TNI was obtained
-  // before the name was inserted with getCppName and because we know the name
-  // is not on the stack (currently being defined), we can surmise here that if
-  // we got the name we've also already emitted its definition.
-  if (TNI != TypeNames.end())
-    return false;
-
   // 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); // push on type stack
-  bool didRecurse = false;
+  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;\n";
+      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 = printTypeDefInternal(argTy);
+        bool isForward = printTypeInternal(argTy);
         std::string argName(getCppName(argTy));
         Out << typeName << "_args.push_back(" << argName;
         if (isForward)
           Out << "_fwd";
-        Out << ");\n";
+        Out << ");";
+        nl(Out);
       }
-      bool isForward = printTypeDefInternal(FT->getReturnType());
+      bool isForward = printTypeInternal(FT->getReturnType());
       std::string retTypeName(getCppName(FT->getReturnType()));
-      Out << "FunctionType* " << typeName << " = FunctionType::get(\n"
-          << "  /*Result=*/" << retTypeName;
+      Out << "FunctionType* " << typeName << " = FunctionType::get(";
+      in(); nl(Out) << "/*Result=*/" << retTypeName;
       if (isForward)
         Out << "_fwd";
-      Out << ",\n  /*Params=*/" << typeName << "_args,\n  /*isVarArg=*/"
-          << (FT->isVarArg() ? "true" : "false") << ");\n";
+      Out << ",";
+      nl(Out) << "/*Params=*/" << typeName << "_args,";
+      nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
+      out(); 
+      nl(Out);
       break;
     }
     case Type::StructTyID: {
       const StructType* ST = cast<StructType>(Ty);
-      Out << "std::vector<const Type*>" << typeName << "_fields;\n";
+      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 = printTypeDefInternal(fieldTy);
+        bool isForward = printTypeInternal(fieldTy);
         std::string fieldName(getCppName(fieldTy));
         Out << typeName << "_fields.push_back(" << fieldName;
         if (isForward)
           Out << "_fwd";
-        Out << ");\n";
+        Out << ");";
+        nl(Out);
       }
       Out << "StructType* " << typeName << " = StructType::get("
-          << typeName << "_fields);\n";
+          << 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 = printTypeDefInternal(ET);
+      bool isForward = printTypeInternal(ET);
       std::string elemName(getCppName(ET));
       Out << "ArrayType* " << typeName << " = ArrayType::get("
           << elemName << (isForward ? "_fwd" : "") 
-          << ", " << utostr(AT->getNumElements()) << ");\n";
+          << ", " << utostr(AT->getNumElements()) << ");";
+      nl(Out);
       break;
     }
     case Type::PointerTyID: {
       const PointerType* PT = cast<PointerType>(Ty);
       const Type* ET = PT->getElementType();
-      bool isForward = printTypeDefInternal(ET);
+      bool isForward = printTypeInternal(ET);
       std::string elemName(getCppName(ET));
       Out << "PointerType* " << typeName << " = PointerType::get("
-          << elemName << (isForward ? "_fwd" : "") << ");\n";
+          << elemName << (isForward ? "_fwd" : "") << ");";
+      nl(Out);
       break;
     }
-    case Type::PackedTyID: {
-      const PackedType* PT = cast<PackedType>(Ty);
+    case Type::VectorTyID: {
+      const VectorType* PT = cast<VectorType>(Ty);
       const Type* ET = PT->getElementType();
-      bool isForward = printTypeDefInternal(ET);
+      bool isForward = printTypeInternal(ET);
       std::string elemName(getCppName(ET));
-      Out << "PackedType* " << typeName << " = PackedType::get("
+      Out << "VectorType* " << typeName << " = VectorType::get("
           << elemName << (isForward ? "_fwd" : "") 
-          << ", " << utostr(PT->getNumElements()) << ");\n";
+          << ", " << utostr(PT->getNumElements()) << ");";
+      nl(Out);
       break;
     }
     case Type::OpaqueTyID: {
-      const OpaqueType* OT = cast<OpaqueType>(Ty);
-      Out << "OpaqueType* " << typeName << " = OpaqueType::get();\n";
+      Out << "OpaqueType* " << typeName << " = OpaqueType::get();";
+      nl(Out);
       break;
     }
     default:
-      assert(!"Invalid TypeID");
+      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())
-      printTypeDef(I->getInitializer()->getType());
-    printTypeDef(I->getType());
+      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) {
-    printTypeDef(FI->getReturnType());
-    printTypeDef(FI->getFunctionType());
+    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) {
-      printTypeDef(AI->getType());
+      printType(AI->getType());
     }
 
     // Add all of the basic blocks and instructions
     for (Function::const_iterator BB = FI->begin(),
          E = FI->end(); BB != E; ++BB) {
-      printTypeDef(BB->getType());
+      printType(BB->getType());
       for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; 
            ++I) {
-        printTypeDef(I->getType());
+        printType(I->getType());
+        for (unsigned i = 0; i < I->getNumOperands(); ++i)
+          printType(I->getOperand(i)->getType());
       }
     }
   }
 }
 
-void
-CppWriter::printConstants(const Module* M) {
-  const SymbolTable& ST = M->getSymbolTable();
-
-  // Print the constants, in type plane order.
-  for (SymbolTable::plane_const_iterator PI = ST.plane_begin();
-       PI != ST.plane_end(); ++PI ) {
-    SymbolTable::value_const_iterator VI = ST.value_begin(PI->first);
-    SymbolTable::value_const_iterator VE = ST.value_end(PI->first);
-
-    for (; VI != VE; ++VI) {
-      const Value* V = VI->second;
-      const Constant *CPV = dyn_cast<Constant>(V) ;
-      if (CPV && !isa<GlobalValue>(V)) {
-        printConstant(CPV);
-      }
-    }
-  }
 
-  // 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())
-      printConstant(I->getInitializer());
-}
-
-// printSymbolTable - Run through symbol table looking for constants
-// and types. Emit their declarations.
-void CppWriter::printSymbolTable(const SymbolTable &ST) {
-
-  // Print the types.
-  for (SymbolTable::type_const_iterator TI = ST.type_begin();
-       TI != ST.type_end(); ++TI ) {
-    Out << "\t" << getLLVMName(TI->first) << " = type ";
-
-    // Make sure we print out at least one level of the type structure, so
-    // that we do not get %FILE = type %FILE
-    //
-    printTypeAtLeastOneLevel(TI->second) << "\n";
-  }
-
-}
-
-
-/// printConstant - Print out a constant pool entry...
-///
+// printConstant - Print out a constant pool entry...
 void CppWriter::printConstant(const Constant *CV) {
-  const int IndentSize = 2;
-  static std::string Indent = "\n";
+  // 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 << ");\n";
+        << typeName << ");";
+    nl(Out);
     return;
   }
-  if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
-    Out << "Constant* " << constName << " = ConstantBool::get(" 
-        << (CB == ConstantBool::True ? "true" : "false")
-        << ");";
-  } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) {
-    Out << "Constant* " << constName << " = ConstantSInt::get(" 
-        << typeName << ", " << CI->getValue() << ");";
-  } else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) {
-    Out << "Constant* " << constName << " = ConstantUInt::get(" 
-        << typeName << ", " << CI->getValue() << ");";
+  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 << "Constant* " << constName << " = ConstantAggregateZero::get(" 
-        << typeName << ");";
+    Out << "ConstantAggregateZero* " << constName 
+        << " = ConstantAggregateZero::get(" << typeName << ");";
   } else if (isa<ConstantPointerNull>(CV)) {
-    Out << "Constant* " << constName << " = ConstanPointerNull::get(" 
-        << typeName << ");";
+    Out << "ConstantPointerNull* " << constName 
+        << " = ConstanPointerNull::get(" << typeName << ");";
   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
-    Out << "ConstantFP::get(" << typeName << ", ";
-    // We would like to output the FP constant value in exponential notation,
-    // but we cannot do this if doing so will lose precision.  Check here to
-    // make sure that we only output it in exponential format if we can parse
-    // the value back and get the same value.
-    //
-    std::string StrVal = ftostr(CFP->getValue());
-
-    // Check to make sure that the stringized number is not some string like
-    // "Inf" or NaN, that atof will accept, but the lexer will not.  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')))
-      // Reparse stringized version!
-      if (atof(StrVal.c_str()) == CFP->getValue()) {
-        Out << StrVal;
-        return;
-      }
-
-    // Otherwise we could not reparse it to exactly the same value, so we must
-    // output the string in hexadecimal format!
-    assert(sizeof(double) == sizeof(uint64_t) &&
-           "assuming that double is 64 bits!");
-    Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())) << ");";
+    Out << "ConstantFP* " << constName << " = ";
+    printCFP(CFP);
+    Out << ";";
   } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
-    if (CA->isString()) {
+    if (CA->isString() && CA->getType()->getElementType() == Type::Int8Ty) {
       Out << "Constant* " << constName << " = ConstantArray::get(\"";
-      PrintEscapedString(CA->getAsString(),Out);
-      Out << "\");";
-    } else {
-      Out << "std::vector<Constant*> " << constName << "_elems;\n";
+      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));
+        printConstant(CA->getOperand(i)); // recurse to print operands
         Out << constName << "_elems.push_back("
-            << getCppName(CA->getOperand(i)) << ");\n";
+            << 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;\n";
+    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(CA->getOperand(i)) << ");\n";
+          << getCppName(CS->getOperand(i)) << ");";
+      nl(Out);
     }
     Out << "Constant* " << constName << " = ConstantStruct::get(" 
         << typeName << ", " << constName << "_fields);";
-  } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CV)) {
-    Out << "std::vector<Constant*> " << constName << "_elems;\n";
+  } 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)) << ");\n";
+          << getCppName(CP->getOperand(i)) << ");";
+      nl(Out);
     }
-    Out << "Constant* " << constName << " = ConstantPacked::get(" 
+    Out << "Constant* " << constName << " = ConstantVector::get(" 
         << typeName << ", " << constName << "_elems);";
   } else if (isa<UndefValue>(CV)) {
-    Out << "Constant* " << constName << " = UndefValue::get(" 
-        << typeName << ");\n";
+    Out << "UndefValue* " << constName << " = UndefValue::get(" 
+        << typeName << ");";
   } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
-    Out << CE->getOpcodeName() << " (";
-
-    for (User::const_op_iterator OI=CE->op_begin(); OI != CE->op_end(); ++OI) {
-      //printTypeInt(Out, (*OI)->getType(), TypeTable);
-      //WriteAsOperandInternal(Out, *OI, PrintName, TypeTable, Machine);
-      if (OI+1 != CE->op_end())
-        Out << ", ";
-    }
-
-    if (CE->getOpcode() == Instruction::Cast) {
-      Out << " to ";
-      // printTypeInt(Out, CE->getType(), TypeTable);
+    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], "
+          << constName << "_indices.size()"
+          << " );";
+    } 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 << ");";
     }
-    Out << ')';
-
   } else {
-    Out << "<placeholder or erroneous Constant>";
+    error("Bad Constant");
+    Out << "Constant* " << constName << " = 0; ";
   }
-  Out << "\n";
+  nl(Out);
 }
 
-/// printFunction - Print all aspects of a function.
-///
-void CppWriter::printFunction(const Function *F) {
-  std::string funcTypeName(getCppName(F->getFunctionType()));
+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());
 
-  Out << "Function* ";
-  printCppName(F);
-  Out << " = new Function(" << funcTypeName << ", " ;
-  printLinkageType(F->getLinkage());
-  Out << ", \"" << F->getName() << "\", mod);\n";
-  printCppName(F);
-  Out << "->setCallingConv(";
-  printCallingConv(F->getCallingConv());
-  Out << ");\n";
-  if (F->hasSection()) {
-    printCppName(F);
-    Out << "->setSection(" << F->getSection() << ");\n";
-  }
-  if (F->getAlignment()) {
-    printCppName(F);
-    Out << "->setAlignment(" << F->getAlignment() << ");\n";
+  // 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);
+          }
+        }
+      }
+    }
   }
+}
 
-  Machine.incorporateFunction(F);
+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);
+    }
+  }
+}
 
-  if (!F->isExternal()) {
-    Out << "{";
-    // Output all of its basic blocks... for the function
-    for (Function::const_iterator I = F->begin(), E = F->end(); I != E; ++I)
-      printBasicBlock(I);
-    Out << "}\n";
+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);
 
-  Machine.purgeFunction();
+  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 (GV->getVisibility() != GlobalValue::DefaultVisibility) {
+    printCppName(GV);
+    Out << "->setVisibility(";
+    printVisibilityType(GV->getVisibility());
+    Out << ");";
+    nl(Out);
+  }
+  if (is_inline) {
+    out(); Out << "}"; nl(Out);
+  }
 }
 
-/// printArgument - This member is called for every argument that is passed into
-/// the function.  Simply print it out
-///
-void CppWriter::printArgument(const Argument *Arg) {
-  // Insert commas as we go... the first arg doesn't get a comma
-  if (Arg != Arg->getParent()->arg_begin()) 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);
+  }
+}
 
-  // Output type...
-  printType(Arg->getType());
+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;
 
-  // Output name, if available...
-  if (Arg->hasName())
-    Out << ' ' << getLLVMName(Arg->getName());
+  // 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;
 }
 
-/// printBasicBlock - This member is called for each basic block in a method.
-///
-void CppWriter::printBasicBlock(const BasicBlock *BB) {
-  if (BB->hasName()) {              // Print out the label if it exists...
-    Out << "\n" << getLLVMName(BB->getName(), false) << ':';
-  } else if (!BB->use_empty()) {      // Don't print block # of no uses...
-    Out << "\n; <label>:";
-    int Slot = Machine.getSlot(BB);
-    if (Slot != -1)
-      Out << Slot;
-    else
-      Out << "<badref>";
+// 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));
   }
 
-  if (BB->getParent() == 0)
-    Out << "\t\t; Error: Block without parent!";
-  else {
-    if (BB != &BB->getParent()->front()) {  // Not the entry block?
-      // Output predecessors for the block...
-      Out << "\t\t;";
-      pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
-
-      if (PI == PE) {
-        Out << " No predecessors!";
+  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 {
-        Out << " preds =";
-        writeOperand(*PI, false, true);
-        for (++PI; PI != PE; ++PI) {
-          Out << ',';
-          writeOperand(*PI, false, true);
-        }
+        error("Branch with 2 operands?");
       }
+      Out << bbname << ");";
+      break;
     }
-  }
-
-  Out << "\n";
-
-  // Output all of the instructions in the basic block...
-  for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I)
-    printInstruction(*I);
-}
-
-
-/// printInfoComment - Print a little comment after the instruction indicating
-/// which slot it occupies.
-///
-void CppWriter::printInfoComment(const Value &V) {
-  if (V.getType() != Type::VoidTy) {
-    Out << "\t\t; <";
-    printType(V.getType()) << '>';
-
-    if (!V.hasName()) {
-      int SlotNum = Machine.getSlot(&V);
-      if (SlotNum == -1)
-        Out << ":<badref>";
-      else
-        Out << ':' << SlotNum; // Print out the def slot taken.
+    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;
     }
-    Out << " [#uses=" << V.getNumUses() << ']';  // Output # uses
-  }
-}
-
-/// printInstruction - This member is called for each Instruction in a function..
-///
-void CppWriter::printInstruction(const Instruction &I) {
-  Out << "\t";
-
-  // Print out name if it exists...
-  if (I.hasName())
-    Out << getLLVMName(I.getName()) << " = ";
-
-  // If this is a volatile load or store, print out the volatile marker.
-  if ((isa<LoadInst>(I)  && cast<LoadInst>(I).isVolatile()) ||
-      (isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) {
-      Out << "volatile ";
-  } else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
-    // If this is a call, check if it's a tail call.
-    Out << "tail ";
-  }
-
-  // Print out the opcode...
-  Out << I.getOpcodeName();
-
-  // Print out the type of the operands...
-  const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;
-
-  // Special case conditional branches to swizzle the condition out to the front
-  if (isa<BranchInst>(I) && I.getNumOperands() > 1) {
-    writeOperand(I.getOperand(2), true);
-    Out << ',';
-    writeOperand(Operand, true);
-    Out << ',';
-    writeOperand(I.getOperand(1), true);
-
-  } else if (isa<SwitchInst>(I)) {
-    // Special case switch statement to get formatting nice and correct...
-    writeOperand(Operand        , true); Out << ',';
-    writeOperand(I.getOperand(1), true); Out << " [";
-
-    for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
-      Out << "\n\t\t";
-      writeOperand(I.getOperand(op  ), true); Out << ',';
-      writeOperand(I.getOperand(op+1), true);
+    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.begin(), " << iName << "_params.end(), \"";    
+      printEscapedString(inv->getName());
+      Out << "\", " << bbname << ");";
+      nl(Out) << iName << "->setCallingConv(";
+      printCallingConv(inv->getCallingConv());
+      Out << ");";
+      printParamAttrs(inv->getParamAttrs(), iName);
+      Out << iName << "->setParamAttrs(" << iName << "_PAL);";
+      nl(Out);
+      break;
     }
-    Out << "\n\t]";
-  } else if (isa<PHINode>(I)) {
-    Out << ' ';
-    printType(I.getType());
-    Out << ' ';
-
-    for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
-      if (op) Out << ", ";
-      Out << '[';
-      writeOperand(I.getOperand(op  ), false); Out << ',';
-      writeOperand(I.getOperand(op+1), false); Out << " ]";
+    case Instruction::Unwind: {
+      Out << "new UnwindInst("
+          << bbname << ");";
+      break;
     }
-  } else if (isa<ReturnInst>(I) && !Operand) {
-    Out << " void";
-  } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
-    // Print the calling convention being used.
-    switch (CI->getCallingConv()) {
-    case CallingConv::C: break;   // default
-    case CallingConv::CSRet: Out << " csretcc"; break;
-    case CallingConv::Fast:  Out << " fastcc"; break;
-    case CallingConv::Cold:  Out << " coldcc"; break;
-    default: Out << " cc" << CI->getCallingConv(); break;
+    case Instruction::Unreachable:{
+      Out << "new UnreachableInst("
+          << bbname << ");";
+      break;
     }
-
-    const PointerType  *PTy = cast<PointerType>(Operand->getType());
-    const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
-    const Type       *RetTy = FTy->getReturnType();
-
-    // If possible, print out the short form of the call instruction.  We can
-    // only do this if the first argument is a pointer to a nonvararg function,
-    // and if the return type is not a pointer to a function.
-    //
-    if (!FTy->isVarArg() &&
-        (!isa<PointerType>(RetTy) ||
-         !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      Out << ' '; printType(RetTy);
-      writeOperand(Operand, false);
-    } else {
-      writeOperand(Operand, true);
+    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;
     }
-    Out << '(';
-    if (CI->getNumOperands() > 1) writeOperand(CI->getOperand(1), true);
-    for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) {
-      Out << ',';
-      writeOperand(I.getOperand(op), true);
+    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;
     }
-
-    Out << " )";
-  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
-    const PointerType  *PTy = cast<PointerType>(Operand->getType());
-    const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
-    const Type       *RetTy = FTy->getReturnType();
-
-    // Print the calling convention being used.
-    switch (II->getCallingConv()) {
-    case CallingConv::C: break;   // default
-    case CallingConv::CSRet: Out << " csretcc"; break;
-    case CallingConv::Fast:  Out << " fastcc"; break;
-    case CallingConv::Cold:  Out << " coldcc"; break;
-    default: Out << " cc" << II->getCallingConv(); 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;
     }
-
-    // If possible, print out the short form of the invoke instruction. We can
-    // only do this if the first argument is a pointer to a nonvararg function,
-    // and if the return type is not a pointer to a function.
-    //
-    if (!FTy->isVarArg() &&
-        (!isa<PointerType>(RetTy) ||
-         !isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
-      Out << ' '; printType(RetTy);
-      writeOperand(Operand, false);
-    } else {
-      writeOperand(Operand, true);
+    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;
     }
-
-    Out << '(';
-    if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true);
-    for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) {
-      Out << ',';
-      writeOperand(I.getOperand(op), true);
+    case Instruction::Free: {
+      Out << "FreeInst* " << iName << " = new FreeInst("
+          << getCppName(I->getOperand(0)) << ", " << bbname << ");";
+      break;
     }
-
-    Out << " )\n\t\t\tto";
-    writeOperand(II->getNormalDest(), true);
-    Out << " unwind";
-    writeOperand(II->getUnwindDest(), true);
-
-  } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
-    Out << ' ';
-    printType(AI->getType()->getElementType());
-    if (AI->isArrayAllocation()) {
-      Out << ',';
-      writeOperand(AI->getArraySize(), true);
+    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;
     }
-    if (AI->getAlignment()) {
-      Out << ", align " << AI->getAlignment();
+    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;
     }
-  } else if (isa<CastInst>(I)) {
-    if (Operand) writeOperand(Operand, true);   // Work with broken code
-    Out << " to ";
-    printType(I.getType());
-  } else if (isa<VAArgInst>(I)) {
-    if (Operand) writeOperand(Operand, true);   // Work with broken code
-    Out << ", ";
-    printType(I.getType());
-  } else if (Operand) {   // Print the normal way...
-
-    // PrintAllTypes - Instructions who have operands of all the same type
-    // omit the type from all but the first operand.  If the instruction has
-    // different type operands (for example br), then they are all printed.
-    bool PrintAllTypes = false;
-    const Type *TheType = Operand->getType();
-
-    // Shift Left & Right print both types even for Ubyte LHS, and select prints
-    // types even if all operands are bools.
-    if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) ||
-        isa<ShuffleVectorInst>(I)) {
-      PrintAllTypes = true;
-    } else {
-      for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
-        Operand = I.getOperand(i);
-        if (Operand->getType() != TheType) {
-          PrintAllTypes = true;    // We have differing types!  Print them all!
-          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.begin(), " 
+            << iName << "_indices.end()";
       }
+      Out << ", \"";
+      printEscapedString(gep->getName());
+      Out << "\", " << bbname << ");";
+      break;
     }
-
-    if (!PrintAllTypes) {
-      Out << ' ';
-      printType(TheType);
+    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;
     }
-
-    for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
-      if (i) Out << ',';
-      writeOperand(I.getOperand(i), PrintAllTypes);
+    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() > 2) {
+        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.begin(), "
+            << iName << "_params.end(), \"";
+      } 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 << ");";
+      printParamAttrs(call->getParamAttrs(), iName);
+      Out << iName << "->setParamAttrs(" << iName << "_PAL);";
+      nl(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;
     }
   }
-
-  printInfoComment(I);
-  Out << "\n";
+  DefinedValues.insert(I);
+  nl(Out);
+  delete [] opNames;
 }
 
+// Print out the types, constants and declarations needed by one function
+void CppWriter::printFunctionUses(const Function* F) {
 
-//===----------------------------------------------------------------------===//
-//                       External Interface declarations
-//===----------------------------------------------------------------------===//
+  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());
 
-//===----------------------------------------------------------------------===//
-//===--                    SlotMachine Implementation
-//===----------------------------------------------------------------------===//
-
-#if 0
-#define SC_DEBUG(X) std::cerr << X
-#else
-#define SC_DEBUG(X)
-#endif
-
-// Module level constructor. Causes the contents of the Module (sans functions)
-// to be added to the slot table.
-SlotMachine::SlotMachine(const Module *M)
-  : TheModule(M)    ///< Saved for lazy initialization.
-  , mMap()
-  , mTypes()
-  , fMap()
-  , fTypes()
-{
-  assert(M != 0 && "Invalid Module");
-  processModule();
-}
-
-// Iterate through all the global variables, functions, and global
-// variable initializers and create slots for them.
-void SlotMachine::processModule() {
-  // 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)
-    createSlot(I);
-
-  // Add all the functions to the table
-  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
-       FI != FE; ++FI) {
-    createSlot(FI);
-    // Add all the function arguments
-    for(Function::const_arg_iterator AI = FI->arg_begin(),
-        AE = FI->arg_end(); AI != AE; ++AI)
-      createSlot(AI);
+    // 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());
+    }
+  }
 
-    // Add all of the basic blocks and instructions
-    for (Function::const_iterator BB = FI->begin(),
-         E = FI->end(); BB != E; ++BB) {
-      createSlot(BB);
-      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; 
-           ++I) {
-        createSlot(I);
+  // 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);
       }
     }
   }
-}
 
-// Process the arguments, basic blocks, and instructions  of a function.
-void SlotMachine::processFunction() {
+  // 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);
+  }
 }
 
-// Clean up after incorporating a function. This is the only way
-// to get out of the function incorporation state that affects the
-// getSlot/createSlot lock. Function incorporation state is indicated
-// by TheFunction != 0.
-void SlotMachine::purgeFunction() {
-  SC_DEBUG("begin purgeFunction!\n");
-  fMap.clear(); // Simply discard the function level map
-  fTypes.clear();
-  TheFunction = 0;
-  FunctionProcessed = false;
-  SC_DEBUG("end purgeFunction!\n");
+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 (F->getVisibility() != GlobalValue::DefaultVisibility) {
+    printCppName(F);
+    Out << "->setVisibility(";
+    printVisibilityType(F->getVisibility());
+    Out << ");";
+    nl(Out);
+  }
+  if (is_inline) {
+    Out << "}";
+    nl(Out);
+  }
+  printParamAttrs(F->getParamAttrs(), getCppName(F));
+  printCppName(F);
+  Out << "->setParamAttrs(" << getCppName(F) << "_PAL);";
+  nl(Out);
 }
 
-/// Get the slot number for a value. This function will assert if you
-/// ask for a Value that hasn't previously been inserted with createSlot.
-/// Types are forbidden because Type does not inherit from Value (any more).
-int SlotMachine::getSlot(const Value *V) {
-  assert( V && "Can't get slot for null Value" );
-  assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-    "Can't insert a non-GlobalValue Constant into SlotMachine");
-
-  // Get the type of the value
-  const Type* VTy = V->getType();
-
-  // Find the type plane in the module map
-  TypedPlanes::const_iterator MI = mMap.find(VTy);
-
-  if ( TheFunction ) {
-    // Lookup the type in the function map too
-    TypedPlanes::const_iterator FI = fMap.find(VTy);
-    // If there is a corresponding type plane in the function map
-    if ( FI != fMap.end() ) {
-      // Lookup the Value in the function map
-      ValueMap::const_iterator FVI = FI->second.map.find(V);
-      // If the value doesn't exist in the function map
-      if ( FVI == FI->second.map.end() ) {
-        // Look up the value in the module map.
-        if (MI == mMap.end()) return -1;
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it, it wasn't inserted
-        if (MVI == MI->second.map.end()) return -1;
-        assert( MVI != MI->second.map.end() && "Value not found");
-        // We found it only at the module level
-        return MVI->second;
-
-      // else the value exists in the function map
-      } else {
-        // Return the slot number as the module's contribution to
-        // the type plane plus the index in the function's contribution
-        // to the type plane.
-        if (MI != mMap.end())
-          return MI->second.next_slot + FVI->second;
-        else
-          return FVI->second;
+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);
       }
     }
   }
 
-  // N.B. Can get here only if either !TheFunction or the function doesn't
-  // have a corresponding type plane for the Value
-
-  // Make sure the type plane exists
-  if (MI == mMap.end()) return -1;
-  // Lookup the value in the module's map
-  ValueMap::const_iterator MVI = MI->second.map.find(V);
-  // Make sure we found it.
-  if (MVI == MI->second.map.end()) return -1;
-  // Return it.
-  return MVI->second;
-}
+  // 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);
+  }
 
-/// Get the slot number for a type. This function will assert if you
-/// ask for a Type that hasn't previously been inserted with createSlot.
-int SlotMachine::getSlot(const Type *Ty) {
-  assert( Ty && "Can't get slot for null Type" );
-
-  if ( TheFunction ) {
-    // Lookup the Type in the function map
-    TypeMap::const_iterator FTI = fTypes.map.find(Ty);
-    // If the Type doesn't exist in the function map
-    if ( FTI == fTypes.map.end() ) {
-      TypeMap::const_iterator MTI = mTypes.map.find(Ty);
-      // If we didn't find it, it wasn't inserted
-      if (MTI == mTypes.map.end())
-        return -1;
-      // We found it only at the module level
-      return MTI->second;
-
-    // else the value exists in the function map
-    } else {
-      // Return the slot number as the module's contribution to
-      // the type plane plus the index in the function's contribution
-      // to the type plane.
-      return mTypes.next_slot + FTI->second;
+  // 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);
     }
   }
 
-  // N.B. Can get here only if !TheFunction
+  // 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);
+  }
+}
 
-  // Lookup the value in the module's map
-  TypeMap::const_iterator MTI = mTypes.map.find(Ty);
-  // Make sure we found it.
-  if (MTI == mTypes.map.end()) return -1;
-  // Return it.
-  return MTI->second;
+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);
 }
 
-// Create a new slot, or return the existing slot if it is already
-// inserted. Note that the logic here parallels getSlot but instead
-// of asserting when the Value* isn't found, it inserts the value.
-unsigned SlotMachine::createSlot(const Value *V) {
-  assert( V && "Can't insert a null Value to SlotMachine");
-  assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-    "Can't insert a non-GlobalValue Constant into SlotMachine");
-
-  const Type* VTy = V->getType();
-
-  // Just ignore void typed things
-  if (VTy == Type::VoidTy) return 0; // FIXME: Wrong return value!
-
-  // Look up the type plane for the Value's type from the module map
-  TypedPlanes::const_iterator MI = mMap.find(VTy);
-
-  if ( TheFunction ) {
-    // Get the type plane for the Value's type from the function map
-    TypedPlanes::const_iterator FI = fMap.find(VTy);
-    // If there is a corresponding type plane in the function map
-    if ( FI != fMap.end() ) {
-      // Lookup the Value in the function map
-      ValueMap::const_iterator FVI = FI->second.map.find(V);
-      // If the value doesn't exist in the function map
-      if ( FVI == FI->second.map.end() ) {
-        // If there is no corresponding type plane in the module map
-        if ( MI == mMap.end() )
-          return insertValue(V);
-        // Look up the value in the module map
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it, it wasn't inserted
-        if ( MVI == MI->second.map.end() )
-          return insertValue(V);
-        else
-          // We found it only at the module level
-          return MVI->second;
-
-      // else the value exists in the function map
-      } else {
-        if ( MI == mMap.end() )
-          return FVI->second;
-        else
-          // Return the slot number as the module's contribution to
-          // the type plane plus the index in the function's contribution
-          // to the type plane.
-          return MI->second.next_slot + FVI->second;
-      }
+void CppWriter::printModuleBody() {
+  // Print out all the type definitions
+  nl(Out) << "// Type Definitions"; nl(Out);
+  printTypes(TheModule);
 
-    // else there is not a corresponding type plane in the function map
-    } else {
-      // If the type plane doesn't exists at the module level
-      if ( MI == mMap.end() ) {
-        return insertValue(V);
-      // else type plane exists at the module level, examine it
-      } else {
-        // Look up the value in the module's map
-        ValueMap::const_iterator MVI = MI->second.map.find(V);
-        // If we didn't find it there either
-        if ( MVI == MI->second.map.end() )
-          // Return the slot number as the module's contribution to
-          // the type plane plus the index of the function map insertion.
-          return MI->second.next_slot + insertValue(V);
-        else
-          return MVI->second;
-      }
-    }
+  // 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);
   }
 
-  // N.B. Can only get here if !TheFunction
+  // 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);
 
-  // If the module map's type plane is not for the Value's type
-  if ( MI != mMap.end() ) {
-    // Lookup the value in the module's map
-    ValueMap::const_iterator MVI = MI->second.map.find(V);
-    if ( MVI != MI->second.map.end() )
-      return MVI->second;
+  // 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);
   }
 
-  return insertValue(V);
+  // 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);
+    }
+  }
 }
 
-// Create a new slot, or return the existing slot if it is already
-// inserted. Note that the logic here parallels getSlot but instead
-// of asserting when the Value* isn't found, it inserts the value.
-unsigned SlotMachine::createSlot(const Type *Ty) {
-  assert( Ty && "Can't insert a null Type to SlotMachine");
-
-  if ( TheFunction ) {
-    // Lookup the Type in the function map
-    TypeMap::const_iterator FTI = fTypes.map.find(Ty);
-    // If the type doesn't exist in the function map
-    if ( FTI == fTypes.map.end() ) {
-      // Look up the type in the module map
-      TypeMap::const_iterator MTI = mTypes.map.find(Ty);
-      // If we didn't find it, it wasn't inserted
-      if ( MTI == mTypes.map.end() )
-        return insertValue(Ty);
-      else
-        // We found it only at the module level
-        return MTI->second;
+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);
+}
 
-    // else the value exists in the function map
-    } else {
-      // Return the slot number as the module's contribution to
-      // the type plane plus the index in the function's contribution
-      // to the type plane.
-      return mTypes.next_slot + FTI->second;
-    }
+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() 
+            << "\");";
   }
 
-  // N.B. Can only get here if !TheFunction
+  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);
+}
 
-  // Lookup the type in the module's map
-  TypeMap::const_iterator MTI = mTypes.map.find(Ty);
-  if ( MTI != mTypes.map.end() )
-    return MTI->second;
+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";
+}
 
-  return insertValue(Ty);
+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";
 }
 
-// Low level insert function. Minimal checking is done. This
-// function is just for the convenience of createSlot (above).
-unsigned SlotMachine::insertValue(const Value *V ) {
-  assert(V && "Can't insert a null Value into SlotMachine!");
-  assert(!isa<Constant>(V) || isa<GlobalValue>(V) &&
-    "Can't insert a non-GlobalValue Constant into SlotMachine");
-
-  // If this value does not contribute to a plane (is void)
-  // or if the value already has a name then ignore it.
-  if (V->getType() == Type::VoidTy || V->hasName() ) {
-      SC_DEBUG("ignored value " << *V << "\n");
-      return 0;   // FIXME: Wrong return value
+void CppWriter::printFunctions() {
+  const Module::FunctionListType &funcs = TheModule->getFunctionList();
+  Module::const_iterator I  = funcs.begin();
+  Module::const_iterator IE = funcs.end();
+
+  for (; I != IE; ++I) {
+    const Function &func = *I;
+    if (!func.isDeclaration()) {
+      std::string name("define_");
+      name += func.getName();
+      printFunction(name, func.getName());
+    }
   }
+}
 
-  const Type *VTy = V->getType();
-  unsigned DestSlot = 0;
+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 ( TheFunction ) {
-    TypedPlanes::iterator I = fMap.find( VTy );
-    if ( I == fMap.end() )
-      I = fMap.insert(std::make_pair(VTy,ValuePlane())).first;
-    DestSlot = I->second.map[V] = I->second.next_slot++;
-  } else {
-    TypedPlanes::iterator I = mMap.find( VTy );
-    if ( I == mMap.end() )
-      I = mMap.insert(std::make_pair(VTy,ValuePlane())).first;
-    DestSlot = I->second.map[V] = I->second.next_slot++;
+  if (!GV) {
+    error(std::string("Variable '") + varName + "' not found in input module");
+    return;
   }
-
-  SC_DEBUG("  Inserting value [" << VTy << "] = " << V << " slot=" <<
-           DestSlot << " [");
-  // G = Global, C = Constant, T = Type, F = Function, o = other
-  SC_DEBUG((isa<GlobalVariable>(V) ? 'G' : (isa<Function>(V) ? 'F' :
-           (isa<Constant>(V) ? 'C' : 'o'))));
-  SC_DEBUG("]\n");
-  return DestSlot;
+  Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
+  printVariableUses(GV);
+  printVariableHead(GV);
+  printVariableBody(GV);
+  Out << "return " << getCppName(GV) << ";\n";
+  Out << "}\n";
 }
 
-// Low level insert function. Minimal checking is done. This
-// function is just for the convenience of createSlot (above).
-unsigned SlotMachine::insertValue(const Type *Ty ) {
-  assert(Ty && "Can't insert a null Type into SlotMachine!");
-
-  unsigned DestSlot = fTypes.map[Ty] = fTypes.next_slot++;
-  SC_DEBUG("  Inserting type [" << DestSlot << "] = " << Ty << "\n");
-  return DestSlot;
+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
@@ -1961,35 +1882,73 @@ unsigned SlotMachine::insertValue(const Type *Ty ) {
 namespace llvm {
 
 void WriteModuleToCppFile(Module* mod, std::ostream& o) {
-  o << "#include <llvm/Module.h>\n";
-  o << "#include <llvm/DerivedTypes.h>\n";
-  o << "#include <llvm/Constants.h>\n";
-  o << "#include <llvm/GlobalVariable.h>\n";
-  o << "#include <llvm/Function.h>\n";
-  o << "#include <llvm/CallingConv.h>\n";
-  o << "#include <llvm/BasicBlock.h>\n";
-  o << "#include <llvm/Instructions.h>\n";
-  o << "#include <llvm/Pass.h>\n";
-  o << "#include <llvm/PassManager.h>\n";
-  o << "#include <llvm/Analysis/Verifier.h>\n";
-  o << "#include <llvm/Assembly/PrintModulePass.h>\n";
-  o << "#include <algorithm>\n";
-  o << "#include <iostream>\n\n";
-  o << "using namespace llvm;\n\n";
-  o << "Module* makeLLVMModule();\n\n";
-  o << "int main(int argc, char**argv) {\n";
-  o << "  Module* Mod = makeLLVMModule();\n";
-  o << "  verifyModule(*Mod, PrintMessageAction);\n";
-  o << "  PassManager PM;\n";
-  o << "  PM.add(new PrintModulePass(&std::cout));\n";
-  o << "  PM.run(*Mod);\n";
-  o << "  return 0;\n";
-  o << "}\n\n";
-  o << "Module* makeLLVMModule() {\n";
-  SlotMachine SlotTable(mod);
-  CppWriter W(o, SlotTable, mod);
-  W.write(mod);
-  o << "}\n";
+  // 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 ||
+      GenerationType == GenFunctions) {
+    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 GenFunctions:
+      W.printFunctions();
+      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");
+  }
 }
 
 }