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"
16249423Sdim#include "llvm/ADT/SmallPtrSet.h"
17249423Sdim#include "llvm/ADT/StringExtras.h"
18249423Sdim#include "llvm/Config/config.h"
19249423Sdim#include "llvm/IR/CallingConv.h"
20249423Sdim#include "llvm/IR/Constants.h"
21249423Sdim#include "llvm/IR/DerivedTypes.h"
22249423Sdim#include "llvm/IR/InlineAsm.h"
23249423Sdim#include "llvm/IR/Instruction.h"
24249423Sdim#include "llvm/IR/Instructions.h"
25249423Sdim#include "llvm/IR/Module.h"
26224145Sdim#include "llvm/MC/MCAsmInfo.h"
27224145Sdim#include "llvm/MC/MCInstrInfo.h"
28224145Sdim#include "llvm/MC/MCSubtargetInfo.h"
29249423Sdim#include "llvm/Pass.h"
30249423Sdim#include "llvm/PassManager.h"
31193323Sed#include "llvm/Support/CommandLine.h"
32198090Srdivacky#include "llvm/Support/ErrorHandling.h"
33198090Srdivacky#include "llvm/Support/FormattedStream.h"
34226633Sdim#include "llvm/Support/TargetRegistry.h"
35193323Sed#include <algorithm>
36263508Sdim#include <cctype>
37234353Sdim#include <cstdio>
38234353Sdim#include <map>
39193323Sed#include <set>
40193323Sedusing namespace llvm;
41193323Sed
42193323Sedstatic cl::opt<std::string>
43193323SedFuncName("cppfname", cl::desc("Specify the name of the generated function"),
44193323Sed         cl::value_desc("function name"));
45193323Sed
46193323Sedenum WhatToGenerate {
47193323Sed  GenProgram,
48193323Sed  GenModule,
49193323Sed  GenContents,
50193323Sed  GenFunction,
51193323Sed  GenFunctions,
52193323Sed  GenInline,
53193323Sed  GenVariable,
54193323Sed  GenType
55193323Sed};
56193323Sed
57193323Sedstatic cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
58193323Sed  cl::desc("Choose what kind of output to generate"),
59193323Sed  cl::init(GenProgram),
60193323Sed  cl::values(
61193323Sed    clEnumValN(GenProgram,  "program",   "Generate a complete program"),
62193323Sed    clEnumValN(GenModule,   "module",    "Generate a module definition"),
63193323Sed    clEnumValN(GenContents, "contents",  "Generate contents of a module"),
64193323Sed    clEnumValN(GenFunction, "function",  "Generate a function definition"),
65193323Sed    clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
66193323Sed    clEnumValN(GenInline,   "inline",    "Generate an inline function"),
67193323Sed    clEnumValN(GenVariable, "variable",  "Generate a variable definition"),
68193323Sed    clEnumValN(GenType,     "type",      "Generate a type definition"),
69193323Sed    clEnumValEnd
70193323Sed  )
71193323Sed);
72193323Sed
73193323Sedstatic cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
74193323Sed  cl::desc("Specify the name of the thing to generate"),
75193323Sed  cl::init("!bad!"));
76193323Sed
77198090Srdivackyextern "C" void LLVMInitializeCppBackendTarget() {
78198090Srdivacky  // Register the target.
79198090Srdivacky  RegisterTargetMachine<CPPTargetMachine> X(TheCppBackendTarget);
80198090Srdivacky}
81193323Sed
82193323Sednamespace {
83226633Sdim  typedef std::vector<Type*> TypeList;
84226633Sdim  typedef std::map<Type*,std::string> TypeMap;
85193323Sed  typedef std::map<const Value*,std::string> ValueMap;
86193323Sed  typedef std::set<std::string> NameSet;
87226633Sdim  typedef std::set<Type*> TypeSet;
88193323Sed  typedef std::set<const Value*> ValueSet;
89193323Sed  typedef std::map<const Value*,std::string> ForwardRefMap;
90193323Sed
91193323Sed  /// CppWriter - This class is the main chunk of code that converts an LLVM
92193323Sed  /// module to a C++ translation unit.
93193323Sed  class CppWriter : public ModulePass {
94198090Srdivacky    formatted_raw_ostream &Out;
95193323Sed    const Module *TheModule;
96193323Sed    uint64_t uniqueNum;
97193323Sed    TypeMap TypeNames;
98193323Sed    ValueMap ValueNames;
99193323Sed    NameSet UsedNames;
100193323Sed    TypeSet DefinedTypes;
101193323Sed    ValueSet DefinedValues;
102193323Sed    ForwardRefMap ForwardRefs;
103193323Sed    bool is_inline;
104210299Sed    unsigned indent_level;
105193323Sed
106193323Sed  public:
107193323Sed    static char ID;
108198090Srdivacky    explicit CppWriter(formatted_raw_ostream &o) :
109212904Sdim      ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
110193323Sed
111193323Sed    virtual const char *getPassName() const { return "C++ backend"; }
112193323Sed
113193323Sed    bool runOnModule(Module &M);
114193323Sed
115193323Sed    void printProgram(const std::string& fname, const std::string& modName );
116193323Sed    void printModule(const std::string& fname, const std::string& modName );
117193323Sed    void printContents(const std::string& fname, const std::string& modName );
118193323Sed    void printFunction(const std::string& fname, const std::string& funcName );
119193323Sed    void printFunctions();
120193323Sed    void printInline(const std::string& fname, const std::string& funcName );
121193323Sed    void printVariable(const std::string& fname, const std::string& varName );
122193323Sed    void printType(const std::string& fname, const std::string& typeName );
123193323Sed
124193323Sed    void error(const std::string& msg);
125193323Sed
126210299Sed
127210299Sed    formatted_raw_ostream& nl(formatted_raw_ostream &Out, int delta = 0);
128210299Sed    inline void in() { indent_level++; }
129210299Sed    inline void out() { if (indent_level >0) indent_level--; }
130210299Sed
131193323Sed  private:
132193323Sed    void printLinkageType(GlobalValue::LinkageTypes LT);
133193323Sed    void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
134239462Sdim    void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM);
135198090Srdivacky    void printCallingConv(CallingConv::ID cc);
136193323Sed    void printEscapedString(const std::string& str);
137193323Sed    void printCFP(const ConstantFP* CFP);
138193323Sed
139226633Sdim    std::string getCppName(Type* val);
140226633Sdim    inline void printCppName(Type* val);
141193323Sed
142193323Sed    std::string getCppName(const Value* val);
143193323Sed    inline void printCppName(const Value* val);
144193323Sed
145249423Sdim    void printAttributes(const AttributeSet &PAL, const std::string &name);
146226633Sdim    void printType(Type* Ty);
147193323Sed    void printTypes(const Module* M);
148193323Sed
149193323Sed    void printConstant(const Constant *CPV);
150193323Sed    void printConstants(const Module* M);
151193323Sed
152193323Sed    void printVariableUses(const GlobalVariable *GV);
153193323Sed    void printVariableHead(const GlobalVariable *GV);
154193323Sed    void printVariableBody(const GlobalVariable *GV);
155193323Sed
156193323Sed    void printFunctionUses(const Function *F);
157193323Sed    void printFunctionHead(const Function *F);
158193323Sed    void printFunctionBody(const Function *F);
159193323Sed    void printInstruction(const Instruction *I, const std::string& bbname);
160226633Sdim    std::string getOpName(const Value*);
161193323Sed
162193323Sed    void printModuleBody();
163193323Sed  };
164210299Sed} // end anonymous namespace.
165193323Sed
166210299Sedformatted_raw_ostream &CppWriter::nl(formatted_raw_ostream &Out, int delta) {
167210299Sed  Out << '\n';
168210299Sed  if (delta >= 0 || indent_level >= unsigned(-delta))
169210299Sed    indent_level += delta;
170210299Sed  Out.indent(indent_level);
171210299Sed  return Out;
172210299Sed}
173193323Sed
174210299Sedstatic inline void sanitize(std::string &str) {
175210299Sed  for (size_t i = 0; i < str.length(); ++i)
176210299Sed    if (!isalnum(str[i]) && str[i] != '_')
177210299Sed      str[i] = '_';
178210299Sed}
179193323Sed
180226633Sdimstatic std::string getTypePrefix(Type *Ty) {
181210299Sed  switch (Ty->getTypeID()) {
182210299Sed  case Type::VoidTyID:     return "void_";
183210299Sed  case Type::IntegerTyID:
184210299Sed    return "int" + utostr(cast<IntegerType>(Ty)->getBitWidth()) + "_";
185210299Sed  case Type::FloatTyID:    return "float_";
186210299Sed  case Type::DoubleTyID:   return "double_";
187210299Sed  case Type::LabelTyID:    return "label_";
188210299Sed  case Type::FunctionTyID: return "func_";
189210299Sed  case Type::StructTyID:   return "struct_";
190210299Sed  case Type::ArrayTyID:    return "array_";
191210299Sed  case Type::PointerTyID:  return "ptr_";
192210299Sed  case Type::VectorTyID:   return "packed_";
193210299Sed  default:                 return "other_";
194193323Sed  }
195210299Sed}
196193323Sed
197210299Sedvoid CppWriter::error(const std::string& msg) {
198210299Sed  report_fatal_error(msg);
199210299Sed}
200193323Sed
201234353Sdimstatic inline std::string ftostr(const APFloat& V) {
202234353Sdim  std::string Buf;
203234353Sdim  if (&V.getSemantics() == &APFloat::IEEEdouble) {
204234353Sdim    raw_string_ostream(Buf) << V.convertToDouble();
205234353Sdim    return Buf;
206234353Sdim  } else if (&V.getSemantics() == &APFloat::IEEEsingle) {
207234353Sdim    raw_string_ostream(Buf) << (double)V.convertToFloat();
208234353Sdim    return Buf;
209234353Sdim  }
210234353Sdim  return "<unknown format in ftostr>"; // error
211234353Sdim}
212234353Sdim
213210299Sed// printCFP - Print a floating point constant .. very carefully :)
214210299Sed// This makes sure that conversion to/from floating yields the same binary
215210299Sed// result so that we don't lose precision.
216210299Sedvoid CppWriter::printCFP(const ConstantFP *CFP) {
217210299Sed  bool ignored;
218210299Sed  APFloat APF = APFloat(CFP->getValueAPF());  // copy
219210299Sed  if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
220210299Sed    APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
221210299Sed  Out << "ConstantFP::get(mod->getContext(), ";
222210299Sed  Out << "APFloat(";
223193323Sed#if HAVE_PRINTF_A
224210299Sed  char Buffer[100];
225210299Sed  sprintf(Buffer, "%A", APF.convertToDouble());
226210299Sed  if ((!strncmp(Buffer, "0x", 2) ||
227210299Sed       !strncmp(Buffer, "-0x", 3) ||
228210299Sed       !strncmp(Buffer, "+0x", 3)) &&
229210299Sed      APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
230210299Sed    if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
231210299Sed      Out << "BitsToDouble(" << Buffer << ")";
232210299Sed    else
233210299Sed      Out << "BitsToFloat((float)" << Buffer << ")";
234210299Sed    Out << ")";
235210299Sed  } else {
236193323Sed#endif
237210299Sed    std::string StrVal = ftostr(CFP->getValueAPF());
238193323Sed
239210299Sed    while (StrVal[0] == ' ')
240210299Sed      StrVal.erase(StrVal.begin());
241193323Sed
242210299Sed    // Check to make sure that the stringized number is not some string like
243210299Sed    // "Inf" or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
244210299Sed    if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
245210299Sed         ((StrVal[0] == '-' || StrVal[0] == '+') &&
246210299Sed          (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
247210299Sed        (CFP->isExactlyValue(atof(StrVal.c_str())))) {
248210299Sed      if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
249210299Sed        Out <<  StrVal;
250193323Sed      else
251210299Sed        Out << StrVal << "f";
252210299Sed    } else if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
253210299Sed      Out << "BitsToDouble(0x"
254210299Sed          << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
255210299Sed          << "ULL) /* " << StrVal << " */";
256210299Sed    else
257210299Sed      Out << "BitsToFloat(0x"
258210299Sed          << utohexstr((uint32_t)CFP->getValueAPF().
259210299Sed                                      bitcastToAPInt().getZExtValue())
260210299Sed          << "U) /* " << StrVal << " */";
261210299Sed    Out << ")";
262193323Sed#if HAVE_PRINTF_A
263210299Sed  }
264193323Sed#endif
265210299Sed  Out << ")";
266210299Sed}
267210299Sed
268210299Sedvoid CppWriter::printCallingConv(CallingConv::ID cc){
269210299Sed  // Print the calling convention.
270210299Sed  switch (cc) {
271210299Sed  case CallingConv::C:     Out << "CallingConv::C"; break;
272210299Sed  case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
273210299Sed  case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
274210299Sed  case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
275210299Sed  default:                 Out << cc; break;
276193323Sed  }
277210299Sed}
278193323Sed
279210299Sedvoid CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
280210299Sed  switch (LT) {
281210299Sed  case GlobalValue::InternalLinkage:
282210299Sed    Out << "GlobalValue::InternalLinkage"; break;
283210299Sed  case GlobalValue::PrivateLinkage:
284210299Sed    Out << "GlobalValue::PrivateLinkage"; break;
285210299Sed  case GlobalValue::LinkerPrivateLinkage:
286210299Sed    Out << "GlobalValue::LinkerPrivateLinkage"; break;
287210299Sed  case GlobalValue::LinkerPrivateWeakLinkage:
288210299Sed    Out << "GlobalValue::LinkerPrivateWeakLinkage"; break;
289210299Sed  case GlobalValue::AvailableExternallyLinkage:
290210299Sed    Out << "GlobalValue::AvailableExternallyLinkage "; break;
291210299Sed  case GlobalValue::LinkOnceAnyLinkage:
292210299Sed    Out << "GlobalValue::LinkOnceAnyLinkage "; break;
293210299Sed  case GlobalValue::LinkOnceODRLinkage:
294210299Sed    Out << "GlobalValue::LinkOnceODRLinkage "; break;
295210299Sed  case GlobalValue::WeakAnyLinkage:
296210299Sed    Out << "GlobalValue::WeakAnyLinkage"; break;
297210299Sed  case GlobalValue::WeakODRLinkage:
298210299Sed    Out << "GlobalValue::WeakODRLinkage"; break;
299210299Sed  case GlobalValue::AppendingLinkage:
300210299Sed    Out << "GlobalValue::AppendingLinkage"; break;
301210299Sed  case GlobalValue::ExternalLinkage:
302210299Sed    Out << "GlobalValue::ExternalLinkage"; break;
303210299Sed  case GlobalValue::DLLImportLinkage:
304210299Sed    Out << "GlobalValue::DLLImportLinkage"; break;
305210299Sed  case GlobalValue::DLLExportLinkage:
306210299Sed    Out << "GlobalValue::DLLExportLinkage"; break;
307210299Sed  case GlobalValue::ExternalWeakLinkage:
308210299Sed    Out << "GlobalValue::ExternalWeakLinkage"; break;
309210299Sed  case GlobalValue::CommonLinkage:
310210299Sed    Out << "GlobalValue::CommonLinkage"; break;
311193323Sed  }
312210299Sed}
313193323Sed
314210299Sedvoid CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
315210299Sed  switch (VisType) {
316210299Sed  case GlobalValue::DefaultVisibility:
317210299Sed    Out << "GlobalValue::DefaultVisibility";
318210299Sed    break;
319210299Sed  case GlobalValue::HiddenVisibility:
320210299Sed    Out << "GlobalValue::HiddenVisibility";
321210299Sed    break;
322210299Sed  case GlobalValue::ProtectedVisibility:
323210299Sed    Out << "GlobalValue::ProtectedVisibility";
324210299Sed    break;
325193323Sed  }
326210299Sed}
327193323Sed
328239462Sdimvoid CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) {
329239462Sdim  switch (TLM) {
330239462Sdim    case GlobalVariable::NotThreadLocal:
331239462Sdim      Out << "GlobalVariable::NotThreadLocal";
332239462Sdim      break;
333239462Sdim    case GlobalVariable::GeneralDynamicTLSModel:
334239462Sdim      Out << "GlobalVariable::GeneralDynamicTLSModel";
335239462Sdim      break;
336239462Sdim    case GlobalVariable::LocalDynamicTLSModel:
337239462Sdim      Out << "GlobalVariable::LocalDynamicTLSModel";
338239462Sdim      break;
339239462Sdim    case GlobalVariable::InitialExecTLSModel:
340239462Sdim      Out << "GlobalVariable::InitialExecTLSModel";
341239462Sdim      break;
342239462Sdim    case GlobalVariable::LocalExecTLSModel:
343239462Sdim      Out << "GlobalVariable::LocalExecTLSModel";
344239462Sdim      break;
345239462Sdim  }
346239462Sdim}
347239462Sdim
348210299Sed// printEscapedString - Print each character of the specified string, escaping
349210299Sed// it if it is not printable or if it is an escape char.
350210299Sedvoid CppWriter::printEscapedString(const std::string &Str) {
351210299Sed  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
352210299Sed    unsigned char C = Str[i];
353210299Sed    if (isprint(C) && C != '"' && C != '\\') {
354210299Sed      Out << C;
355210299Sed    } else {
356210299Sed      Out << "\\x"
357210299Sed          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
358210299Sed          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
359193323Sed    }
360193323Sed  }
361210299Sed}
362193323Sed
363226633Sdimstd::string CppWriter::getCppName(Type* Ty) {
364210299Sed  // First, handle the primitive types .. easy
365210299Sed  if (Ty->isPrimitiveType() || Ty->isIntegerTy()) {
366210299Sed    switch (Ty->getTypeID()) {
367210299Sed    case Type::VoidTyID:   return "Type::getVoidTy(mod->getContext())";
368210299Sed    case Type::IntegerTyID: {
369210299Sed      unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
370210299Sed      return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")";
371193323Sed    }
372210299Sed    case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(mod->getContext())";
373210299Sed    case Type::FloatTyID:    return "Type::getFloatTy(mod->getContext())";
374210299Sed    case Type::DoubleTyID:   return "Type::getDoubleTy(mod->getContext())";
375210299Sed    case Type::LabelTyID:    return "Type::getLabelTy(mod->getContext())";
376218893Sdim    case Type::X86_MMXTyID:  return "Type::getX86_MMXTy(mod->getContext())";
377210299Sed    default:
378210299Sed      error("Invalid primitive type");
379210299Sed      break;
380210299Sed    }
381210299Sed    // shouldn't be returned, but make it sensible
382210299Sed    return "Type::getVoidTy(mod->getContext())";
383193323Sed  }
384193323Sed
385210299Sed  // Now, see if we've seen the type before and return that
386210299Sed  TypeMap::iterator I = TypeNames.find(Ty);
387210299Sed  if (I != TypeNames.end())
388210299Sed    return I->second;
389193323Sed
390210299Sed  // Okay, let's build a new name for this type. Start with a prefix
391210299Sed  const char* prefix = 0;
392210299Sed  switch (Ty->getTypeID()) {
393210299Sed  case Type::FunctionTyID:    prefix = "FuncTy_"; break;
394210299Sed  case Type::StructTyID:      prefix = "StructTy_"; break;
395210299Sed  case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
396210299Sed  case Type::PointerTyID:     prefix = "PointerTy_"; break;
397210299Sed  case Type::VectorTyID:      prefix = "VectorTy_"; break;
398210299Sed  default:                    prefix = "OtherTy_"; break; // prevent breakage
399210299Sed  }
400193323Sed
401210299Sed  // See if the type has a name in the symboltable and build accordingly
402210299Sed  std::string name;
403226633Sdim  if (StructType *STy = dyn_cast<StructType>(Ty))
404224145Sdim    if (STy->hasName())
405224145Sdim      name = STy->getName();
406224145Sdim
407224145Sdim  if (name.empty())
408224145Sdim    name = utostr(uniqueNum++);
409224145Sdim
410224145Sdim  name = std::string(prefix) + name;
411210299Sed  sanitize(name);
412193323Sed
413210299Sed  // Save the name
414210299Sed  return TypeNames[Ty] = name;
415210299Sed}
416193323Sed
417226633Sdimvoid CppWriter::printCppName(Type* Ty) {
418210299Sed  printEscapedString(getCppName(Ty));
419210299Sed}
420193323Sed
421210299Sedstd::string CppWriter::getCppName(const Value* val) {
422210299Sed  std::string name;
423210299Sed  ValueMap::iterator I = ValueNames.find(val);
424210299Sed  if (I != ValueNames.end() && I->first == val)
425210299Sed    return  I->second;
426193323Sed
427210299Sed  if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
428210299Sed    name = std::string("gvar_") +
429210299Sed      getTypePrefix(GV->getType()->getElementType());
430210299Sed  } else if (isa<Function>(val)) {
431210299Sed    name = std::string("func_");
432210299Sed  } else if (const Constant* C = dyn_cast<Constant>(val)) {
433210299Sed    name = std::string("const_") + getTypePrefix(C->getType());
434210299Sed  } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
435210299Sed    if (is_inline) {
436210299Sed      unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
437210299Sed                                      Function::const_arg_iterator(Arg)) + 1;
438210299Sed      name = std::string("arg_") + utostr(argNum);
439210299Sed      NameSet::iterator NI = UsedNames.find(name);
440210299Sed      if (NI != UsedNames.end())
441210299Sed        name += std::string("_") + utostr(uniqueNum++);
442210299Sed      UsedNames.insert(name);
443210299Sed      return ValueNames[val] = name;
444193323Sed    } else {
445193323Sed      name = getTypePrefix(val->getType());
446193323Sed    }
447210299Sed  } else {
448210299Sed    name = getTypePrefix(val->getType());
449193323Sed  }
450210299Sed  if (val->hasName())
451210299Sed    name += val->getName();
452210299Sed  else
453210299Sed    name += utostr(uniqueNum++);
454210299Sed  sanitize(name);
455210299Sed  NameSet::iterator NI = UsedNames.find(name);
456210299Sed  if (NI != UsedNames.end())
457210299Sed    name += std::string("_") + utostr(uniqueNum++);
458210299Sed  UsedNames.insert(name);
459210299Sed  return ValueNames[val] = name;
460210299Sed}
461193323Sed
462210299Sedvoid CppWriter::printCppName(const Value* val) {
463210299Sed  printEscapedString(getCppName(val));
464210299Sed}
465193323Sed
466249423Sdimvoid CppWriter::printAttributes(const AttributeSet &PAL,
467210299Sed                                const std::string &name) {
468249423Sdim  Out << "AttributeSet " << name << "_PAL;";
469210299Sed  nl(Out);
470210299Sed  if (!PAL.isEmpty()) {
471210299Sed    Out << '{'; in(); nl(Out);
472249423Sdim    Out << "SmallVector<AttributeSet, 4> Attrs;"; nl(Out);
473249423Sdim    Out << "AttributeSet PAS;"; in(); nl(Out);
474210299Sed    for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
475249423Sdim      unsigned index = PAL.getSlotIndex(i);
476249423Sdim      AttrBuilder attrs(PAL.getSlotAttributes(i), index);
477249423Sdim      Out << "{"; in(); nl(Out);
478249423Sdim      Out << "AttrBuilder B;"; nl(Out);
479243830Sdim
480249423Sdim#define HANDLE_ATTR(X)                                                  \
481249423Sdim      if (attrs.contains(Attribute::X)) {                               \
482249423Sdim        Out << "B.addAttribute(Attribute::" #X ");"; nl(Out);           \
483249423Sdim        attrs.removeAttribute(Attribute::X);                            \
484249423Sdim      }
485243830Sdim
486210299Sed      HANDLE_ATTR(SExt);
487210299Sed      HANDLE_ATTR(ZExt);
488210299Sed      HANDLE_ATTR(NoReturn);
489210299Sed      HANDLE_ATTR(InReg);
490210299Sed      HANDLE_ATTR(StructRet);
491210299Sed      HANDLE_ATTR(NoUnwind);
492210299Sed      HANDLE_ATTR(NoAlias);
493210299Sed      HANDLE_ATTR(ByVal);
494210299Sed      HANDLE_ATTR(Nest);
495210299Sed      HANDLE_ATTR(ReadNone);
496210299Sed      HANDLE_ATTR(ReadOnly);
497210299Sed      HANDLE_ATTR(NoInline);
498210299Sed      HANDLE_ATTR(AlwaysInline);
499263508Sdim      HANDLE_ATTR(OptimizeNone);
500210299Sed      HANDLE_ATTR(OptimizeForSize);
501210299Sed      HANDLE_ATTR(StackProtect);
502210299Sed      HANDLE_ATTR(StackProtectReq);
503249423Sdim      HANDLE_ATTR(StackProtectStrong);
504210299Sed      HANDLE_ATTR(NoCapture);
505212904Sdim      HANDLE_ATTR(NoRedZone);
506212904Sdim      HANDLE_ATTR(NoImplicitFloat);
507212904Sdim      HANDLE_ATTR(Naked);
508212904Sdim      HANDLE_ATTR(InlineHint);
509226633Sdim      HANDLE_ATTR(ReturnsTwice);
510226633Sdim      HANDLE_ATTR(UWTable);
511226633Sdim      HANDLE_ATTR(NonLazyBind);
512243830Sdim      HANDLE_ATTR(MinSize);
513193323Sed#undef HANDLE_ATTR
514249423Sdim
515249423Sdim      if (attrs.contains(Attribute::StackAlignment)) {
516249423Sdim        Out << "B.addStackAlignmentAttr(" << attrs.getStackAlignment()<<')';
517249423Sdim        nl(Out);
518249423Sdim        attrs.removeAttribute(Attribute::StackAlignment);
519249423Sdim      }
520249423Sdim
521249423Sdim      Out << "PAS = AttributeSet::get(mod->getContext(), ";
522249423Sdim      if (index == ~0U)
523249423Sdim        Out << "~0U,";
524249423Sdim      else
525249423Sdim        Out << index << "U,";
526249423Sdim      Out << " B);"; out(); nl(Out);
527249423Sdim      Out << "}"; out(); nl(Out);
528193323Sed      nl(Out);
529249423Sdim      Out << "Attrs.push_back(PAS);"; nl(Out);
530193323Sed    }
531249423Sdim    Out << name << "_PAL = AttributeSet::get(mod->getContext(), Attrs);";
532210299Sed    nl(Out);
533210299Sed    out(); nl(Out);
534210299Sed    Out << '}'; nl(Out);
535193323Sed  }
536210299Sed}
537193323Sed
538226633Sdimvoid CppWriter::printType(Type* Ty) {
539210299Sed  // We don't print definitions for primitive types
540210299Sed  if (Ty->isPrimitiveType() || Ty->isIntegerTy())
541224145Sdim    return;
542193323Sed
543210299Sed  // If we already defined this type, we don't need to define it again.
544210299Sed  if (DefinedTypes.find(Ty) != DefinedTypes.end())
545224145Sdim    return;
546193323Sed
547210299Sed  // Everything below needs the name for the type so get it now.
548210299Sed  std::string typeName(getCppName(Ty));
549193323Sed
550210299Sed  // Print the type definition
551210299Sed  switch (Ty->getTypeID()) {
552210299Sed  case Type::FunctionTyID:  {
553226633Sdim    FunctionType* FT = cast<FunctionType>(Ty);
554224145Sdim    Out << "std::vector<Type*>" << typeName << "_args;";
555210299Sed    nl(Out);
556210299Sed    FunctionType::param_iterator PI = FT->param_begin();
557210299Sed    FunctionType::param_iterator PE = FT->param_end();
558210299Sed    for (; PI != PE; ++PI) {
559226633Sdim      Type* argTy = static_cast<Type*>(*PI);
560224145Sdim      printType(argTy);
561210299Sed      std::string argName(getCppName(argTy));
562210299Sed      Out << typeName << "_args.push_back(" << argName;
563210299Sed      Out << ");";
564193323Sed      nl(Out);
565193323Sed    }
566224145Sdim    printType(FT->getReturnType());
567210299Sed    std::string retTypeName(getCppName(FT->getReturnType()));
568210299Sed    Out << "FunctionType* " << typeName << " = FunctionType::get(";
569210299Sed    in(); nl(Out) << "/*Result=*/" << retTypeName;
570210299Sed    Out << ",";
571210299Sed    nl(Out) << "/*Params=*/" << typeName << "_args,";
572210299Sed    nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
573210299Sed    out();
574210299Sed    nl(Out);
575210299Sed    break;
576210299Sed  }
577210299Sed  case Type::StructTyID: {
578226633Sdim    StructType* ST = cast<StructType>(Ty);
579226633Sdim    if (!ST->isLiteral()) {
580226633Sdim      Out << "StructType *" << typeName << " = mod->getTypeByName(\"";
581224145Sdim      printEscapedString(ST->getName());
582224145Sdim      Out << "\");";
583224145Sdim      nl(Out);
584226633Sdim      Out << "if (!" << typeName << ") {";
585226633Sdim      nl(Out);
586226633Sdim      Out << typeName << " = ";
587226633Sdim      Out << "StructType::create(mod->getContext(), \"";
588226633Sdim      printEscapedString(ST->getName());
589226633Sdim      Out << "\");";
590226633Sdim      nl(Out);
591226633Sdim      Out << "}";
592226633Sdim      nl(Out);
593224145Sdim      // Indicate that this type is now defined.
594224145Sdim      DefinedTypes.insert(Ty);
595224145Sdim    }
596224145Sdim
597224145Sdim    Out << "std::vector<Type*>" << typeName << "_fields;";
598210299Sed    nl(Out);
599210299Sed    StructType::element_iterator EI = ST->element_begin();
600210299Sed    StructType::element_iterator EE = ST->element_end();
601210299Sed    for (; EI != EE; ++EI) {
602226633Sdim      Type* fieldTy = static_cast<Type*>(*EI);
603224145Sdim      printType(fieldTy);
604210299Sed      std::string fieldName(getCppName(fieldTy));
605210299Sed      Out << typeName << "_fields.push_back(" << fieldName;
606210299Sed      Out << ");";
607193323Sed      nl(Out);
608193323Sed    }
609224145Sdim
610226633Sdim    if (ST->isLiteral()) {
611224145Sdim      Out << "StructType *" << typeName << " = ";
612224145Sdim      Out << "StructType::get(" << "mod->getContext(), ";
613224145Sdim    } else {
614226633Sdim      Out << "if (" << typeName << "->isOpaque()) {";
615226633Sdim      nl(Out);
616224145Sdim      Out << typeName << "->setBody(";
617224145Sdim    }
618224145Sdim
619224145Sdim    Out << typeName << "_fields, /*isPacked=*/"
620210299Sed        << (ST->isPacked() ? "true" : "false") << ");";
621210299Sed    nl(Out);
622226633Sdim    if (!ST->isLiteral()) {
623226633Sdim      Out << "}";
624226633Sdim      nl(Out);
625226633Sdim    }
626210299Sed    break;
627210299Sed  }
628210299Sed  case Type::ArrayTyID: {
629226633Sdim    ArrayType* AT = cast<ArrayType>(Ty);
630226633Sdim    Type* ET = AT->getElementType();
631224145Sdim    printType(ET);
632224145Sdim    if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
633224145Sdim      std::string elemName(getCppName(ET));
634224145Sdim      Out << "ArrayType* " << typeName << " = ArrayType::get("
635224145Sdim          << elemName
636224145Sdim          << ", " << utostr(AT->getNumElements()) << ");";
637224145Sdim      nl(Out);
638224145Sdim    }
639210299Sed    break;
640210299Sed  }
641210299Sed  case Type::PointerTyID: {
642226633Sdim    PointerType* PT = cast<PointerType>(Ty);
643226633Sdim    Type* ET = PT->getElementType();
644224145Sdim    printType(ET);
645224145Sdim    if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
646224145Sdim      std::string elemName(getCppName(ET));
647224145Sdim      Out << "PointerType* " << typeName << " = PointerType::get("
648224145Sdim          << elemName
649224145Sdim          << ", " << utostr(PT->getAddressSpace()) << ");";
650224145Sdim      nl(Out);
651224145Sdim    }
652210299Sed    break;
653210299Sed  }
654210299Sed  case Type::VectorTyID: {
655226633Sdim    VectorType* PT = cast<VectorType>(Ty);
656226633Sdim    Type* ET = PT->getElementType();
657224145Sdim    printType(ET);
658224145Sdim    if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
659224145Sdim      std::string elemName(getCppName(ET));
660224145Sdim      Out << "VectorType* " << typeName << " = VectorType::get("
661224145Sdim          << elemName
662224145Sdim          << ", " << utostr(PT->getNumElements()) << ");";
663224145Sdim      nl(Out);
664224145Sdim    }
665210299Sed    break;
666210299Sed  }
667210299Sed  default:
668210299Sed    error("Invalid TypeID");
669210299Sed  }
670193323Sed
671210299Sed  // Indicate that this type is now defined.
672210299Sed  DefinedTypes.insert(Ty);
673193323Sed
674210299Sed  // Finally, separate the type definition from other with a newline.
675210299Sed  nl(Out);
676210299Sed}
677193323Sed
678210299Sedvoid CppWriter::printTypes(const Module* M) {
679224145Sdim  // Add all of the global variables to the value table.
680210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
681210299Sed         E = TheModule->global_end(); I != E; ++I) {
682210299Sed    if (I->hasInitializer())
683210299Sed      printType(I->getInitializer()->getType());
684210299Sed    printType(I->getType());
685210299Sed  }
686210299Sed
687210299Sed  // Add all the functions to the table
688210299Sed  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
689210299Sed       FI != FE; ++FI) {
690210299Sed    printType(FI->getReturnType());
691210299Sed    printType(FI->getFunctionType());
692210299Sed    // Add all the function arguments
693210299Sed    for (Function::const_arg_iterator AI = FI->arg_begin(),
694210299Sed           AE = FI->arg_end(); AI != AE; ++AI) {
695210299Sed      printType(AI->getType());
696193323Sed    }
697193323Sed
698210299Sed    // Add all of the basic blocks and instructions
699210299Sed    for (Function::const_iterator BB = FI->begin(),
700210299Sed           E = FI->end(); BB != E; ++BB) {
701210299Sed      printType(BB->getType());
702210299Sed      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
703210299Sed           ++I) {
704210299Sed        printType(I->getType());
705210299Sed        for (unsigned i = 0; i < I->getNumOperands(); ++i)
706210299Sed          printType(I->getOperand(i)->getType());
707193323Sed      }
708193323Sed    }
709193323Sed  }
710210299Sed}
711193323Sed
712193323Sed
713210299Sed// printConstant - Print out a constant pool entry...
714210299Sedvoid CppWriter::printConstant(const Constant *CV) {
715210299Sed  // First, if the constant is actually a GlobalValue (variable or function)
716210299Sed  // or its already in the constant list then we've printed it already and we
717210299Sed  // can just return.
718210299Sed  if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
719210299Sed    return;
720193323Sed
721210299Sed  std::string constName(getCppName(CV));
722210299Sed  std::string typeName(getCppName(CV->getType()));
723193323Sed
724210299Sed  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
725210299Sed    std::string constValue = CI->getValue().toString(10, true);
726210299Sed    Out << "ConstantInt* " << constName
727210299Sed        << " = ConstantInt::get(mod->getContext(), APInt("
728210299Sed        << cast<IntegerType>(CI->getType())->getBitWidth()
729210299Sed        << ", StringRef(\"" <<  constValue << "\"), 10));";
730210299Sed  } else if (isa<ConstantAggregateZero>(CV)) {
731210299Sed    Out << "ConstantAggregateZero* " << constName
732210299Sed        << " = ConstantAggregateZero::get(" << typeName << ");";
733210299Sed  } else if (isa<ConstantPointerNull>(CV)) {
734210299Sed    Out << "ConstantPointerNull* " << constName
735210299Sed        << " = ConstantPointerNull::get(" << typeName << ");";
736210299Sed  } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
737210299Sed    Out << "ConstantFP* " << constName << " = ";
738210299Sed    printCFP(CFP);
739210299Sed    Out << ";";
740210299Sed  } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
741234353Sdim    Out << "std::vector<Constant*> " << constName << "_elems;";
742234353Sdim    nl(Out);
743234353Sdim    unsigned N = CA->getNumOperands();
744234353Sdim    for (unsigned i = 0; i < N; ++i) {
745234353Sdim      printConstant(CA->getOperand(i)); // recurse to print operands
746234353Sdim      Out << constName << "_elems.push_back("
747234353Sdim          << getCppName(CA->getOperand(i)) << ");";
748193323Sed      nl(Out);
749210299Sed    }
750234353Sdim    Out << "Constant* " << constName << " = ConstantArray::get("
751234353Sdim        << typeName << ", " << constName << "_elems);";
752210299Sed  } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
753210299Sed    Out << "std::vector<Constant*> " << constName << "_fields;";
754210299Sed    nl(Out);
755210299Sed    unsigned N = CS->getNumOperands();
756210299Sed    for (unsigned i = 0; i < N; i++) {
757210299Sed      printConstant(CS->getOperand(i));
758210299Sed      Out << constName << "_fields.push_back("
759210299Sed          << getCppName(CS->getOperand(i)) << ");";
760210299Sed      nl(Out);
761210299Sed    }
762210299Sed    Out << "Constant* " << constName << " = ConstantStruct::get("
763210299Sed        << typeName << ", " << constName << "_fields);";
764234353Sdim  } else if (const ConstantVector *CVec = dyn_cast<ConstantVector>(CV)) {
765210299Sed    Out << "std::vector<Constant*> " << constName << "_elems;";
766210299Sed    nl(Out);
767234353Sdim    unsigned N = CVec->getNumOperands();
768210299Sed    for (unsigned i = 0; i < N; ++i) {
769234353Sdim      printConstant(CVec->getOperand(i));
770210299Sed      Out << constName << "_elems.push_back("
771234353Sdim          << getCppName(CVec->getOperand(i)) << ");";
772210299Sed      nl(Out);
773210299Sed    }
774210299Sed    Out << "Constant* " << constName << " = ConstantVector::get("
775210299Sed        << typeName << ", " << constName << "_elems);";
776210299Sed  } else if (isa<UndefValue>(CV)) {
777210299Sed    Out << "UndefValue* " << constName << " = UndefValue::get("
778210299Sed        << typeName << ");";
779234353Sdim  } else if (const ConstantDataSequential *CDS =
780234353Sdim               dyn_cast<ConstantDataSequential>(CV)) {
781234353Sdim    if (CDS->isString()) {
782234353Sdim      Out << "Constant *" << constName <<
783234353Sdim      " = ConstantDataArray::getString(mod->getContext(), \"";
784234353Sdim      StringRef Str = CDS->getAsString();
785234353Sdim      bool nullTerminate = false;
786234353Sdim      if (Str.back() == 0) {
787234353Sdim        Str = Str.drop_back();
788234353Sdim        nullTerminate = true;
789234353Sdim      }
790234353Sdim      printEscapedString(Str);
791234353Sdim      // Determine if we want null termination or not.
792234353Sdim      if (nullTerminate)
793234353Sdim        Out << "\", true);";
794234353Sdim      else
795234353Sdim        Out << "\", false);";// No null terminator
796234353Sdim    } else {
797234353Sdim      // TODO: Could generate more efficient code generating CDS calls instead.
798234353Sdim      Out << "std::vector<Constant*> " << constName << "_elems;";
799234353Sdim      nl(Out);
800234353Sdim      for (unsigned i = 0; i != CDS->getNumElements(); ++i) {
801234353Sdim        Constant *Elt = CDS->getElementAsConstant(i);
802234353Sdim        printConstant(Elt);
803234353Sdim        Out << constName << "_elems.push_back(" << getCppName(Elt) << ");";
804234353Sdim        nl(Out);
805234353Sdim      }
806234353Sdim      Out << "Constant* " << constName;
807234353Sdim
808234353Sdim      if (isa<ArrayType>(CDS->getType()))
809234353Sdim        Out << " = ConstantArray::get(";
810234353Sdim      else
811234353Sdim        Out << " = ConstantVector::get(";
812234353Sdim      Out << typeName << ", " << constName << "_elems);";
813234353Sdim    }
814210299Sed  } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
815210299Sed    if (CE->getOpcode() == Instruction::GetElementPtr) {
816210299Sed      Out << "std::vector<Constant*> " << constName << "_indices;";
817210299Sed      nl(Out);
818210299Sed      printConstant(CE->getOperand(0));
819210299Sed      for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
820210299Sed        printConstant(CE->getOperand(i));
821210299Sed        Out << constName << "_indices.push_back("
822210299Sed            << getCppName(CE->getOperand(i)) << ");";
823193323Sed        nl(Out);
824210299Sed      }
825210299Sed      Out << "Constant* " << constName
826210299Sed          << " = ConstantExpr::getGetElementPtr("
827210299Sed          << getCppName(CE->getOperand(0)) << ", "
828226633Sdim          << constName << "_indices);";
829210299Sed    } else if (CE->isCast()) {
830210299Sed      printConstant(CE->getOperand(0));
831210299Sed      Out << "Constant* " << constName << " = ConstantExpr::getCast(";
832210299Sed      switch (CE->getOpcode()) {
833210299Sed      default: llvm_unreachable("Invalid cast opcode");
834210299Sed      case Instruction::Trunc: Out << "Instruction::Trunc"; break;
835210299Sed      case Instruction::ZExt:  Out << "Instruction::ZExt"; break;
836210299Sed      case Instruction::SExt:  Out << "Instruction::SExt"; break;
837210299Sed      case Instruction::FPTrunc:  Out << "Instruction::FPTrunc"; break;
838210299Sed      case Instruction::FPExt:  Out << "Instruction::FPExt"; break;
839210299Sed      case Instruction::FPToUI:  Out << "Instruction::FPToUI"; break;
840210299Sed      case Instruction::FPToSI:  Out << "Instruction::FPToSI"; break;
841210299Sed      case Instruction::UIToFP:  Out << "Instruction::UIToFP"; break;
842210299Sed      case Instruction::SIToFP:  Out << "Instruction::SIToFP"; break;
843210299Sed      case Instruction::PtrToInt:  Out << "Instruction::PtrToInt"; break;
844210299Sed      case Instruction::IntToPtr:  Out << "Instruction::IntToPtr"; break;
845210299Sed      case Instruction::BitCast:  Out << "Instruction::BitCast"; break;
846210299Sed      }
847210299Sed      Out << ", " << getCppName(CE->getOperand(0)) << ", "
848210299Sed          << getCppName(CE->getType()) << ");";
849210299Sed    } else {
850210299Sed      unsigned N = CE->getNumOperands();
851210299Sed      for (unsigned i = 0; i < N; ++i ) {
852210299Sed        printConstant(CE->getOperand(i));
853210299Sed      }
854210299Sed      Out << "Constant* " << constName << " = ConstantExpr::";
855210299Sed      switch (CE->getOpcode()) {
856210299Sed      case Instruction::Add:    Out << "getAdd(";  break;
857210299Sed      case Instruction::FAdd:   Out << "getFAdd(";  break;
858210299Sed      case Instruction::Sub:    Out << "getSub("; break;
859210299Sed      case Instruction::FSub:   Out << "getFSub("; break;
860210299Sed      case Instruction::Mul:    Out << "getMul("; break;
861210299Sed      case Instruction::FMul:   Out << "getFMul("; break;
862210299Sed      case Instruction::UDiv:   Out << "getUDiv("; break;
863210299Sed      case Instruction::SDiv:   Out << "getSDiv("; break;
864210299Sed      case Instruction::FDiv:   Out << "getFDiv("; break;
865210299Sed      case Instruction::URem:   Out << "getURem("; break;
866210299Sed      case Instruction::SRem:   Out << "getSRem("; break;
867210299Sed      case Instruction::FRem:   Out << "getFRem("; break;
868210299Sed      case Instruction::And:    Out << "getAnd("; break;
869210299Sed      case Instruction::Or:     Out << "getOr("; break;
870210299Sed      case Instruction::Xor:    Out << "getXor("; break;
871210299Sed      case Instruction::ICmp:
872210299Sed        Out << "getICmp(ICmpInst::ICMP_";
873210299Sed        switch (CE->getPredicate()) {
874210299Sed        case ICmpInst::ICMP_EQ:  Out << "EQ"; break;
875210299Sed        case ICmpInst::ICMP_NE:  Out << "NE"; break;
876210299Sed        case ICmpInst::ICMP_SLT: Out << "SLT"; break;
877210299Sed        case ICmpInst::ICMP_ULT: Out << "ULT"; break;
878210299Sed        case ICmpInst::ICMP_SGT: Out << "SGT"; break;
879210299Sed        case ICmpInst::ICMP_UGT: Out << "UGT"; break;
880210299Sed        case ICmpInst::ICMP_SLE: Out << "SLE"; break;
881210299Sed        case ICmpInst::ICMP_ULE: Out << "ULE"; break;
882210299Sed        case ICmpInst::ICMP_SGE: Out << "SGE"; break;
883210299Sed        case ICmpInst::ICMP_UGE: Out << "UGE"; break;
884210299Sed        default: error("Invalid ICmp Predicate");
885193323Sed        }
886210299Sed        break;
887210299Sed      case Instruction::FCmp:
888210299Sed        Out << "getFCmp(FCmpInst::FCMP_";
889210299Sed        switch (CE->getPredicate()) {
890210299Sed        case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
891210299Sed        case FCmpInst::FCMP_ORD:   Out << "ORD"; break;
892210299Sed        case FCmpInst::FCMP_UNO:   Out << "UNO"; break;
893210299Sed        case FCmpInst::FCMP_OEQ:   Out << "OEQ"; break;
894210299Sed        case FCmpInst::FCMP_UEQ:   Out << "UEQ"; break;
895210299Sed        case FCmpInst::FCMP_ONE:   Out << "ONE"; break;
896210299Sed        case FCmpInst::FCMP_UNE:   Out << "UNE"; break;
897210299Sed        case FCmpInst::FCMP_OLT:   Out << "OLT"; break;
898210299Sed        case FCmpInst::FCMP_ULT:   Out << "ULT"; break;
899210299Sed        case FCmpInst::FCMP_OGT:   Out << "OGT"; break;
900210299Sed        case FCmpInst::FCMP_UGT:   Out << "UGT"; break;
901210299Sed        case FCmpInst::FCMP_OLE:   Out << "OLE"; break;
902210299Sed        case FCmpInst::FCMP_ULE:   Out << "ULE"; break;
903210299Sed        case FCmpInst::FCMP_OGE:   Out << "OGE"; break;
904210299Sed        case FCmpInst::FCMP_UGE:   Out << "UGE"; break;
905210299Sed        case FCmpInst::FCMP_TRUE:  Out << "TRUE"; break;
906210299Sed        default: error("Invalid FCmp Predicate");
907193323Sed        }
908210299Sed        break;
909210299Sed      case Instruction::Shl:     Out << "getShl("; break;
910210299Sed      case Instruction::LShr:    Out << "getLShr("; break;
911210299Sed      case Instruction::AShr:    Out << "getAShr("; break;
912210299Sed      case Instruction::Select:  Out << "getSelect("; break;
913210299Sed      case Instruction::ExtractElement: Out << "getExtractElement("; break;
914210299Sed      case Instruction::InsertElement:  Out << "getInsertElement("; break;
915210299Sed      case Instruction::ShuffleVector:  Out << "getShuffleVector("; break;
916210299Sed      default:
917210299Sed        error("Invalid constant expression");
918210299Sed        break;
919193323Sed      }
920210299Sed      Out << getCppName(CE->getOperand(0));
921210299Sed      for (unsigned i = 1; i < CE->getNumOperands(); ++i)
922210299Sed        Out << ", " << getCppName(CE->getOperand(i));
923210299Sed      Out << ");";
924193323Sed    }
925210299Sed  } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
926210299Sed    Out << "Constant* " << constName << " = ";
927210299Sed    Out << "BlockAddress::get(" << getOpName(BA->getBasicBlock()) << ");";
928210299Sed  } else {
929210299Sed    error("Bad Constant");
930210299Sed    Out << "Constant* " << constName << " = 0; ";
931193323Sed  }
932210299Sed  nl(Out);
933210299Sed}
934193323Sed
935210299Sedvoid CppWriter::printConstants(const Module* M) {
936210299Sed  // Traverse all the global variables looking for constant initializers
937210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
938210299Sed         E = TheModule->global_end(); I != E; ++I)
939210299Sed    if (I->hasInitializer())
940210299Sed      printConstant(I->getInitializer());
941193323Sed
942210299Sed  // Traverse the LLVM functions looking for constants
943210299Sed  for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
944210299Sed       FI != FE; ++FI) {
945210299Sed    // Add all of the basic blocks and instructions
946210299Sed    for (Function::const_iterator BB = FI->begin(),
947210299Sed           E = FI->end(); BB != E; ++BB) {
948210299Sed      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
949210299Sed           ++I) {
950210299Sed        for (unsigned i = 0; i < I->getNumOperands(); ++i) {
951210299Sed          if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
952210299Sed            printConstant(C);
953193323Sed          }
954193323Sed        }
955193323Sed      }
956193323Sed    }
957193323Sed  }
958210299Sed}
959193323Sed
960210299Sedvoid CppWriter::printVariableUses(const GlobalVariable *GV) {
961210299Sed  nl(Out) << "// Type Definitions";
962210299Sed  nl(Out);
963210299Sed  printType(GV->getType());
964210299Sed  if (GV->hasInitializer()) {
965224145Sdim    const Constant *Init = GV->getInitializer();
966210299Sed    printType(Init->getType());
967224145Sdim    if (const Function *F = dyn_cast<Function>(Init)) {
968210299Sed      nl(Out)<< "/ Function Declarations"; nl(Out);
969210299Sed      printFunctionHead(F);
970224145Sdim    } else if (const GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
971210299Sed      nl(Out) << "// Global Variable Declarations"; nl(Out);
972210299Sed      printVariableHead(gv);
973210299Sed
974210299Sed      nl(Out) << "// Global Variable Definitions"; nl(Out);
975210299Sed      printVariableBody(gv);
976210299Sed    } else  {
977210299Sed      nl(Out) << "// Constant Definitions"; nl(Out);
978210299Sed      printConstant(Init);
979193323Sed    }
980193323Sed  }
981210299Sed}
982193323Sed
983210299Sedvoid CppWriter::printVariableHead(const GlobalVariable *GV) {
984210299Sed  nl(Out) << "GlobalVariable* " << getCppName(GV);
985210299Sed  if (is_inline) {
986210299Sed    Out << " = mod->getGlobalVariable(mod->getContext(), ";
987193323Sed    printEscapedString(GV->getName());
988210299Sed    Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
989210299Sed    nl(Out) << "if (!" << getCppName(GV) << ") {";
990210299Sed    in(); nl(Out) << getCppName(GV);
991210299Sed  }
992210299Sed  Out << " = new GlobalVariable(/*Module=*/*mod, ";
993210299Sed  nl(Out) << "/*Type=*/";
994210299Sed  printCppName(GV->getType()->getElementType());
995210299Sed  Out << ",";
996210299Sed  nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
997210299Sed  Out << ",";
998210299Sed  nl(Out) << "/*Linkage=*/";
999210299Sed  printLinkageType(GV->getLinkage());
1000210299Sed  Out << ",";
1001210299Sed  nl(Out) << "/*Initializer=*/0, ";
1002210299Sed  if (GV->hasInitializer()) {
1003210299Sed    Out << "// has initializer, specified below";
1004210299Sed  }
1005210299Sed  nl(Out) << "/*Name=*/\"";
1006210299Sed  printEscapedString(GV->getName());
1007210299Sed  Out << "\");";
1008210299Sed  nl(Out);
1009210299Sed
1010210299Sed  if (GV->hasSection()) {
1011210299Sed    printCppName(GV);
1012210299Sed    Out << "->setSection(\"";
1013210299Sed    printEscapedString(GV->getSection());
1014198090Srdivacky    Out << "\");";
1015193323Sed    nl(Out);
1016193323Sed  }
1017210299Sed  if (GV->getAlignment()) {
1018210299Sed    printCppName(GV);
1019210299Sed    Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
1020210299Sed    nl(Out);
1021210299Sed  }
1022210299Sed  if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
1023210299Sed    printCppName(GV);
1024210299Sed    Out << "->setVisibility(";
1025210299Sed    printVisibilityType(GV->getVisibility());
1026210299Sed    Out << ");";
1027210299Sed    nl(Out);
1028210299Sed  }
1029210299Sed  if (GV->isThreadLocal()) {
1030210299Sed    printCppName(GV);
1031239462Sdim    Out << "->setThreadLocalMode(";
1032239462Sdim    printThreadLocalMode(GV->getThreadLocalMode());
1033239462Sdim    Out << ");";
1034210299Sed    nl(Out);
1035210299Sed  }
1036210299Sed  if (is_inline) {
1037210299Sed    out(); Out << "}"; nl(Out);
1038210299Sed  }
1039210299Sed}
1040193323Sed
1041210299Sedvoid CppWriter::printVariableBody(const GlobalVariable *GV) {
1042210299Sed  if (GV->hasInitializer()) {
1043210299Sed    printCppName(GV);
1044210299Sed    Out << "->setInitializer(";
1045210299Sed    Out << getCppName(GV->getInitializer()) << ");";
1046210299Sed    nl(Out);
1047193323Sed  }
1048210299Sed}
1049193323Sed
1050226633Sdimstd::string CppWriter::getOpName(const Value* V) {
1051210299Sed  if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
1052210299Sed    return getCppName(V);
1053193323Sed
1054210299Sed  // See if its alread in the map of forward references, if so just return the
1055210299Sed  // name we already set up for it
1056210299Sed  ForwardRefMap::const_iterator I = ForwardRefs.find(V);
1057210299Sed  if (I != ForwardRefs.end())
1058210299Sed    return I->second;
1059193323Sed
1060210299Sed  // This is a new forward reference. Generate a unique name for it
1061210299Sed  std::string result(std::string("fwdref_") + utostr(uniqueNum++));
1062193323Sed
1063210299Sed  // Yes, this is a hack. An Argument is the smallest instantiable value that
1064210299Sed  // we can make as a placeholder for the real value. We'll replace these
1065210299Sed  // Argument instances later.
1066210299Sed  Out << "Argument* " << result << " = new Argument("
1067210299Sed      << getCppName(V->getType()) << ");";
1068210299Sed  nl(Out);
1069210299Sed  ForwardRefs[V] = result;
1070210299Sed  return result;
1071210299Sed}
1072193323Sed
1073228379Sdimstatic StringRef ConvertAtomicOrdering(AtomicOrdering Ordering) {
1074228379Sdim  switch (Ordering) {
1075228379Sdim    case NotAtomic: return "NotAtomic";
1076228379Sdim    case Unordered: return "Unordered";
1077228379Sdim    case Monotonic: return "Monotonic";
1078228379Sdim    case Acquire: return "Acquire";
1079228379Sdim    case Release: return "Release";
1080228379Sdim    case AcquireRelease: return "AcquireRelease";
1081228379Sdim    case SequentiallyConsistent: return "SequentiallyConsistent";
1082228379Sdim  }
1083228379Sdim  llvm_unreachable("Unknown ordering");
1084228379Sdim}
1085228379Sdim
1086228379Sdimstatic StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) {
1087228379Sdim  switch (SynchScope) {
1088228379Sdim    case SingleThread: return "SingleThread";
1089228379Sdim    case CrossThread: return "CrossThread";
1090228379Sdim  }
1091228379Sdim  llvm_unreachable("Unknown synch scope");
1092228379Sdim}
1093228379Sdim
1094210299Sed// printInstruction - This member is called for each Instruction in a function.
1095210299Sedvoid CppWriter::printInstruction(const Instruction *I,
1096210299Sed                                 const std::string& bbname) {
1097210299Sed  std::string iName(getCppName(I));
1098193323Sed
1099210299Sed  // Before we emit this instruction, we need to take care of generating any
1100210299Sed  // forward references. So, we get the names of all the operands in advance
1101210299Sed  const unsigned Ops(I->getNumOperands());
1102210299Sed  std::string* opNames = new std::string[Ops];
1103210299Sed  for (unsigned i = 0; i < Ops; i++)
1104210299Sed    opNames[i] = getOpName(I->getOperand(i));
1105193323Sed
1106210299Sed  switch (I->getOpcode()) {
1107210299Sed  default:
1108210299Sed    error("Invalid instruction");
1109210299Sed    break;
1110193323Sed
1111210299Sed  case Instruction::Ret: {
1112210299Sed    const ReturnInst* ret =  cast<ReturnInst>(I);
1113210299Sed    Out << "ReturnInst::Create(mod->getContext(), "
1114210299Sed        << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
1115210299Sed    break;
1116210299Sed  }
1117210299Sed  case Instruction::Br: {
1118210299Sed    const BranchInst* br = cast<BranchInst>(I);
1119210299Sed    Out << "BranchInst::Create(" ;
1120210299Sed    if (br->getNumOperands() == 3) {
1121210299Sed      Out << opNames[2] << ", "
1122210299Sed          << opNames[1] << ", "
1123210299Sed          << opNames[0] << ", ";
1124193323Sed
1125210299Sed    } else if (br->getNumOperands() == 1) {
1126210299Sed      Out << opNames[0] << ", ";
1127210299Sed    } else {
1128210299Sed      error("Branch with 2 operands?");
1129193323Sed    }
1130210299Sed    Out << bbname << ");";
1131210299Sed    break;
1132210299Sed  }
1133210299Sed  case Instruction::Switch: {
1134210299Sed    const SwitchInst *SI = cast<SwitchInst>(I);
1135210299Sed    Out << "SwitchInst* " << iName << " = SwitchInst::Create("
1136226633Sdim        << getOpName(SI->getCondition()) << ", "
1137226633Sdim        << getOpName(SI->getDefaultDest()) << ", "
1138210299Sed        << SI->getNumCases() << ", " << bbname << ");";
1139210299Sed    nl(Out);
1140234353Sdim    for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end();
1141234353Sdim         i != e; ++i) {
1142263508Sdim      const ConstantInt* CaseVal = i.getCaseValue();
1143234353Sdim      const BasicBlock *BB = i.getCaseSuccessor();
1144210299Sed      Out << iName << "->addCase("
1145226633Sdim          << getOpName(CaseVal) << ", "
1146226633Sdim          << getOpName(BB) << ");";
1147193323Sed      nl(Out);
1148193323Sed    }
1149210299Sed    break;
1150210299Sed  }
1151210299Sed  case Instruction::IndirectBr: {
1152210299Sed    const IndirectBrInst *IBI = cast<IndirectBrInst>(I);
1153210299Sed    Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create("
1154210299Sed        << opNames[0] << ", " << IBI->getNumDestinations() << ");";
1155210299Sed    nl(Out);
1156210299Sed    for (unsigned i = 1; i != IBI->getNumOperands(); ++i) {
1157210299Sed      Out << iName << "->addDestination(" << opNames[i] << ");";
1158198892Srdivacky      nl(Out);
1159198892Srdivacky    }
1160210299Sed    break;
1161210299Sed  }
1162226633Sdim  case Instruction::Resume: {
1163263508Sdim    Out << "ResumeInst::Create(" << opNames[0] << ", " << bbname << ");";
1164226633Sdim    break;
1165226633Sdim  }
1166210299Sed  case Instruction::Invoke: {
1167210299Sed    const InvokeInst* inv = cast<InvokeInst>(I);
1168210299Sed    Out << "std::vector<Value*> " << iName << "_params;";
1169210299Sed    nl(Out);
1170210299Sed    for (unsigned i = 0; i < inv->getNumArgOperands(); ++i) {
1171210299Sed      Out << iName << "_params.push_back("
1172210299Sed          << getOpName(inv->getArgOperand(i)) << ");";
1173193323Sed      nl(Out);
1174193323Sed    }
1175210299Sed    // FIXME: This shouldn't use magic numbers -3, -2, and -1.
1176210299Sed    Out << "InvokeInst *" << iName << " = InvokeInst::Create("
1177263508Sdim        << getOpName(inv->getCalledValue()) << ", "
1178210299Sed        << getOpName(inv->getNormalDest()) << ", "
1179210299Sed        << getOpName(inv->getUnwindDest()) << ", "
1180226633Sdim        << iName << "_params, \"";
1181210299Sed    printEscapedString(inv->getName());
1182210299Sed    Out << "\", " << bbname << ");";
1183210299Sed    nl(Out) << iName << "->setCallingConv(";
1184210299Sed    printCallingConv(inv->getCallingConv());
1185210299Sed    Out << ");";
1186210299Sed    printAttributes(inv->getAttributes(), iName);
1187210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1188210299Sed    nl(Out);
1189210299Sed    break;
1190210299Sed  }
1191210299Sed  case Instruction::Unreachable: {
1192210299Sed    Out << "new UnreachableInst("
1193210299Sed        << "mod->getContext(), "
1194210299Sed        << bbname << ");";
1195210299Sed    break;
1196210299Sed  }
1197210299Sed  case Instruction::Add:
1198210299Sed  case Instruction::FAdd:
1199210299Sed  case Instruction::Sub:
1200210299Sed  case Instruction::FSub:
1201210299Sed  case Instruction::Mul:
1202210299Sed  case Instruction::FMul:
1203210299Sed  case Instruction::UDiv:
1204210299Sed  case Instruction::SDiv:
1205210299Sed  case Instruction::FDiv:
1206210299Sed  case Instruction::URem:
1207210299Sed  case Instruction::SRem:
1208210299Sed  case Instruction::FRem:
1209210299Sed  case Instruction::And:
1210210299Sed  case Instruction::Or:
1211210299Sed  case Instruction::Xor:
1212210299Sed  case Instruction::Shl:
1213210299Sed  case Instruction::LShr:
1214210299Sed  case Instruction::AShr:{
1215210299Sed    Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
1216210299Sed    switch (I->getOpcode()) {
1217210299Sed    case Instruction::Add: Out << "Instruction::Add"; break;
1218210299Sed    case Instruction::FAdd: Out << "Instruction::FAdd"; break;
1219210299Sed    case Instruction::Sub: Out << "Instruction::Sub"; break;
1220210299Sed    case Instruction::FSub: Out << "Instruction::FSub"; break;
1221210299Sed    case Instruction::Mul: Out << "Instruction::Mul"; break;
1222210299Sed    case Instruction::FMul: Out << "Instruction::FMul"; break;
1223210299Sed    case Instruction::UDiv:Out << "Instruction::UDiv"; break;
1224210299Sed    case Instruction::SDiv:Out << "Instruction::SDiv"; break;
1225210299Sed    case Instruction::FDiv:Out << "Instruction::FDiv"; break;
1226210299Sed    case Instruction::URem:Out << "Instruction::URem"; break;
1227210299Sed    case Instruction::SRem:Out << "Instruction::SRem"; break;
1228210299Sed    case Instruction::FRem:Out << "Instruction::FRem"; break;
1229210299Sed    case Instruction::And: Out << "Instruction::And"; break;
1230210299Sed    case Instruction::Or:  Out << "Instruction::Or";  break;
1231210299Sed    case Instruction::Xor: Out << "Instruction::Xor"; break;
1232210299Sed    case Instruction::Shl: Out << "Instruction::Shl"; break;
1233210299Sed    case Instruction::LShr:Out << "Instruction::LShr"; break;
1234210299Sed    case Instruction::AShr:Out << "Instruction::AShr"; break;
1235210299Sed    default: Out << "Instruction::BadOpCode"; break;
1236193323Sed    }
1237210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1238210299Sed    printEscapedString(I->getName());
1239210299Sed    Out << "\", " << bbname << ");";
1240210299Sed    break;
1241210299Sed  }
1242210299Sed  case Instruction::FCmp: {
1243210299Sed    Out << "FCmpInst* " << iName << " = new FCmpInst(*" << bbname << ", ";
1244210299Sed    switch (cast<FCmpInst>(I)->getPredicate()) {
1245210299Sed    case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
1246210299Sed    case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
1247210299Sed    case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
1248210299Sed    case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
1249210299Sed    case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
1250210299Sed    case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
1251210299Sed    case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
1252210299Sed    case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
1253210299Sed    case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
1254210299Sed    case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
1255210299Sed    case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
1256210299Sed    case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
1257210299Sed    case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
1258210299Sed    case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
1259210299Sed    case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
1260210299Sed    case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
1261210299Sed    default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
1262193323Sed    }
1263210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1264210299Sed    printEscapedString(I->getName());
1265210299Sed    Out << "\");";
1266210299Sed    break;
1267210299Sed  }
1268210299Sed  case Instruction::ICmp: {
1269210299Sed    Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
1270210299Sed    switch (cast<ICmpInst>(I)->getPredicate()) {
1271210299Sed    case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
1272210299Sed    case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
1273210299Sed    case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
1274210299Sed    case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
1275210299Sed    case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
1276210299Sed    case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
1277210299Sed    case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
1278210299Sed    case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
1279210299Sed    case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
1280210299Sed    case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
1281210299Sed    default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
1282193323Sed    }
1283210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1284210299Sed    printEscapedString(I->getName());
1285210299Sed    Out << "\");";
1286210299Sed    break;
1287210299Sed  }
1288210299Sed  case Instruction::Alloca: {
1289210299Sed    const AllocaInst* allocaI = cast<AllocaInst>(I);
1290210299Sed    Out << "AllocaInst* " << iName << " = new AllocaInst("
1291210299Sed        << getCppName(allocaI->getAllocatedType()) << ", ";
1292210299Sed    if (allocaI->isArrayAllocation())
1293210299Sed      Out << opNames[0] << ", ";
1294210299Sed    Out << "\"";
1295210299Sed    printEscapedString(allocaI->getName());
1296210299Sed    Out << "\", " << bbname << ");";
1297210299Sed    if (allocaI->getAlignment())
1298210299Sed      nl(Out) << iName << "->setAlignment("
1299210299Sed          << allocaI->getAlignment() << ");";
1300210299Sed    break;
1301210299Sed  }
1302210299Sed  case Instruction::Load: {
1303210299Sed    const LoadInst* load = cast<LoadInst>(I);
1304210299Sed    Out << "LoadInst* " << iName << " = new LoadInst("
1305210299Sed        << opNames[0] << ", \"";
1306210299Sed    printEscapedString(load->getName());
1307210299Sed    Out << "\", " << (load->isVolatile() ? "true" : "false" )
1308210299Sed        << ", " << bbname << ");";
1309228379Sdim    if (load->getAlignment())
1310228379Sdim      nl(Out) << iName << "->setAlignment("
1311228379Sdim              << load->getAlignment() << ");";
1312228379Sdim    if (load->isAtomic()) {
1313228379Sdim      StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
1314228379Sdim      StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
1315228379Sdim      nl(Out) << iName << "->setAtomic("
1316228379Sdim              << Ordering << ", " << CrossThread << ");";
1317228379Sdim    }
1318210299Sed    break;
1319210299Sed  }
1320210299Sed  case Instruction::Store: {
1321210299Sed    const StoreInst* store = cast<StoreInst>(I);
1322228379Sdim    Out << "StoreInst* " << iName << " = new StoreInst("
1323210299Sed        << opNames[0] << ", "
1324210299Sed        << opNames[1] << ", "
1325210299Sed        << (store->isVolatile() ? "true" : "false")
1326210299Sed        << ", " << bbname << ");";
1327228379Sdim    if (store->getAlignment())
1328228379Sdim      nl(Out) << iName << "->setAlignment("
1329228379Sdim              << store->getAlignment() << ");";
1330228379Sdim    if (store->isAtomic()) {
1331228379Sdim      StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
1332228379Sdim      StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
1333228379Sdim      nl(Out) << iName << "->setAtomic("
1334228379Sdim              << Ordering << ", " << CrossThread << ");";
1335228379Sdim    }
1336210299Sed    break;
1337210299Sed  }
1338210299Sed  case Instruction::GetElementPtr: {
1339210299Sed    const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
1340210299Sed    if (gep->getNumOperands() <= 2) {
1341210299Sed      Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
1342210299Sed          << opNames[0];
1343210299Sed      if (gep->getNumOperands() == 2)
1344210299Sed        Out << ", " << opNames[1];
1345210299Sed    } else {
1346210299Sed      Out << "std::vector<Value*> " << iName << "_indices;";
1347210299Sed      nl(Out);
1348210299Sed      for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
1349210299Sed        Out << iName << "_indices.push_back("
1350210299Sed            << opNames[i] << ");";
1351193323Sed        nl(Out);
1352193323Sed      }
1353210299Sed      Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
1354226633Sdim          << opNames[0] << ", " << iName << "_indices";
1355193323Sed    }
1356210299Sed    Out << ", \"";
1357210299Sed    printEscapedString(gep->getName());
1358210299Sed    Out << "\", " << bbname << ");";
1359210299Sed    break;
1360210299Sed  }
1361210299Sed  case Instruction::PHI: {
1362210299Sed    const PHINode* phi = cast<PHINode>(I);
1363193323Sed
1364210299Sed    Out << "PHINode* " << iName << " = PHINode::Create("
1365221345Sdim        << getCppName(phi->getType()) << ", "
1366221345Sdim        << phi->getNumIncomingValues() << ", \"";
1367210299Sed    printEscapedString(phi->getName());
1368210299Sed    Out << "\", " << bbname << ");";
1369210299Sed    nl(Out);
1370224145Sdim    for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
1371210299Sed      Out << iName << "->addIncoming("
1372224145Sdim          << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", "
1373224145Sdim          << getOpName(phi->getIncomingBlock(i)) << ");";
1374193323Sed      nl(Out);
1375193323Sed    }
1376210299Sed    break;
1377210299Sed  }
1378210299Sed  case Instruction::Trunc:
1379210299Sed  case Instruction::ZExt:
1380210299Sed  case Instruction::SExt:
1381210299Sed  case Instruction::FPTrunc:
1382210299Sed  case Instruction::FPExt:
1383210299Sed  case Instruction::FPToUI:
1384210299Sed  case Instruction::FPToSI:
1385210299Sed  case Instruction::UIToFP:
1386210299Sed  case Instruction::SIToFP:
1387210299Sed  case Instruction::PtrToInt:
1388210299Sed  case Instruction::IntToPtr:
1389210299Sed  case Instruction::BitCast: {
1390210299Sed    const CastInst* cst = cast<CastInst>(I);
1391210299Sed    Out << "CastInst* " << iName << " = new ";
1392210299Sed    switch (I->getOpcode()) {
1393210299Sed    case Instruction::Trunc:    Out << "TruncInst"; break;
1394210299Sed    case Instruction::ZExt:     Out << "ZExtInst"; break;
1395210299Sed    case Instruction::SExt:     Out << "SExtInst"; break;
1396210299Sed    case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
1397210299Sed    case Instruction::FPExt:    Out << "FPExtInst"; break;
1398210299Sed    case Instruction::FPToUI:   Out << "FPToUIInst"; break;
1399210299Sed    case Instruction::FPToSI:   Out << "FPToSIInst"; break;
1400210299Sed    case Instruction::UIToFP:   Out << "UIToFPInst"; break;
1401210299Sed    case Instruction::SIToFP:   Out << "SIToFPInst"; break;
1402210299Sed    case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
1403210299Sed    case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
1404210299Sed    case Instruction::BitCast:  Out << "BitCastInst"; break;
1405234353Sdim    default: llvm_unreachable("Unreachable");
1406193323Sed    }
1407210299Sed    Out << "(" << opNames[0] << ", "
1408210299Sed        << getCppName(cst->getType()) << ", \"";
1409210299Sed    printEscapedString(cst->getName());
1410210299Sed    Out << "\", " << bbname << ");";
1411210299Sed    break;
1412210299Sed  }
1413210299Sed  case Instruction::Call: {
1414210299Sed    const CallInst* call = cast<CallInst>(I);
1415210299Sed    if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
1416210299Sed      Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
1417210299Sed          << getCppName(ila->getFunctionType()) << ", \""
1418210299Sed          << ila->getAsmString() << "\", \""
1419210299Sed          << ila->getConstraintString() << "\","
1420210299Sed          << (ila->hasSideEffects() ? "true" : "false") << ");";
1421193323Sed      nl(Out);
1422193323Sed    }
1423210299Sed    if (call->getNumArgOperands() > 1) {
1424210299Sed      Out << "std::vector<Value*> " << iName << "_params;";
1425193323Sed      nl(Out);
1426210299Sed      for (unsigned i = 0; i < call->getNumArgOperands(); ++i) {
1427210299Sed        Out << iName << "_params.push_back(" << opNames[i] << ");";
1428193323Sed        nl(Out);
1429193323Sed      }
1430210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1431212904Sdim          << opNames[call->getNumArgOperands()] << ", "
1432226633Sdim          << iName << "_params, \"";
1433210299Sed    } else if (call->getNumArgOperands() == 1) {
1434210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1435210299Sed          << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \"";
1436210299Sed    } else {
1437210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1438210299Sed          << opNames[call->getNumArgOperands()] << ", \"";
1439193323Sed    }
1440210299Sed    printEscapedString(call->getName());
1441210299Sed    Out << "\", " << bbname << ");";
1442210299Sed    nl(Out) << iName << "->setCallingConv(";
1443210299Sed    printCallingConv(call->getCallingConv());
1444210299Sed    Out << ");";
1445210299Sed    nl(Out) << iName << "->setTailCall("
1446210299Sed        << (call->isTailCall() ? "true" : "false");
1447210299Sed    Out << ");";
1448210299Sed    nl(Out);
1449210299Sed    printAttributes(call->getAttributes(), iName);
1450210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1451210299Sed    nl(Out);
1452210299Sed    break;
1453210299Sed  }
1454210299Sed  case Instruction::Select: {
1455210299Sed    const SelectInst* sel = cast<SelectInst>(I);
1456210299Sed    Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
1457210299Sed    Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1458210299Sed    printEscapedString(sel->getName());
1459210299Sed    Out << "\", " << bbname << ");";
1460210299Sed    break;
1461210299Sed  }
1462210299Sed  case Instruction::UserOp1:
1463210299Sed    /// FALL THROUGH
1464210299Sed  case Instruction::UserOp2: {
1465210299Sed    /// FIXME: What should be done here?
1466210299Sed    break;
1467210299Sed  }
1468210299Sed  case Instruction::VAArg: {
1469210299Sed    const VAArgInst* va = cast<VAArgInst>(I);
1470210299Sed    Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
1471210299Sed        << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
1472210299Sed    printEscapedString(va->getName());
1473210299Sed    Out << "\", " << bbname << ");";
1474210299Sed    break;
1475210299Sed  }
1476210299Sed  case Instruction::ExtractElement: {
1477210299Sed    const ExtractElementInst* eei = cast<ExtractElementInst>(I);
1478210299Sed    Out << "ExtractElementInst* " << getCppName(eei)
1479210299Sed        << " = new ExtractElementInst(" << opNames[0]
1480210299Sed        << ", " << opNames[1] << ", \"";
1481210299Sed    printEscapedString(eei->getName());
1482210299Sed    Out << "\", " << bbname << ");";
1483210299Sed    break;
1484210299Sed  }
1485210299Sed  case Instruction::InsertElement: {
1486210299Sed    const InsertElementInst* iei = cast<InsertElementInst>(I);
1487210299Sed    Out << "InsertElementInst* " << getCppName(iei)
1488210299Sed        << " = InsertElementInst::Create(" << opNames[0]
1489210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1490210299Sed    printEscapedString(iei->getName());
1491210299Sed    Out << "\", " << bbname << ");";
1492210299Sed    break;
1493210299Sed  }
1494210299Sed  case Instruction::ShuffleVector: {
1495210299Sed    const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
1496210299Sed    Out << "ShuffleVectorInst* " << getCppName(svi)
1497210299Sed        << " = new ShuffleVectorInst(" << opNames[0]
1498210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1499210299Sed    printEscapedString(svi->getName());
1500210299Sed    Out << "\", " << bbname << ");";
1501210299Sed    break;
1502210299Sed  }
1503210299Sed  case Instruction::ExtractValue: {
1504210299Sed    const ExtractValueInst *evi = cast<ExtractValueInst>(I);
1505210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1506210299Sed    nl(Out);
1507210299Sed    for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
1508210299Sed      Out << iName << "_indices.push_back("
1509210299Sed          << evi->idx_begin()[i] << ");";
1510193323Sed      nl(Out);
1511193323Sed    }
1512210299Sed    Out << "ExtractValueInst* " << getCppName(evi)
1513210299Sed        << " = ExtractValueInst::Create(" << opNames[0]
1514210299Sed        << ", "
1515226633Sdim        << iName << "_indices, \"";
1516210299Sed    printEscapedString(evi->getName());
1517210299Sed    Out << "\", " << bbname << ");";
1518210299Sed    break;
1519193323Sed  }
1520210299Sed  case Instruction::InsertValue: {
1521210299Sed    const InsertValueInst *ivi = cast<InsertValueInst>(I);
1522210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1523210299Sed    nl(Out);
1524210299Sed    for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
1525210299Sed      Out << iName << "_indices.push_back("
1526210299Sed          << ivi->idx_begin()[i] << ");";
1527210299Sed      nl(Out);
1528210299Sed    }
1529210299Sed    Out << "InsertValueInst* " << getCppName(ivi)
1530210299Sed        << " = InsertValueInst::Create(" << opNames[0]
1531210299Sed        << ", " << opNames[1] << ", "
1532226633Sdim        << iName << "_indices, \"";
1533210299Sed    printEscapedString(ivi->getName());
1534210299Sed    Out << "\", " << bbname << ");";
1535210299Sed    break;
1536210299Sed  }
1537228379Sdim  case Instruction::Fence: {
1538228379Sdim    const FenceInst *fi = cast<FenceInst>(I);
1539228379Sdim    StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering());
1540228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope());
1541228379Sdim    Out << "FenceInst* " << iName
1542228379Sdim        << " = new FenceInst(mod->getContext(), "
1543228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1544228379Sdim        << ");";
1545228379Sdim    break;
1546210299Sed  }
1547228379Sdim  case Instruction::AtomicCmpXchg: {
1548228379Sdim    const AtomicCmpXchgInst *cxi = cast<AtomicCmpXchgInst>(I);
1549228379Sdim    StringRef Ordering = ConvertAtomicOrdering(cxi->getOrdering());
1550228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope());
1551228379Sdim    Out << "AtomicCmpXchgInst* " << iName
1552228379Sdim        << " = new AtomicCmpXchgInst("
1553228379Sdim        << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", "
1554228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1555228379Sdim        << ");";
1556228379Sdim    nl(Out) << iName << "->setName(\"";
1557228379Sdim    printEscapedString(cxi->getName());
1558228379Sdim    Out << "\");";
1559228379Sdim    break;
1560228379Sdim  }
1561228379Sdim  case Instruction::AtomicRMW: {
1562228379Sdim    const AtomicRMWInst *rmwi = cast<AtomicRMWInst>(I);
1563228379Sdim    StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering());
1564228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope());
1565228379Sdim    StringRef Operation;
1566228379Sdim    switch (rmwi->getOperation()) {
1567228379Sdim      case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break;
1568228379Sdim      case AtomicRMWInst::Add:  Operation = "AtomicRMWInst::Add"; break;
1569228379Sdim      case AtomicRMWInst::Sub:  Operation = "AtomicRMWInst::Sub"; break;
1570228379Sdim      case AtomicRMWInst::And:  Operation = "AtomicRMWInst::And"; break;
1571228379Sdim      case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break;
1572228379Sdim      case AtomicRMWInst::Or:   Operation = "AtomicRMWInst::Or"; break;
1573228379Sdim      case AtomicRMWInst::Xor:  Operation = "AtomicRMWInst::Xor"; break;
1574228379Sdim      case AtomicRMWInst::Max:  Operation = "AtomicRMWInst::Max"; break;
1575228379Sdim      case AtomicRMWInst::Min:  Operation = "AtomicRMWInst::Min"; break;
1576228379Sdim      case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break;
1577228379Sdim      case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break;
1578228379Sdim      case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation");
1579228379Sdim    }
1580228379Sdim    Out << "AtomicRMWInst* " << iName
1581228379Sdim        << " = new AtomicRMWInst("
1582228379Sdim        << Operation << ", "
1583228379Sdim        << opNames[0] << ", " << opNames[1] << ", "
1584228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1585228379Sdim        << ");";
1586228379Sdim    nl(Out) << iName << "->setName(\"";
1587228379Sdim    printEscapedString(rmwi->getName());
1588228379Sdim    Out << "\");";
1589228379Sdim    break;
1590228379Sdim  }
1591263508Sdim  case Instruction::LandingPad: {
1592263508Sdim    const LandingPadInst *lpi = cast<LandingPadInst>(I);
1593263508Sdim    Out << "LandingPadInst* " << iName << " = LandingPadInst::Create(";
1594263508Sdim    printCppName(lpi->getType());
1595263508Sdim    Out << ", " << opNames[0] << ", " << lpi->getNumClauses() << ", \"";
1596263508Sdim    printEscapedString(lpi->getName());
1597263508Sdim    Out << "\", " << bbname << ");";
1598263508Sdim    nl(Out) << iName << "->setCleanup("
1599263508Sdim            << (lpi->isCleanup() ? "true" : "false")
1600263508Sdim            << ");";
1601263508Sdim    for (unsigned i = 0, e = lpi->getNumClauses(); i != e; ++i)
1602263508Sdim      nl(Out) << iName << "->addClause(" << opNames[i+1] << ");";
1603263508Sdim    break;
1604228379Sdim  }
1605263508Sdim  }
1606193323Sed  DefinedValues.insert(I);
1607193323Sed  nl(Out);
1608193323Sed  delete [] opNames;
1609193323Sed}
1610193323Sed
1611210299Sed// Print out the types, constants and declarations needed by one function
1612210299Sedvoid CppWriter::printFunctionUses(const Function* F) {
1613210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1614210299Sed  if (!is_inline) {
1615210299Sed    // Print the function's return type
1616210299Sed    printType(F->getReturnType());
1617193323Sed
1618210299Sed    // Print the function's function type
1619210299Sed    printType(F->getFunctionType());
1620193323Sed
1621210299Sed    // Print the types of each of the function's arguments
1622210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1623210299Sed         AI != AE; ++AI) {
1624210299Sed      printType(AI->getType());
1625193323Sed    }
1626210299Sed  }
1627193323Sed
1628210299Sed  // Print type definitions for every type referenced by an instruction and
1629210299Sed  // make a note of any global values or constants that are referenced
1630210299Sed  SmallPtrSet<GlobalValue*,64> gvs;
1631210299Sed  SmallPtrSet<Constant*,64> consts;
1632210299Sed  for (Function::const_iterator BB = F->begin(), BE = F->end();
1633210299Sed       BB != BE; ++BB){
1634210299Sed    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
1635210299Sed         I != E; ++I) {
1636210299Sed      // Print the type of the instruction itself
1637210299Sed      printType(I->getType());
1638193323Sed
1639210299Sed      // Print the type of each of the instruction's operands
1640210299Sed      for (unsigned i = 0; i < I->getNumOperands(); ++i) {
1641210299Sed        Value* operand = I->getOperand(i);
1642210299Sed        printType(operand->getType());
1643193323Sed
1644210299Sed        // If the operand references a GVal or Constant, make a note of it
1645210299Sed        if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1646210299Sed          gvs.insert(GV);
1647218893Sdim          if (GenerationType != GenFunction)
1648218893Sdim            if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1649218893Sdim              if (GVar->hasInitializer())
1650218893Sdim                consts.insert(GVar->getInitializer());
1651218893Sdim        } else if (Constant* C = dyn_cast<Constant>(operand)) {
1652210299Sed          consts.insert(C);
1653218893Sdim          for (unsigned j = 0; j < C->getNumOperands(); ++j) {
1654218893Sdim            // If the operand references a GVal or Constant, make a note of it
1655218893Sdim            Value* operand = C->getOperand(j);
1656218893Sdim            printType(operand->getType());
1657218893Sdim            if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1658218893Sdim              gvs.insert(GV);
1659218893Sdim              if (GenerationType != GenFunction)
1660218893Sdim                if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1661218893Sdim                  if (GVar->hasInitializer())
1662218893Sdim                    consts.insert(GVar->getInitializer());
1663218893Sdim            }
1664218893Sdim          }
1665218893Sdim        }
1666193323Sed      }
1667193323Sed    }
1668210299Sed  }
1669193323Sed
1670210299Sed  // Print the function declarations for any functions encountered
1671210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1672210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1673210299Sed       I != E; ++I) {
1674210299Sed    if (Function* Fun = dyn_cast<Function>(*I)) {
1675210299Sed      if (!is_inline || Fun != F)
1676210299Sed        printFunctionHead(Fun);
1677193323Sed    }
1678210299Sed  }
1679193323Sed
1680210299Sed  // Print the global variable declarations for any variables encountered
1681210299Sed  nl(Out) << "// Global Variable Declarations"; nl(Out);
1682210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1683210299Sed       I != E; ++I) {
1684210299Sed    if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
1685210299Sed      printVariableHead(F);
1686210299Sed  }
1687193323Sed
1688218893Sdim  // Print the constants found
1689210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1690210299Sed  for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(),
1691210299Sed         E = consts.end(); I != E; ++I) {
1692210299Sed    printConstant(*I);
1693210299Sed  }
1694193323Sed
1695210299Sed  // Process the global variables definitions now that all the constants have
1696210299Sed  // been emitted. These definitions just couple the gvars with their constant
1697210299Sed  // initializers.
1698218893Sdim  if (GenerationType != GenFunction) {
1699218893Sdim    nl(Out) << "// Global Variable Definitions"; nl(Out);
1700218893Sdim    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1701218893Sdim         I != E; ++I) {
1702218893Sdim      if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
1703218893Sdim        printVariableBody(GV);
1704218893Sdim    }
1705193323Sed  }
1706210299Sed}
1707193323Sed
1708210299Sedvoid CppWriter::printFunctionHead(const Function* F) {
1709210299Sed  nl(Out) << "Function* " << getCppName(F);
1710226633Sdim  Out << " = mod->getFunction(\"";
1711226633Sdim  printEscapedString(F->getName());
1712226633Sdim  Out << "\");";
1713226633Sdim  nl(Out) << "if (!" << getCppName(F) << ") {";
1714226633Sdim  nl(Out) << getCppName(F);
1715226633Sdim
1716210299Sed  Out<< " = Function::Create(";
1717210299Sed  nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
1718210299Sed  nl(Out) << "/*Linkage=*/";
1719210299Sed  printLinkageType(F->getLinkage());
1720210299Sed  Out << ",";
1721210299Sed  nl(Out) << "/*Name=*/\"";
1722210299Sed  printEscapedString(F->getName());
1723210299Sed  Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
1724210299Sed  nl(Out,-1);
1725210299Sed  printCppName(F);
1726210299Sed  Out << "->setCallingConv(";
1727210299Sed  printCallingConv(F->getCallingConv());
1728210299Sed  Out << ");";
1729210299Sed  nl(Out);
1730210299Sed  if (F->hasSection()) {
1731193323Sed    printCppName(F);
1732210299Sed    Out << "->setSection(\"" << F->getSection() << "\");";
1733210299Sed    nl(Out);
1734210299Sed  }
1735210299Sed  if (F->getAlignment()) {
1736210299Sed    printCppName(F);
1737210299Sed    Out << "->setAlignment(" << F->getAlignment() << ");";
1738210299Sed    nl(Out);
1739210299Sed  }
1740210299Sed  if (F->getVisibility() != GlobalValue::DefaultVisibility) {
1741210299Sed    printCppName(F);
1742210299Sed    Out << "->setVisibility(";
1743210299Sed    printVisibilityType(F->getVisibility());
1744193323Sed    Out << ");";
1745193323Sed    nl(Out);
1746210299Sed  }
1747210299Sed  if (F->hasGC()) {
1748193323Sed    printCppName(F);
1749210299Sed    Out << "->setGC(\"" << F->getGC() << "\");";
1750193323Sed    nl(Out);
1751193323Sed  }
1752226633Sdim  Out << "}";
1753226633Sdim  nl(Out);
1754210299Sed  printAttributes(F->getAttributes(), getCppName(F));
1755210299Sed  printCppName(F);
1756210299Sed  Out << "->setAttributes(" << getCppName(F) << "_PAL);";
1757210299Sed  nl(Out);
1758210299Sed}
1759193323Sed
1760210299Sedvoid CppWriter::printFunctionBody(const Function *F) {
1761210299Sed  if (F->isDeclaration())
1762210299Sed    return; // external functions have no bodies.
1763193323Sed
1764210299Sed  // Clear the DefinedValues and ForwardRefs maps because we can't have
1765210299Sed  // cross-function forward refs
1766210299Sed  ForwardRefs.clear();
1767210299Sed  DefinedValues.clear();
1768193323Sed
1769210299Sed  // Create all the argument values
1770210299Sed  if (!is_inline) {
1771210299Sed    if (!F->arg_empty()) {
1772210299Sed      Out << "Function::arg_iterator args = " << getCppName(F)
1773210299Sed          << "->arg_begin();";
1774210299Sed      nl(Out);
1775210299Sed    }
1776210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1777210299Sed         AI != AE; ++AI) {
1778210299Sed      Out << "Value* " << getCppName(AI) << " = args++;";
1779210299Sed      nl(Out);
1780210299Sed      if (AI->hasName()) {
1781228379Sdim        Out << getCppName(AI) << "->setName(\"";
1782228379Sdim        printEscapedString(AI->getName());
1783228379Sdim        Out << "\");";
1784193323Sed        nl(Out);
1785193323Sed      }
1786193323Sed    }
1787210299Sed  }
1788193323Sed
1789210299Sed  // Create all the basic blocks
1790210299Sed  nl(Out);
1791210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1792210299Sed       BI != BE; ++BI) {
1793210299Sed    std::string bbname(getCppName(BI));
1794210299Sed    Out << "BasicBlock* " << bbname <<
1795210299Sed           " = BasicBlock::Create(mod->getContext(), \"";
1796210299Sed    if (BI->hasName())
1797210299Sed      printEscapedString(BI->getName());
1798210299Sed    Out << "\"," << getCppName(BI->getParent()) << ",0);";
1799193323Sed    nl(Out);
1800210299Sed  }
1801193323Sed
1802210299Sed  // Output all of its basic blocks... for the function
1803210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1804210299Sed       BI != BE; ++BI) {
1805210299Sed    std::string bbname(getCppName(BI));
1806210299Sed    nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
1807210299Sed    nl(Out);
1808193323Sed
1809210299Sed    // Output all of the instructions in the basic block...
1810210299Sed    for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
1811210299Sed         I != E; ++I) {
1812210299Sed      printInstruction(I,bbname);
1813193323Sed    }
1814210299Sed  }
1815193323Sed
1816210299Sed  // Loop over the ForwardRefs and resolve them now that all instructions
1817210299Sed  // are generated.
1818210299Sed  if (!ForwardRefs.empty()) {
1819210299Sed    nl(Out) << "// Resolve Forward References";
1820210299Sed    nl(Out);
1821193323Sed  }
1822193323Sed
1823210299Sed  while (!ForwardRefs.empty()) {
1824210299Sed    ForwardRefMap::iterator I = ForwardRefs.begin();
1825210299Sed    Out << I->second << "->replaceAllUsesWith("
1826210299Sed        << getCppName(I->first) << "); delete " << I->second << ";";
1827193323Sed    nl(Out);
1828210299Sed    ForwardRefs.erase(I);
1829193323Sed  }
1830210299Sed}
1831193323Sed
1832210299Sedvoid CppWriter::printInline(const std::string& fname,
1833210299Sed                            const std::string& func) {
1834210299Sed  const Function* F = TheModule->getFunction(func);
1835210299Sed  if (!F) {
1836210299Sed    error(std::string("Function '") + func + "' not found in input module");
1837210299Sed    return;
1838210299Sed  }
1839210299Sed  if (F->isDeclaration()) {
1840210299Sed    error(std::string("Function '") + func + "' is external!");
1841210299Sed    return;
1842210299Sed  }
1843210299Sed  nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
1844210299Sed          << getCppName(F);
1845210299Sed  unsigned arg_count = 1;
1846210299Sed  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1847210299Sed       AI != AE; ++AI) {
1848263508Sdim    Out << ", Value* arg_" << arg_count++;
1849210299Sed  }
1850210299Sed  Out << ") {";
1851210299Sed  nl(Out);
1852210299Sed  is_inline = true;
1853210299Sed  printFunctionUses(F);
1854210299Sed  printFunctionBody(F);
1855210299Sed  is_inline = false;
1856210299Sed  Out << "return " << getCppName(F->begin()) << ";";
1857210299Sed  nl(Out) << "}";
1858210299Sed  nl(Out);
1859210299Sed}
1860193323Sed
1861210299Sedvoid CppWriter::printModuleBody() {
1862210299Sed  // Print out all the type definitions
1863210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1864210299Sed  printTypes(TheModule);
1865193323Sed
1866210299Sed  // Functions can call each other and global variables can reference them so
1867210299Sed  // define all the functions first before emitting their function bodies.
1868210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1869210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1870210299Sed       I != E; ++I)
1871210299Sed    printFunctionHead(I);
1872193323Sed
1873210299Sed  // Process the global variables declarations. We can't initialze them until
1874210299Sed  // after the constants are printed so just print a header for each global
1875210299Sed  nl(Out) << "// Global Variable Declarations\n"; nl(Out);
1876210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1877210299Sed         E = TheModule->global_end(); I != E; ++I) {
1878210299Sed    printVariableHead(I);
1879210299Sed  }
1880193323Sed
1881210299Sed  // Print out all the constants definitions. Constants don't recurse except
1882210299Sed  // through GlobalValues. All GlobalValues have been declared at this point
1883210299Sed  // so we can proceed to generate the constants.
1884210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1885210299Sed  printConstants(TheModule);
1886193323Sed
1887210299Sed  // Process the global variables definitions now that all the constants have
1888210299Sed  // been emitted. These definitions just couple the gvars with their constant
1889210299Sed  // initializers.
1890210299Sed  nl(Out) << "// Global Variable Definitions"; nl(Out);
1891210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1892210299Sed         E = TheModule->global_end(); I != E; ++I) {
1893210299Sed    printVariableBody(I);
1894193323Sed  }
1895193323Sed
1896210299Sed  // Finally, we can safely put out all of the function bodies.
1897210299Sed  nl(Out) << "// Function Definitions"; nl(Out);
1898210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1899210299Sed       I != E; ++I) {
1900210299Sed    if (!I->isDeclaration()) {
1901210299Sed      nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
1902210299Sed              << ")";
1903210299Sed      nl(Out) << "{";
1904210299Sed      nl(Out,1);
1905210299Sed      printFunctionBody(I);
1906210299Sed      nl(Out,-1) << "}";
1907210299Sed      nl(Out);
1908210299Sed    }
1909193323Sed  }
1910210299Sed}
1911193323Sed
1912210299Sedvoid CppWriter::printProgram(const std::string& fname,
1913210299Sed                             const std::string& mName) {
1914210299Sed  Out << "#include <llvm/Pass.h>\n";
1915210299Sed  Out << "#include <llvm/PassManager.h>\n";
1916249423Sdim
1917210299Sed  Out << "#include <llvm/ADT/SmallVector.h>\n";
1918210299Sed  Out << "#include <llvm/Analysis/Verifier.h>\n";
1919210299Sed  Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
1920249423Sdim  Out << "#include <llvm/IR/BasicBlock.h>\n";
1921249423Sdim  Out << "#include <llvm/IR/CallingConv.h>\n";
1922249423Sdim  Out << "#include <llvm/IR/Constants.h>\n";
1923249423Sdim  Out << "#include <llvm/IR/DerivedTypes.h>\n";
1924249423Sdim  Out << "#include <llvm/IR/Function.h>\n";
1925249423Sdim  Out << "#include <llvm/IR/GlobalVariable.h>\n";
1926249423Sdim  Out << "#include <llvm/IR/InlineAsm.h>\n";
1927249423Sdim  Out << "#include <llvm/IR/Instructions.h>\n";
1928249423Sdim  Out << "#include <llvm/IR/LLVMContext.h>\n";
1929249423Sdim  Out << "#include <llvm/IR/Module.h>\n";
1930249423Sdim  Out << "#include <llvm/Support/FormattedStream.h>\n";
1931249423Sdim  Out << "#include <llvm/Support/MathExtras.h>\n";
1932210299Sed  Out << "#include <algorithm>\n";
1933210299Sed  Out << "using namespace llvm;\n\n";
1934210299Sed  Out << "Module* " << fname << "();\n\n";
1935210299Sed  Out << "int main(int argc, char**argv) {\n";
1936210299Sed  Out << "  Module* Mod = " << fname << "();\n";
1937210299Sed  Out << "  verifyModule(*Mod, PrintMessageAction);\n";
1938210299Sed  Out << "  PassManager PM;\n";
1939210299Sed  Out << "  PM.add(createPrintModulePass(&outs()));\n";
1940210299Sed  Out << "  PM.run(*Mod);\n";
1941210299Sed  Out << "  return 0;\n";
1942210299Sed  Out << "}\n\n";
1943210299Sed  printModule(fname,mName);
1944210299Sed}
1945193323Sed
1946210299Sedvoid CppWriter::printModule(const std::string& fname,
1947210299Sed                            const std::string& mName) {
1948210299Sed  nl(Out) << "Module* " << fname << "() {";
1949210299Sed  nl(Out,1) << "// Module Construction";
1950210299Sed  nl(Out) << "Module* mod = new Module(\"";
1951210299Sed  printEscapedString(mName);
1952210299Sed  Out << "\", getGlobalContext());";
1953210299Sed  if (!TheModule->getTargetTriple().empty()) {
1954210299Sed    nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
1955210299Sed  }
1956210299Sed  if (!TheModule->getTargetTriple().empty()) {
1957210299Sed    nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
1958210299Sed            << "\");";
1959210299Sed  }
1960193323Sed
1961210299Sed  if (!TheModule->getModuleInlineAsm().empty()) {
1962210299Sed    nl(Out) << "mod->setModuleInlineAsm(\"";
1963210299Sed    printEscapedString(TheModule->getModuleInlineAsm());
1964210299Sed    Out << "\");";
1965193323Sed  }
1966210299Sed  nl(Out);
1967193323Sed
1968210299Sed  printModuleBody();
1969210299Sed  nl(Out) << "return mod;";
1970210299Sed  nl(Out,-1) << "}";
1971210299Sed  nl(Out);
1972210299Sed}
1973193323Sed
1974210299Sedvoid CppWriter::printContents(const std::string& fname,
1975210299Sed                              const std::string& mName) {
1976210299Sed  Out << "\nModule* " << fname << "(Module *mod) {\n";
1977210299Sed  Out << "\nmod->setModuleIdentifier(\"";
1978210299Sed  printEscapedString(mName);
1979210299Sed  Out << "\");\n";
1980210299Sed  printModuleBody();
1981210299Sed  Out << "\nreturn mod;\n";
1982210299Sed  Out << "\n}\n";
1983210299Sed}
1984210299Sed
1985210299Sedvoid CppWriter::printFunction(const std::string& fname,
1986210299Sed                              const std::string& funcName) {
1987210299Sed  const Function* F = TheModule->getFunction(funcName);
1988210299Sed  if (!F) {
1989210299Sed    error(std::string("Function '") + funcName + "' not found in input module");
1990210299Sed    return;
1991193323Sed  }
1992210299Sed  Out << "\nFunction* " << fname << "(Module *mod) {\n";
1993210299Sed  printFunctionUses(F);
1994210299Sed  printFunctionHead(F);
1995210299Sed  printFunctionBody(F);
1996210299Sed  Out << "return " << getCppName(F) << ";\n";
1997210299Sed  Out << "}\n";
1998210299Sed}
1999193323Sed
2000210299Sedvoid CppWriter::printFunctions() {
2001210299Sed  const Module::FunctionListType &funcs = TheModule->getFunctionList();
2002210299Sed  Module::const_iterator I  = funcs.begin();
2003210299Sed  Module::const_iterator IE = funcs.end();
2004193323Sed
2005210299Sed  for (; I != IE; ++I) {
2006210299Sed    const Function &func = *I;
2007210299Sed    if (!func.isDeclaration()) {
2008210299Sed      std::string name("define_");
2009210299Sed      name += func.getName();
2010210299Sed      printFunction(name, func.getName());
2011193323Sed    }
2012193323Sed  }
2013210299Sed}
2014193323Sed
2015210299Sedvoid CppWriter::printVariable(const std::string& fname,
2016210299Sed                              const std::string& varName) {
2017210299Sed  const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
2018193323Sed
2019210299Sed  if (!GV) {
2020210299Sed    error(std::string("Variable '") + varName + "' not found in input module");
2021210299Sed    return;
2022193323Sed  }
2023210299Sed  Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
2024210299Sed  printVariableUses(GV);
2025210299Sed  printVariableHead(GV);
2026210299Sed  printVariableBody(GV);
2027210299Sed  Out << "return " << getCppName(GV) << ";\n";
2028210299Sed  Out << "}\n";
2029210299Sed}
2030193323Sed
2031224145Sdimvoid CppWriter::printType(const std::string &fname,
2032224145Sdim                          const std::string &typeName) {
2033226633Sdim  Type* Ty = TheModule->getTypeByName(typeName);
2034210299Sed  if (!Ty) {
2035210299Sed    error(std::string("Type '") + typeName + "' not found in input module");
2036210299Sed    return;
2037193323Sed  }
2038210299Sed  Out << "\nType* " << fname << "(Module *mod) {\n";
2039210299Sed  printType(Ty);
2040210299Sed  Out << "return " << getCppName(Ty) << ";\n";
2041210299Sed  Out << "}\n";
2042210299Sed}
2043193323Sed
2044210299Sedbool CppWriter::runOnModule(Module &M) {
2045210299Sed  TheModule = &M;
2046193323Sed
2047210299Sed  // Emit a header
2048210299Sed  Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
2049193323Sed
2050210299Sed  // Get the name of the function we're supposed to generate
2051210299Sed  std::string fname = FuncName.getValue();
2052193323Sed
2053210299Sed  // Get the name of the thing we are to generate
2054210299Sed  std::string tgtname = NameToGenerate.getValue();
2055210299Sed  if (GenerationType == GenModule ||
2056210299Sed      GenerationType == GenContents ||
2057210299Sed      GenerationType == GenProgram ||
2058210299Sed      GenerationType == GenFunctions) {
2059210299Sed    if (tgtname == "!bad!") {
2060210299Sed      if (M.getModuleIdentifier() == "-")
2061210299Sed        tgtname = "<stdin>";
2062210299Sed      else
2063210299Sed        tgtname = M.getModuleIdentifier();
2064193323Sed    }
2065210299Sed  } else if (tgtname == "!bad!")
2066210299Sed    error("You must use the -for option with -gen-{function,variable,type}");
2067193323Sed
2068210299Sed  switch (WhatToGenerate(GenerationType)) {
2069210299Sed   case GenProgram:
2070210299Sed    if (fname.empty())
2071210299Sed      fname = "makeLLVMModule";
2072210299Sed    printProgram(fname,tgtname);
2073210299Sed    break;
2074210299Sed   case GenModule:
2075210299Sed    if (fname.empty())
2076210299Sed      fname = "makeLLVMModule";
2077210299Sed    printModule(fname,tgtname);
2078210299Sed    break;
2079210299Sed   case GenContents:
2080210299Sed    if (fname.empty())
2081210299Sed      fname = "makeLLVMModuleContents";
2082210299Sed    printContents(fname,tgtname);
2083210299Sed    break;
2084210299Sed   case GenFunction:
2085210299Sed    if (fname.empty())
2086210299Sed      fname = "makeLLVMFunction";
2087210299Sed    printFunction(fname,tgtname);
2088210299Sed    break;
2089210299Sed   case GenFunctions:
2090210299Sed    printFunctions();
2091210299Sed    break;
2092210299Sed   case GenInline:
2093210299Sed    if (fname.empty())
2094210299Sed      fname = "makeLLVMInline";
2095210299Sed    printInline(fname,tgtname);
2096210299Sed    break;
2097210299Sed   case GenVariable:
2098210299Sed    if (fname.empty())
2099210299Sed      fname = "makeLLVMVariable";
2100210299Sed    printVariable(fname,tgtname);
2101210299Sed    break;
2102210299Sed   case GenType:
2103210299Sed    if (fname.empty())
2104210299Sed      fname = "makeLLVMType";
2105210299Sed    printType(fname,tgtname);
2106210299Sed    break;
2107193323Sed  }
2108210299Sed
2109210299Sed  return false;
2110193323Sed}
2111193323Sed
2112193323Sedchar CppWriter::ID = 0;
2113193323Sed
2114193323Sed//===----------------------------------------------------------------------===//
2115193323Sed//                       External Interface declaration
2116193323Sed//===----------------------------------------------------------------------===//
2117193323Sed
2118208599Srdivackybool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
2119208599Srdivacky                                           formatted_raw_ostream &o,
2120208599Srdivacky                                           CodeGenFileType FileType,
2121239462Sdim                                           bool DisableVerify,
2122239462Sdim                                           AnalysisID StartAfter,
2123239462Sdim                                           AnalysisID StopAfter) {
2124203954Srdivacky  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
2125193323Sed  PM.add(new CppWriter(o));
2126193323Sed  return false;
2127193323Sed}
2128