CPPBackend.cpp revision 218893
1193323Sed//===-- CPPBackend.cpp - Library for converting LLVM code to C++ code -----===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the writing of the LLVM IR as a set of C++ calls to the
11193323Sed// LLVM IR interface. The input module is assumed to be verified.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#include "CPPTargetMachine.h"
16193323Sed#include "llvm/CallingConv.h"
17193323Sed#include "llvm/Constants.h"
18193323Sed#include "llvm/DerivedTypes.h"
19193323Sed#include "llvm/InlineAsm.h"
20193323Sed#include "llvm/Instruction.h"
21193323Sed#include "llvm/Instructions.h"
22193323Sed#include "llvm/Module.h"
23193323Sed#include "llvm/Pass.h"
24193323Sed#include "llvm/PassManager.h"
25193323Sed#include "llvm/TypeSymbolTable.h"
26193323Sed#include "llvm/ADT/SmallPtrSet.h"
27193323Sed#include "llvm/Support/CommandLine.h"
28198090Srdivacky#include "llvm/Support/ErrorHandling.h"
29198090Srdivacky#include "llvm/Support/FormattedStream.h"
30198090Srdivacky#include "llvm/Target/TargetRegistry.h"
31198090Srdivacky#include "llvm/ADT/StringExtras.h"
32193323Sed#include "llvm/Config/config.h"
33193323Sed#include <algorithm>
34193323Sed#include <set>
35193323Sed
36193323Sedusing namespace llvm;
37193323Sed
38193323Sedstatic cl::opt<std::string>
39193323SedFuncName("cppfname", cl::desc("Specify the name of the generated function"),
40193323Sed         cl::value_desc("function name"));
41193323Sed
42193323Sedenum WhatToGenerate {
43193323Sed  GenProgram,
44193323Sed  GenModule,
45193323Sed  GenContents,
46193323Sed  GenFunction,
47193323Sed  GenFunctions,
48193323Sed  GenInline,
49193323Sed  GenVariable,
50193323Sed  GenType
51193323Sed};
52193323Sed
53193323Sedstatic cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
54193323Sed  cl::desc("Choose what kind of output to generate"),
55193323Sed  cl::init(GenProgram),
56193323Sed  cl::values(
57193323Sed    clEnumValN(GenProgram,  "program",   "Generate a complete program"),
58193323Sed    clEnumValN(GenModule,   "module",    "Generate a module definition"),
59193323Sed    clEnumValN(GenContents, "contents",  "Generate contents of a module"),
60193323Sed    clEnumValN(GenFunction, "function",  "Generate a function definition"),
61193323Sed    clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
62193323Sed    clEnumValN(GenInline,   "inline",    "Generate an inline function"),
63193323Sed    clEnumValN(GenVariable, "variable",  "Generate a variable definition"),
64193323Sed    clEnumValN(GenType,     "type",      "Generate a type definition"),
65193323Sed    clEnumValEnd
66193323Sed  )
67193323Sed);
68193323Sed
69193323Sedstatic cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
70193323Sed  cl::desc("Specify the name of the thing to generate"),
71193323Sed  cl::init("!bad!"));
72193323Sed
73198090Srdivackyextern "C" void LLVMInitializeCppBackendTarget() {
74198090Srdivacky  // Register the target.
75198090Srdivacky  RegisterTargetMachine<CPPTargetMachine> X(TheCppBackendTarget);
76198090Srdivacky}
77193323Sed
78193323Sednamespace {
79193323Sed  typedef std::vector<const Type*> TypeList;
80193323Sed  typedef std::map<const Type*,std::string> TypeMap;
81193323Sed  typedef std::map<const Value*,std::string> ValueMap;
82193323Sed  typedef std::set<std::string> NameSet;
83193323Sed  typedef std::set<const Type*> TypeSet;
84193323Sed  typedef std::set<const Value*> ValueSet;
85193323Sed  typedef std::map<const Value*,std::string> ForwardRefMap;
86193323Sed
87193323Sed  /// CppWriter - This class is the main chunk of code that converts an LLVM
88193323Sed  /// module to a C++ translation unit.
89193323Sed  class CppWriter : public ModulePass {
90198090Srdivacky    formatted_raw_ostream &Out;
91193323Sed    const Module *TheModule;
92193323Sed    uint64_t uniqueNum;
93193323Sed    TypeMap TypeNames;
94193323Sed    ValueMap ValueNames;
95193323Sed    TypeMap UnresolvedTypes;
96193323Sed    TypeList TypeStack;
97193323Sed    NameSet UsedNames;
98193323Sed    TypeSet DefinedTypes;
99193323Sed    ValueSet DefinedValues;
100193323Sed    ForwardRefMap ForwardRefs;
101193323Sed    bool is_inline;
102210299Sed    unsigned indent_level;
103193323Sed
104193323Sed  public:
105193323Sed    static char ID;
106198090Srdivacky    explicit CppWriter(formatted_raw_ostream &o) :
107212904Sdim      ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
108193323Sed
109193323Sed    virtual const char *getPassName() const { return "C++ backend"; }
110193323Sed
111193323Sed    bool runOnModule(Module &M);
112193323Sed
113193323Sed    void printProgram(const std::string& fname, const std::string& modName );
114193323Sed    void printModule(const std::string& fname, const std::string& modName );
115193323Sed    void printContents(const std::string& fname, const std::string& modName );
116193323Sed    void printFunction(const std::string& fname, const std::string& funcName );
117193323Sed    void printFunctions();
118193323Sed    void printInline(const std::string& fname, const std::string& funcName );
119193323Sed    void printVariable(const std::string& fname, const std::string& varName );
120193323Sed    void printType(const std::string& fname, const std::string& typeName );
121193323Sed
122193323Sed    void error(const std::string& msg);
123193323Sed
124210299Sed
125210299Sed    formatted_raw_ostream& nl(formatted_raw_ostream &Out, int delta = 0);
126210299Sed    inline void in() { indent_level++; }
127210299Sed    inline void out() { if (indent_level >0) indent_level--; }
128210299Sed
129193323Sed  private:
130193323Sed    void printLinkageType(GlobalValue::LinkageTypes LT);
131193323Sed    void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
132198090Srdivacky    void printCallingConv(CallingConv::ID cc);
133193323Sed    void printEscapedString(const std::string& str);
134193323Sed    void printCFP(const ConstantFP* CFP);
135193323Sed
136193323Sed    std::string getCppName(const Type* val);
137193323Sed    inline void printCppName(const Type* val);
138193323Sed
139193323Sed    std::string getCppName(const Value* val);
140193323Sed    inline void printCppName(const Value* val);
141193323Sed
142193323Sed    void printAttributes(const AttrListPtr &PAL, const std::string &name);
143193323Sed    bool printTypeInternal(const Type* Ty);
144193323Sed    inline void printType(const Type* Ty);
145193323Sed    void printTypes(const Module* M);
146193323Sed
147193323Sed    void printConstant(const Constant *CPV);
148193323Sed    void printConstants(const Module* M);
149193323Sed
150193323Sed    void printVariableUses(const GlobalVariable *GV);
151193323Sed    void printVariableHead(const GlobalVariable *GV);
152193323Sed    void printVariableBody(const GlobalVariable *GV);
153193323Sed
154193323Sed    void printFunctionUses(const Function *F);
155193323Sed    void printFunctionHead(const Function *F);
156193323Sed    void printFunctionBody(const Function *F);
157193323Sed    void printInstruction(const Instruction *I, const std::string& bbname);
158193323Sed    std::string getOpName(Value*);
159193323Sed
160193323Sed    void printModuleBody();
161193323Sed  };
162210299Sed} // end anonymous namespace.
163193323Sed
164210299Sedformatted_raw_ostream &CppWriter::nl(formatted_raw_ostream &Out, int delta) {
165210299Sed  Out << '\n';
166210299Sed  if (delta >= 0 || indent_level >= unsigned(-delta))
167210299Sed    indent_level += delta;
168210299Sed  Out.indent(indent_level);
169210299Sed  return Out;
170210299Sed}
171193323Sed
172210299Sedstatic inline void sanitize(std::string &str) {
173210299Sed  for (size_t i = 0; i < str.length(); ++i)
174210299Sed    if (!isalnum(str[i]) && str[i] != '_')
175210299Sed      str[i] = '_';
176210299Sed}
177193323Sed
178210299Sedstatic std::string getTypePrefix(const Type *Ty) {
179210299Sed  switch (Ty->getTypeID()) {
180210299Sed  case Type::VoidTyID:     return "void_";
181210299Sed  case Type::IntegerTyID:
182210299Sed    return "int" + utostr(cast<IntegerType>(Ty)->getBitWidth()) + "_";
183210299Sed  case Type::FloatTyID:    return "float_";
184210299Sed  case Type::DoubleTyID:   return "double_";
185210299Sed  case Type::LabelTyID:    return "label_";
186210299Sed  case Type::FunctionTyID: return "func_";
187210299Sed  case Type::StructTyID:   return "struct_";
188210299Sed  case Type::ArrayTyID:    return "array_";
189210299Sed  case Type::PointerTyID:  return "ptr_";
190210299Sed  case Type::VectorTyID:   return "packed_";
191210299Sed  case Type::OpaqueTyID:   return "opaque_";
192210299Sed  default:                 return "other_";
193193323Sed  }
194210299Sed  return "unknown_";
195210299Sed}
196193323Sed
197210299Sed// Looks up the type in the symbol table and returns a pointer to its name or
198210299Sed// a null pointer if it wasn't found. Note that this isn't the same as the
199210299Sed// Mode::getTypeName function which will return an empty string, not a null
200210299Sed// pointer if the name is not found.
201210299Sedstatic const std::string *
202210299SedfindTypeName(const TypeSymbolTable& ST, const Type* Ty) {
203210299Sed  TypeSymbolTable::const_iterator TI = ST.begin();
204210299Sed  TypeSymbolTable::const_iterator TE = ST.end();
205210299Sed  for (;TI != TE; ++TI)
206210299Sed    if (TI->second == Ty)
207210299Sed      return &(TI->first);
208210299Sed  return 0;
209210299Sed}
210193323Sed
211210299Sedvoid CppWriter::error(const std::string& msg) {
212210299Sed  report_fatal_error(msg);
213210299Sed}
214193323Sed
215210299Sed// printCFP - Print a floating point constant .. very carefully :)
216210299Sed// This makes sure that conversion to/from floating yields the same binary
217210299Sed// result so that we don't lose precision.
218210299Sedvoid CppWriter::printCFP(const ConstantFP *CFP) {
219210299Sed  bool ignored;
220210299Sed  APFloat APF = APFloat(CFP->getValueAPF());  // copy
221210299Sed  if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
222210299Sed    APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
223210299Sed  Out << "ConstantFP::get(mod->getContext(), ";
224210299Sed  Out << "APFloat(";
225193323Sed#if HAVE_PRINTF_A
226210299Sed  char Buffer[100];
227210299Sed  sprintf(Buffer, "%A", APF.convertToDouble());
228210299Sed  if ((!strncmp(Buffer, "0x", 2) ||
229210299Sed       !strncmp(Buffer, "-0x", 3) ||
230210299Sed       !strncmp(Buffer, "+0x", 3)) &&
231210299Sed      APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
232210299Sed    if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
233210299Sed      Out << "BitsToDouble(" << Buffer << ")";
234210299Sed    else
235210299Sed      Out << "BitsToFloat((float)" << Buffer << ")";
236210299Sed    Out << ")";
237210299Sed  } else {
238193323Sed#endif
239210299Sed    std::string StrVal = ftostr(CFP->getValueAPF());
240193323Sed
241210299Sed    while (StrVal[0] == ' ')
242210299Sed      StrVal.erase(StrVal.begin());
243193323Sed
244210299Sed    // Check to make sure that the stringized number is not some string like
245210299Sed    // "Inf" or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
246210299Sed    if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
247210299Sed         ((StrVal[0] == '-' || StrVal[0] == '+') &&
248210299Sed          (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
249210299Sed        (CFP->isExactlyValue(atof(StrVal.c_str())))) {
250210299Sed      if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
251210299Sed        Out <<  StrVal;
252193323Sed      else
253210299Sed        Out << StrVal << "f";
254210299Sed    } else if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
255210299Sed      Out << "BitsToDouble(0x"
256210299Sed          << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
257210299Sed          << "ULL) /* " << StrVal << " */";
258210299Sed    else
259210299Sed      Out << "BitsToFloat(0x"
260210299Sed          << utohexstr((uint32_t)CFP->getValueAPF().
261210299Sed                                      bitcastToAPInt().getZExtValue())
262210299Sed          << "U) /* " << StrVal << " */";
263210299Sed    Out << ")";
264193323Sed#if HAVE_PRINTF_A
265210299Sed  }
266193323Sed#endif
267210299Sed  Out << ")";
268210299Sed}
269210299Sed
270210299Sedvoid CppWriter::printCallingConv(CallingConv::ID cc){
271210299Sed  // Print the calling convention.
272210299Sed  switch (cc) {
273210299Sed  case CallingConv::C:     Out << "CallingConv::C"; break;
274210299Sed  case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
275210299Sed  case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
276210299Sed  case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
277210299Sed  default:                 Out << cc; break;
278193323Sed  }
279210299Sed}
280193323Sed
281210299Sedvoid CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
282210299Sed  switch (LT) {
283210299Sed  case GlobalValue::InternalLinkage:
284210299Sed    Out << "GlobalValue::InternalLinkage"; break;
285210299Sed  case GlobalValue::PrivateLinkage:
286210299Sed    Out << "GlobalValue::PrivateLinkage"; break;
287210299Sed  case GlobalValue::LinkerPrivateLinkage:
288210299Sed    Out << "GlobalValue::LinkerPrivateLinkage"; break;
289210299Sed  case GlobalValue::LinkerPrivateWeakLinkage:
290210299Sed    Out << "GlobalValue::LinkerPrivateWeakLinkage"; break;
291212904Sdim  case GlobalValue::LinkerPrivateWeakDefAutoLinkage:
292212904Sdim    Out << "GlobalValue::LinkerPrivateWeakDefAutoLinkage"; break;
293210299Sed  case GlobalValue::AvailableExternallyLinkage:
294210299Sed    Out << "GlobalValue::AvailableExternallyLinkage "; break;
295210299Sed  case GlobalValue::LinkOnceAnyLinkage:
296210299Sed    Out << "GlobalValue::LinkOnceAnyLinkage "; break;
297210299Sed  case GlobalValue::LinkOnceODRLinkage:
298210299Sed    Out << "GlobalValue::LinkOnceODRLinkage "; break;
299210299Sed  case GlobalValue::WeakAnyLinkage:
300210299Sed    Out << "GlobalValue::WeakAnyLinkage"; break;
301210299Sed  case GlobalValue::WeakODRLinkage:
302210299Sed    Out << "GlobalValue::WeakODRLinkage"; break;
303210299Sed  case GlobalValue::AppendingLinkage:
304210299Sed    Out << "GlobalValue::AppendingLinkage"; break;
305210299Sed  case GlobalValue::ExternalLinkage:
306210299Sed    Out << "GlobalValue::ExternalLinkage"; break;
307210299Sed  case GlobalValue::DLLImportLinkage:
308210299Sed    Out << "GlobalValue::DLLImportLinkage"; break;
309210299Sed  case GlobalValue::DLLExportLinkage:
310210299Sed    Out << "GlobalValue::DLLExportLinkage"; break;
311210299Sed  case GlobalValue::ExternalWeakLinkage:
312210299Sed    Out << "GlobalValue::ExternalWeakLinkage"; break;
313210299Sed  case GlobalValue::CommonLinkage:
314210299Sed    Out << "GlobalValue::CommonLinkage"; break;
315193323Sed  }
316210299Sed}
317193323Sed
318210299Sedvoid CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
319210299Sed  switch (VisType) {
320210299Sed  default: llvm_unreachable("Unknown GVar visibility");
321210299Sed  case GlobalValue::DefaultVisibility:
322210299Sed    Out << "GlobalValue::DefaultVisibility";
323210299Sed    break;
324210299Sed  case GlobalValue::HiddenVisibility:
325210299Sed    Out << "GlobalValue::HiddenVisibility";
326210299Sed    break;
327210299Sed  case GlobalValue::ProtectedVisibility:
328210299Sed    Out << "GlobalValue::ProtectedVisibility";
329210299Sed    break;
330193323Sed  }
331210299Sed}
332193323Sed
333210299Sed// printEscapedString - Print each character of the specified string, escaping
334210299Sed// it if it is not printable or if it is an escape char.
335210299Sedvoid CppWriter::printEscapedString(const std::string &Str) {
336210299Sed  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
337210299Sed    unsigned char C = Str[i];
338210299Sed    if (isprint(C) && C != '"' && C != '\\') {
339210299Sed      Out << C;
340210299Sed    } else {
341210299Sed      Out << "\\x"
342210299Sed          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
343210299Sed          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
344193323Sed    }
345193323Sed  }
346210299Sed}
347193323Sed
348210299Sedstd::string CppWriter::getCppName(const Type* Ty) {
349210299Sed  // First, handle the primitive types .. easy
350210299Sed  if (Ty->isPrimitiveType() || Ty->isIntegerTy()) {
351210299Sed    switch (Ty->getTypeID()) {
352210299Sed    case Type::VoidTyID:   return "Type::getVoidTy(mod->getContext())";
353210299Sed    case Type::IntegerTyID: {
354210299Sed      unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
355210299Sed      return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")";
356193323Sed    }
357210299Sed    case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(mod->getContext())";
358210299Sed    case Type::FloatTyID:    return "Type::getFloatTy(mod->getContext())";
359210299Sed    case Type::DoubleTyID:   return "Type::getDoubleTy(mod->getContext())";
360210299Sed    case Type::LabelTyID:    return "Type::getLabelTy(mod->getContext())";
361218893Sdim    case Type::X86_MMXTyID:  return "Type::getX86_MMXTy(mod->getContext())";
362210299Sed    default:
363210299Sed      error("Invalid primitive type");
364210299Sed      break;
365210299Sed    }
366210299Sed    // shouldn't be returned, but make it sensible
367210299Sed    return "Type::getVoidTy(mod->getContext())";
368193323Sed  }
369193323Sed
370210299Sed  // Now, see if we've seen the type before and return that
371210299Sed  TypeMap::iterator I = TypeNames.find(Ty);
372210299Sed  if (I != TypeNames.end())
373210299Sed    return I->second;
374193323Sed
375210299Sed  // Okay, let's build a new name for this type. Start with a prefix
376210299Sed  const char* prefix = 0;
377210299Sed  switch (Ty->getTypeID()) {
378210299Sed  case Type::FunctionTyID:    prefix = "FuncTy_"; break;
379210299Sed  case Type::StructTyID:      prefix = "StructTy_"; break;
380210299Sed  case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
381210299Sed  case Type::PointerTyID:     prefix = "PointerTy_"; break;
382210299Sed  case Type::OpaqueTyID:      prefix = "OpaqueTy_"; break;
383210299Sed  case Type::VectorTyID:      prefix = "VectorTy_"; break;
384210299Sed  default:                    prefix = "OtherTy_"; break; // prevent breakage
385210299Sed  }
386193323Sed
387210299Sed  // See if the type has a name in the symboltable and build accordingly
388210299Sed  const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty);
389210299Sed  std::string name;
390210299Sed  if (tName)
391210299Sed    name = std::string(prefix) + *tName;
392210299Sed  else
393210299Sed    name = std::string(prefix) + utostr(uniqueNum++);
394210299Sed  sanitize(name);
395193323Sed
396210299Sed  // Save the name
397210299Sed  return TypeNames[Ty] = name;
398210299Sed}
399193323Sed
400210299Sedvoid CppWriter::printCppName(const Type* Ty) {
401210299Sed  printEscapedString(getCppName(Ty));
402210299Sed}
403193323Sed
404210299Sedstd::string CppWriter::getCppName(const Value* val) {
405210299Sed  std::string name;
406210299Sed  ValueMap::iterator I = ValueNames.find(val);
407210299Sed  if (I != ValueNames.end() && I->first == val)
408210299Sed    return  I->second;
409193323Sed
410210299Sed  if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
411210299Sed    name = std::string("gvar_") +
412210299Sed      getTypePrefix(GV->getType()->getElementType());
413210299Sed  } else if (isa<Function>(val)) {
414210299Sed    name = std::string("func_");
415210299Sed  } else if (const Constant* C = dyn_cast<Constant>(val)) {
416210299Sed    name = std::string("const_") + getTypePrefix(C->getType());
417210299Sed  } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
418210299Sed    if (is_inline) {
419210299Sed      unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
420210299Sed                                      Function::const_arg_iterator(Arg)) + 1;
421210299Sed      name = std::string("arg_") + utostr(argNum);
422210299Sed      NameSet::iterator NI = UsedNames.find(name);
423210299Sed      if (NI != UsedNames.end())
424210299Sed        name += std::string("_") + utostr(uniqueNum++);
425210299Sed      UsedNames.insert(name);
426210299Sed      return ValueNames[val] = name;
427193323Sed    } else {
428193323Sed      name = getTypePrefix(val->getType());
429193323Sed    }
430210299Sed  } else {
431210299Sed    name = getTypePrefix(val->getType());
432193323Sed  }
433210299Sed  if (val->hasName())
434210299Sed    name += val->getName();
435210299Sed  else
436210299Sed    name += utostr(uniqueNum++);
437210299Sed  sanitize(name);
438210299Sed  NameSet::iterator NI = UsedNames.find(name);
439210299Sed  if (NI != UsedNames.end())
440210299Sed    name += std::string("_") + utostr(uniqueNum++);
441210299Sed  UsedNames.insert(name);
442210299Sed  return ValueNames[val] = name;
443210299Sed}
444193323Sed
445210299Sedvoid CppWriter::printCppName(const Value* val) {
446210299Sed  printEscapedString(getCppName(val));
447210299Sed}
448193323Sed
449210299Sedvoid CppWriter::printAttributes(const AttrListPtr &PAL,
450210299Sed                                const std::string &name) {
451210299Sed  Out << "AttrListPtr " << name << "_PAL;";
452210299Sed  nl(Out);
453210299Sed  if (!PAL.isEmpty()) {
454210299Sed    Out << '{'; in(); nl(Out);
455210299Sed    Out << "SmallVector<AttributeWithIndex, 4> Attrs;"; nl(Out);
456210299Sed    Out << "AttributeWithIndex PAWI;"; nl(Out);
457210299Sed    for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
458210299Sed      unsigned index = PAL.getSlot(i).Index;
459210299Sed      Attributes attrs = PAL.getSlot(i).Attrs;
460210299Sed      Out << "PAWI.Index = " << index << "U; PAWI.Attrs = 0 ";
461193323Sed#define HANDLE_ATTR(X)                 \
462210299Sed      if (attrs & Attribute::X)      \
463210299Sed        Out << " | Attribute::" #X;  \
464210299Sed      attrs &= ~Attribute::X;
465210299Sed
466210299Sed      HANDLE_ATTR(SExt);
467210299Sed      HANDLE_ATTR(ZExt);
468210299Sed      HANDLE_ATTR(NoReturn);
469210299Sed      HANDLE_ATTR(InReg);
470210299Sed      HANDLE_ATTR(StructRet);
471210299Sed      HANDLE_ATTR(NoUnwind);
472210299Sed      HANDLE_ATTR(NoAlias);
473210299Sed      HANDLE_ATTR(ByVal);
474210299Sed      HANDLE_ATTR(Nest);
475210299Sed      HANDLE_ATTR(ReadNone);
476210299Sed      HANDLE_ATTR(ReadOnly);
477210299Sed      HANDLE_ATTR(NoInline);
478210299Sed      HANDLE_ATTR(AlwaysInline);
479210299Sed      HANDLE_ATTR(OptimizeForSize);
480210299Sed      HANDLE_ATTR(StackProtect);
481210299Sed      HANDLE_ATTR(StackProtectReq);
482210299Sed      HANDLE_ATTR(NoCapture);
483212904Sdim      HANDLE_ATTR(NoRedZone);
484212904Sdim      HANDLE_ATTR(NoImplicitFloat);
485212904Sdim      HANDLE_ATTR(Naked);
486212904Sdim      HANDLE_ATTR(InlineHint);
487193323Sed#undef HANDLE_ATTR
488212904Sdim      if (attrs & Attribute::StackAlignment)
489212904Sdim        Out << " | Attribute::constructStackAlignmentFromInt("
490212904Sdim            << Attribute::getStackAlignmentFromAttrs(attrs)
491212904Sdim            << ")";
492212904Sdim      attrs &= ~Attribute::StackAlignment;
493210299Sed      assert(attrs == 0 && "Unhandled attribute!");
494210299Sed      Out << ";";
495193323Sed      nl(Out);
496210299Sed      Out << "Attrs.push_back(PAWI);";
497210299Sed      nl(Out);
498193323Sed    }
499210299Sed    Out << name << "_PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());";
500210299Sed    nl(Out);
501210299Sed    out(); nl(Out);
502210299Sed    Out << '}'; nl(Out);
503193323Sed  }
504210299Sed}
505193323Sed
506210299Sedbool CppWriter::printTypeInternal(const Type* Ty) {
507210299Sed  // We don't print definitions for primitive types
508210299Sed  if (Ty->isPrimitiveType() || Ty->isIntegerTy())
509210299Sed    return false;
510193323Sed
511210299Sed  // If we already defined this type, we don't need to define it again.
512210299Sed  if (DefinedTypes.find(Ty) != DefinedTypes.end())
513210299Sed    return false;
514193323Sed
515210299Sed  // Everything below needs the name for the type so get it now.
516210299Sed  std::string typeName(getCppName(Ty));
517193323Sed
518210299Sed  // Search the type stack for recursion. If we find it, then generate this
519210299Sed  // as an OpaqueType, but make sure not to do this multiple times because
520210299Sed  // the type could appear in multiple places on the stack. Once the opaque
521210299Sed  // definition is issued, it must not be re-issued. Consequently we have to
522210299Sed  // check the UnresolvedTypes list as well.
523210299Sed  TypeList::const_iterator TI = std::find(TypeStack.begin(), TypeStack.end(),
524210299Sed                                          Ty);
525210299Sed  if (TI != TypeStack.end()) {
526210299Sed    TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
527210299Sed    if (I == UnresolvedTypes.end()) {
528210299Sed      Out << "PATypeHolder " << typeName;
529210299Sed      Out << "_fwd = OpaqueType::get(mod->getContext());";
530210299Sed      nl(Out);
531210299Sed      UnresolvedTypes[Ty] = typeName;
532193323Sed    }
533210299Sed    return true;
534210299Sed  }
535193323Sed
536210299Sed  // We're going to print a derived type which, by definition, contains other
537210299Sed  // types. So, push this one we're printing onto the type stack to assist with
538210299Sed  // recursive definitions.
539210299Sed  TypeStack.push_back(Ty);
540193323Sed
541210299Sed  // Print the type definition
542210299Sed  switch (Ty->getTypeID()) {
543210299Sed  case Type::FunctionTyID:  {
544210299Sed    const FunctionType* FT = cast<FunctionType>(Ty);
545210299Sed    Out << "std::vector<const Type*>" << typeName << "_args;";
546210299Sed    nl(Out);
547210299Sed    FunctionType::param_iterator PI = FT->param_begin();
548210299Sed    FunctionType::param_iterator PE = FT->param_end();
549210299Sed    for (; PI != PE; ++PI) {
550210299Sed      const Type* argTy = static_cast<const Type*>(*PI);
551210299Sed      bool isForward = printTypeInternal(argTy);
552210299Sed      std::string argName(getCppName(argTy));
553210299Sed      Out << typeName << "_args.push_back(" << argName;
554193323Sed      if (isForward)
555193323Sed        Out << "_fwd";
556210299Sed      Out << ");";
557193323Sed      nl(Out);
558193323Sed    }
559210299Sed    bool isForward = printTypeInternal(FT->getReturnType());
560210299Sed    std::string retTypeName(getCppName(FT->getReturnType()));
561210299Sed    Out << "FunctionType* " << typeName << " = FunctionType::get(";
562210299Sed    in(); nl(Out) << "/*Result=*/" << retTypeName;
563210299Sed    if (isForward)
564210299Sed      Out << "_fwd";
565210299Sed    Out << ",";
566210299Sed    nl(Out) << "/*Params=*/" << typeName << "_args,";
567210299Sed    nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
568210299Sed    out();
569210299Sed    nl(Out);
570210299Sed    break;
571210299Sed  }
572210299Sed  case Type::StructTyID: {
573210299Sed    const StructType* ST = cast<StructType>(Ty);
574210299Sed    Out << "std::vector<const Type*>" << typeName << "_fields;";
575210299Sed    nl(Out);
576210299Sed    StructType::element_iterator EI = ST->element_begin();
577210299Sed    StructType::element_iterator EE = ST->element_end();
578210299Sed    for (; EI != EE; ++EI) {
579210299Sed      const Type* fieldTy = static_cast<const Type*>(*EI);
580210299Sed      bool isForward = printTypeInternal(fieldTy);
581210299Sed      std::string fieldName(getCppName(fieldTy));
582210299Sed      Out << typeName << "_fields.push_back(" << fieldName;
583210299Sed      if (isForward)
584210299Sed        Out << "_fwd";
585210299Sed      Out << ");";
586193323Sed      nl(Out);
587193323Sed    }
588210299Sed    Out << "StructType* " << typeName << " = StructType::get("
589210299Sed        << "mod->getContext(), "
590210299Sed        << typeName << "_fields, /*isPacked=*/"
591210299Sed        << (ST->isPacked() ? "true" : "false") << ");";
592210299Sed    nl(Out);
593210299Sed    break;
594210299Sed  }
595210299Sed  case Type::ArrayTyID: {
596210299Sed    const ArrayType* AT = cast<ArrayType>(Ty);
597210299Sed    const Type* ET = AT->getElementType();
598210299Sed    bool isForward = printTypeInternal(ET);
599210299Sed    std::string elemName(getCppName(ET));
600210299Sed    Out << "ArrayType* " << typeName << " = ArrayType::get("
601210299Sed        << elemName << (isForward ? "_fwd" : "")
602210299Sed        << ", " << utostr(AT->getNumElements()) << ");";
603210299Sed    nl(Out);
604210299Sed    break;
605210299Sed  }
606210299Sed  case Type::PointerTyID: {
607210299Sed    const PointerType* PT = cast<PointerType>(Ty);
608210299Sed    const Type* ET = PT->getElementType();
609210299Sed    bool isForward = printTypeInternal(ET);
610210299Sed    std::string elemName(getCppName(ET));
611210299Sed    Out << "PointerType* " << typeName << " = PointerType::get("
612210299Sed        << elemName << (isForward ? "_fwd" : "")
613210299Sed        << ", " << utostr(PT->getAddressSpace()) << ");";
614210299Sed    nl(Out);
615210299Sed    break;
616210299Sed  }
617210299Sed  case Type::VectorTyID: {
618210299Sed    const VectorType* PT = cast<VectorType>(Ty);
619210299Sed    const Type* ET = PT->getElementType();
620210299Sed    bool isForward = printTypeInternal(ET);
621210299Sed    std::string elemName(getCppName(ET));
622210299Sed    Out << "VectorType* " << typeName << " = VectorType::get("
623210299Sed        << elemName << (isForward ? "_fwd" : "")
624210299Sed        << ", " << utostr(PT->getNumElements()) << ");";
625210299Sed    nl(Out);
626210299Sed    break;
627210299Sed  }
628210299Sed  case Type::OpaqueTyID: {
629210299Sed    Out << "OpaqueType* " << typeName;
630210299Sed    Out << " = OpaqueType::get(mod->getContext());";
631210299Sed    nl(Out);
632210299Sed    break;
633210299Sed  }
634210299Sed  default:
635210299Sed    error("Invalid TypeID");
636210299Sed  }
637193323Sed
638210299Sed  // If the type had a name, make sure we recreate it.
639210299Sed  const std::string* progTypeName =
640210299Sed    findTypeName(TheModule->getTypeSymbolTable(),Ty);
641210299Sed  if (progTypeName) {
642210299Sed    Out << "mod->addTypeName(\"" << *progTypeName << "\", "
643210299Sed        << typeName << ");";
644210299Sed    nl(Out);
645210299Sed  }
646193323Sed
647210299Sed  // Pop us off the type stack
648210299Sed  TypeStack.pop_back();
649193323Sed
650210299Sed  // Indicate that this type is now defined.
651210299Sed  DefinedTypes.insert(Ty);
652193323Sed
653210299Sed  // Early resolve as many unresolved types as possible. Search the unresolved
654210299Sed  // types map for the type we just printed. Now that its definition is complete
655210299Sed  // we can resolve any previous references to it. This prevents a cascade of
656210299Sed  // unresolved types.
657210299Sed  TypeMap::iterator I = UnresolvedTypes.find(Ty);
658210299Sed  if (I != UnresolvedTypes.end()) {
659210299Sed    Out << "cast<OpaqueType>(" << I->second
660210299Sed        << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");";
661210299Sed    nl(Out);
662210299Sed    Out << I->second << " = cast<";
663210299Sed    switch (Ty->getTypeID()) {
664210299Sed    case Type::FunctionTyID: Out << "FunctionType"; break;
665210299Sed    case Type::ArrayTyID:    Out << "ArrayType"; break;
666210299Sed    case Type::StructTyID:   Out << "StructType"; break;
667210299Sed    case Type::VectorTyID:   Out << "VectorType"; break;
668210299Sed    case Type::PointerTyID:  Out << "PointerType"; break;
669210299Sed    case Type::OpaqueTyID:   Out << "OpaqueType"; break;
670210299Sed    default:                 Out << "NoSuchDerivedType"; break;
671193323Sed    }
672210299Sed    Out << ">(" << I->second << "_fwd.get());";
673210299Sed    nl(Out); nl(Out);
674210299Sed    UnresolvedTypes.erase(I);
675210299Sed  }
676193323Sed
677210299Sed  // Finally, separate the type definition from other with a newline.
678210299Sed  nl(Out);
679193323Sed
680210299Sed  // We weren't a recursive type
681210299Sed  return false;
682210299Sed}
683193323Sed
684210299Sed// Prints a type definition. Returns true if it could not resolve all the
685210299Sed// types in the definition but had to use a forward reference.
686210299Sedvoid CppWriter::printType(const Type* Ty) {
687210299Sed  assert(TypeStack.empty());
688210299Sed  TypeStack.clear();
689210299Sed  printTypeInternal(Ty);
690210299Sed  assert(TypeStack.empty());
691210299Sed}
692193323Sed
693210299Sedvoid CppWriter::printTypes(const Module* M) {
694210299Sed  // Walk the symbol table and print out all its types
695210299Sed  const TypeSymbolTable& symtab = M->getTypeSymbolTable();
696210299Sed  for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end();
697210299Sed       TI != TE; ++TI) {
698193323Sed
699210299Sed    // For primitive types and types already defined, just add a name
700210299Sed    TypeMap::const_iterator TNI = TypeNames.find(TI->second);
701210299Sed    if (TI->second->isIntegerTy() || TI->second->isPrimitiveType() ||
702210299Sed        TNI != TypeNames.end()) {
703210299Sed      Out << "mod->addTypeName(\"";
704210299Sed      printEscapedString(TI->first);
705210299Sed      Out << "\", " << getCppName(TI->second) << ");";
706210299Sed      nl(Out);
707210299Sed      // For everything else, define the type
708210299Sed    } else {
709210299Sed      printType(TI->second);
710193323Sed    }
711210299Sed  }
712193323Sed
713210299Sed  // Add all of the global variables to the value table...
714210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
715210299Sed         E = TheModule->global_end(); I != E; ++I) {
716210299Sed    if (I->hasInitializer())
717210299Sed      printType(I->getInitializer()->getType());
718210299Sed    printType(I->getType());
719210299Sed  }
720210299Sed
721210299Sed  // Add all the functions to the table
722210299Sed  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
723210299Sed       FI != FE; ++FI) {
724210299Sed    printType(FI->getReturnType());
725210299Sed    printType(FI->getFunctionType());
726210299Sed    // Add all the function arguments
727210299Sed    for (Function::const_arg_iterator AI = FI->arg_begin(),
728210299Sed           AE = FI->arg_end(); AI != AE; ++AI) {
729210299Sed      printType(AI->getType());
730193323Sed    }
731193323Sed
732210299Sed    // Add all of the basic blocks and instructions
733210299Sed    for (Function::const_iterator BB = FI->begin(),
734210299Sed           E = FI->end(); BB != E; ++BB) {
735210299Sed      printType(BB->getType());
736210299Sed      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
737210299Sed           ++I) {
738210299Sed        printType(I->getType());
739210299Sed        for (unsigned i = 0; i < I->getNumOperands(); ++i)
740210299Sed          printType(I->getOperand(i)->getType());
741193323Sed      }
742193323Sed    }
743193323Sed  }
744210299Sed}
745193323Sed
746193323Sed
747210299Sed// printConstant - Print out a constant pool entry...
748210299Sedvoid CppWriter::printConstant(const Constant *CV) {
749210299Sed  // First, if the constant is actually a GlobalValue (variable or function)
750210299Sed  // or its already in the constant list then we've printed it already and we
751210299Sed  // can just return.
752210299Sed  if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
753210299Sed    return;
754193323Sed
755210299Sed  std::string constName(getCppName(CV));
756210299Sed  std::string typeName(getCppName(CV->getType()));
757193323Sed
758210299Sed  if (isa<GlobalValue>(CV)) {
759210299Sed    // Skip variables and functions, we emit them elsewhere
760210299Sed    return;
761210299Sed  }
762193323Sed
763210299Sed  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
764210299Sed    std::string constValue = CI->getValue().toString(10, true);
765210299Sed    Out << "ConstantInt* " << constName
766210299Sed        << " = ConstantInt::get(mod->getContext(), APInt("
767210299Sed        << cast<IntegerType>(CI->getType())->getBitWidth()
768210299Sed        << ", StringRef(\"" <<  constValue << "\"), 10));";
769210299Sed  } else if (isa<ConstantAggregateZero>(CV)) {
770210299Sed    Out << "ConstantAggregateZero* " << constName
771210299Sed        << " = ConstantAggregateZero::get(" << typeName << ");";
772210299Sed  } else if (isa<ConstantPointerNull>(CV)) {
773210299Sed    Out << "ConstantPointerNull* " << constName
774210299Sed        << " = ConstantPointerNull::get(" << typeName << ");";
775210299Sed  } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
776210299Sed    Out << "ConstantFP* " << constName << " = ";
777210299Sed    printCFP(CFP);
778210299Sed    Out << ";";
779210299Sed  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
780210299Sed    if (CA->isString() &&
781210299Sed        CA->getType()->getElementType() ==
782210299Sed            Type::getInt8Ty(CA->getContext())) {
783210299Sed      Out << "Constant* " << constName <<
784210299Sed             " = ConstantArray::get(mod->getContext(), \"";
785210299Sed      std::string tmp = CA->getAsString();
786210299Sed      bool nullTerminate = false;
787210299Sed      if (tmp[tmp.length()-1] == 0) {
788210299Sed        tmp.erase(tmp.length()-1);
789210299Sed        nullTerminate = true;
790193323Sed      }
791210299Sed      printEscapedString(tmp);
792210299Sed      // Determine if we want null termination or not.
793210299Sed      if (nullTerminate)
794210299Sed        Out << "\", true"; // Indicate that the null terminator should be
795210299Sed                           // added.
796210299Sed      else
797210299Sed        Out << "\", false";// No null terminator
798210299Sed      Out << ");";
799210299Sed    } else {
800193323Sed      Out << "std::vector<Constant*> " << constName << "_elems;";
801193323Sed      nl(Out);
802210299Sed      unsigned N = CA->getNumOperands();
803193323Sed      for (unsigned i = 0; i < N; ++i) {
804210299Sed        printConstant(CA->getOperand(i)); // recurse to print operands
805193323Sed        Out << constName << "_elems.push_back("
806210299Sed            << getCppName(CA->getOperand(i)) << ");";
807193323Sed        nl(Out);
808193323Sed      }
809210299Sed      Out << "Constant* " << constName << " = ConstantArray::get("
810193323Sed          << typeName << ", " << constName << "_elems);";
811210299Sed    }
812210299Sed  } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
813210299Sed    Out << "std::vector<Constant*> " << constName << "_fields;";
814210299Sed    nl(Out);
815210299Sed    unsigned N = CS->getNumOperands();
816210299Sed    for (unsigned i = 0; i < N; i++) {
817210299Sed      printConstant(CS->getOperand(i));
818210299Sed      Out << constName << "_fields.push_back("
819210299Sed          << getCppName(CS->getOperand(i)) << ");";
820210299Sed      nl(Out);
821210299Sed    }
822210299Sed    Out << "Constant* " << constName << " = ConstantStruct::get("
823210299Sed        << typeName << ", " << constName << "_fields);";
824210299Sed  } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
825210299Sed    Out << "std::vector<Constant*> " << constName << "_elems;";
826210299Sed    nl(Out);
827210299Sed    unsigned N = CP->getNumOperands();
828210299Sed    for (unsigned i = 0; i < N; ++i) {
829210299Sed      printConstant(CP->getOperand(i));
830210299Sed      Out << constName << "_elems.push_back("
831210299Sed          << getCppName(CP->getOperand(i)) << ");";
832210299Sed      nl(Out);
833210299Sed    }
834210299Sed    Out << "Constant* " << constName << " = ConstantVector::get("
835210299Sed        << typeName << ", " << constName << "_elems);";
836210299Sed  } else if (isa<UndefValue>(CV)) {
837210299Sed    Out << "UndefValue* " << constName << " = UndefValue::get("
838210299Sed        << typeName << ");";
839210299Sed  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
840210299Sed    if (CE->getOpcode() == Instruction::GetElementPtr) {
841210299Sed      Out << "std::vector<Constant*> " << constName << "_indices;";
842210299Sed      nl(Out);
843210299Sed      printConstant(CE->getOperand(0));
844210299Sed      for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
845210299Sed        printConstant(CE->getOperand(i));
846210299Sed        Out << constName << "_indices.push_back("
847210299Sed            << getCppName(CE->getOperand(i)) << ");";
848193323Sed        nl(Out);
849210299Sed      }
850210299Sed      Out << "Constant* " << constName
851210299Sed          << " = ConstantExpr::getGetElementPtr("
852210299Sed          << getCppName(CE->getOperand(0)) << ", "
853210299Sed          << "&" << constName << "_indices[0], "
854210299Sed          << constName << "_indices.size()"
855210299Sed          << ");";
856210299Sed    } else if (CE->isCast()) {
857210299Sed      printConstant(CE->getOperand(0));
858210299Sed      Out << "Constant* " << constName << " = ConstantExpr::getCast(";
859210299Sed      switch (CE->getOpcode()) {
860210299Sed      default: llvm_unreachable("Invalid cast opcode");
861210299Sed      case Instruction::Trunc: Out << "Instruction::Trunc"; break;
862210299Sed      case Instruction::ZExt:  Out << "Instruction::ZExt"; break;
863210299Sed      case Instruction::SExt:  Out << "Instruction::SExt"; break;
864210299Sed      case Instruction::FPTrunc:  Out << "Instruction::FPTrunc"; break;
865210299Sed      case Instruction::FPExt:  Out << "Instruction::FPExt"; break;
866210299Sed      case Instruction::FPToUI:  Out << "Instruction::FPToUI"; break;
867210299Sed      case Instruction::FPToSI:  Out << "Instruction::FPToSI"; break;
868210299Sed      case Instruction::UIToFP:  Out << "Instruction::UIToFP"; break;
869210299Sed      case Instruction::SIToFP:  Out << "Instruction::SIToFP"; break;
870210299Sed      case Instruction::PtrToInt:  Out << "Instruction::PtrToInt"; break;
871210299Sed      case Instruction::IntToPtr:  Out << "Instruction::IntToPtr"; break;
872210299Sed      case Instruction::BitCast:  Out << "Instruction::BitCast"; break;
873210299Sed      }
874210299Sed      Out << ", " << getCppName(CE->getOperand(0)) << ", "
875210299Sed          << getCppName(CE->getType()) << ");";
876210299Sed    } else {
877210299Sed      unsigned N = CE->getNumOperands();
878210299Sed      for (unsigned i = 0; i < N; ++i ) {
879210299Sed        printConstant(CE->getOperand(i));
880210299Sed      }
881210299Sed      Out << "Constant* " << constName << " = ConstantExpr::";
882210299Sed      switch (CE->getOpcode()) {
883210299Sed      case Instruction::Add:    Out << "getAdd(";  break;
884210299Sed      case Instruction::FAdd:   Out << "getFAdd(";  break;
885210299Sed      case Instruction::Sub:    Out << "getSub("; break;
886210299Sed      case Instruction::FSub:   Out << "getFSub("; break;
887210299Sed      case Instruction::Mul:    Out << "getMul("; break;
888210299Sed      case Instruction::FMul:   Out << "getFMul("; break;
889210299Sed      case Instruction::UDiv:   Out << "getUDiv("; break;
890210299Sed      case Instruction::SDiv:   Out << "getSDiv("; break;
891210299Sed      case Instruction::FDiv:   Out << "getFDiv("; break;
892210299Sed      case Instruction::URem:   Out << "getURem("; break;
893210299Sed      case Instruction::SRem:   Out << "getSRem("; break;
894210299Sed      case Instruction::FRem:   Out << "getFRem("; break;
895210299Sed      case Instruction::And:    Out << "getAnd("; break;
896210299Sed      case Instruction::Or:     Out << "getOr("; break;
897210299Sed      case Instruction::Xor:    Out << "getXor("; break;
898210299Sed      case Instruction::ICmp:
899210299Sed        Out << "getICmp(ICmpInst::ICMP_";
900210299Sed        switch (CE->getPredicate()) {
901210299Sed        case ICmpInst::ICMP_EQ:  Out << "EQ"; break;
902210299Sed        case ICmpInst::ICMP_NE:  Out << "NE"; break;
903210299Sed        case ICmpInst::ICMP_SLT: Out << "SLT"; break;
904210299Sed        case ICmpInst::ICMP_ULT: Out << "ULT"; break;
905210299Sed        case ICmpInst::ICMP_SGT: Out << "SGT"; break;
906210299Sed        case ICmpInst::ICMP_UGT: Out << "UGT"; break;
907210299Sed        case ICmpInst::ICMP_SLE: Out << "SLE"; break;
908210299Sed        case ICmpInst::ICMP_ULE: Out << "ULE"; break;
909210299Sed        case ICmpInst::ICMP_SGE: Out << "SGE"; break;
910210299Sed        case ICmpInst::ICMP_UGE: Out << "UGE"; break;
911210299Sed        default: error("Invalid ICmp Predicate");
912193323Sed        }
913210299Sed        break;
914210299Sed      case Instruction::FCmp:
915210299Sed        Out << "getFCmp(FCmpInst::FCMP_";
916210299Sed        switch (CE->getPredicate()) {
917210299Sed        case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
918210299Sed        case FCmpInst::FCMP_ORD:   Out << "ORD"; break;
919210299Sed        case FCmpInst::FCMP_UNO:   Out << "UNO"; break;
920210299Sed        case FCmpInst::FCMP_OEQ:   Out << "OEQ"; break;
921210299Sed        case FCmpInst::FCMP_UEQ:   Out << "UEQ"; break;
922210299Sed        case FCmpInst::FCMP_ONE:   Out << "ONE"; break;
923210299Sed        case FCmpInst::FCMP_UNE:   Out << "UNE"; break;
924210299Sed        case FCmpInst::FCMP_OLT:   Out << "OLT"; break;
925210299Sed        case FCmpInst::FCMP_ULT:   Out << "ULT"; break;
926210299Sed        case FCmpInst::FCMP_OGT:   Out << "OGT"; break;
927210299Sed        case FCmpInst::FCMP_UGT:   Out << "UGT"; break;
928210299Sed        case FCmpInst::FCMP_OLE:   Out << "OLE"; break;
929210299Sed        case FCmpInst::FCMP_ULE:   Out << "ULE"; break;
930210299Sed        case FCmpInst::FCMP_OGE:   Out << "OGE"; break;
931210299Sed        case FCmpInst::FCMP_UGE:   Out << "UGE"; break;
932210299Sed        case FCmpInst::FCMP_TRUE:  Out << "TRUE"; break;
933210299Sed        default: error("Invalid FCmp Predicate");
934193323Sed        }
935210299Sed        break;
936210299Sed      case Instruction::Shl:     Out << "getShl("; break;
937210299Sed      case Instruction::LShr:    Out << "getLShr("; break;
938210299Sed      case Instruction::AShr:    Out << "getAShr("; break;
939210299Sed      case Instruction::Select:  Out << "getSelect("; break;
940210299Sed      case Instruction::ExtractElement: Out << "getExtractElement("; break;
941210299Sed      case Instruction::InsertElement:  Out << "getInsertElement("; break;
942210299Sed      case Instruction::ShuffleVector:  Out << "getShuffleVector("; break;
943210299Sed      default:
944210299Sed        error("Invalid constant expression");
945210299Sed        break;
946193323Sed      }
947210299Sed      Out << getCppName(CE->getOperand(0));
948210299Sed      for (unsigned i = 1; i < CE->getNumOperands(); ++i)
949210299Sed        Out << ", " << getCppName(CE->getOperand(i));
950210299Sed      Out << ");";
951193323Sed    }
952210299Sed  } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
953210299Sed    Out << "Constant* " << constName << " = ";
954210299Sed    Out << "BlockAddress::get(" << getOpName(BA->getBasicBlock()) << ");";
955210299Sed  } else {
956210299Sed    error("Bad Constant");
957210299Sed    Out << "Constant* " << constName << " = 0; ";
958193323Sed  }
959210299Sed  nl(Out);
960210299Sed}
961193323Sed
962210299Sedvoid CppWriter::printConstants(const Module* M) {
963210299Sed  // Traverse all the global variables looking for constant initializers
964210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
965210299Sed         E = TheModule->global_end(); I != E; ++I)
966210299Sed    if (I->hasInitializer())
967210299Sed      printConstant(I->getInitializer());
968193323Sed
969210299Sed  // Traverse the LLVM functions looking for constants
970210299Sed  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
971210299Sed       FI != FE; ++FI) {
972210299Sed    // Add all of the basic blocks and instructions
973210299Sed    for (Function::const_iterator BB = FI->begin(),
974210299Sed           E = FI->end(); BB != E; ++BB) {
975210299Sed      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
976210299Sed           ++I) {
977210299Sed        for (unsigned i = 0; i < I->getNumOperands(); ++i) {
978210299Sed          if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
979210299Sed            printConstant(C);
980193323Sed          }
981193323Sed        }
982193323Sed      }
983193323Sed    }
984193323Sed  }
985210299Sed}
986193323Sed
987210299Sedvoid CppWriter::printVariableUses(const GlobalVariable *GV) {
988210299Sed  nl(Out) << "// Type Definitions";
989210299Sed  nl(Out);
990210299Sed  printType(GV->getType());
991210299Sed  if (GV->hasInitializer()) {
992210299Sed    Constant *Init = GV->getInitializer();
993210299Sed    printType(Init->getType());
994210299Sed    if (Function *F = dyn_cast<Function>(Init)) {
995210299Sed      nl(Out)<< "/ Function Declarations"; nl(Out);
996210299Sed      printFunctionHead(F);
997210299Sed    } else if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
998210299Sed      nl(Out) << "// Global Variable Declarations"; nl(Out);
999210299Sed      printVariableHead(gv);
1000210299Sed
1001210299Sed      nl(Out) << "// Global Variable Definitions"; nl(Out);
1002210299Sed      printVariableBody(gv);
1003210299Sed    } else  {
1004210299Sed      nl(Out) << "// Constant Definitions"; nl(Out);
1005210299Sed      printConstant(Init);
1006193323Sed    }
1007193323Sed  }
1008210299Sed}
1009193323Sed
1010210299Sedvoid CppWriter::printVariableHead(const GlobalVariable *GV) {
1011210299Sed  nl(Out) << "GlobalVariable* " << getCppName(GV);
1012210299Sed  if (is_inline) {
1013210299Sed    Out << " = mod->getGlobalVariable(mod->getContext(), ";
1014193323Sed    printEscapedString(GV->getName());
1015210299Sed    Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
1016210299Sed    nl(Out) << "if (!" << getCppName(GV) << ") {";
1017210299Sed    in(); nl(Out) << getCppName(GV);
1018210299Sed  }
1019210299Sed  Out << " = new GlobalVariable(/*Module=*/*mod, ";
1020210299Sed  nl(Out) << "/*Type=*/";
1021210299Sed  printCppName(GV->getType()->getElementType());
1022210299Sed  Out << ",";
1023210299Sed  nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
1024210299Sed  Out << ",";
1025210299Sed  nl(Out) << "/*Linkage=*/";
1026210299Sed  printLinkageType(GV->getLinkage());
1027210299Sed  Out << ",";
1028210299Sed  nl(Out) << "/*Initializer=*/0, ";
1029210299Sed  if (GV->hasInitializer()) {
1030210299Sed    Out << "// has initializer, specified below";
1031210299Sed  }
1032210299Sed  nl(Out) << "/*Name=*/\"";
1033210299Sed  printEscapedString(GV->getName());
1034210299Sed  Out << "\");";
1035210299Sed  nl(Out);
1036210299Sed
1037210299Sed  if (GV->hasSection()) {
1038210299Sed    printCppName(GV);
1039210299Sed    Out << "->setSection(\"";
1040210299Sed    printEscapedString(GV->getSection());
1041198090Srdivacky    Out << "\");";
1042193323Sed    nl(Out);
1043193323Sed  }
1044210299Sed  if (GV->getAlignment()) {
1045210299Sed    printCppName(GV);
1046210299Sed    Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
1047210299Sed    nl(Out);
1048210299Sed  }
1049210299Sed  if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
1050210299Sed    printCppName(GV);
1051210299Sed    Out << "->setVisibility(";
1052210299Sed    printVisibilityType(GV->getVisibility());
1053210299Sed    Out << ");";
1054210299Sed    nl(Out);
1055210299Sed  }
1056210299Sed  if (GV->isThreadLocal()) {
1057210299Sed    printCppName(GV);
1058210299Sed    Out << "->setThreadLocal(true);";
1059210299Sed    nl(Out);
1060210299Sed  }
1061210299Sed  if (is_inline) {
1062210299Sed    out(); Out << "}"; nl(Out);
1063210299Sed  }
1064210299Sed}
1065193323Sed
1066210299Sedvoid CppWriter::printVariableBody(const GlobalVariable *GV) {
1067210299Sed  if (GV->hasInitializer()) {
1068210299Sed    printCppName(GV);
1069210299Sed    Out << "->setInitializer(";
1070210299Sed    Out << getCppName(GV->getInitializer()) << ");";
1071210299Sed    nl(Out);
1072193323Sed  }
1073210299Sed}
1074193323Sed
1075210299Sedstd::string CppWriter::getOpName(Value* V) {
1076210299Sed  if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
1077210299Sed    return getCppName(V);
1078193323Sed
1079210299Sed  // See if its alread in the map of forward references, if so just return the
1080210299Sed  // name we already set up for it
1081210299Sed  ForwardRefMap::const_iterator I = ForwardRefs.find(V);
1082210299Sed  if (I != ForwardRefs.end())
1083210299Sed    return I->second;
1084193323Sed
1085210299Sed  // This is a new forward reference. Generate a unique name for it
1086210299Sed  std::string result(std::string("fwdref_") + utostr(uniqueNum++));
1087193323Sed
1088210299Sed  // Yes, this is a hack. An Argument is the smallest instantiable value that
1089210299Sed  // we can make as a placeholder for the real value. We'll replace these
1090210299Sed  // Argument instances later.
1091210299Sed  Out << "Argument* " << result << " = new Argument("
1092210299Sed      << getCppName(V->getType()) << ");";
1093210299Sed  nl(Out);
1094210299Sed  ForwardRefs[V] = result;
1095210299Sed  return result;
1096210299Sed}
1097193323Sed
1098210299Sed// printInstruction - This member is called for each Instruction in a function.
1099210299Sedvoid CppWriter::printInstruction(const Instruction *I,
1100210299Sed                                 const std::string& bbname) {
1101210299Sed  std::string iName(getCppName(I));
1102193323Sed
1103210299Sed  // Before we emit this instruction, we need to take care of generating any
1104210299Sed  // forward references. So, we get the names of all the operands in advance
1105210299Sed  const unsigned Ops(I->getNumOperands());
1106210299Sed  std::string* opNames = new std::string[Ops];
1107210299Sed  for (unsigned i = 0; i < Ops; i++)
1108210299Sed    opNames[i] = getOpName(I->getOperand(i));
1109193323Sed
1110210299Sed  switch (I->getOpcode()) {
1111210299Sed  default:
1112210299Sed    error("Invalid instruction");
1113210299Sed    break;
1114193323Sed
1115210299Sed  case Instruction::Ret: {
1116210299Sed    const ReturnInst* ret =  cast<ReturnInst>(I);
1117210299Sed    Out << "ReturnInst::Create(mod->getContext(), "
1118210299Sed        << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
1119210299Sed    break;
1120210299Sed  }
1121210299Sed  case Instruction::Br: {
1122210299Sed    const BranchInst* br = cast<BranchInst>(I);
1123210299Sed    Out << "BranchInst::Create(" ;
1124210299Sed    if (br->getNumOperands() == 3) {
1125210299Sed      Out << opNames[2] << ", "
1126210299Sed          << opNames[1] << ", "
1127210299Sed          << opNames[0] << ", ";
1128193323Sed
1129210299Sed    } else if (br->getNumOperands() == 1) {
1130210299Sed      Out << opNames[0] << ", ";
1131210299Sed    } else {
1132210299Sed      error("Branch with 2 operands?");
1133193323Sed    }
1134210299Sed    Out << bbname << ");";
1135210299Sed    break;
1136210299Sed  }
1137210299Sed  case Instruction::Switch: {
1138210299Sed    const SwitchInst *SI = cast<SwitchInst>(I);
1139210299Sed    Out << "SwitchInst* " << iName << " = SwitchInst::Create("
1140210299Sed        << opNames[0] << ", "
1141210299Sed        << opNames[1] << ", "
1142210299Sed        << SI->getNumCases() << ", " << bbname << ");";
1143210299Sed    nl(Out);
1144210299Sed    for (unsigned i = 2; i != SI->getNumOperands(); i += 2) {
1145210299Sed      Out << iName << "->addCase("
1146210299Sed          << opNames[i] << ", "
1147210299Sed          << opNames[i+1] << ");";
1148193323Sed      nl(Out);
1149193323Sed    }
1150210299Sed    break;
1151210299Sed  }
1152210299Sed  case Instruction::IndirectBr: {
1153210299Sed    const IndirectBrInst *IBI = cast<IndirectBrInst>(I);
1154210299Sed    Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create("
1155210299Sed        << opNames[0] << ", " << IBI->getNumDestinations() << ");";
1156210299Sed    nl(Out);
1157210299Sed    for (unsigned i = 1; i != IBI->getNumOperands(); ++i) {
1158210299Sed      Out << iName << "->addDestination(" << opNames[i] << ");";
1159198892Srdivacky      nl(Out);
1160198892Srdivacky    }
1161210299Sed    break;
1162210299Sed  }
1163210299Sed  case Instruction::Invoke: {
1164210299Sed    const InvokeInst* inv = cast<InvokeInst>(I);
1165210299Sed    Out << "std::vector<Value*> " << iName << "_params;";
1166210299Sed    nl(Out);
1167210299Sed    for (unsigned i = 0; i < inv->getNumArgOperands(); ++i) {
1168210299Sed      Out << iName << "_params.push_back("
1169210299Sed          << getOpName(inv->getArgOperand(i)) << ");";
1170193323Sed      nl(Out);
1171193323Sed    }
1172210299Sed    // FIXME: This shouldn't use magic numbers -3, -2, and -1.
1173210299Sed    Out << "InvokeInst *" << iName << " = InvokeInst::Create("
1174210299Sed        << getOpName(inv->getCalledFunction()) << ", "
1175210299Sed        << getOpName(inv->getNormalDest()) << ", "
1176210299Sed        << getOpName(inv->getUnwindDest()) << ", "
1177210299Sed        << iName << "_params.begin(), "
1178210299Sed        << iName << "_params.end(), \"";
1179210299Sed    printEscapedString(inv->getName());
1180210299Sed    Out << "\", " << bbname << ");";
1181210299Sed    nl(Out) << iName << "->setCallingConv(";
1182210299Sed    printCallingConv(inv->getCallingConv());
1183210299Sed    Out << ");";
1184210299Sed    printAttributes(inv->getAttributes(), iName);
1185210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1186210299Sed    nl(Out);
1187210299Sed    break;
1188210299Sed  }
1189210299Sed  case Instruction::Unwind: {
1190210299Sed    Out << "new UnwindInst("
1191210299Sed        << bbname << ");";
1192210299Sed    break;
1193210299Sed  }
1194210299Sed  case Instruction::Unreachable: {
1195210299Sed    Out << "new UnreachableInst("
1196210299Sed        << "mod->getContext(), "
1197210299Sed        << bbname << ");";
1198210299Sed    break;
1199210299Sed  }
1200210299Sed  case Instruction::Add:
1201210299Sed  case Instruction::FAdd:
1202210299Sed  case Instruction::Sub:
1203210299Sed  case Instruction::FSub:
1204210299Sed  case Instruction::Mul:
1205210299Sed  case Instruction::FMul:
1206210299Sed  case Instruction::UDiv:
1207210299Sed  case Instruction::SDiv:
1208210299Sed  case Instruction::FDiv:
1209210299Sed  case Instruction::URem:
1210210299Sed  case Instruction::SRem:
1211210299Sed  case Instruction::FRem:
1212210299Sed  case Instruction::And:
1213210299Sed  case Instruction::Or:
1214210299Sed  case Instruction::Xor:
1215210299Sed  case Instruction::Shl:
1216210299Sed  case Instruction::LShr:
1217210299Sed  case Instruction::AShr:{
1218210299Sed    Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
1219210299Sed    switch (I->getOpcode()) {
1220210299Sed    case Instruction::Add: Out << "Instruction::Add"; break;
1221210299Sed    case Instruction::FAdd: Out << "Instruction::FAdd"; break;
1222210299Sed    case Instruction::Sub: Out << "Instruction::Sub"; break;
1223210299Sed    case Instruction::FSub: Out << "Instruction::FSub"; break;
1224210299Sed    case Instruction::Mul: Out << "Instruction::Mul"; break;
1225210299Sed    case Instruction::FMul: Out << "Instruction::FMul"; break;
1226210299Sed    case Instruction::UDiv:Out << "Instruction::UDiv"; break;
1227210299Sed    case Instruction::SDiv:Out << "Instruction::SDiv"; break;
1228210299Sed    case Instruction::FDiv:Out << "Instruction::FDiv"; break;
1229210299Sed    case Instruction::URem:Out << "Instruction::URem"; break;
1230210299Sed    case Instruction::SRem:Out << "Instruction::SRem"; break;
1231210299Sed    case Instruction::FRem:Out << "Instruction::FRem"; break;
1232210299Sed    case Instruction::And: Out << "Instruction::And"; break;
1233210299Sed    case Instruction::Or:  Out << "Instruction::Or";  break;
1234210299Sed    case Instruction::Xor: Out << "Instruction::Xor"; break;
1235210299Sed    case Instruction::Shl: Out << "Instruction::Shl"; break;
1236210299Sed    case Instruction::LShr:Out << "Instruction::LShr"; break;
1237210299Sed    case Instruction::AShr:Out << "Instruction::AShr"; break;
1238210299Sed    default: Out << "Instruction::BadOpCode"; break;
1239193323Sed    }
1240210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1241210299Sed    printEscapedString(I->getName());
1242210299Sed    Out << "\", " << bbname << ");";
1243210299Sed    break;
1244210299Sed  }
1245210299Sed  case Instruction::FCmp: {
1246210299Sed    Out << "FCmpInst* " << iName << " = new FCmpInst(*" << bbname << ", ";
1247210299Sed    switch (cast<FCmpInst>(I)->getPredicate()) {
1248210299Sed    case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
1249210299Sed    case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
1250210299Sed    case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
1251210299Sed    case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
1252210299Sed    case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
1253210299Sed    case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
1254210299Sed    case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
1255210299Sed    case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
1256210299Sed    case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
1257210299Sed    case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
1258210299Sed    case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
1259210299Sed    case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
1260210299Sed    case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
1261210299Sed    case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
1262210299Sed    case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
1263210299Sed    case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
1264210299Sed    default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
1265193323Sed    }
1266210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1267210299Sed    printEscapedString(I->getName());
1268210299Sed    Out << "\");";
1269210299Sed    break;
1270210299Sed  }
1271210299Sed  case Instruction::ICmp: {
1272210299Sed    Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
1273210299Sed    switch (cast<ICmpInst>(I)->getPredicate()) {
1274210299Sed    case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
1275210299Sed    case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
1276210299Sed    case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
1277210299Sed    case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
1278210299Sed    case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
1279210299Sed    case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
1280210299Sed    case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
1281210299Sed    case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
1282210299Sed    case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
1283210299Sed    case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
1284210299Sed    default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
1285193323Sed    }
1286210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1287210299Sed    printEscapedString(I->getName());
1288210299Sed    Out << "\");";
1289210299Sed    break;
1290210299Sed  }
1291210299Sed  case Instruction::Alloca: {
1292210299Sed    const AllocaInst* allocaI = cast<AllocaInst>(I);
1293210299Sed    Out << "AllocaInst* " << iName << " = new AllocaInst("
1294210299Sed        << getCppName(allocaI->getAllocatedType()) << ", ";
1295210299Sed    if (allocaI->isArrayAllocation())
1296210299Sed      Out << opNames[0] << ", ";
1297210299Sed    Out << "\"";
1298210299Sed    printEscapedString(allocaI->getName());
1299210299Sed    Out << "\", " << bbname << ");";
1300210299Sed    if (allocaI->getAlignment())
1301210299Sed      nl(Out) << iName << "->setAlignment("
1302210299Sed          << allocaI->getAlignment() << ");";
1303210299Sed    break;
1304210299Sed  }
1305210299Sed  case Instruction::Load: {
1306210299Sed    const LoadInst* load = cast<LoadInst>(I);
1307210299Sed    Out << "LoadInst* " << iName << " = new LoadInst("
1308210299Sed        << opNames[0] << ", \"";
1309210299Sed    printEscapedString(load->getName());
1310210299Sed    Out << "\", " << (load->isVolatile() ? "true" : "false" )
1311210299Sed        << ", " << bbname << ");";
1312210299Sed    break;
1313210299Sed  }
1314210299Sed  case Instruction::Store: {
1315210299Sed    const StoreInst* store = cast<StoreInst>(I);
1316210299Sed    Out << " new StoreInst("
1317210299Sed        << opNames[0] << ", "
1318210299Sed        << opNames[1] << ", "
1319210299Sed        << (store->isVolatile() ? "true" : "false")
1320210299Sed        << ", " << bbname << ");";
1321210299Sed    break;
1322210299Sed  }
1323210299Sed  case Instruction::GetElementPtr: {
1324210299Sed    const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
1325210299Sed    if (gep->getNumOperands() <= 2) {
1326210299Sed      Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
1327210299Sed          << opNames[0];
1328210299Sed      if (gep->getNumOperands() == 2)
1329210299Sed        Out << ", " << opNames[1];
1330210299Sed    } else {
1331210299Sed      Out << "std::vector<Value*> " << iName << "_indices;";
1332210299Sed      nl(Out);
1333210299Sed      for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
1334210299Sed        Out << iName << "_indices.push_back("
1335210299Sed            << opNames[i] << ");";
1336193323Sed        nl(Out);
1337193323Sed      }
1338210299Sed      Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
1339210299Sed          << opNames[0] << ", " << iName << "_indices.begin(), "
1340210299Sed          << iName << "_indices.end()";
1341193323Sed    }
1342210299Sed    Out << ", \"";
1343210299Sed    printEscapedString(gep->getName());
1344210299Sed    Out << "\", " << bbname << ");";
1345210299Sed    break;
1346210299Sed  }
1347210299Sed  case Instruction::PHI: {
1348210299Sed    const PHINode* phi = cast<PHINode>(I);
1349193323Sed
1350210299Sed    Out << "PHINode* " << iName << " = PHINode::Create("
1351210299Sed        << getCppName(phi->getType()) << ", \"";
1352210299Sed    printEscapedString(phi->getName());
1353210299Sed    Out << "\", " << bbname << ");";
1354210299Sed    nl(Out) << iName << "->reserveOperandSpace("
1355210299Sed      << phi->getNumIncomingValues()
1356210299Sed        << ");";
1357210299Sed    nl(Out);
1358210299Sed    for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
1359210299Sed      Out << iName << "->addIncoming("
1360210299Sed          << opNames[i] << ", " << opNames[i+1] << ");";
1361193323Sed      nl(Out);
1362193323Sed    }
1363210299Sed    break;
1364210299Sed  }
1365210299Sed  case Instruction::Trunc:
1366210299Sed  case Instruction::ZExt:
1367210299Sed  case Instruction::SExt:
1368210299Sed  case Instruction::FPTrunc:
1369210299Sed  case Instruction::FPExt:
1370210299Sed  case Instruction::FPToUI:
1371210299Sed  case Instruction::FPToSI:
1372210299Sed  case Instruction::UIToFP:
1373210299Sed  case Instruction::SIToFP:
1374210299Sed  case Instruction::PtrToInt:
1375210299Sed  case Instruction::IntToPtr:
1376210299Sed  case Instruction::BitCast: {
1377210299Sed    const CastInst* cst = cast<CastInst>(I);
1378210299Sed    Out << "CastInst* " << iName << " = new ";
1379210299Sed    switch (I->getOpcode()) {
1380210299Sed    case Instruction::Trunc:    Out << "TruncInst"; break;
1381210299Sed    case Instruction::ZExt:     Out << "ZExtInst"; break;
1382210299Sed    case Instruction::SExt:     Out << "SExtInst"; break;
1383210299Sed    case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
1384210299Sed    case Instruction::FPExt:    Out << "FPExtInst"; break;
1385210299Sed    case Instruction::FPToUI:   Out << "FPToUIInst"; break;
1386210299Sed    case Instruction::FPToSI:   Out << "FPToSIInst"; break;
1387210299Sed    case Instruction::UIToFP:   Out << "UIToFPInst"; break;
1388210299Sed    case Instruction::SIToFP:   Out << "SIToFPInst"; break;
1389210299Sed    case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
1390210299Sed    case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
1391210299Sed    case Instruction::BitCast:  Out << "BitCastInst"; break;
1392210299Sed    default: assert(!"Unreachable"); break;
1393193323Sed    }
1394210299Sed    Out << "(" << opNames[0] << ", "
1395210299Sed        << getCppName(cst->getType()) << ", \"";
1396210299Sed    printEscapedString(cst->getName());
1397210299Sed    Out << "\", " << bbname << ");";
1398210299Sed    break;
1399210299Sed  }
1400210299Sed  case Instruction::Call: {
1401210299Sed    const CallInst* call = cast<CallInst>(I);
1402210299Sed    if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
1403210299Sed      Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
1404210299Sed          << getCppName(ila->getFunctionType()) << ", \""
1405210299Sed          << ila->getAsmString() << "\", \""
1406210299Sed          << ila->getConstraintString() << "\","
1407210299Sed          << (ila->hasSideEffects() ? "true" : "false") << ");";
1408193323Sed      nl(Out);
1409193323Sed    }
1410210299Sed    if (call->getNumArgOperands() > 1) {
1411210299Sed      Out << "std::vector<Value*> " << iName << "_params;";
1412193323Sed      nl(Out);
1413210299Sed      for (unsigned i = 0; i < call->getNumArgOperands(); ++i) {
1414210299Sed        Out << iName << "_params.push_back(" << opNames[i] << ");";
1415193323Sed        nl(Out);
1416193323Sed      }
1417210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1418212904Sdim          << opNames[call->getNumArgOperands()] << ", "
1419212904Sdim          << iName << "_params.begin(), "
1420210299Sed          << iName << "_params.end(), \"";
1421210299Sed    } else if (call->getNumArgOperands() == 1) {
1422210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1423210299Sed          << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \"";
1424210299Sed    } else {
1425210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1426210299Sed          << opNames[call->getNumArgOperands()] << ", \"";
1427193323Sed    }
1428210299Sed    printEscapedString(call->getName());
1429210299Sed    Out << "\", " << bbname << ");";
1430210299Sed    nl(Out) << iName << "->setCallingConv(";
1431210299Sed    printCallingConv(call->getCallingConv());
1432210299Sed    Out << ");";
1433210299Sed    nl(Out) << iName << "->setTailCall("
1434210299Sed        << (call->isTailCall() ? "true" : "false");
1435210299Sed    Out << ");";
1436210299Sed    nl(Out);
1437210299Sed    printAttributes(call->getAttributes(), iName);
1438210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1439210299Sed    nl(Out);
1440210299Sed    break;
1441210299Sed  }
1442210299Sed  case Instruction::Select: {
1443210299Sed    const SelectInst* sel = cast<SelectInst>(I);
1444210299Sed    Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
1445210299Sed    Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1446210299Sed    printEscapedString(sel->getName());
1447210299Sed    Out << "\", " << bbname << ");";
1448210299Sed    break;
1449210299Sed  }
1450210299Sed  case Instruction::UserOp1:
1451210299Sed    /// FALL THROUGH
1452210299Sed  case Instruction::UserOp2: {
1453210299Sed    /// FIXME: What should be done here?
1454210299Sed    break;
1455210299Sed  }
1456210299Sed  case Instruction::VAArg: {
1457210299Sed    const VAArgInst* va = cast<VAArgInst>(I);
1458210299Sed    Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
1459210299Sed        << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
1460210299Sed    printEscapedString(va->getName());
1461210299Sed    Out << "\", " << bbname << ");";
1462210299Sed    break;
1463210299Sed  }
1464210299Sed  case Instruction::ExtractElement: {
1465210299Sed    const ExtractElementInst* eei = cast<ExtractElementInst>(I);
1466210299Sed    Out << "ExtractElementInst* " << getCppName(eei)
1467210299Sed        << " = new ExtractElementInst(" << opNames[0]
1468210299Sed        << ", " << opNames[1] << ", \"";
1469210299Sed    printEscapedString(eei->getName());
1470210299Sed    Out << "\", " << bbname << ");";
1471210299Sed    break;
1472210299Sed  }
1473210299Sed  case Instruction::InsertElement: {
1474210299Sed    const InsertElementInst* iei = cast<InsertElementInst>(I);
1475210299Sed    Out << "InsertElementInst* " << getCppName(iei)
1476210299Sed        << " = InsertElementInst::Create(" << opNames[0]
1477210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1478210299Sed    printEscapedString(iei->getName());
1479210299Sed    Out << "\", " << bbname << ");";
1480210299Sed    break;
1481210299Sed  }
1482210299Sed  case Instruction::ShuffleVector: {
1483210299Sed    const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
1484210299Sed    Out << "ShuffleVectorInst* " << getCppName(svi)
1485210299Sed        << " = new ShuffleVectorInst(" << opNames[0]
1486210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1487210299Sed    printEscapedString(svi->getName());
1488210299Sed    Out << "\", " << bbname << ");";
1489210299Sed    break;
1490210299Sed  }
1491210299Sed  case Instruction::ExtractValue: {
1492210299Sed    const ExtractValueInst *evi = cast<ExtractValueInst>(I);
1493210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1494210299Sed    nl(Out);
1495210299Sed    for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
1496210299Sed      Out << iName << "_indices.push_back("
1497210299Sed          << evi->idx_begin()[i] << ");";
1498193323Sed      nl(Out);
1499193323Sed    }
1500210299Sed    Out << "ExtractValueInst* " << getCppName(evi)
1501210299Sed        << " = ExtractValueInst::Create(" << opNames[0]
1502210299Sed        << ", "
1503210299Sed        << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
1504210299Sed    printEscapedString(evi->getName());
1505210299Sed    Out << "\", " << bbname << ");";
1506210299Sed    break;
1507193323Sed  }
1508210299Sed  case Instruction::InsertValue: {
1509210299Sed    const InsertValueInst *ivi = cast<InsertValueInst>(I);
1510210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1511210299Sed    nl(Out);
1512210299Sed    for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
1513210299Sed      Out << iName << "_indices.push_back("
1514210299Sed          << ivi->idx_begin()[i] << ");";
1515210299Sed      nl(Out);
1516210299Sed    }
1517210299Sed    Out << "InsertValueInst* " << getCppName(ivi)
1518210299Sed        << " = InsertValueInst::Create(" << opNames[0]
1519210299Sed        << ", " << opNames[1] << ", "
1520210299Sed        << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
1521210299Sed    printEscapedString(ivi->getName());
1522210299Sed    Out << "\", " << bbname << ");";
1523210299Sed    break;
1524210299Sed  }
1525210299Sed  }
1526193323Sed  DefinedValues.insert(I);
1527193323Sed  nl(Out);
1528193323Sed  delete [] opNames;
1529193323Sed}
1530193323Sed
1531210299Sed// Print out the types, constants and declarations needed by one function
1532210299Sedvoid CppWriter::printFunctionUses(const Function* F) {
1533210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1534210299Sed  if (!is_inline) {
1535210299Sed    // Print the function's return type
1536210299Sed    printType(F->getReturnType());
1537193323Sed
1538210299Sed    // Print the function's function type
1539210299Sed    printType(F->getFunctionType());
1540193323Sed
1541210299Sed    // Print the types of each of the function's arguments
1542210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1543210299Sed         AI != AE; ++AI) {
1544210299Sed      printType(AI->getType());
1545193323Sed    }
1546210299Sed  }
1547193323Sed
1548210299Sed  // Print type definitions for every type referenced by an instruction and
1549210299Sed  // make a note of any global values or constants that are referenced
1550210299Sed  SmallPtrSet<GlobalValue*,64> gvs;
1551210299Sed  SmallPtrSet<Constant*,64> consts;
1552210299Sed  for (Function::const_iterator BB = F->begin(), BE = F->end();
1553210299Sed       BB != BE; ++BB){
1554210299Sed    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
1555210299Sed         I != E; ++I) {
1556210299Sed      // Print the type of the instruction itself
1557210299Sed      printType(I->getType());
1558193323Sed
1559210299Sed      // Print the type of each of the instruction's operands
1560210299Sed      for (unsigned i = 0; i < I->getNumOperands(); ++i) {
1561210299Sed        Value* operand = I->getOperand(i);
1562210299Sed        printType(operand->getType());
1563193323Sed
1564210299Sed        // If the operand references a GVal or Constant, make a note of it
1565210299Sed        if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1566210299Sed          gvs.insert(GV);
1567218893Sdim          if (GenerationType != GenFunction)
1568218893Sdim            if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1569218893Sdim              if (GVar->hasInitializer())
1570218893Sdim                consts.insert(GVar->getInitializer());
1571218893Sdim        } else if (Constant* C = dyn_cast<Constant>(operand)) {
1572210299Sed          consts.insert(C);
1573218893Sdim          for (unsigned j = 0; j < C->getNumOperands(); ++j) {
1574218893Sdim            // If the operand references a GVal or Constant, make a note of it
1575218893Sdim            Value* operand = C->getOperand(j);
1576218893Sdim            printType(operand->getType());
1577218893Sdim            if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1578218893Sdim              gvs.insert(GV);
1579218893Sdim              if (GenerationType != GenFunction)
1580218893Sdim                if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1581218893Sdim                  if (GVar->hasInitializer())
1582218893Sdim                    consts.insert(GVar->getInitializer());
1583218893Sdim            }
1584218893Sdim          }
1585218893Sdim        }
1586193323Sed      }
1587193323Sed    }
1588210299Sed  }
1589193323Sed
1590210299Sed  // Print the function declarations for any functions encountered
1591210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1592210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1593210299Sed       I != E; ++I) {
1594210299Sed    if (Function* Fun = dyn_cast<Function>(*I)) {
1595210299Sed      if (!is_inline || Fun != F)
1596210299Sed        printFunctionHead(Fun);
1597193323Sed    }
1598210299Sed  }
1599193323Sed
1600210299Sed  // Print the global variable declarations for any variables encountered
1601210299Sed  nl(Out) << "// Global Variable Declarations"; nl(Out);
1602210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1603210299Sed       I != E; ++I) {
1604210299Sed    if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
1605210299Sed      printVariableHead(F);
1606210299Sed  }
1607193323Sed
1608218893Sdim  // Print the constants found
1609210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1610210299Sed  for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(),
1611210299Sed         E = consts.end(); I != E; ++I) {
1612210299Sed    printConstant(*I);
1613210299Sed  }
1614193323Sed
1615210299Sed  // Process the global variables definitions now that all the constants have
1616210299Sed  // been emitted. These definitions just couple the gvars with their constant
1617210299Sed  // initializers.
1618218893Sdim  if (GenerationType != GenFunction) {
1619218893Sdim    nl(Out) << "// Global Variable Definitions"; nl(Out);
1620218893Sdim    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1621218893Sdim         I != E; ++I) {
1622218893Sdim      if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
1623218893Sdim        printVariableBody(GV);
1624218893Sdim    }
1625193323Sed  }
1626210299Sed}
1627193323Sed
1628210299Sedvoid CppWriter::printFunctionHead(const Function* F) {
1629210299Sed  nl(Out) << "Function* " << getCppName(F);
1630210299Sed  if (is_inline) {
1631210299Sed    Out << " = mod->getFunction(\"";
1632193323Sed    printEscapedString(F->getName());
1633210299Sed    Out << "\", " << getCppName(F->getFunctionType()) << ");";
1634210299Sed    nl(Out) << "if (!" << getCppName(F) << ") {";
1635210299Sed    nl(Out) << getCppName(F);
1636210299Sed  }
1637210299Sed  Out<< " = Function::Create(";
1638210299Sed  nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
1639210299Sed  nl(Out) << "/*Linkage=*/";
1640210299Sed  printLinkageType(F->getLinkage());
1641210299Sed  Out << ",";
1642210299Sed  nl(Out) << "/*Name=*/\"";
1643210299Sed  printEscapedString(F->getName());
1644210299Sed  Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
1645210299Sed  nl(Out,-1);
1646210299Sed  printCppName(F);
1647210299Sed  Out << "->setCallingConv(";
1648210299Sed  printCallingConv(F->getCallingConv());
1649210299Sed  Out << ");";
1650210299Sed  nl(Out);
1651210299Sed  if (F->hasSection()) {
1652193323Sed    printCppName(F);
1653210299Sed    Out << "->setSection(\"" << F->getSection() << "\");";
1654210299Sed    nl(Out);
1655210299Sed  }
1656210299Sed  if (F->getAlignment()) {
1657210299Sed    printCppName(F);
1658210299Sed    Out << "->setAlignment(" << F->getAlignment() << ");";
1659210299Sed    nl(Out);
1660210299Sed  }
1661210299Sed  if (F->getVisibility() != GlobalValue::DefaultVisibility) {
1662210299Sed    printCppName(F);
1663210299Sed    Out << "->setVisibility(";
1664210299Sed    printVisibilityType(F->getVisibility());
1665193323Sed    Out << ");";
1666193323Sed    nl(Out);
1667210299Sed  }
1668210299Sed  if (F->hasGC()) {
1669193323Sed    printCppName(F);
1670210299Sed    Out << "->setGC(\"" << F->getGC() << "\");";
1671193323Sed    nl(Out);
1672193323Sed  }
1673210299Sed  if (is_inline) {
1674210299Sed    Out << "}";
1675210299Sed    nl(Out);
1676210299Sed  }
1677210299Sed  printAttributes(F->getAttributes(), getCppName(F));
1678210299Sed  printCppName(F);
1679210299Sed  Out << "->setAttributes(" << getCppName(F) << "_PAL);";
1680210299Sed  nl(Out);
1681210299Sed}
1682193323Sed
1683210299Sedvoid CppWriter::printFunctionBody(const Function *F) {
1684210299Sed  if (F->isDeclaration())
1685210299Sed    return; // external functions have no bodies.
1686193323Sed
1687210299Sed  // Clear the DefinedValues and ForwardRefs maps because we can't have
1688210299Sed  // cross-function forward refs
1689210299Sed  ForwardRefs.clear();
1690210299Sed  DefinedValues.clear();
1691193323Sed
1692210299Sed  // Create all the argument values
1693210299Sed  if (!is_inline) {
1694210299Sed    if (!F->arg_empty()) {
1695210299Sed      Out << "Function::arg_iterator args = " << getCppName(F)
1696210299Sed          << "->arg_begin();";
1697210299Sed      nl(Out);
1698210299Sed    }
1699210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1700210299Sed         AI != AE; ++AI) {
1701210299Sed      Out << "Value* " << getCppName(AI) << " = args++;";
1702210299Sed      nl(Out);
1703210299Sed      if (AI->hasName()) {
1704210299Sed        Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
1705193323Sed        nl(Out);
1706193323Sed      }
1707193323Sed    }
1708210299Sed  }
1709193323Sed
1710210299Sed  // Create all the basic blocks
1711210299Sed  nl(Out);
1712210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1713210299Sed       BI != BE; ++BI) {
1714210299Sed    std::string bbname(getCppName(BI));
1715210299Sed    Out << "BasicBlock* " << bbname <<
1716210299Sed           " = BasicBlock::Create(mod->getContext(), \"";
1717210299Sed    if (BI->hasName())
1718210299Sed      printEscapedString(BI->getName());
1719210299Sed    Out << "\"," << getCppName(BI->getParent()) << ",0);";
1720193323Sed    nl(Out);
1721210299Sed  }
1722193323Sed
1723210299Sed  // Output all of its basic blocks... for the function
1724210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1725210299Sed       BI != BE; ++BI) {
1726210299Sed    std::string bbname(getCppName(BI));
1727210299Sed    nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
1728210299Sed    nl(Out);
1729193323Sed
1730210299Sed    // Output all of the instructions in the basic block...
1731210299Sed    for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
1732210299Sed         I != E; ++I) {
1733210299Sed      printInstruction(I,bbname);
1734193323Sed    }
1735210299Sed  }
1736193323Sed
1737210299Sed  // Loop over the ForwardRefs and resolve them now that all instructions
1738210299Sed  // are generated.
1739210299Sed  if (!ForwardRefs.empty()) {
1740210299Sed    nl(Out) << "// Resolve Forward References";
1741210299Sed    nl(Out);
1742193323Sed  }
1743193323Sed
1744210299Sed  while (!ForwardRefs.empty()) {
1745210299Sed    ForwardRefMap::iterator I = ForwardRefs.begin();
1746210299Sed    Out << I->second << "->replaceAllUsesWith("
1747210299Sed        << getCppName(I->first) << "); delete " << I->second << ";";
1748193323Sed    nl(Out);
1749210299Sed    ForwardRefs.erase(I);
1750193323Sed  }
1751210299Sed}
1752193323Sed
1753210299Sedvoid CppWriter::printInline(const std::string& fname,
1754210299Sed                            const std::string& func) {
1755210299Sed  const Function* F = TheModule->getFunction(func);
1756210299Sed  if (!F) {
1757210299Sed    error(std::string("Function '") + func + "' not found in input module");
1758210299Sed    return;
1759210299Sed  }
1760210299Sed  if (F->isDeclaration()) {
1761210299Sed    error(std::string("Function '") + func + "' is external!");
1762210299Sed    return;
1763210299Sed  }
1764210299Sed  nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
1765210299Sed          << getCppName(F);
1766210299Sed  unsigned arg_count = 1;
1767210299Sed  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1768210299Sed       AI != AE; ++AI) {
1769210299Sed    Out << ", Value* arg_" << arg_count;
1770210299Sed  }
1771210299Sed  Out << ") {";
1772210299Sed  nl(Out);
1773210299Sed  is_inline = true;
1774210299Sed  printFunctionUses(F);
1775210299Sed  printFunctionBody(F);
1776210299Sed  is_inline = false;
1777210299Sed  Out << "return " << getCppName(F->begin()) << ";";
1778210299Sed  nl(Out) << "}";
1779210299Sed  nl(Out);
1780210299Sed}
1781193323Sed
1782210299Sedvoid CppWriter::printModuleBody() {
1783210299Sed  // Print out all the type definitions
1784210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1785210299Sed  printTypes(TheModule);
1786193323Sed
1787210299Sed  // Functions can call each other and global variables can reference them so
1788210299Sed  // define all the functions first before emitting their function bodies.
1789210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1790210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1791210299Sed       I != E; ++I)
1792210299Sed    printFunctionHead(I);
1793193323Sed
1794210299Sed  // Process the global variables declarations. We can't initialze them until
1795210299Sed  // after the constants are printed so just print a header for each global
1796210299Sed  nl(Out) << "// Global Variable Declarations\n"; nl(Out);
1797210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1798210299Sed         E = TheModule->global_end(); I != E; ++I) {
1799210299Sed    printVariableHead(I);
1800210299Sed  }
1801193323Sed
1802210299Sed  // Print out all the constants definitions. Constants don't recurse except
1803210299Sed  // through GlobalValues. All GlobalValues have been declared at this point
1804210299Sed  // so we can proceed to generate the constants.
1805210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1806210299Sed  printConstants(TheModule);
1807193323Sed
1808210299Sed  // Process the global variables definitions now that all the constants have
1809210299Sed  // been emitted. These definitions just couple the gvars with their constant
1810210299Sed  // initializers.
1811210299Sed  nl(Out) << "// Global Variable Definitions"; nl(Out);
1812210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1813210299Sed         E = TheModule->global_end(); I != E; ++I) {
1814210299Sed    printVariableBody(I);
1815193323Sed  }
1816193323Sed
1817210299Sed  // Finally, we can safely put out all of the function bodies.
1818210299Sed  nl(Out) << "// Function Definitions"; nl(Out);
1819210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1820210299Sed       I != E; ++I) {
1821210299Sed    if (!I->isDeclaration()) {
1822210299Sed      nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
1823210299Sed              << ")";
1824210299Sed      nl(Out) << "{";
1825210299Sed      nl(Out,1);
1826210299Sed      printFunctionBody(I);
1827210299Sed      nl(Out,-1) << "}";
1828210299Sed      nl(Out);
1829210299Sed    }
1830193323Sed  }
1831210299Sed}
1832193323Sed
1833210299Sedvoid CppWriter::printProgram(const std::string& fname,
1834210299Sed                             const std::string& mName) {
1835210299Sed  Out << "#include <llvm/LLVMContext.h>\n";
1836210299Sed  Out << "#include <llvm/Module.h>\n";
1837210299Sed  Out << "#include <llvm/DerivedTypes.h>\n";
1838210299Sed  Out << "#include <llvm/Constants.h>\n";
1839210299Sed  Out << "#include <llvm/GlobalVariable.h>\n";
1840210299Sed  Out << "#include <llvm/Function.h>\n";
1841210299Sed  Out << "#include <llvm/CallingConv.h>\n";
1842210299Sed  Out << "#include <llvm/BasicBlock.h>\n";
1843210299Sed  Out << "#include <llvm/Instructions.h>\n";
1844210299Sed  Out << "#include <llvm/InlineAsm.h>\n";
1845210299Sed  Out << "#include <llvm/Support/FormattedStream.h>\n";
1846210299Sed  Out << "#include <llvm/Support/MathExtras.h>\n";
1847210299Sed  Out << "#include <llvm/Pass.h>\n";
1848210299Sed  Out << "#include <llvm/PassManager.h>\n";
1849210299Sed  Out << "#include <llvm/ADT/SmallVector.h>\n";
1850210299Sed  Out << "#include <llvm/Analysis/Verifier.h>\n";
1851210299Sed  Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
1852210299Sed  Out << "#include <algorithm>\n";
1853210299Sed  Out << "using namespace llvm;\n\n";
1854210299Sed  Out << "Module* " << fname << "();\n\n";
1855210299Sed  Out << "int main(int argc, char**argv) {\n";
1856210299Sed  Out << "  Module* Mod = " << fname << "();\n";
1857210299Sed  Out << "  verifyModule(*Mod, PrintMessageAction);\n";
1858210299Sed  Out << "  PassManager PM;\n";
1859210299Sed  Out << "  PM.add(createPrintModulePass(&outs()));\n";
1860210299Sed  Out << "  PM.run(*Mod);\n";
1861210299Sed  Out << "  return 0;\n";
1862210299Sed  Out << "}\n\n";
1863210299Sed  printModule(fname,mName);
1864210299Sed}
1865193323Sed
1866210299Sedvoid CppWriter::printModule(const std::string& fname,
1867210299Sed                            const std::string& mName) {
1868210299Sed  nl(Out) << "Module* " << fname << "() {";
1869210299Sed  nl(Out,1) << "// Module Construction";
1870210299Sed  nl(Out) << "Module* mod = new Module(\"";
1871210299Sed  printEscapedString(mName);
1872210299Sed  Out << "\", getGlobalContext());";
1873210299Sed  if (!TheModule->getTargetTriple().empty()) {
1874210299Sed    nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
1875210299Sed  }
1876210299Sed  if (!TheModule->getTargetTriple().empty()) {
1877210299Sed    nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
1878210299Sed            << "\");";
1879210299Sed  }
1880193323Sed
1881210299Sed  if (!TheModule->getModuleInlineAsm().empty()) {
1882210299Sed    nl(Out) << "mod->setModuleInlineAsm(\"";
1883210299Sed    printEscapedString(TheModule->getModuleInlineAsm());
1884210299Sed    Out << "\");";
1885193323Sed  }
1886210299Sed  nl(Out);
1887193323Sed
1888210299Sed  // Loop over the dependent libraries and emit them.
1889210299Sed  Module::lib_iterator LI = TheModule->lib_begin();
1890210299Sed  Module::lib_iterator LE = TheModule->lib_end();
1891210299Sed  while (LI != LE) {
1892210299Sed    Out << "mod->addLibrary(\"" << *LI << "\");";
1893210299Sed    nl(Out);
1894210299Sed    ++LI;
1895193323Sed  }
1896210299Sed  printModuleBody();
1897210299Sed  nl(Out) << "return mod;";
1898210299Sed  nl(Out,-1) << "}";
1899210299Sed  nl(Out);
1900210299Sed}
1901193323Sed
1902210299Sedvoid CppWriter::printContents(const std::string& fname,
1903210299Sed                              const std::string& mName) {
1904210299Sed  Out << "\nModule* " << fname << "(Module *mod) {\n";
1905210299Sed  Out << "\nmod->setModuleIdentifier(\"";
1906210299Sed  printEscapedString(mName);
1907210299Sed  Out << "\");\n";
1908210299Sed  printModuleBody();
1909210299Sed  Out << "\nreturn mod;\n";
1910210299Sed  Out << "\n}\n";
1911210299Sed}
1912210299Sed
1913210299Sedvoid CppWriter::printFunction(const std::string& fname,
1914210299Sed                              const std::string& funcName) {
1915210299Sed  const Function* F = TheModule->getFunction(funcName);
1916210299Sed  if (!F) {
1917210299Sed    error(std::string("Function '") + funcName + "' not found in input module");
1918210299Sed    return;
1919193323Sed  }
1920210299Sed  Out << "\nFunction* " << fname << "(Module *mod) {\n";
1921210299Sed  printFunctionUses(F);
1922210299Sed  printFunctionHead(F);
1923210299Sed  printFunctionBody(F);
1924210299Sed  Out << "return " << getCppName(F) << ";\n";
1925210299Sed  Out << "}\n";
1926210299Sed}
1927193323Sed
1928210299Sedvoid CppWriter::printFunctions() {
1929210299Sed  const Module::FunctionListType &funcs = TheModule->getFunctionList();
1930210299Sed  Module::const_iterator I  = funcs.begin();
1931210299Sed  Module::const_iterator IE = funcs.end();
1932193323Sed
1933210299Sed  for (; I != IE; ++I) {
1934210299Sed    const Function &func = *I;
1935210299Sed    if (!func.isDeclaration()) {
1936210299Sed      std::string name("define_");
1937210299Sed      name += func.getName();
1938210299Sed      printFunction(name, func.getName());
1939193323Sed    }
1940193323Sed  }
1941210299Sed}
1942193323Sed
1943210299Sedvoid CppWriter::printVariable(const std::string& fname,
1944210299Sed                              const std::string& varName) {
1945210299Sed  const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
1946193323Sed
1947210299Sed  if (!GV) {
1948210299Sed    error(std::string("Variable '") + varName + "' not found in input module");
1949210299Sed    return;
1950193323Sed  }
1951210299Sed  Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
1952210299Sed  printVariableUses(GV);
1953210299Sed  printVariableHead(GV);
1954210299Sed  printVariableBody(GV);
1955210299Sed  Out << "return " << getCppName(GV) << ";\n";
1956210299Sed  Out << "}\n";
1957210299Sed}
1958193323Sed
1959210299Sedvoid CppWriter::printType(const std::string& fname,
1960210299Sed                          const std::string& typeName) {
1961210299Sed  const Type* Ty = TheModule->getTypeByName(typeName);
1962210299Sed  if (!Ty) {
1963210299Sed    error(std::string("Type '") + typeName + "' not found in input module");
1964210299Sed    return;
1965193323Sed  }
1966210299Sed  Out << "\nType* " << fname << "(Module *mod) {\n";
1967210299Sed  printType(Ty);
1968210299Sed  Out << "return " << getCppName(Ty) << ";\n";
1969210299Sed  Out << "}\n";
1970210299Sed}
1971193323Sed
1972210299Sedbool CppWriter::runOnModule(Module &M) {
1973210299Sed  TheModule = &M;
1974193323Sed
1975210299Sed  // Emit a header
1976210299Sed  Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
1977193323Sed
1978210299Sed  // Get the name of the function we're supposed to generate
1979210299Sed  std::string fname = FuncName.getValue();
1980193323Sed
1981210299Sed  // Get the name of the thing we are to generate
1982210299Sed  std::string tgtname = NameToGenerate.getValue();
1983210299Sed  if (GenerationType == GenModule ||
1984210299Sed      GenerationType == GenContents ||
1985210299Sed      GenerationType == GenProgram ||
1986210299Sed      GenerationType == GenFunctions) {
1987210299Sed    if (tgtname == "!bad!") {
1988210299Sed      if (M.getModuleIdentifier() == "-")
1989210299Sed        tgtname = "<stdin>";
1990210299Sed      else
1991210299Sed        tgtname = M.getModuleIdentifier();
1992193323Sed    }
1993210299Sed  } else if (tgtname == "!bad!")
1994210299Sed    error("You must use the -for option with -gen-{function,variable,type}");
1995193323Sed
1996210299Sed  switch (WhatToGenerate(GenerationType)) {
1997210299Sed   case GenProgram:
1998210299Sed    if (fname.empty())
1999210299Sed      fname = "makeLLVMModule";
2000210299Sed    printProgram(fname,tgtname);
2001210299Sed    break;
2002210299Sed   case GenModule:
2003210299Sed    if (fname.empty())
2004210299Sed      fname = "makeLLVMModule";
2005210299Sed    printModule(fname,tgtname);
2006210299Sed    break;
2007210299Sed   case GenContents:
2008210299Sed    if (fname.empty())
2009210299Sed      fname = "makeLLVMModuleContents";
2010210299Sed    printContents(fname,tgtname);
2011210299Sed    break;
2012210299Sed   case GenFunction:
2013210299Sed    if (fname.empty())
2014210299Sed      fname = "makeLLVMFunction";
2015210299Sed    printFunction(fname,tgtname);
2016210299Sed    break;
2017210299Sed   case GenFunctions:
2018210299Sed    printFunctions();
2019210299Sed    break;
2020210299Sed   case GenInline:
2021210299Sed    if (fname.empty())
2022210299Sed      fname = "makeLLVMInline";
2023210299Sed    printInline(fname,tgtname);
2024210299Sed    break;
2025210299Sed   case GenVariable:
2026210299Sed    if (fname.empty())
2027210299Sed      fname = "makeLLVMVariable";
2028210299Sed    printVariable(fname,tgtname);
2029210299Sed    break;
2030210299Sed   case GenType:
2031210299Sed    if (fname.empty())
2032210299Sed      fname = "makeLLVMType";
2033210299Sed    printType(fname,tgtname);
2034210299Sed    break;
2035210299Sed   default:
2036210299Sed    error("Invalid generation option");
2037193323Sed  }
2038210299Sed
2039210299Sed  return false;
2040193323Sed}
2041193323Sed
2042193323Sedchar CppWriter::ID = 0;
2043193323Sed
2044193323Sed//===----------------------------------------------------------------------===//
2045193323Sed//                       External Interface declaration
2046193323Sed//===----------------------------------------------------------------------===//
2047193323Sed
2048208599Srdivackybool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
2049208599Srdivacky                                           formatted_raw_ostream &o,
2050208599Srdivacky                                           CodeGenFileType FileType,
2051208599Srdivacky                                           CodeGenOpt::Level OptLevel,
2052208599Srdivacky                                           bool DisableVerify) {
2053203954Srdivacky  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
2054193323Sed  PM.add(new CppWriter(o));
2055193323Sed  return false;
2056193323Sed}
2057