summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/llvm2cpp/CppWriter.cpp379
1 files changed, 244 insertions, 135 deletions
diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp
index a30635eb2f..2783467aa7 100644
--- a/tools/llvm2cpp/CppWriter.cpp
+++ b/tools/llvm2cpp/CppWriter.cpp
@@ -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 @@ class CppWriter {
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 @@ private:
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 @@ CppWriter::getCppName(const Type* Ty)
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 @@ CppWriter::printTypeDef(const Type* Ty) {
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 @@ CppWriter::printTypeDefInternal(const Type* Ty) {
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 @@ CppWriter::printTypeDefInternal(const Type* Ty) {
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 @@ CppWriter::printTypeDefInternal(const Type* Ty) {
// 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 @@ void CppWriter::printConstant(const Constant *CV) {
} 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 @@ void CppWriter::printConstant(const Constant *CV) {
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 @@ void CppWriter::printFunctionBody(const Function *F) {
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 @@ void CppWriter::printFunctionBody(const Function *F) {
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
{
std::string iName(getCppName(I));
+ // Before we emit this instruction, we need to take care of generating any
+ // forward references. So, we get the names of all the operands in advance
+ std::string* opNames = new std::string[I->getNumOperands()];
+ for (unsigned i = 0; i < I->getNumOperands(); i++) {
+ opNames[i] = getOpName(I->getOperand(i));
+ }
+
switch (I->getOpcode()) {
case Instruction::Ret: {
const ReturnInst* ret = cast<ReturnInst>(I);
- Out << " 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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
}
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
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";
+ }
}
}