[llvm-commits] CVS: llvm/tools/llvm2cpp/CppWriter.cpp

Reid Spencer reid at x10sys.com
Tue May 30 14:18:35 PDT 2006



Changes in directory llvm/tools/llvm2cpp:

CppWriter.cpp updated: 1.5 -> 1.6
---
Log message:

Fix more bugs. This version now passes all of the Feature test except for
a floating point conversion problem with NAN in intrinsics.ll. llvm2cpp
makes an attempt to provide the correct conversion, based on the 
implementation in the CBackend writer, but it doesn't get NAN correct.


---
Diffs of the changes:  (+244 -135)

 CppWriter.cpp |  379 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 244 insertions(+), 135 deletions(-)


Index: llvm/tools/llvm2cpp/CppWriter.cpp
diff -u llvm/tools/llvm2cpp/CppWriter.cpp:1.5 llvm/tools/llvm2cpp/CppWriter.cpp:1.6
--- llvm/tools/llvm2cpp/CppWriter.cpp:1.5	Tue May 30 05:21:41 2006
+++ llvm/tools/llvm2cpp/CppWriter.cpp	Tue May 30 16:18:23 2006
@@ -24,17 +24,32 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/CommandLine.h"
 #include <algorithm>
 #include <iostream>
 #include <set>
 
 using namespace llvm;
 
+static cl::opt<std::string>
+ModName("modname", cl::desc("Specify the module name to use"),
+        cl::value_desc("module name"));
+
+static cl::opt<std::string>
+FuncName("funcname", cl::desc("Specify the name of the generated function"),
+         cl::value_desc("function name"));
+
+static cl::opt<bool>
+Fragment("fragment", cl::desc("Don't generate a complete program"));
+
 namespace {
 typedef std::vector<const Type*> TypeList;
 typedef std::map<const Type*,std::string> TypeMap;
 typedef std::map<const Value*,std::string> ValueMap;
 typedef std::set<std::string> NameSet;
+typedef std::set<const Type*> TypeSet;
+typedef std::set<const Value*> ValueSet;
+typedef std::map<const Value*,std::string> ForwardRefMap;
 
 class CppWriter {
   std::ostream &Out;
@@ -45,6 +60,9 @@
   TypeMap UnresolvedTypes;
   TypeList TypeStack;
   NameSet UsedNames;
+  TypeSet DefinedTypes;
+  ValueSet DefinedValues;
+  ForwardRefMap ForwardRefs;
 
 public:
   inline CppWriter(std::ostream &o, const Module *M)
@@ -76,8 +94,75 @@
   inline void printTypeDef(const Type* Ty);
   bool printTypeDefInternal(const Type* Ty);
   void printEscapedString(const std::string& str);
+
+  std::string getOpName(Value*);
+
+  void printCFP(const ConstantFP* CFP);
 };
 
+// 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) {
+#if HAVE_PRINTF_A
+  char Buffer[100];
+  sprintf(Buffer, "%A", CFP->getValue());
+  if ((!strncmp(Buffer, "0x", 2) ||
+       !strncmp(Buffer, "-0x", 3) ||
+       !strncmp(Buffer, "+0x", 3)) &&
+      (atof(Buffer) == CFP->getValue()))
+    Out << Buffer;
+  else {
+#else
+  std::string StrVal = ftostr(CFP->getValue());
+
+  while (StrVal[0] == ' ')
+    StrVal.erase(StrVal.begin());
+
+  // Check to make sure that the stringized number is not some string like "Inf"
+  // or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
+  if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
+      ((StrVal[0] == '-' || StrVal[0] == '+') &&
+       (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
+      (atof(StrVal.c_str()) == CFP->getValue()))
+    Out << StrVal;
+  else if (CFP->getType() == Type::DoubleTy) {
+    Out << "0x" << std::hex << DoubleToBits(CFP->getValue()) << std::dec
+        << "ULL /* " << StrVal << " */";
+  } else  {
+    Out << "0x" << std::hex << FloatToBits(CFP->getValue()) << std::dec
+        << "U /* " << StrVal << " */";
+  }
+#endif
+#if HAVE_PRINTF_A
+  }
+#endif
+}
+
+std::string
+CppWriter::getOpName(Value* V) {
+  if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
+    return getCppName(V);
+
+  // See if its alread in the map of forward references, if so just return the
+  // name we already set up for it
+  ForwardRefMap::const_iterator I = ForwardRefs.find(V);
+  if (I != ForwardRefs.end())
+    return I->second;
+
+  // This is a new forward reference. Generate a unique name for it
+  std::string result(std::string("fwdref_") + utostr(uniqueNum++));
+
+  // Yes, this is a hack. An Argument is the smallest instantiable value that
+  // we can make as a placeholder for the real value. We'll replace these
+  // Argument instances later.
+  Out << "  Argument* " << result << " = new Argument(" 
+      << getCppName(V->getType()) << ");\n";
+  ForwardRefs[V] = result;
+  return result;
+}
+
 // printEscapedString - Print each character of the specified string, escaping
 // it if it is not printable or if it is an escape char.
 void 
@@ -239,7 +324,9 @@
 void CppWriter::printModule(const Module *M) {
   Out << "\n// Module Construction\n";
   Out << "Module* mod = new Module(\"";
-  if (M->getModuleIdentifier() == "-")
+  if (!ModName.empty())
+    printEscapedString(ModName);
+  else if (M->getModuleIdentifier() == "-")
     printEscapedString("<stdin>");
   else 
     printEscapedString(M->getModuleIdentifier());
@@ -406,27 +493,6 @@
   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;
-    }
-    Out << ">(" << I->second << "_fwd.get());\n\n";
-    UnresolvedTypes.erase(I);
-  }
 }
 
 bool
