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>
36234353Sdim#include <cstdio>
37234353Sdim#include <map>
38193323Sed#include <set>
39193323Sedusing namespace llvm;
40193323Sed
41193323Sedstatic cl::opt<std::string>
42193323SedFuncName("cppfname", cl::desc("Specify the name of the generated function"),
43193323Sed         cl::value_desc("function name"));
44193323Sed
45193323Sedenum WhatToGenerate {
46193323Sed  GenProgram,
47193323Sed  GenModule,
48193323Sed  GenContents,
49193323Sed  GenFunction,
50193323Sed  GenFunctions,
51193323Sed  GenInline,
52193323Sed  GenVariable,
53193323Sed  GenType
54193323Sed};
55193323Sed
56193323Sedstatic cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
57193323Sed  cl::desc("Choose what kind of output to generate"),
58193323Sed  cl::init(GenProgram),
59193323Sed  cl::values(
60193323Sed    clEnumValN(GenProgram,  "program",   "Generate a complete program"),
61193323Sed    clEnumValN(GenModule,   "module",    "Generate a module definition"),
62193323Sed    clEnumValN(GenContents, "contents",  "Generate contents of a module"),
63193323Sed    clEnumValN(GenFunction, "function",  "Generate a function definition"),
64193323Sed    clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
65193323Sed    clEnumValN(GenInline,   "inline",    "Generate an inline function"),
66193323Sed    clEnumValN(GenVariable, "variable",  "Generate a variable definition"),
67193323Sed    clEnumValN(GenType,     "type",      "Generate a type definition"),
68193323Sed    clEnumValEnd
69193323Sed  )
70193323Sed);
71193323Sed
72193323Sedstatic cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
73193323Sed  cl::desc("Specify the name of the thing to generate"),
74193323Sed  cl::init("!bad!"));
75193323Sed
76198090Srdivackyextern "C" void LLVMInitializeCppBackendTarget() {
77198090Srdivacky  // Register the target.
78198090Srdivacky  RegisterTargetMachine<CPPTargetMachine> X(TheCppBackendTarget);
79198090Srdivacky}
80193323Sed
81193323Sednamespace {
82226633Sdim  typedef std::vector<Type*> TypeList;
83226633Sdim  typedef std::map<Type*,std::string> TypeMap;
84193323Sed  typedef std::map<const Value*,std::string> ValueMap;
85193323Sed  typedef std::set<std::string> NameSet;
86226633Sdim  typedef std::set<Type*> TypeSet;
87193323Sed  typedef std::set<const Value*> ValueSet;
88193323Sed  typedef std::map<const Value*,std::string> ForwardRefMap;
89193323Sed
90193323Sed  /// CppWriter - This class is the main chunk of code that converts an LLVM
91193323Sed  /// module to a C++ translation unit.
92193323Sed  class CppWriter : public ModulePass {
93198090Srdivacky    formatted_raw_ostream &Out;
94193323Sed    const Module *TheModule;
95193323Sed    uint64_t uniqueNum;
96193323Sed    TypeMap TypeNames;
97193323Sed    ValueMap ValueNames;
98193323Sed    NameSet UsedNames;
99193323Sed    TypeSet DefinedTypes;
100193323Sed    ValueSet DefinedValues;
101193323Sed    ForwardRefMap ForwardRefs;
102193323Sed    bool is_inline;
103210299Sed    unsigned indent_level;
104193323Sed
105193323Sed  public:
106193323Sed    static char ID;
107198090Srdivacky    explicit CppWriter(formatted_raw_ostream &o) :
108212904Sdim      ModulePass(ID), Out(o), uniqueNum(0), is_inline(false), indent_level(0){}
109193323Sed
110193323Sed    virtual const char *getPassName() const { return "C++ backend"; }
111193323Sed
112193323Sed    bool runOnModule(Module &M);
113193323Sed
114193323Sed    void printProgram(const std::string& fname, const std::string& modName );
115193323Sed    void printModule(const std::string& fname, const std::string& modName );
116193323Sed    void printContents(const std::string& fname, const std::string& modName );
117193323Sed    void printFunction(const std::string& fname, const std::string& funcName );
118193323Sed    void printFunctions();
119193323Sed    void printInline(const std::string& fname, const std::string& funcName );
120193323Sed    void printVariable(const std::string& fname, const std::string& varName );
121193323Sed    void printType(const std::string& fname, const std::string& typeName );
122193323Sed
123193323Sed    void error(const std::string& msg);
124193323Sed
125210299Sed
126210299Sed    formatted_raw_ostream& nl(formatted_raw_ostream &Out, int delta = 0);
127210299Sed    inline void in() { indent_level++; }
128210299Sed    inline void out() { if (indent_level >0) indent_level--; }
129210299Sed
130193323Sed  private:
131193323Sed    void printLinkageType(GlobalValue::LinkageTypes LT);
132193323Sed    void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
133239462Sdim    void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM);
134198090Srdivacky    void printCallingConv(CallingConv::ID cc);
135193323Sed    void printEscapedString(const std::string& str);
136193323Sed    void printCFP(const ConstantFP* CFP);
137193323Sed
138226633Sdim    std::string getCppName(Type* val);
139226633Sdim    inline void printCppName(Type* val);
140193323Sed
141193323Sed    std::string getCppName(const Value* val);
142193323Sed    inline void printCppName(const Value* val);
143193323Sed
144249423Sdim    void printAttributes(const AttributeSet &PAL, const std::string &name);
145226633Sdim    void printType(Type* Ty);
146193323Sed    void printTypes(const Module* M);
147193323Sed
148193323Sed    void printConstant(const Constant *CPV);
149193323Sed    void printConstants(const Module* M);
150193323Sed
151193323Sed    void printVariableUses(const GlobalVariable *GV);
152193323Sed    void printVariableHead(const GlobalVariable *GV);
153193323Sed    void printVariableBody(const GlobalVariable *GV);
154193323Sed
155193323Sed    void printFunctionUses(const Function *F);
156193323Sed    void printFunctionHead(const Function *F);
157193323Sed    void printFunctionBody(const Function *F);
158193323Sed    void printInstruction(const Instruction *I, const std::string& bbname);
159226633Sdim    std::string getOpName(const Value*);
160193323Sed
161193323Sed    void printModuleBody();
162193323Sed  };
163210299Sed} // end anonymous namespace.
164193323Sed
165210299Sedformatted_raw_ostream &CppWriter::nl(formatted_raw_ostream &Out, int delta) {
166210299Sed  Out << '\n';
167210299Sed  if (delta >= 0 || indent_level >= unsigned(-delta))
168210299Sed    indent_level += delta;
169210299Sed  Out.indent(indent_level);
170210299Sed  return Out;
171210299Sed}
172193323Sed
173210299Sedstatic inline void sanitize(std::string &str) {
174210299Sed  for (size_t i = 0; i < str.length(); ++i)
175210299Sed    if (!isalnum(str[i]) && str[i] != '_')
176210299Sed      str[i] = '_';
177210299Sed}
178193323Sed
179226633Sdimstatic std::string getTypePrefix(Type *Ty) {
180210299Sed  switch (Ty->getTypeID()) {
181210299Sed  case Type::VoidTyID:     return "void_";
182210299Sed  case Type::IntegerTyID:
183210299Sed    return "int" + utostr(cast<IntegerType>(Ty)->getBitWidth()) + "_";
184210299Sed  case Type::FloatTyID:    return "float_";
185210299Sed  case Type::DoubleTyID:   return "double_";
186210299Sed  case Type::LabelTyID:    return "label_";
187210299Sed  case Type::FunctionTyID: return "func_";
188210299Sed  case Type::StructTyID:   return "struct_";
189210299Sed  case Type::ArrayTyID:    return "array_";
190210299Sed  case Type::PointerTyID:  return "ptr_";
191210299Sed  case Type::VectorTyID:   return "packed_";
192210299Sed  default:                 return "other_";
193193323Sed  }
194210299Sed}
195193323Sed
196210299Sedvoid CppWriter::error(const std::string& msg) {
197210299Sed  report_fatal_error(msg);
198210299Sed}
199193323Sed
200234353Sdimstatic inline std::string ftostr(const APFloat& V) {
201234353Sdim  std::string Buf;
202234353Sdim  if (&V.getSemantics() == &APFloat::IEEEdouble) {
203234353Sdim    raw_string_ostream(Buf) << V.convertToDouble();
204234353Sdim    return Buf;
205234353Sdim  } else if (&V.getSemantics() == &APFloat::IEEEsingle) {
206234353Sdim    raw_string_ostream(Buf) << (double)V.convertToFloat();
207234353Sdim    return Buf;
208234353Sdim  }
209234353Sdim  return "<unknown format in ftostr>"; // error
210234353Sdim}
211234353Sdim
212210299Sed// printCFP - Print a floating point constant .. very carefully :)
213210299Sed// This makes sure that conversion to/from floating yields the same binary
214210299Sed// result so that we don't lose precision.
215210299Sedvoid CppWriter::printCFP(const ConstantFP *CFP) {
216210299Sed  bool ignored;
217210299Sed  APFloat APF = APFloat(CFP->getValueAPF());  // copy
218210299Sed  if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
219210299Sed    APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
220210299Sed  Out << "ConstantFP::get(mod->getContext(), ";
221210299Sed  Out << "APFloat(";
222193323Sed#if HAVE_PRINTF_A
223210299Sed  char Buffer[100];
224210299Sed  sprintf(Buffer, "%A", APF.convertToDouble());
225210299Sed  if ((!strncmp(Buffer, "0x", 2) ||
226210299Sed       !strncmp(Buffer, "-0x", 3) ||
227210299Sed       !strncmp(Buffer, "+0x", 3)) &&
228210299Sed      APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
229210299Sed    if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
230210299Sed      Out << "BitsToDouble(" << Buffer << ")";
231210299Sed    else
232210299Sed      Out << "BitsToFloat((float)" << Buffer << ")";
233210299Sed    Out << ")";
234210299Sed  } else {
235193323Sed#endif
236210299Sed    std::string StrVal = ftostr(CFP->getValueAPF());
237193323Sed
238210299Sed    while (StrVal[0] == ' ')
239210299Sed      StrVal.erase(StrVal.begin());
240193323Sed
241210299Sed    // Check to make sure that the stringized number is not some string like
242210299Sed    // "Inf" or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
243210299Sed    if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
244210299Sed         ((StrVal[0] == '-' || StrVal[0] == '+') &&
245210299Sed          (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
246210299Sed        (CFP->isExactlyValue(atof(StrVal.c_str())))) {
247210299Sed      if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
248210299Sed        Out <<  StrVal;
249193323Sed      else
250210299Sed        Out << StrVal << "f";
251210299Sed    } else if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
252210299Sed      Out << "BitsToDouble(0x"
253210299Sed          << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
254210299Sed          << "ULL) /* " << StrVal << " */";
255210299Sed    else
256210299Sed      Out << "BitsToFloat(0x"
257210299Sed          << utohexstr((uint32_t)CFP->getValueAPF().
258210299Sed                                      bitcastToAPInt().getZExtValue())
259210299Sed          << "U) /* " << StrVal << " */";
260210299Sed    Out << ")";
261193323Sed#if HAVE_PRINTF_A
262210299Sed  }
263193323Sed#endif
264210299Sed  Out << ")";
265210299Sed}
266210299Sed
267210299Sedvoid CppWriter::printCallingConv(CallingConv::ID cc){
268210299Sed  // Print the calling convention.
269210299Sed  switch (cc) {
270210299Sed  case CallingConv::C:     Out << "CallingConv::C"; break;
271210299Sed  case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
272210299Sed  case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
273210299Sed  case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
274210299Sed  default:                 Out << cc; break;
275193323Sed  }
276210299Sed}
277193323Sed
278210299Sedvoid CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
279210299Sed  switch (LT) {
280210299Sed  case GlobalValue::InternalLinkage:
281210299Sed    Out << "GlobalValue::InternalLinkage"; break;
282210299Sed  case GlobalValue::PrivateLinkage:
283210299Sed    Out << "GlobalValue::PrivateLinkage"; break;
284210299Sed  case GlobalValue::LinkerPrivateLinkage:
285210299Sed    Out << "GlobalValue::LinkerPrivateLinkage"; break;
286210299Sed  case GlobalValue::LinkerPrivateWeakLinkage:
287210299Sed    Out << "GlobalValue::LinkerPrivateWeakLinkage"; break;
288210299Sed  case GlobalValue::AvailableExternallyLinkage:
289210299Sed    Out << "GlobalValue::AvailableExternallyLinkage "; break;
290210299Sed  case GlobalValue::LinkOnceAnyLinkage:
291210299Sed    Out << "GlobalValue::LinkOnceAnyLinkage "; break;
292210299Sed  case GlobalValue::LinkOnceODRLinkage:
293210299Sed    Out << "GlobalValue::LinkOnceODRLinkage "; break;
294243830Sdim  case GlobalValue::LinkOnceODRAutoHideLinkage:
295243830Sdim    Out << "GlobalValue::LinkOnceODRAutoHideLinkage"; break;
296210299Sed  case GlobalValue::WeakAnyLinkage:
297210299Sed    Out << "GlobalValue::WeakAnyLinkage"; break;
298210299Sed  case GlobalValue::WeakODRLinkage:
299210299Sed    Out << "GlobalValue::WeakODRLinkage"; break;
300210299Sed  case GlobalValue::AppendingLinkage:
301210299Sed    Out << "GlobalValue::AppendingLinkage"; break;
302210299Sed  case GlobalValue::ExternalLinkage:
303210299Sed    Out << "GlobalValue::ExternalLinkage"; break;
304210299Sed  case GlobalValue::DLLImportLinkage:
305210299Sed    Out << "GlobalValue::DLLImportLinkage"; break;
306210299Sed  case GlobalValue::DLLExportLinkage:
307210299Sed    Out << "GlobalValue::DLLExportLinkage"; break;
308210299Sed  case GlobalValue::ExternalWeakLinkage:
309210299Sed    Out << "GlobalValue::ExternalWeakLinkage"; break;
310210299Sed  case GlobalValue::CommonLinkage:
311210299Sed    Out << "GlobalValue::CommonLinkage"; break;
312193323Sed  }
313210299Sed}
314193323Sed
315210299Sedvoid CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
316210299Sed  switch (VisType) {
317210299Sed  case GlobalValue::DefaultVisibility:
318210299Sed    Out << "GlobalValue::DefaultVisibility";
319210299Sed    break;
320210299Sed  case GlobalValue::HiddenVisibility:
321210299Sed    Out << "GlobalValue::HiddenVisibility";
322210299Sed    break;
323210299Sed  case GlobalValue::ProtectedVisibility:
324210299Sed    Out << "GlobalValue::ProtectedVisibility";
325210299Sed    break;
326193323Sed  }
327210299Sed}
328193323Sed
329239462Sdimvoid CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) {
330239462Sdim  switch (TLM) {
331239462Sdim    case GlobalVariable::NotThreadLocal:
332239462Sdim      Out << "GlobalVariable::NotThreadLocal";
333239462Sdim      break;
334239462Sdim    case GlobalVariable::GeneralDynamicTLSModel:
335239462Sdim      Out << "GlobalVariable::GeneralDynamicTLSModel";
336239462Sdim      break;
337239462Sdim    case GlobalVariable::LocalDynamicTLSModel:
338239462Sdim      Out << "GlobalVariable::LocalDynamicTLSModel";
339239462Sdim      break;
340239462Sdim    case GlobalVariable::InitialExecTLSModel:
341239462Sdim      Out << "GlobalVariable::InitialExecTLSModel";
342239462Sdim      break;
343239462Sdim    case GlobalVariable::LocalExecTLSModel:
344239462Sdim      Out << "GlobalVariable::LocalExecTLSModel";
345239462Sdim      break;
346239462Sdim  }
347239462Sdim}
348239462Sdim
349210299Sed// printEscapedString - Print each character of the specified string, escaping
350210299Sed// it if it is not printable or if it is an escape char.
351210299Sedvoid CppWriter::printEscapedString(const std::string &Str) {
352210299Sed  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
353210299Sed    unsigned char C = Str[i];
354210299Sed    if (isprint(C) && C != '"' && C != '\\') {
355210299Sed      Out << C;
356210299Sed    } else {
357210299Sed      Out << "\\x"
358210299Sed          << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
359210299Sed          << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
360193323Sed    }
361193323Sed  }
362210299Sed}
363193323Sed
364226633Sdimstd::string CppWriter::getCppName(Type* Ty) {
365210299Sed  // First, handle the primitive types .. easy
366210299Sed  if (Ty->isPrimitiveType() || Ty->isIntegerTy()) {
367210299Sed    switch (Ty->getTypeID()) {
368210299Sed    case Type::VoidTyID:   return "Type::getVoidTy(mod->getContext())";
369210299Sed    case Type::IntegerTyID: {
370210299Sed      unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
371210299Sed      return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")";
372193323Sed    }
373210299Sed    case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(mod->getContext())";
374210299Sed    case Type::FloatTyID:    return "Type::getFloatTy(mod->getContext())";
375210299Sed    case Type::DoubleTyID:   return "Type::getDoubleTy(mod->getContext())";
376210299Sed    case Type::LabelTyID:    return "Type::getLabelTy(mod->getContext())";
377218893Sdim    case Type::X86_MMXTyID:  return "Type::getX86_MMXTy(mod->getContext())";
378210299Sed    default:
379210299Sed      error("Invalid primitive type");
380210299Sed      break;
381210299Sed    }
382210299Sed    // shouldn't be returned, but make it sensible
383210299Sed    return "Type::getVoidTy(mod->getContext())";
384193323Sed  }
385193323Sed
386210299Sed  // Now, see if we've seen the type before and return that
387210299Sed  TypeMap::iterator I = TypeNames.find(Ty);
388210299Sed  if (I != TypeNames.end())
389210299Sed    return I->second;
390193323Sed
391210299Sed  // Okay, let's build a new name for this type. Start with a prefix
392210299Sed  const char* prefix = 0;
393210299Sed  switch (Ty->getTypeID()) {
394210299Sed  case Type::FunctionTyID:    prefix = "FuncTy_"; break;
395210299Sed  case Type::StructTyID:      prefix = "StructTy_"; break;
396210299Sed  case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
397210299Sed  case Type::PointerTyID:     prefix = "PointerTy_"; break;
398210299Sed  case Type::VectorTyID:      prefix = "VectorTy_"; break;
399210299Sed  default:                    prefix = "OtherTy_"; break; // prevent breakage
400210299Sed  }
401193323Sed
402210299Sed  // See if the type has a name in the symboltable and build accordingly
403210299Sed  std::string name;
404226633Sdim  if (StructType *STy = dyn_cast<StructType>(Ty))
405224145Sdim    if (STy->hasName())
406224145Sdim      name = STy->getName();
407224145Sdim
408224145Sdim  if (name.empty())
409224145Sdim    name = utostr(uniqueNum++);
410224145Sdim
411224145Sdim  name = std::string(prefix) + name;
412210299Sed  sanitize(name);
413193323Sed
414210299Sed  // Save the name
415210299Sed  return TypeNames[Ty] = name;
416210299Sed}
417193323Sed
418226633Sdimvoid CppWriter::printCppName(Type* Ty) {
419210299Sed  printEscapedString(getCppName(Ty));
420210299Sed}
421193323Sed
422210299Sedstd::string CppWriter::getCppName(const Value* val) {
423210299Sed  std::string name;
424210299Sed  ValueMap::iterator I = ValueNames.find(val);
425210299Sed  if (I != ValueNames.end() && I->first == val)
426210299Sed    return  I->second;
427193323Sed
428210299Sed  if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
429210299Sed    name = std::string("gvar_") +
430210299Sed      getTypePrefix(GV->getType()->getElementType());
431210299Sed  } else if (isa<Function>(val)) {
432210299Sed    name = std::string("func_");
433210299Sed  } else if (const Constant* C = dyn_cast<Constant>(val)) {
434210299Sed    name = std::string("const_") + getTypePrefix(C->getType());
435210299Sed  } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
436210299Sed    if (is_inline) {
437210299Sed      unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
438210299Sed                                      Function::const_arg_iterator(Arg)) + 1;
439210299Sed      name = std::string("arg_") + utostr(argNum);
440210299Sed      NameSet::iterator NI = UsedNames.find(name);
441210299Sed      if (NI != UsedNames.end())
442210299Sed        name += std::string("_") + utostr(uniqueNum++);
443210299Sed      UsedNames.insert(name);
444210299Sed      return ValueNames[val] = name;
445193323Sed    } else {
446193323Sed      name = getTypePrefix(val->getType());
447193323Sed    }
448210299Sed  } else {
449210299Sed    name = getTypePrefix(val->getType());
450193323Sed  }
451210299Sed  if (val->hasName())
452210299Sed    name += val->getName();
453210299Sed  else
454210299Sed    name += utostr(uniqueNum++);
455210299Sed  sanitize(name);
456210299Sed  NameSet::iterator NI = UsedNames.find(name);
457210299Sed  if (NI != UsedNames.end())
458210299Sed    name += std::string("_") + utostr(uniqueNum++);
459210299Sed  UsedNames.insert(name);
460210299Sed  return ValueNames[val] = name;
461210299Sed}
462193323Sed
463210299Sedvoid CppWriter::printCppName(const Value* val) {
464210299Sed  printEscapedString(getCppName(val));
465210299Sed}
466193323Sed
467249423Sdimvoid CppWriter::printAttributes(const AttributeSet &PAL,
468210299Sed                                const std::string &name) {
469249423Sdim  Out << "AttributeSet " << name << "_PAL;";
470210299Sed  nl(Out);
471210299Sed  if (!PAL.isEmpty()) {
472210299Sed    Out << '{'; in(); nl(Out);
473249423Sdim    Out << "SmallVector<AttributeSet, 4> Attrs;"; nl(Out);
474249423Sdim    Out << "AttributeSet PAS;"; in(); nl(Out);
475210299Sed    for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
476249423Sdim      unsigned index = PAL.getSlotIndex(i);
477249423Sdim      AttrBuilder attrs(PAL.getSlotAttributes(i), index);
478249423Sdim      Out << "{"; in(); nl(Out);
479249423Sdim      Out << "AttrBuilder B;"; nl(Out);
480243830Sdim
481249423Sdim#define HANDLE_ATTR(X)                                                  \
482249423Sdim      if (attrs.contains(Attribute::X)) {                               \
483249423Sdim        Out << "B.addAttribute(Attribute::" #X ");"; nl(Out);           \
484249423Sdim        attrs.removeAttribute(Attribute::X);                            \
485249423Sdim      }
486243830Sdim
487210299Sed      HANDLE_ATTR(SExt);
488210299Sed      HANDLE_ATTR(ZExt);
489210299Sed      HANDLE_ATTR(NoReturn);
490210299Sed      HANDLE_ATTR(InReg);
491210299Sed      HANDLE_ATTR(StructRet);
492210299Sed      HANDLE_ATTR(NoUnwind);
493210299Sed      HANDLE_ATTR(NoAlias);
494210299Sed      HANDLE_ATTR(ByVal);
495210299Sed      HANDLE_ATTR(Nest);
496210299Sed      HANDLE_ATTR(ReadNone);
497210299Sed      HANDLE_ATTR(ReadOnly);
498210299Sed      HANDLE_ATTR(NoInline);
499210299Sed      HANDLE_ATTR(AlwaysInline);
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) {
1142239462Sdim      const IntegersSubset CaseVal = i.getCaseValueEx();
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: {
1163226633Sdim    Out << "ResumeInst::Create(mod->getContext(), " << opNames[0]
1164226633Sdim        << ", " << bbname << ");";
1165226633Sdim    break;
1166226633Sdim  }
1167210299Sed  case Instruction::Invoke: {
1168210299Sed    const InvokeInst* inv = cast<InvokeInst>(I);
1169210299Sed    Out << "std::vector<Value*> " << iName << "_params;";
1170210299Sed    nl(Out);
1171210299Sed    for (unsigned i = 0; i < inv->getNumArgOperands(); ++i) {
1172210299Sed      Out << iName << "_params.push_back("
1173210299Sed          << getOpName(inv->getArgOperand(i)) << ");";
1174193323Sed      nl(Out);
1175193323Sed    }
1176210299Sed    // FIXME: This shouldn't use magic numbers -3, -2, and -1.
1177210299Sed    Out << "InvokeInst *" << iName << " = InvokeInst::Create("
1178210299Sed        << getOpName(inv->getCalledFunction()) << ", "
1179210299Sed        << getOpName(inv->getNormalDest()) << ", "
1180210299Sed        << getOpName(inv->getUnwindDest()) << ", "
1181226633Sdim        << iName << "_params, \"";
1182210299Sed    printEscapedString(inv->getName());
1183210299Sed    Out << "\", " << bbname << ");";
1184210299Sed    nl(Out) << iName << "->setCallingConv(";
1185210299Sed    printCallingConv(inv->getCallingConv());
1186210299Sed    Out << ");";
1187210299Sed    printAttributes(inv->getAttributes(), iName);
1188210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1189210299Sed    nl(Out);
1190210299Sed    break;
1191210299Sed  }
1192210299Sed  case Instruction::Unreachable: {
1193210299Sed    Out << "new UnreachableInst("
1194210299Sed        << "mod->getContext(), "
1195210299Sed        << bbname << ");";
1196210299Sed    break;
1197210299Sed  }
1198210299Sed  case Instruction::Add:
1199210299Sed  case Instruction::FAdd:
1200210299Sed  case Instruction::Sub:
1201210299Sed  case Instruction::FSub:
1202210299Sed  case Instruction::Mul:
1203210299Sed  case Instruction::FMul:
1204210299Sed  case Instruction::UDiv:
1205210299Sed  case Instruction::SDiv:
1206210299Sed  case Instruction::FDiv:
1207210299Sed  case Instruction::URem:
1208210299Sed  case Instruction::SRem:
1209210299Sed  case Instruction::FRem:
1210210299Sed  case Instruction::And:
1211210299Sed  case Instruction::Or:
1212210299Sed  case Instruction::Xor:
1213210299Sed  case Instruction::Shl:
1214210299Sed  case Instruction::LShr:
1215210299Sed  case Instruction::AShr:{
1216210299Sed    Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
1217210299Sed    switch (I->getOpcode()) {
1218210299Sed    case Instruction::Add: Out << "Instruction::Add"; break;
1219210299Sed    case Instruction::FAdd: Out << "Instruction::FAdd"; break;
1220210299Sed    case Instruction::Sub: Out << "Instruction::Sub"; break;
1221210299Sed    case Instruction::FSub: Out << "Instruction::FSub"; break;
1222210299Sed    case Instruction::Mul: Out << "Instruction::Mul"; break;
1223210299Sed    case Instruction::FMul: Out << "Instruction::FMul"; break;
1224210299Sed    case Instruction::UDiv:Out << "Instruction::UDiv"; break;
1225210299Sed    case Instruction::SDiv:Out << "Instruction::SDiv"; break;
1226210299Sed    case Instruction::FDiv:Out << "Instruction::FDiv"; break;
1227210299Sed    case Instruction::URem:Out << "Instruction::URem"; break;
1228210299Sed    case Instruction::SRem:Out << "Instruction::SRem"; break;
1229210299Sed    case Instruction::FRem:Out << "Instruction::FRem"; break;
1230210299Sed    case Instruction::And: Out << "Instruction::And"; break;
1231210299Sed    case Instruction::Or:  Out << "Instruction::Or";  break;
1232210299Sed    case Instruction::Xor: Out << "Instruction::Xor"; break;
1233210299Sed    case Instruction::Shl: Out << "Instruction::Shl"; break;
1234210299Sed    case Instruction::LShr:Out << "Instruction::LShr"; break;
1235210299Sed    case Instruction::AShr:Out << "Instruction::AShr"; break;
1236210299Sed    default: Out << "Instruction::BadOpCode"; break;
1237193323Sed    }
1238210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1239210299Sed    printEscapedString(I->getName());
1240210299Sed    Out << "\", " << bbname << ");";
1241210299Sed    break;
1242210299Sed  }
1243210299Sed  case Instruction::FCmp: {
1244210299Sed    Out << "FCmpInst* " << iName << " = new FCmpInst(*" << bbname << ", ";
1245210299Sed    switch (cast<FCmpInst>(I)->getPredicate()) {
1246210299Sed    case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
1247210299Sed    case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
1248210299Sed    case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
1249210299Sed    case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
1250210299Sed    case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
1251210299Sed    case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
1252210299Sed    case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
1253210299Sed    case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
1254210299Sed    case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
1255210299Sed    case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
1256210299Sed    case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
1257210299Sed    case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
1258210299Sed    case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
1259210299Sed    case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
1260210299Sed    case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
1261210299Sed    case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
1262210299Sed    default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
1263193323Sed    }
1264210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1265210299Sed    printEscapedString(I->getName());
1266210299Sed    Out << "\");";
1267210299Sed    break;
1268210299Sed  }
1269210299Sed  case Instruction::ICmp: {
1270210299Sed    Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
1271210299Sed    switch (cast<ICmpInst>(I)->getPredicate()) {
1272210299Sed    case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
1273210299Sed    case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
1274210299Sed    case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
1275210299Sed    case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
1276210299Sed    case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
1277210299Sed    case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
1278210299Sed    case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
1279210299Sed    case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
1280210299Sed    case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
1281210299Sed    case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
1282210299Sed    default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
1283193323Sed    }
1284210299Sed    Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
1285210299Sed    printEscapedString(I->getName());
1286210299Sed    Out << "\");";
1287210299Sed    break;
1288210299Sed  }
1289210299Sed  case Instruction::Alloca: {
1290210299Sed    const AllocaInst* allocaI = cast<AllocaInst>(I);
1291210299Sed    Out << "AllocaInst* " << iName << " = new AllocaInst("
1292210299Sed        << getCppName(allocaI->getAllocatedType()) << ", ";
1293210299Sed    if (allocaI->isArrayAllocation())
1294210299Sed      Out << opNames[0] << ", ";
1295210299Sed    Out << "\"";
1296210299Sed    printEscapedString(allocaI->getName());
1297210299Sed    Out << "\", " << bbname << ");";
1298210299Sed    if (allocaI->getAlignment())
1299210299Sed      nl(Out) << iName << "->setAlignment("
1300210299Sed          << allocaI->getAlignment() << ");";
1301210299Sed    break;
1302210299Sed  }
1303210299Sed  case Instruction::Load: {
1304210299Sed    const LoadInst* load = cast<LoadInst>(I);
1305210299Sed    Out << "LoadInst* " << iName << " = new LoadInst("
1306210299Sed        << opNames[0] << ", \"";
1307210299Sed    printEscapedString(load->getName());
1308210299Sed    Out << "\", " << (load->isVolatile() ? "true" : "false" )
1309210299Sed        << ", " << bbname << ");";
1310228379Sdim    if (load->getAlignment())
1311228379Sdim      nl(Out) << iName << "->setAlignment("
1312228379Sdim              << load->getAlignment() << ");";
1313228379Sdim    if (load->isAtomic()) {
1314228379Sdim      StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
1315228379Sdim      StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
1316228379Sdim      nl(Out) << iName << "->setAtomic("
1317228379Sdim              << Ordering << ", " << CrossThread << ");";
1318228379Sdim    }
1319210299Sed    break;
1320210299Sed  }
1321210299Sed  case Instruction::Store: {
1322210299Sed    const StoreInst* store = cast<StoreInst>(I);
1323228379Sdim    Out << "StoreInst* " << iName << " = new StoreInst("
1324210299Sed        << opNames[0] << ", "
1325210299Sed        << opNames[1] << ", "
1326210299Sed        << (store->isVolatile() ? "true" : "false")
1327210299Sed        << ", " << bbname << ");";
1328228379Sdim    if (store->getAlignment())
1329228379Sdim      nl(Out) << iName << "->setAlignment("
1330228379Sdim              << store->getAlignment() << ");";
1331228379Sdim    if (store->isAtomic()) {
1332228379Sdim      StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
1333228379Sdim      StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
1334228379Sdim      nl(Out) << iName << "->setAtomic("
1335228379Sdim              << Ordering << ", " << CrossThread << ");";
1336228379Sdim    }
1337210299Sed    break;
1338210299Sed  }
1339210299Sed  case Instruction::GetElementPtr: {
1340210299Sed    const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
1341210299Sed    if (gep->getNumOperands() <= 2) {
1342210299Sed      Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
1343210299Sed          << opNames[0];
1344210299Sed      if (gep->getNumOperands() == 2)
1345210299Sed        Out << ", " << opNames[1];
1346210299Sed    } else {
1347210299Sed      Out << "std::vector<Value*> " << iName << "_indices;";
1348210299Sed      nl(Out);
1349210299Sed      for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
1350210299Sed        Out << iName << "_indices.push_back("
1351210299Sed            << opNames[i] << ");";
1352193323Sed        nl(Out);
1353193323Sed      }
1354210299Sed      Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
1355226633Sdim          << opNames[0] << ", " << iName << "_indices";
1356193323Sed    }
1357210299Sed    Out << ", \"";
1358210299Sed    printEscapedString(gep->getName());
1359210299Sed    Out << "\", " << bbname << ");";
1360210299Sed    break;
1361210299Sed  }
1362210299Sed  case Instruction::PHI: {
1363210299Sed    const PHINode* phi = cast<PHINode>(I);
1364193323Sed
1365210299Sed    Out << "PHINode* " << iName << " = PHINode::Create("
1366221345Sdim        << getCppName(phi->getType()) << ", "
1367221345Sdim        << phi->getNumIncomingValues() << ", \"";
1368210299Sed    printEscapedString(phi->getName());
1369210299Sed    Out << "\", " << bbname << ");";
1370210299Sed    nl(Out);
1371224145Sdim    for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
1372210299Sed      Out << iName << "->addIncoming("
1373224145Sdim          << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", "
1374224145Sdim          << getOpName(phi->getIncomingBlock(i)) << ");";
1375193323Sed      nl(Out);
1376193323Sed    }
1377210299Sed    break;
1378210299Sed  }
1379210299Sed  case Instruction::Trunc:
1380210299Sed  case Instruction::ZExt:
1381210299Sed  case Instruction::SExt:
1382210299Sed  case Instruction::FPTrunc:
1383210299Sed  case Instruction::FPExt:
1384210299Sed  case Instruction::FPToUI:
1385210299Sed  case Instruction::FPToSI:
1386210299Sed  case Instruction::UIToFP:
1387210299Sed  case Instruction::SIToFP:
1388210299Sed  case Instruction::PtrToInt:
1389210299Sed  case Instruction::IntToPtr:
1390210299Sed  case Instruction::BitCast: {
1391210299Sed    const CastInst* cst = cast<CastInst>(I);
1392210299Sed    Out << "CastInst* " << iName << " = new ";
1393210299Sed    switch (I->getOpcode()) {
1394210299Sed    case Instruction::Trunc:    Out << "TruncInst"; break;
1395210299Sed    case Instruction::ZExt:     Out << "ZExtInst"; break;
1396210299Sed    case Instruction::SExt:     Out << "SExtInst"; break;
1397210299Sed    case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
1398210299Sed    case Instruction::FPExt:    Out << "FPExtInst"; break;
1399210299Sed    case Instruction::FPToUI:   Out << "FPToUIInst"; break;
1400210299Sed    case Instruction::FPToSI:   Out << "FPToSIInst"; break;
1401210299Sed    case Instruction::UIToFP:   Out << "UIToFPInst"; break;
1402210299Sed    case Instruction::SIToFP:   Out << "SIToFPInst"; break;
1403210299Sed    case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
1404210299Sed    case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
1405210299Sed    case Instruction::BitCast:  Out << "BitCastInst"; break;
1406234353Sdim    default: llvm_unreachable("Unreachable");
1407193323Sed    }
1408210299Sed    Out << "(" << opNames[0] << ", "
1409210299Sed        << getCppName(cst->getType()) << ", \"";
1410210299Sed    printEscapedString(cst->getName());
1411210299Sed    Out << "\", " << bbname << ");";
1412210299Sed    break;
1413210299Sed  }
1414210299Sed  case Instruction::Call: {
1415210299Sed    const CallInst* call = cast<CallInst>(I);
1416210299Sed    if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
1417210299Sed      Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
1418210299Sed          << getCppName(ila->getFunctionType()) << ", \""
1419210299Sed          << ila->getAsmString() << "\", \""
1420210299Sed          << ila->getConstraintString() << "\","
1421210299Sed          << (ila->hasSideEffects() ? "true" : "false") << ");";
1422193323Sed      nl(Out);
1423193323Sed    }
1424210299Sed    if (call->getNumArgOperands() > 1) {
1425210299Sed      Out << "std::vector<Value*> " << iName << "_params;";
1426193323Sed      nl(Out);
1427210299Sed      for (unsigned i = 0; i < call->getNumArgOperands(); ++i) {
1428210299Sed        Out << iName << "_params.push_back(" << opNames[i] << ");";
1429193323Sed        nl(Out);
1430193323Sed      }
1431210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1432212904Sdim          << opNames[call->getNumArgOperands()] << ", "
1433226633Sdim          << iName << "_params, \"";
1434210299Sed    } else if (call->getNumArgOperands() == 1) {
1435210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1436210299Sed          << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \"";
1437210299Sed    } else {
1438210299Sed      Out << "CallInst* " << iName << " = CallInst::Create("
1439210299Sed          << opNames[call->getNumArgOperands()] << ", \"";
1440193323Sed    }
1441210299Sed    printEscapedString(call->getName());
1442210299Sed    Out << "\", " << bbname << ");";
1443210299Sed    nl(Out) << iName << "->setCallingConv(";
1444210299Sed    printCallingConv(call->getCallingConv());
1445210299Sed    Out << ");";
1446210299Sed    nl(Out) << iName << "->setTailCall("
1447210299Sed        << (call->isTailCall() ? "true" : "false");
1448210299Sed    Out << ");";
1449210299Sed    nl(Out);
1450210299Sed    printAttributes(call->getAttributes(), iName);
1451210299Sed    Out << iName << "->setAttributes(" << iName << "_PAL);";
1452210299Sed    nl(Out);
1453210299Sed    break;
1454210299Sed  }
1455210299Sed  case Instruction::Select: {
1456210299Sed    const SelectInst* sel = cast<SelectInst>(I);
1457210299Sed    Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
1458210299Sed    Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1459210299Sed    printEscapedString(sel->getName());
1460210299Sed    Out << "\", " << bbname << ");";
1461210299Sed    break;
1462210299Sed  }
1463210299Sed  case Instruction::UserOp1:
1464210299Sed    /// FALL THROUGH
1465210299Sed  case Instruction::UserOp2: {
1466210299Sed    /// FIXME: What should be done here?
1467210299Sed    break;
1468210299Sed  }
1469210299Sed  case Instruction::VAArg: {
1470210299Sed    const VAArgInst* va = cast<VAArgInst>(I);
1471210299Sed    Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
1472210299Sed        << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
1473210299Sed    printEscapedString(va->getName());
1474210299Sed    Out << "\", " << bbname << ");";
1475210299Sed    break;
1476210299Sed  }
1477210299Sed  case Instruction::ExtractElement: {
1478210299Sed    const ExtractElementInst* eei = cast<ExtractElementInst>(I);
1479210299Sed    Out << "ExtractElementInst* " << getCppName(eei)
1480210299Sed        << " = new ExtractElementInst(" << opNames[0]
1481210299Sed        << ", " << opNames[1] << ", \"";
1482210299Sed    printEscapedString(eei->getName());
1483210299Sed    Out << "\", " << bbname << ");";
1484210299Sed    break;
1485210299Sed  }
1486210299Sed  case Instruction::InsertElement: {
1487210299Sed    const InsertElementInst* iei = cast<InsertElementInst>(I);
1488210299Sed    Out << "InsertElementInst* " << getCppName(iei)
1489210299Sed        << " = InsertElementInst::Create(" << opNames[0]
1490210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1491210299Sed    printEscapedString(iei->getName());
1492210299Sed    Out << "\", " << bbname << ");";
1493210299Sed    break;
1494210299Sed  }
1495210299Sed  case Instruction::ShuffleVector: {
1496210299Sed    const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
1497210299Sed    Out << "ShuffleVectorInst* " << getCppName(svi)
1498210299Sed        << " = new ShuffleVectorInst(" << opNames[0]
1499210299Sed        << ", " << opNames[1] << ", " << opNames[2] << ", \"";
1500210299Sed    printEscapedString(svi->getName());
1501210299Sed    Out << "\", " << bbname << ");";
1502210299Sed    break;
1503210299Sed  }
1504210299Sed  case Instruction::ExtractValue: {
1505210299Sed    const ExtractValueInst *evi = cast<ExtractValueInst>(I);
1506210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1507210299Sed    nl(Out);
1508210299Sed    for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
1509210299Sed      Out << iName << "_indices.push_back("
1510210299Sed          << evi->idx_begin()[i] << ");";
1511193323Sed      nl(Out);
1512193323Sed    }
1513210299Sed    Out << "ExtractValueInst* " << getCppName(evi)
1514210299Sed        << " = ExtractValueInst::Create(" << opNames[0]
1515210299Sed        << ", "
1516226633Sdim        << iName << "_indices, \"";
1517210299Sed    printEscapedString(evi->getName());
1518210299Sed    Out << "\", " << bbname << ");";
1519210299Sed    break;
1520193323Sed  }
1521210299Sed  case Instruction::InsertValue: {
1522210299Sed    const InsertValueInst *ivi = cast<InsertValueInst>(I);
1523210299Sed    Out << "std::vector<unsigned> " << iName << "_indices;";
1524210299Sed    nl(Out);
1525210299Sed    for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
1526210299Sed      Out << iName << "_indices.push_back("
1527210299Sed          << ivi->idx_begin()[i] << ");";
1528210299Sed      nl(Out);
1529210299Sed    }
1530210299Sed    Out << "InsertValueInst* " << getCppName(ivi)
1531210299Sed        << " = InsertValueInst::Create(" << opNames[0]
1532210299Sed        << ", " << opNames[1] << ", "
1533226633Sdim        << iName << "_indices, \"";
1534210299Sed    printEscapedString(ivi->getName());
1535210299Sed    Out << "\", " << bbname << ");";
1536210299Sed    break;
1537210299Sed  }
1538228379Sdim  case Instruction::Fence: {
1539228379Sdim    const FenceInst *fi = cast<FenceInst>(I);
1540228379Sdim    StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering());
1541228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope());
1542228379Sdim    Out << "FenceInst* " << iName
1543228379Sdim        << " = new FenceInst(mod->getContext(), "
1544228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1545228379Sdim        << ");";
1546228379Sdim    break;
1547210299Sed  }
1548228379Sdim  case Instruction::AtomicCmpXchg: {
1549228379Sdim    const AtomicCmpXchgInst *cxi = cast<AtomicCmpXchgInst>(I);
1550228379Sdim    StringRef Ordering = ConvertAtomicOrdering(cxi->getOrdering());
1551228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope());
1552228379Sdim    Out << "AtomicCmpXchgInst* " << iName
1553228379Sdim        << " = new AtomicCmpXchgInst("
1554228379Sdim        << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", "
1555228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1556228379Sdim        << ");";
1557228379Sdim    nl(Out) << iName << "->setName(\"";
1558228379Sdim    printEscapedString(cxi->getName());
1559228379Sdim    Out << "\");";
1560228379Sdim    break;
1561228379Sdim  }
1562228379Sdim  case Instruction::AtomicRMW: {
1563228379Sdim    const AtomicRMWInst *rmwi = cast<AtomicRMWInst>(I);
1564228379Sdim    StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering());
1565228379Sdim    StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope());
1566228379Sdim    StringRef Operation;
1567228379Sdim    switch (rmwi->getOperation()) {
1568228379Sdim      case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break;
1569228379Sdim      case AtomicRMWInst::Add:  Operation = "AtomicRMWInst::Add"; break;
1570228379Sdim      case AtomicRMWInst::Sub:  Operation = "AtomicRMWInst::Sub"; break;
1571228379Sdim      case AtomicRMWInst::And:  Operation = "AtomicRMWInst::And"; break;
1572228379Sdim      case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break;
1573228379Sdim      case AtomicRMWInst::Or:   Operation = "AtomicRMWInst::Or"; break;
1574228379Sdim      case AtomicRMWInst::Xor:  Operation = "AtomicRMWInst::Xor"; break;
1575228379Sdim      case AtomicRMWInst::Max:  Operation = "AtomicRMWInst::Max"; break;
1576228379Sdim      case AtomicRMWInst::Min:  Operation = "AtomicRMWInst::Min"; break;
1577228379Sdim      case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break;
1578228379Sdim      case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break;
1579228379Sdim      case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation");
1580228379Sdim    }
1581228379Sdim    Out << "AtomicRMWInst* " << iName
1582228379Sdim        << " = new AtomicRMWInst("
1583228379Sdim        << Operation << ", "
1584228379Sdim        << opNames[0] << ", " << opNames[1] << ", "
1585228379Sdim        << Ordering << ", " << CrossThread << ", " << bbname
1586228379Sdim        << ");";
1587228379Sdim    nl(Out) << iName << "->setName(\"";
1588228379Sdim    printEscapedString(rmwi->getName());
1589228379Sdim    Out << "\");";
1590228379Sdim    break;
1591228379Sdim  }
1592228379Sdim  }
1593193323Sed  DefinedValues.insert(I);
1594193323Sed  nl(Out);
1595193323Sed  delete [] opNames;
1596193323Sed}
1597193323Sed
1598210299Sed// Print out the types, constants and declarations needed by one function
1599210299Sedvoid CppWriter::printFunctionUses(const Function* F) {
1600210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1601210299Sed  if (!is_inline) {
1602210299Sed    // Print the function's return type
1603210299Sed    printType(F->getReturnType());
1604193323Sed
1605210299Sed    // Print the function's function type
1606210299Sed    printType(F->getFunctionType());
1607193323Sed
1608210299Sed    // Print the types of each of the function's arguments
1609210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1610210299Sed         AI != AE; ++AI) {
1611210299Sed      printType(AI->getType());
1612193323Sed    }
1613210299Sed  }
1614193323Sed
1615210299Sed  // Print type definitions for every type referenced by an instruction and
1616210299Sed  // make a note of any global values or constants that are referenced
1617210299Sed  SmallPtrSet<GlobalValue*,64> gvs;
1618210299Sed  SmallPtrSet<Constant*,64> consts;
1619210299Sed  for (Function::const_iterator BB = F->begin(), BE = F->end();
1620210299Sed       BB != BE; ++BB){
1621210299Sed    for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
1622210299Sed         I != E; ++I) {
1623210299Sed      // Print the type of the instruction itself
1624210299Sed      printType(I->getType());
1625193323Sed
1626210299Sed      // Print the type of each of the instruction's operands
1627210299Sed      for (unsigned i = 0; i < I->getNumOperands(); ++i) {
1628210299Sed        Value* operand = I->getOperand(i);
1629210299Sed        printType(operand->getType());
1630193323Sed
1631210299Sed        // If the operand references a GVal or Constant, make a note of it
1632210299Sed        if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1633210299Sed          gvs.insert(GV);
1634218893Sdim          if (GenerationType != GenFunction)
1635218893Sdim            if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1636218893Sdim              if (GVar->hasInitializer())
1637218893Sdim                consts.insert(GVar->getInitializer());
1638218893Sdim        } else if (Constant* C = dyn_cast<Constant>(operand)) {
1639210299Sed          consts.insert(C);
1640218893Sdim          for (unsigned j = 0; j < C->getNumOperands(); ++j) {
1641218893Sdim            // If the operand references a GVal or Constant, make a note of it
1642218893Sdim            Value* operand = C->getOperand(j);
1643218893Sdim            printType(operand->getType());
1644218893Sdim            if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
1645218893Sdim              gvs.insert(GV);
1646218893Sdim              if (GenerationType != GenFunction)
1647218893Sdim                if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
1648218893Sdim                  if (GVar->hasInitializer())
1649218893Sdim                    consts.insert(GVar->getInitializer());
1650218893Sdim            }
1651218893Sdim          }
1652218893Sdim        }
1653193323Sed      }
1654193323Sed    }
1655210299Sed  }
1656193323Sed
1657210299Sed  // Print the function declarations for any functions encountered
1658210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1659210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1660210299Sed       I != E; ++I) {
1661210299Sed    if (Function* Fun = dyn_cast<Function>(*I)) {
1662210299Sed      if (!is_inline || Fun != F)
1663210299Sed        printFunctionHead(Fun);
1664193323Sed    }
1665210299Sed  }
1666193323Sed
1667210299Sed  // Print the global variable declarations for any variables encountered
1668210299Sed  nl(Out) << "// Global Variable Declarations"; nl(Out);
1669210299Sed  for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1670210299Sed       I != E; ++I) {
1671210299Sed    if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
1672210299Sed      printVariableHead(F);
1673210299Sed  }
1674193323Sed
1675218893Sdim  // Print the constants found
1676210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1677210299Sed  for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(),
1678210299Sed         E = consts.end(); I != E; ++I) {
1679210299Sed    printConstant(*I);
1680210299Sed  }
1681193323Sed
1682210299Sed  // Process the global variables definitions now that all the constants have
1683210299Sed  // been emitted. These definitions just couple the gvars with their constant
1684210299Sed  // initializers.
1685218893Sdim  if (GenerationType != GenFunction) {
1686218893Sdim    nl(Out) << "// Global Variable Definitions"; nl(Out);
1687218893Sdim    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
1688218893Sdim         I != E; ++I) {
1689218893Sdim      if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
1690218893Sdim        printVariableBody(GV);
1691218893Sdim    }
1692193323Sed  }
1693210299Sed}
1694193323Sed
1695210299Sedvoid CppWriter::printFunctionHead(const Function* F) {
1696210299Sed  nl(Out) << "Function* " << getCppName(F);
1697226633Sdim  Out << " = mod->getFunction(\"";
1698226633Sdim  printEscapedString(F->getName());
1699226633Sdim  Out << "\");";
1700226633Sdim  nl(Out) << "if (!" << getCppName(F) << ") {";
1701226633Sdim  nl(Out) << getCppName(F);
1702226633Sdim
1703210299Sed  Out<< " = Function::Create(";
1704210299Sed  nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
1705210299Sed  nl(Out) << "/*Linkage=*/";
1706210299Sed  printLinkageType(F->getLinkage());
1707210299Sed  Out << ",";
1708210299Sed  nl(Out) << "/*Name=*/\"";
1709210299Sed  printEscapedString(F->getName());
1710210299Sed  Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
1711210299Sed  nl(Out,-1);
1712210299Sed  printCppName(F);
1713210299Sed  Out << "->setCallingConv(";
1714210299Sed  printCallingConv(F->getCallingConv());
1715210299Sed  Out << ");";
1716210299Sed  nl(Out);
1717210299Sed  if (F->hasSection()) {
1718193323Sed    printCppName(F);
1719210299Sed    Out << "->setSection(\"" << F->getSection() << "\");";
1720210299Sed    nl(Out);
1721210299Sed  }
1722210299Sed  if (F->getAlignment()) {
1723210299Sed    printCppName(F);
1724210299Sed    Out << "->setAlignment(" << F->getAlignment() << ");";
1725210299Sed    nl(Out);
1726210299Sed  }
1727210299Sed  if (F->getVisibility() != GlobalValue::DefaultVisibility) {
1728210299Sed    printCppName(F);
1729210299Sed    Out << "->setVisibility(";
1730210299Sed    printVisibilityType(F->getVisibility());
1731193323Sed    Out << ");";
1732193323Sed    nl(Out);
1733210299Sed  }
1734210299Sed  if (F->hasGC()) {
1735193323Sed    printCppName(F);
1736210299Sed    Out << "->setGC(\"" << F->getGC() << "\");";
1737193323Sed    nl(Out);
1738193323Sed  }
1739226633Sdim  Out << "}";
1740226633Sdim  nl(Out);
1741210299Sed  printAttributes(F->getAttributes(), getCppName(F));
1742210299Sed  printCppName(F);
1743210299Sed  Out << "->setAttributes(" << getCppName(F) << "_PAL);";
1744210299Sed  nl(Out);
1745210299Sed}
1746193323Sed
1747210299Sedvoid CppWriter::printFunctionBody(const Function *F) {
1748210299Sed  if (F->isDeclaration())
1749210299Sed    return; // external functions have no bodies.
1750193323Sed
1751210299Sed  // Clear the DefinedValues and ForwardRefs maps because we can't have
1752210299Sed  // cross-function forward refs
1753210299Sed  ForwardRefs.clear();
1754210299Sed  DefinedValues.clear();
1755193323Sed
1756210299Sed  // Create all the argument values
1757210299Sed  if (!is_inline) {
1758210299Sed    if (!F->arg_empty()) {
1759210299Sed      Out << "Function::arg_iterator args = " << getCppName(F)
1760210299Sed          << "->arg_begin();";
1761210299Sed      nl(Out);
1762210299Sed    }
1763210299Sed    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1764210299Sed         AI != AE; ++AI) {
1765210299Sed      Out << "Value* " << getCppName(AI) << " = args++;";
1766210299Sed      nl(Out);
1767210299Sed      if (AI->hasName()) {
1768228379Sdim        Out << getCppName(AI) << "->setName(\"";
1769228379Sdim        printEscapedString(AI->getName());
1770228379Sdim        Out << "\");";
1771193323Sed        nl(Out);
1772193323Sed      }
1773193323Sed    }
1774210299Sed  }
1775193323Sed
1776210299Sed  // Create all the basic blocks
1777210299Sed  nl(Out);
1778210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1779210299Sed       BI != BE; ++BI) {
1780210299Sed    std::string bbname(getCppName(BI));
1781210299Sed    Out << "BasicBlock* " << bbname <<
1782210299Sed           " = BasicBlock::Create(mod->getContext(), \"";
1783210299Sed    if (BI->hasName())
1784210299Sed      printEscapedString(BI->getName());
1785210299Sed    Out << "\"," << getCppName(BI->getParent()) << ",0);";
1786193323Sed    nl(Out);
1787210299Sed  }
1788193323Sed
1789210299Sed  // Output all of its basic blocks... for the function
1790210299Sed  for (Function::const_iterator BI = F->begin(), BE = F->end();
1791210299Sed       BI != BE; ++BI) {
1792210299Sed    std::string bbname(getCppName(BI));
1793210299Sed    nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
1794210299Sed    nl(Out);
1795193323Sed
1796210299Sed    // Output all of the instructions in the basic block...
1797210299Sed    for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
1798210299Sed         I != E; ++I) {
1799210299Sed      printInstruction(I,bbname);
1800193323Sed    }
1801210299Sed  }
1802193323Sed
1803210299Sed  // Loop over the ForwardRefs and resolve them now that all instructions
1804210299Sed  // are generated.
1805210299Sed  if (!ForwardRefs.empty()) {
1806210299Sed    nl(Out) << "// Resolve Forward References";
1807210299Sed    nl(Out);
1808193323Sed  }
1809193323Sed
1810210299Sed  while (!ForwardRefs.empty()) {
1811210299Sed    ForwardRefMap::iterator I = ForwardRefs.begin();
1812210299Sed    Out << I->second << "->replaceAllUsesWith("
1813210299Sed        << getCppName(I->first) << "); delete " << I->second << ";";
1814193323Sed    nl(Out);
1815210299Sed    ForwardRefs.erase(I);
1816193323Sed  }
1817210299Sed}
1818193323Sed
1819210299Sedvoid CppWriter::printInline(const std::string& fname,
1820210299Sed                            const std::string& func) {
1821210299Sed  const Function* F = TheModule->getFunction(func);
1822210299Sed  if (!F) {
1823210299Sed    error(std::string("Function '") + func + "' not found in input module");
1824210299Sed    return;
1825210299Sed  }
1826210299Sed  if (F->isDeclaration()) {
1827210299Sed    error(std::string("Function '") + func + "' is external!");
1828210299Sed    return;
1829210299Sed  }
1830210299Sed  nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
1831210299Sed          << getCppName(F);
1832210299Sed  unsigned arg_count = 1;
1833210299Sed  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
1834210299Sed       AI != AE; ++AI) {
1835210299Sed    Out << ", Value* arg_" << arg_count;
1836210299Sed  }
1837210299Sed  Out << ") {";
1838210299Sed  nl(Out);
1839210299Sed  is_inline = true;
1840210299Sed  printFunctionUses(F);
1841210299Sed  printFunctionBody(F);
1842210299Sed  is_inline = false;
1843210299Sed  Out << "return " << getCppName(F->begin()) << ";";
1844210299Sed  nl(Out) << "}";
1845210299Sed  nl(Out);
1846210299Sed}
1847193323Sed
1848210299Sedvoid CppWriter::printModuleBody() {
1849210299Sed  // Print out all the type definitions
1850210299Sed  nl(Out) << "// Type Definitions"; nl(Out);
1851210299Sed  printTypes(TheModule);
1852193323Sed
1853210299Sed  // Functions can call each other and global variables can reference them so
1854210299Sed  // define all the functions first before emitting their function bodies.
1855210299Sed  nl(Out) << "// Function Declarations"; nl(Out);
1856210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1857210299Sed       I != E; ++I)
1858210299Sed    printFunctionHead(I);
1859193323Sed
1860210299Sed  // Process the global variables declarations. We can't initialze them until
1861210299Sed  // after the constants are printed so just print a header for each global
1862210299Sed  nl(Out) << "// Global Variable Declarations\n"; nl(Out);
1863210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1864210299Sed         E = TheModule->global_end(); I != E; ++I) {
1865210299Sed    printVariableHead(I);
1866210299Sed  }
1867193323Sed
1868210299Sed  // Print out all the constants definitions. Constants don't recurse except
1869210299Sed  // through GlobalValues. All GlobalValues have been declared at this point
1870210299Sed  // so we can proceed to generate the constants.
1871210299Sed  nl(Out) << "// Constant Definitions"; nl(Out);
1872210299Sed  printConstants(TheModule);
1873193323Sed
1874210299Sed  // Process the global variables definitions now that all the constants have
1875210299Sed  // been emitted. These definitions just couple the gvars with their constant
1876210299Sed  // initializers.
1877210299Sed  nl(Out) << "// Global Variable Definitions"; nl(Out);
1878210299Sed  for (Module::const_global_iterator I = TheModule->global_begin(),
1879210299Sed         E = TheModule->global_end(); I != E; ++I) {
1880210299Sed    printVariableBody(I);
1881193323Sed  }
1882193323Sed
1883210299Sed  // Finally, we can safely put out all of the function bodies.
1884210299Sed  nl(Out) << "// Function Definitions"; nl(Out);
1885210299Sed  for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
1886210299Sed       I != E; ++I) {
1887210299Sed    if (!I->isDeclaration()) {
1888210299Sed      nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
1889210299Sed              << ")";
1890210299Sed      nl(Out) << "{";
1891210299Sed      nl(Out,1);
1892210299Sed      printFunctionBody(I);
1893210299Sed      nl(Out,-1) << "}";
1894210299Sed      nl(Out);
1895210299Sed    }
1896193323Sed  }
1897210299Sed}
1898193323Sed
1899210299Sedvoid CppWriter::printProgram(const std::string& fname,
1900210299Sed                             const std::string& mName) {
1901210299Sed  Out << "#include <llvm/Pass.h>\n";
1902210299Sed  Out << "#include <llvm/PassManager.h>\n";
1903249423Sdim
1904210299Sed  Out << "#include <llvm/ADT/SmallVector.h>\n";
1905210299Sed  Out << "#include <llvm/Analysis/Verifier.h>\n";
1906210299Sed  Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
1907249423Sdim  Out << "#include <llvm/IR/BasicBlock.h>\n";
1908249423Sdim  Out << "#include <llvm/IR/CallingConv.h>\n";
1909249423Sdim  Out << "#include <llvm/IR/Constants.h>\n";
1910249423Sdim  Out << "#include <llvm/IR/DerivedTypes.h>\n";
1911249423Sdim  Out << "#include <llvm/IR/Function.h>\n";
1912249423Sdim  Out << "#include <llvm/IR/GlobalVariable.h>\n";
1913249423Sdim  Out << "#include <llvm/IR/InlineAsm.h>\n";
1914249423Sdim  Out << "#include <llvm/IR/Instructions.h>\n";
1915249423Sdim  Out << "#include <llvm/IR/LLVMContext.h>\n";
1916249423Sdim  Out << "#include <llvm/IR/Module.h>\n";
1917249423Sdim  Out << "#include <llvm/Support/FormattedStream.h>\n";
1918249423Sdim  Out << "#include <llvm/Support/MathExtras.h>\n";
1919210299Sed  Out << "#include <algorithm>\n";
1920210299Sed  Out << "using namespace llvm;\n\n";
1921210299Sed  Out << "Module* " << fname << "();\n\n";
1922210299Sed  Out << "int main(int argc, char**argv) {\n";
1923210299Sed  Out << "  Module* Mod = " << fname << "();\n";
1924210299Sed  Out << "  verifyModule(*Mod, PrintMessageAction);\n";
1925210299Sed  Out << "  PassManager PM;\n";
1926210299Sed  Out << "  PM.add(createPrintModulePass(&outs()));\n";
1927210299Sed  Out << "  PM.run(*Mod);\n";
1928210299Sed  Out << "  return 0;\n";
1929210299Sed  Out << "}\n\n";
1930210299Sed  printModule(fname,mName);
1931210299Sed}
1932193323Sed
1933210299Sedvoid CppWriter::printModule(const std::string& fname,
1934210299Sed                            const std::string& mName) {
1935210299Sed  nl(Out) << "Module* " << fname << "() {";
1936210299Sed  nl(Out,1) << "// Module Construction";
1937210299Sed  nl(Out) << "Module* mod = new Module(\"";
1938210299Sed  printEscapedString(mName);
1939210299Sed  Out << "\", getGlobalContext());";
1940210299Sed  if (!TheModule->getTargetTriple().empty()) {
1941210299Sed    nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
1942210299Sed  }
1943210299Sed  if (!TheModule->getTargetTriple().empty()) {
1944210299Sed    nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
1945210299Sed            << "\");";
1946210299Sed  }
1947193323Sed
1948210299Sed  if (!TheModule->getModuleInlineAsm().empty()) {
1949210299Sed    nl(Out) << "mod->setModuleInlineAsm(\"";
1950210299Sed    printEscapedString(TheModule->getModuleInlineAsm());
1951210299Sed    Out << "\");";
1952193323Sed  }
1953210299Sed  nl(Out);
1954193323Sed
1955210299Sed  printModuleBody();
1956210299Sed  nl(Out) << "return mod;";
1957210299Sed  nl(Out,-1) << "}";
1958210299Sed  nl(Out);
1959210299Sed}
1960193323Sed
1961210299Sedvoid CppWriter::printContents(const std::string& fname,
1962210299Sed                              const std::string& mName) {
1963210299Sed  Out << "\nModule* " << fname << "(Module *mod) {\n";
1964210299Sed  Out << "\nmod->setModuleIdentifier(\"";
1965210299Sed  printEscapedString(mName);
1966210299Sed  Out << "\");\n";
1967210299Sed  printModuleBody();
1968210299Sed  Out << "\nreturn mod;\n";
1969210299Sed  Out << "\n}\n";
1970210299Sed}
1971210299Sed
1972210299Sedvoid CppWriter::printFunction(const std::string& fname,
1973210299Sed                              const std::string& funcName) {
1974210299Sed  const Function* F = TheModule->getFunction(funcName);
1975210299Sed  if (!F) {
1976210299Sed    error(std::string("Function '") + funcName + "' not found in input module");
1977210299Sed    return;
1978193323Sed  }
1979210299Sed  Out << "\nFunction* " << fname << "(Module *mod) {\n";
1980210299Sed  printFunctionUses(F);
1981210299Sed  printFunctionHead(F);
1982210299Sed  printFunctionBody(F);
1983210299Sed  Out << "return " << getCppName(F) << ";\n";
1984210299Sed  Out << "}\n";
1985210299Sed}
1986193323Sed
1987210299Sedvoid CppWriter::printFunctions() {
1988210299Sed  const Module::FunctionListType &funcs = TheModule->getFunctionList();
1989210299Sed  Module::const_iterator I  = funcs.begin();
1990210299Sed  Module::const_iterator IE = funcs.end();
1991193323Sed
1992210299Sed  for (; I != IE; ++I) {
1993210299Sed    const Function &func = *I;
1994210299Sed    if (!func.isDeclaration()) {
1995210299Sed      std::string name("define_");
1996210299Sed      name += func.getName();
1997210299Sed      printFunction(name, func.getName());
1998193323Sed    }
1999193323Sed  }
2000210299Sed}
2001193323Sed
2002210299Sedvoid CppWriter::printVariable(const std::string& fname,
2003210299Sed                              const std::string& varName) {
2004210299Sed  const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
2005193323Sed
2006210299Sed  if (!GV) {
2007210299Sed    error(std::string("Variable '") + varName + "' not found in input module");
2008210299Sed    return;
2009193323Sed  }
2010210299Sed  Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
2011210299Sed  printVariableUses(GV);
2012210299Sed  printVariableHead(GV);
2013210299Sed  printVariableBody(GV);
2014210299Sed  Out << "return " << getCppName(GV) << ";\n";
2015210299Sed  Out << "}\n";
2016210299Sed}
2017193323Sed
2018224145Sdimvoid CppWriter::printType(const std::string &fname,
2019224145Sdim                          const std::string &typeName) {
2020226633Sdim  Type* Ty = TheModule->getTypeByName(typeName);
2021210299Sed  if (!Ty) {
2022210299Sed    error(std::string("Type '") + typeName + "' not found in input module");
2023210299Sed    return;
2024193323Sed  }
2025210299Sed  Out << "\nType* " << fname << "(Module *mod) {\n";
2026210299Sed  printType(Ty);
2027210299Sed  Out << "return " << getCppName(Ty) << ";\n";
2028210299Sed  Out << "}\n";
2029210299Sed}
2030193323Sed
2031210299Sedbool CppWriter::runOnModule(Module &M) {
2032210299Sed  TheModule = &M;
2033193323Sed
2034210299Sed  // Emit a header
2035210299Sed  Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
2036193323Sed
2037210299Sed  // Get the name of the function we're supposed to generate
2038210299Sed  std::string fname = FuncName.getValue();
2039193323Sed
2040210299Sed  // Get the name of the thing we are to generate
2041210299Sed  std::string tgtname = NameToGenerate.getValue();
2042210299Sed  if (GenerationType == GenModule ||
2043210299Sed      GenerationType == GenContents ||
2044210299Sed      GenerationType == GenProgram ||
2045210299Sed      GenerationType == GenFunctions) {
2046210299Sed    if (tgtname == "!bad!") {
2047210299Sed      if (M.getModuleIdentifier() == "-")
2048210299Sed        tgtname = "<stdin>";
2049210299Sed      else
2050210299Sed        tgtname = M.getModuleIdentifier();
2051193323Sed    }
2052210299Sed  } else if (tgtname == "!bad!")
2053210299Sed    error("You must use the -for option with -gen-{function,variable,type}");
2054193323Sed
2055210299Sed  switch (WhatToGenerate(GenerationType)) {
2056210299Sed   case GenProgram:
2057210299Sed    if (fname.empty())
2058210299Sed      fname = "makeLLVMModule";
2059210299Sed    printProgram(fname,tgtname);
2060210299Sed    break;
2061210299Sed   case GenModule:
2062210299Sed    if (fname.empty())
2063210299Sed      fname = "makeLLVMModule";
2064210299Sed    printModule(fname,tgtname);
2065210299Sed    break;
2066210299Sed   case GenContents:
2067210299Sed    if (fname.empty())
2068210299Sed      fname = "makeLLVMModuleContents";
2069210299Sed    printContents(fname,tgtname);
2070210299Sed    break;
2071210299Sed   case GenFunction:
2072210299Sed    if (fname.empty())
2073210299Sed      fname = "makeLLVMFunction";
2074210299Sed    printFunction(fname,tgtname);
2075210299Sed    break;
2076210299Sed   case GenFunctions:
2077210299Sed    printFunctions();
2078210299Sed    break;
2079210299Sed   case GenInline:
2080210299Sed    if (fname.empty())
2081210299Sed      fname = "makeLLVMInline";
2082210299Sed    printInline(fname,tgtname);
2083210299Sed    break;
2084210299Sed   case GenVariable:
2085210299Sed    if (fname.empty())
2086210299Sed      fname = "makeLLVMVariable";
2087210299Sed    printVariable(fname,tgtname);
2088210299Sed    break;
2089210299Sed   case GenType:
2090210299Sed    if (fname.empty())
2091210299Sed      fname = "makeLLVMType";
2092210299Sed    printType(fname,tgtname);
2093210299Sed    break;
2094193323Sed  }
2095210299Sed
2096210299Sed  return false;
2097193323Sed}
2098193323Sed
2099193323Sedchar CppWriter::ID = 0;
2100193323Sed
2101193323Sed//===----------------------------------------------------------------------===//
2102193323Sed//                       External Interface declaration
2103193323Sed//===----------------------------------------------------------------------===//
2104193323Sed
2105208599Srdivackybool CPPTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
2106208599Srdivacky                                           formatted_raw_ostream &o,
2107208599Srdivacky                                           CodeGenFileType FileType,
2108239462Sdim                                           bool DisableVerify,
2109239462Sdim                                           AnalysisID StartAfter,
2110239462Sdim                                           AnalysisID StopAfter) {
2111203954Srdivacky  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
2112193323Sed  PM.add(new CppWriter(o));
2113193323Sed  return false;
2114193323Sed}
2115