@@ -435,16 +501,17 @@
   if (Ty->isPrimitiveType())
     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)) {
     TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
@@ -455,18 +522,10 @@
     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()) {
@@ -559,6 +618,33 @@
 
   // 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 << ");\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;
+    }
+    Out << ">(" << I->second << "_fwd.get());\n\n";
+    UnresolvedTypes.erase(I);
+  }
+
+  // Finally, separate the type definition from other with a newline.
   Out << "\n";
 
   // We weren't a recursive type
@@ -684,6 +770,8 @@
   } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
     Out << "ConstantFP* " << constName << " = ConstantFP::get(" << typeName 
         << ", ";
+    char buffer[64];
+    sprintf(buffer,"%A",CFP->getValue());
     // 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
@@ -698,25 +786,28 @@
     if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
         ((StrVal[0] == '-' || StrVal[0] == '+') &&
          (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
-         (atof(StrVal.c_str()) == CFP->getValue())) 
+        (atof(StrVal.c_str()) == CFP->getValue())) 
     {
-      Out << StrVal << ");";
+      Out << StrVal;
     } else {
+
       // 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 double is 64 bits!");
-      Out << "0x" << utohexstr(DoubleToBits(CFP->getValue())) << ");";
+      assert(sizeof(double) == sizeof(uint64_t) &&
+             "assuming that double is 64 bits!");
+      Out << "0x" << std::hex << DoubleToBits(CFP->getValue()) << std::dec 
+          << "ULL /* " << StrVal << " */";
     }
+    Out << ");";
   } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
     if (CA->isString() && CA->getType()->getElementType() == Type::SByteTy) {
       Out << "Constant* " << constName << " = ConstantArray::get(\"";
       printEscapedString(CA->getAsString());
       // Determine if we want null termination or not.
       if (CA->getType()->getNumElements() <= CA->getAsString().length())
-        Out << "\", " << CA->getType()->getNumElements();
+        Out << "\", false";// No null terminator
       else
-        Out << "\", 0"; // Indicate that the null terminator should be added.
+        Out << "\", true"; // Indicate that the null terminator should be added.
       Out << ");";
     } else { 
       Out << "std::vector<Constant*> " << constName << "_elems;\n";
@@ -840,6 +931,11 @@
   if (F->isExternal())
     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 (!F->arg_empty()) {
     Out << "  Function::arg_iterator args = " << getCppName(F) 
@@ -876,6 +972,17 @@
       printInstruction(I,bbname);
     }
   }
+
+  // Loop over the ForwardRefs and resolve them now that all instructions
+  // are generated.
+  if (!ForwardRefs.empty())
+    Out << "\n  // Resolve Forward References\n";
+  while (!ForwardRefs.empty()) {
+    ForwardRefMap::iterator I = ForwardRefs.begin();
+    Out << "  " << I->second << "->replaceAllUsesWith(" 
+        << getCppName(I->first) << "); delete " << I->second << ";\n";
+    ForwardRefs.erase(I);
+  }
 }
 
 // printInstruction - This member is called for each Instruction in a function.
@@ -884,25 +991,30 @@
 {
   std::string iName(getCppName(I));
 
+  // Before we emit this instruction, we need to take care of generating any
+  // forward references. So, we get the names of all the operands in advance
+  std::string* opNames = new std::string[I->getNumOperands()];
+  for (unsigned i = 0; i < I->getNumOperands(); i++) {
+    opNames[i] = getOpName(I->getOperand(i));
+  }
+
   switch (I->getOpcode()) {
     case Instruction::Ret: {
       const ReturnInst* ret =  cast<ReturnInst>(I);
-      Out << "  ReturnInst* " << iName << " = new ReturnInst(";
-      if (ret->getReturnValue())
-        Out << getCppName(ret->getReturnValue()) << ", ";
-      Out << bbname << ");";
+      Out << "  ReturnInst* " << iName << " = new ReturnInst("
+          << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
       break;
     }
     case Instruction::Br: {
       const BranchInst* br = cast<BranchInst>(I);
       Out << "  BranchInst* " << iName << " = new BranchInst(" ;
       if (br->getNumOperands() == 3 ) {
-        Out << getCppName(br->getOperand(0)) << ", " 
-            << getCppName(br->getOperand(1)) << ", "
-            << getCppName(br->getOperand(2)) << ", ";
+        Out << opNames[0] << ", " 
+            << opNames[1] << ", "
+            << opNames[2] << ", ";
 
       } else if (br->getNumOperands() == 1) {
-        Out << getCppName(br->getOperand(0)) << ", ";
+        Out << opNames[0] << ", ";
       } else {
         assert(!"branch with 2 operands?");
       }
@@ -912,13 +1024,13 @@
     case Instruction::Switch: {
       const SwitchInst* sw = cast<SwitchInst>(I);
       Out << "  SwitchInst* " << iName << " = new SwitchInst("
-          << getCppName(sw->getOperand(0)) << ", "
-          << getCppName(sw->getOperand(1)) << ", "
+          << opNames[0] << ", "
+          << opNames[1] << ", "
           << sw->getNumCases() << ", " << bbname << ");\n";
-      for (unsigned i = 1; i < sw->getNumCases(); i++ ) {
+      for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) {
         Out << "  " << iName << "->addCase(" 
-            << getCppName(sw->getCaseValue(i)) << ", "
-            << getCppName(sw->getSuccessor(i)) << ");\n";
+            << opNames[i] << ", "
+            << opNames[i+1] << ");\n";
       }
       break;
     }
@@ -927,11 +1039,11 @@
       Out << "  std::vector<Value*> " << iName << "_params;\n";
       for (unsigned i = 3; i < inv->getNumOperands(); ++i)
         Out << "  " << iName << "_params.push_back("
-            << getCppName(inv->getOperand(i)) << ");\n";
+            << opNames[i] << ");\n";
       Out << "  InvokeInst* " << iName << " = new InvokeInst("
-          << getCppName(inv->getCalledFunction()) << ", "
-          << getCppName(inv->getNormalDest()) << ", "
-          << getCppName(inv->getUnwindDest()) << ", "
+          << opNames[0] << ", "
+          << opNames[1] << ", "
+          << opNames[2] << ", "
           << iName << "_params, \"";
       printEscapedString(inv->getName());
       Out << "\", " << bbname << ");\n";
@@ -974,8 +1086,7 @@
         case Instruction::Shr: Out << "Instruction::Shr"; break;
         default: Out << "Instruction::BadOpCode"; break;
       }
-      Out << ", " << getCppName(I->getOperand(0));
-      Out << ", " << getCppName(I->getOperand(1)) << ", \"";
+      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
       printEscapedString(I->getName());
       Out << "\", " << bbname << ");";
       break;
@@ -996,8 +1107,7 @@
         case Instruction::SetGT: Out << "Instruction::SetGT"; break;
         default: Out << "Instruction::BadOpCode"; break;
       }
-      Out << ", " << getCppName(I->getOperand(0));
-      Out << ", " << getCppName(I->getOperand(1)) << ", \"";
+      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
       printEscapedString(I->getName());
       Out << "\", " << bbname << ");";
       break;
@@ -1007,7 +1117,7 @@
       Out << "  MallocInst* " << iName << " = new MallocInst("
           << getCppName(mallocI->getAllocatedType()) << ", ";
       if (mallocI->isArrayAllocation())
-        Out << getCppName(mallocI->getArraySize()) << ", ";
+        Out << opNames[0] << ", " ;
       Out << "\"";
       printEscapedString(mallocI->getName());
       Out << "\", " << bbname << ");";
@@ -1026,7 +1136,7 @@
       Out << "  AllocaInst* " << iName << " = new AllocaInst("
           << getCppName(allocaI->getAllocatedType()) << ", ";
       if (allocaI->isArrayAllocation())
-        Out << getCppName(allocaI->getArraySize()) << ", ";
+        Out << opNames[0] << ", ";
       Out << "\"";
       printEscapedString(allocaI->getName());
       Out << "\", " << bbname << ");";
@@ -1038,7 +1148,7 @@
     case Instruction::Load:{
       const LoadInst* load = cast<LoadInst>(I);
       Out << "  LoadInst* " << iName << " = new LoadInst(" 
-          << getCppName(load->getOperand(0)) << ", \"";
+          << opNames[0] << ", \"";
       printEscapedString(load->getName());
       Out << "\", " << (load->isVolatile() ? "true" : "false" )
           << ", " << bbname << ");\n";
@@ -1047,8 +1157,8 @@
     case Instruction::Store: {
       const StoreInst* store = cast<StoreInst>(I);
       Out << "  StoreInst* " << iName << " = new StoreInst(" 
-          << getCppName(store->getOperand(0)) << ", "
-          << getCppName(store->getOperand(1)) << ", "
+          << opNames[0] << ", "
+          << opNames[1] << ", "
           << (store->isVolatile() ? "true" : "false") 
           << ", " << bbname << ");\n";
       break;
@@ -1057,18 +1167,17 @@
       const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
       if (gep->getNumOperands() <= 2) {
         Out << "  GetElementPtrInst* " << iName << " = new GetElementPtrInst("
-            << getCppName(gep->getOperand(0)); 
+            << opNames[0]; 
         if (gep->getNumOperands() == 2)
-          Out << ", " << getCppName(gep->getOperand(1));
-        Out << ", " << bbname;
+          Out << ", " << opNames[1];
       } else {
         Out << "  std::vector<Value*> " << iName << "_indices;\n";
         for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
           Out << "  " << iName << "_indices.push_back("
-              << getCppName(gep->getOperand(i)) << ");\n";
+              << opNames[i] << ");\n";
         }
         Out << "  Instruction* " << iName << " = new GetElementPtrInst(" 
-            << getCppName(gep->getOperand(0)) << ", " << iName << "_indices";
+            << opNames[0] << ", " << iName << "_indices";
       }
       Out << ", \"";
       printEscapedString(gep->getName());
@@ -1085,17 +1194,16 @@
       Out << "  " << iName << "->reserveOperandSpace(" 
         << phi->getNumIncomingValues()
           << ");\n";
-      for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
+      for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
         Out << "  " << iName << "->addIncoming("
-            << getCppName(phi->getIncomingValue(i)) << ", "
-            << getCppName(phi->getIncomingBlock(i)) << ");\n";
+            << opNames[i] << ", " << opNames[i+1] << ");\n";
       }
       break;
     }
     case Instruction::Cast: {
       const CastInst* cst = cast<CastInst>(I);
       Out << "  CastInst* " << iName << " = new CastInst("
-          << getCppName(cst->getOperand(0)) << ", "
+          << opNames[0] << ", "
           << getCppName(cst->getType()) << ", \"";
       printEscapedString(cst->getName());
       Out << "\", " << bbname << ");\n";
@@ -1112,25 +1220,19 @@
       }
       if (call->getNumOperands() > 3) {
         Out << "  std::vector<Value*> " << iName << "_params;\n";
-        for (unsigned i = 1; i < call->getNumOperands(); ++i) {
-          Out << "  " << iName << "_params.push_back("
-              << getCppName(call->getOperand(i)) << ");\n";
-        }
+        for (unsigned i = 1; i < call->getNumOperands(); ++i) 
+          Out << "  " << iName << "_params.push_back(" << opNames[i] << ");\n";
         Out << "  CallInst* " << iName << " = new CallInst("
-            << getCppName(call->getOperand(0)) << ", "
-            << iName << "_params, \"";
+            << opNames[0] << ", " << iName << "_params, \"";
       } else if (call->getNumOperands() == 3) {
         Out << "  CallInst* " << iName << " = new CallInst("
-            << getCppName(call->getOperand(0)) << ", "
-            << getCppName(call->getOperand(1)) << ", "
-            << getCppName(call->getOperand(2)) << ", \"";
+            << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
       } else if (call->getNumOperands() == 2) {
         Out << "  CallInst* " << iName << " = new CallInst("
-            << getCppName(call->getOperand(0)) << ", "
-            << getCppName(call->getOperand(1)) << ", \"";
+            << opNames[0] << ", " << opNames[1] << ", \"";
       } else {
-        Out << "  CallInst* " << iName << " = new CallInst("
-            << getCppName(call->getOperand(0)) << ", \"";
+        Out << "  CallInst* " << iName << " = new CallInst(" << opNames[0] 
+            << ", \"";
       }
       printEscapedString(call->getName());
       Out << "\", " << bbname << ");\n";
@@ -1145,9 +1247,7 @@
     case Instruction::Select: {
       const SelectInst* sel = cast<SelectInst>(I);
       Out << "  SelectInst* " << getCppName(sel) << " = new SelectInst(";
-      Out << getCppName(sel->getCondition()) << ", ";
-      Out << getCppName(sel->getTrueValue()) << ", ";
-      Out << getCppName(sel->getFalseValue()) << ", \"";
+      Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
       printEscapedString(sel->getName());
       Out << "\", " << bbname << ");\n";
       break;
@@ -1161,8 +1261,7 @@
     case Instruction::VAArg: {
       const VAArgInst* va = cast<VAArgInst>(I);
       Out << "  VAArgInst* " << getCppName(va) << " = new VAArgInst("
-          << getCppName(va->getOperand(0)) << ", "
-          << getCppName(va->getType()) << ", \"";
+          << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
       printEscapedString(va->getName());
       Out << "\", " << bbname << ");\n";
       break;
@@ -1170,8 +1269,8 @@
     case Instruction::ExtractElement: {
       const ExtractElementInst* eei = cast<ExtractElementInst>(I);
       Out << "  ExtractElementInst* " << getCppName(eei) 
-          << " = new ExtractElementInst(" << getCppName(eei->getOperand(0))
-          << ", " << getCppName(eei->getOperand(1)) << ", \"";
+          << " = new ExtractElementInst(" << opNames[0]
+          << ", " << opNames[1] << ", \"";
       printEscapedString(eei->getName());
       Out << "\", " << bbname << ");\n";
       break;
@@ -1179,9 +1278,8 @@
     case Instruction::InsertElement: {
       const InsertElementInst* iei = cast<InsertElementInst>(I);
       Out << "  InsertElementInst* " << getCppName(iei) 
-          << " = new InsertElementInst(" << getCppName(iei->getOperand(0))
-          << ", " << getCppName(iei->getOperand(1)) << ", "
-          << getCppName(iei->getOperand(2)) << ", \"";
+          << " = new InsertElementInst(" << opNames[0]
+          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
       printEscapedString(iei->getName());
       Out << "\", " << bbname << ");\n";
       break;
@@ -1189,15 +1287,15 @@
     case Instruction::ShuffleVector: {
       const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
       Out << "  ShuffleVectorInst* " << getCppName(svi) 
-          << " = new ShuffleVectorInst(" << getCppName(svi->getOperand(0))
-          << ", " << getCppName(svi->getOperand(1)) << ", "
-          << getCppName(svi->getOperand(2)) << ", \"";
+          << " = new ShuffleVectorInst(" << opNames[0]
+          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
       printEscapedString(svi->getName());
       Out << "\", " << bbname << ");\n";
       break;
     }
   }
   Out << "\n";
+  delete [] opNames;
 }
 
 }  // end anonymous llvm
@@ -1205,38 +1303,49 @@
 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/InlineAsm.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 << "  std::cerr.flush();\n";
-  o << "  std::cout.flush();\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";
-  CppWriter W(o, mod);
-  W.printModule(mod);
-  o << "return mod;\n";
-  o << "}\n";
+  std::string fname = FuncName.getValue();
+  if (fname.empty())
+    fname = "makeLLVMModule";
+  if (Fragment) {
+    o << "Module* " << fname << "() {\n";
+    CppWriter W(o, mod);
+    W.printModule(mod);
+    o << "return mod;\n";
+    o << "}\n";
+  } else {
+    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/InlineAsm.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* " << fname << "();\n\n";
+    o << "int main(int argc, char**argv) {\n";
+    o << "  Module* Mod = makeLLVMModule();\n";
+    o << "  verifyModule(*Mod, PrintMessageAction);\n";
+    o << "  std::cerr.flush();\n";
+    o << "  std::cout.flush();\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* " << fname << "() {\n";
+    CppWriter W(o, mod);
+    W.printModule(mod);
+    o << "return mod;\n";
+    o << "}\n";
+  }
 }
 
 }






More information about the llvm-commits mailing list