CPPBackend.cpp revision 1a53eadbffb089de517071e575152c0cbe39b7c9
15027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===-- CPPBackend.cpp - Library for converting LLVM code to C++ code -----===//
25027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//
35027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//                     The LLVM Compiler Infrastructure
45027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//
55027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
65027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov// License. See LICENSE.TXT for details.
75027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//
85027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
95027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//
105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov// This file implements the writing of the LLVM IR as a set of C++ calls to the
115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov// LLVM IR interface. The input module is assumed to be verified.
125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//
135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "CPPTargetMachine.h"
165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/CallingConv.h"
175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Constants.h"
185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/DerivedTypes.h"
195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/InlineAsm.h"
205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Instruction.h"
215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Instructions.h"
225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Module.h"
235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Pass.h"
245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/PassManager.h"
255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/TypeSymbolTable.h"
265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Target/TargetMachineRegistry.h"
275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/ADT/StringExtras.h"
285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/ADT/STLExtras.h"
295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/ADT/SmallPtrSet.h"
305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Support/CommandLine.h"
311a53eadbffb089de517071e575152c0cbe39b7c9Bill Wendling#include "llvm/Support/Streams.h"
325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Config/config.h"
335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include <algorithm>
345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include <set>
355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovusing namespace llvm;
375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovstatic cl::opt<std::string>
398d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton KorobeynikovFuncName("cppfname", cl::desc("Specify the name of the generated function"),
405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         cl::value_desc("function name"));
415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovenum WhatToGenerate {
435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenProgram,
445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenModule,
455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenContents,
465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenFunction,
475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenFunctions,
485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenInline,
495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenVariable,
505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenType
515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov};
525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
538d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikovstatic cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::desc("Choose what kind of output to generate"),
555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::init(GenProgram),
565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::values(
578d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenProgram,  "program",   "Generate a complete program"),
588d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenModule,   "module",    "Generate a module definition"),
598d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenContents, "contents",  "Generate contents of a module"),
608d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenFunction, "function",  "Generate a function definition"),
618d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
628d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenInline,   "inline",    "Generate an inline function"),
638d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenVariable, "variable",  "Generate a variable definition"),
648d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenType,     "type",      "Generate a type definition"),
655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    clEnumValEnd
665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  )
675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov);
685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
698d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikovstatic cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::desc("Specify the name of the thing to generate"),
715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::init("!bad!"));
725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
73844731a7f1909f55935e3514c9e713a62d67662eDan Gohman// Register the target.
74844731a7f1909f55935e3514c9e713a62d67662eDan Gohmanstatic RegisterTarget<CPPTargetMachine> X("cpp", "  C++ backend");
755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
76844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace {
775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::vector<const Type*> TypeList;
785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Type*,std::string> TypeMap;
795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Value*,std::string> ValueMap;
805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<std::string> NameSet;
815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<const Type*> TypeSet;
825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<const Value*> ValueSet;
835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Value*,std::string> ForwardRefMap;
845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  /// CppWriter - This class is the main chunk of code that converts an LLVM
865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  /// module to a C++ translation unit.
875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  class CppWriter : public ModulePass {
885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const char* progname;
895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::ostream &Out;
905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Module *TheModule;
915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    uint64_t uniqueNum;
925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap TypeNames;
935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ValueMap ValueNames;
945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap UnresolvedTypes;
955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeList TypeStack;
965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    NameSet UsedNames;
975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeSet DefinedTypes;
985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ValueSet DefinedValues;
995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefMap ForwardRefs;
1005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    bool is_inline;
1015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  public:
1035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    static char ID;
104966e7997b5690ac5799e0b67fe216e4c81e1357bAnton Korobeynikov    explicit CppWriter(std::ostream &o) :
105966e7997b5690ac5799e0b67fe216e4c81e1357bAnton Korobeynikov      ModulePass((intptr_t)&ID), Out(o), uniqueNum(0), is_inline(false) {}
1065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    virtual const char *getPassName() const { return "C++ backend"; }
1085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    bool runOnModule(Module &M);
1105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printProgram(const std::string& fname, const std::string& modName );
1125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printModule(const std::string& fname, const std::string& modName );
1135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printContents(const std::string& fname, const std::string& modName );
1145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printFunction(const std::string& fname, const std::string& funcName );
1155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printFunctions();
1165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printInline(const std::string& fname, const std::string& funcName );
1175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printVariable(const std::string& fname, const std::string& varName );
1185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printType(const std::string& fname, const std::string& typeName );
1195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void error(const std::string& msg);
1215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  private:
1235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printLinkageType(GlobalValue::LinkageTypes LT);
1245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
1255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printCallingConv(unsigned cc);
1265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printEscapedString(const std::string& str);
1275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printCFP(const ConstantFP* CFP);
1285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string getCppName(const Type* val);
1305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    inline void printCppName(const Type* val);
1315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string getCppName(const Value* val);
1335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    inline void printCppName(const Value* val);
1345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printParamAttrs(const PAListPtr &PAL, const std::string &name);
1365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    bool printTypeInternal(const Type* Ty);
1375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    inline void printType(const Type* Ty);
1385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printTypes(const Module* M);
1395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printConstant(const Constant *CPV);
1415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printConstants(const Module* M);
1425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printVariableUses(const GlobalVariable *GV);
1445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printVariableHead(const GlobalVariable *GV);
1455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printVariableBody(const GlobalVariable *GV);
1465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printFunctionUses(const Function *F);
1485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printFunctionHead(const Function *F);
1495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printFunctionBody(const Function *F);
1505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printInstruction(const Instruction *I, const std::string& bbname);
1515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string getOpName(Value*);
1525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    void printModuleBody();
1545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  };
1555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  static unsigned indent_level = 0;
1575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline std::ostream& nl(std::ostream& Out, int delta = 0) {
1585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\n";
1595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (delta >= 0 || indent_level >= unsigned(-delta))
1605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      indent_level += delta;
1615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (unsigned i = 0; i < indent_level; ++i)
1625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "  ";
1635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return Out;
1645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
1655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline void in() { indent_level++; }
1675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline void out() { if (indent_level >0) indent_level--; }
1685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline void
1705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  sanitize(std::string& str) {
1715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (size_t i = 0; i < str.length(); ++i)
1725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!isalnum(str[i]) && str[i] != '_')
1735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        str[i] = '_';
1745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
1755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline std::string
1775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  getTypePrefix(const Type* Ty ) {
1785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (Ty->getTypeID()) {
1795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VoidTyID:     return "void_";
1805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::IntegerTyID:
1815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return std::string("int") + utostr(cast<IntegerType>(Ty)->getBitWidth()) +
1825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        "_";
1835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FloatTyID:    return "float_";
1845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::DoubleTyID:   return "double_";
1855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::LabelTyID:    return "label_";
1865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FunctionTyID: return "func_";
1875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::StructTyID:   return "struct_";
1885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::ArrayTyID:    return "array_";
1895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::PointerTyID:  return "ptr_";
1905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VectorTyID:   return "packed_";
1915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::OpaqueTyID:   return "opaque_";
1925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:                 return "other_";
1935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
1945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return "unknown_";
1955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
1965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
1975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Looks up the type in the symbol table and returns a pointer to its name or
1985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // a null pointer if it wasn't found. Note that this isn't the same as the
1995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Mode::getTypeName function which will return an empty string, not a null
2005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // pointer if the name is not found.
2015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  inline const std::string*
2025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  findTypeName(const TypeSymbolTable& ST, const Type* Ty) {
2035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeSymbolTable::const_iterator TI = ST.begin();
2045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeSymbolTable::const_iterator TE = ST.end();
2055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (;TI != TE; ++TI)
2065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (TI->second == Ty)
2075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        return &(TI->first);
2085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return 0;
2095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::error(const std::string& msg) {
2121a53eadbffb089de517071e575152c0cbe39b7c9Bill Wendling    cerr << progname << ": " << msg << "\n";
2135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    exit(2);
2145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printCFP - Print a floating point constant .. very carefully :)
2175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // This makes sure that conversion to/from floating yields the same binary
2185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // result so that we don't lose precision.
2195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCFP(const ConstantFP *CFP) {
2205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    APFloat APF = APFloat(CFP->getValueAPF());  // copy
2215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (CFP->getType() == Type::FloatTy)
2225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
2235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "ConstantFP::get(";
2245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "APFloat(";
2255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#if HAVE_PRINTF_A
2265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    char Buffer[100];
2275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    sprintf(Buffer, "%A", APF.convertToDouble());
2285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if ((!strncmp(Buffer, "0x", 2) ||
2295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         !strncmp(Buffer, "-0x", 3) ||
2305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         !strncmp(Buffer, "+0x", 3)) &&
2315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
2325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (CFP->getType() == Type::DoubleTy)
2335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "BitsToDouble(" << Buffer << ")";
2345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else
2355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "BitsToFloat((float)" << Buffer << ")";
2365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ")";
2375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else {
2385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#endif
2395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string StrVal = ftostr(CFP->getValueAPF());
2405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      while (StrVal[0] == ' ')
2425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        StrVal.erase(StrVal.begin());
2435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Check to make sure that the stringized number is not some string like
2455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // "Inf" or NaN.  Check that the string matches the "[-+]?[0-9]" regex.
2465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
2475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           ((StrVal[0] == '-' || StrVal[0] == '+') &&
2485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
2495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          (CFP->isExactlyValue(atof(StrVal.c_str())))) {
2505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (CFP->getType() == Type::DoubleTy)
2515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out <<  StrVal;
2525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
2535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << StrVal << "f";
2545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (CFP->getType() == Type::DoubleTy)
2555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "BitsToDouble(0x" << std::hex
2565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << CFP->getValueAPF().convertToAPInt().getZExtValue()
2575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << std::dec << "ULL) /* " << StrVal << " */";
2585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else
2595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "BitsToFloat(0x" << std::hex
2605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (uint32_t)CFP->getValueAPF().convertToAPInt().getZExtValue()
2615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << std::dec << "U) /* " << StrVal << " */";
2625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ")";
2635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#if HAVE_PRINTF_A
2645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
2655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#endif
2665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ")";
2675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCallingConv(unsigned cc){
2705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the calling convention.
2715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (cc) {
2725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::C:     Out << "CallingConv::C"; break;
2735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
2745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
2755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
2765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:                 Out << cc; break;
2775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
2785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
2815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (LT) {
2825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::InternalLinkage:
2835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::InternalLinkage"; break;
2845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::LinkOnceLinkage:
2855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::LinkOnceLinkage "; break;
2865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::WeakLinkage:
2875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::WeakLinkage"; break;
2885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::AppendingLinkage:
2895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::AppendingLinkage"; break;
2905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::ExternalLinkage:
2915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::ExternalLinkage"; break;
2925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DLLImportLinkage:
2935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DLLImportLinkage"; break;
2945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DLLExportLinkage:
2955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DLLExportLinkage"; break;
2965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::ExternalWeakLinkage:
2975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::ExternalWeakLinkage"; break;
2985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::GhostLinkage:
2995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::GhostLinkage"; break;
300aafce77b17d340aace52bcd49d1944109d82f14aDale Johannesen    case GlobalValue::CommonLinkage:
301aafce77b17d340aace52bcd49d1944109d82f14aDale Johannesen      Out << "GlobalValue::CommonLinkage"; break;
3025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
3065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (VisType) {
3075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default: assert(0 && "Unknown GVar visibility");
3085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DefaultVisibility:
3095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DefaultVisibility";
3105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::HiddenVisibility:
3125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::HiddenVisibility";
3135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::ProtectedVisibility:
3155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::ProtectedVisibility";
3165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printEscapedString - Print each character of the specified string, escaping
3215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // it if it is not printable or if it is an escape char.
3225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printEscapedString(const std::string &Str) {
3235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
3245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned char C = Str[i];
3255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (isprint(C) && C != '"' && C != '\\') {
3265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << C;
3275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
3285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "\\x"
3295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
3305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
3315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
3325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getCppName(const Type* Ty) {
3365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // First, handle the primitive types .. easy
3375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (Ty->isPrimitiveType() || Ty->isInteger()) {
3385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (Ty->getTypeID()) {
3395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::VoidTyID:   return "Type::VoidTy";
3405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::IntegerTyID: {
3415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
3425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        return "IntegerType::get(" + utostr(BitWidth) + ")";
3435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
3445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::FloatTyID:  return "Type::FloatTy";
3455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::DoubleTyID: return "Type::DoubleTy";
3465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::LabelTyID:  return "Type::LabelTy";
3475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default:
3485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        error("Invalid primitive type");
3495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        break;
3505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
3515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return "Type::VoidTy"; // shouldn't be returned, but make it sensible
3525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Now, see if we've seen the type before and return that
3555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap::iterator I = TypeNames.find(Ty);
3565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != TypeNames.end())
3575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return I->second;
3585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Okay, let's build a new name for this type. Start with a prefix
3605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const char* prefix = 0;
3615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (Ty->getTypeID()) {
3625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FunctionTyID:    prefix = "FuncTy_"; break;
3635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::StructTyID:      prefix = "StructTy_"; break;
3645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
3655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::PointerTyID:     prefix = "PointerTy_"; break;
3665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::OpaqueTyID:      prefix = "OpaqueTy_"; break;
3675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VectorTyID:      prefix = "VectorTy_"; break;
3685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:                    prefix = "OtherTy_"; break; // prevent breakage
3695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // See if the type has a name in the symboltable and build accordingly
3725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty);
3735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string name;
3745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (tName)
3755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string(prefix) + *tName;
3765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    else
3775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string(prefix) + utostr(uniqueNum++);
3785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    sanitize(name);
3795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Save the name
3815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return TypeNames[Ty] = name;
3825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCppName(const Type* Ty) {
3855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(getCppName(Ty));
3865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getCppName(const Value* val) {
3895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string name;
3905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ValueMap::iterator I = ValueNames.find(val);
3915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != ValueNames.end() && I->first == val)
3925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return  I->second;
3935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
3955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("gvar_") +
3965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        getTypePrefix(GV->getType()->getElementType());
3975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<Function>(val)) {
3985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("func_");
3995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const Constant* C = dyn_cast<Constant>(val)) {
4005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("const_") + getTypePrefix(C->getType());
4015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
4025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (is_inline) {
4035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
4045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                        Function::const_arg_iterator(Arg)) + 1;
4055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name = std::string("arg_") + utostr(argNum);
4065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        NameSet::iterator NI = UsedNames.find(name);
4075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (NI != UsedNames.end())
4085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          name += std::string("_") + utostr(uniqueNum++);
4095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        UsedNames.insert(name);
4105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        return ValueNames[val] = name;
4115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
4125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name = getTypePrefix(val->getType());
4135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
4145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else {
4155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = getTypePrefix(val->getType());
4165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
4175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    name += (val->hasName() ? val->getName() : utostr(uniqueNum++));
4185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    sanitize(name);
4195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    NameSet::iterator NI = UsedNames.find(name);
4205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (NI != UsedNames.end())
4215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name += std::string("_") + utostr(uniqueNum++);
4225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    UsedNames.insert(name);
4235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return ValueNames[val] = name;
4245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCppName(const Value* val) {
4275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(getCppName(val));
4285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printParamAttrs(const PAListPtr &PAL,
4315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                  const std::string &name) {
4329474ede38b7f991347c48b467397c88cbe99c163Nicolas Geoffray    Out << "PAListPtr " << name << "_PAL;";
4335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
4345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!PAL.isEmpty()) {
4355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << '{'; in(); nl(Out);
4365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "SmallVector<ParamAttrsWithIndex, 4> Attrs;"; nl(Out);
4375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
4385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
4395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        uint16_t index = PAL.getSlot(i).Index;
4405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        ParameterAttributes attrs = PAL.getSlot(i).Attrs;
4419474ede38b7f991347c48b467397c88cbe99c163Nicolas Geoffray        Out << "PAWI.Index = " << index << "; PAWI.Attrs = 0 ";
4425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::SExt)
4435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::SExt";
4445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::ZExt)
4455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::ZExt";
4465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::StructRet)
4475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::StructRet";
4485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::InReg)
4495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::InReg";
4505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::NoReturn)
4515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::NoReturn";
4525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::NoUnwind)
4535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::NoUnwind";
4545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::ByVal)
4555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::ByVal";
4565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::NoAlias)
4575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::NoAlias";
4585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::Nest)
4595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::Nest";
4605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::ReadNone)
4615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::ReadNone";
4625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (attrs & ParamAttr::ReadOnly)
4635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << " | ParamAttr::ReadOnly";
4645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ";";
4655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
4665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Attrs.push_back(PAWI);";
4675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
4685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
4695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << name << "_PAL = PAListPtr::get(Attrs.begin(), Attrs.end());";
4705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
4715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out(); nl(Out);
4725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << '}'; nl(Out);
4735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
4745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  bool CppWriter::printTypeInternal(const Type* Ty) {
4775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We don't print definitions for primitive types
4785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (Ty->isPrimitiveType() || Ty->isInteger())
4795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return false;
4805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // If we already defined this type, we don't need to define it again.
4825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (DefinedTypes.find(Ty) != DefinedTypes.end())
4835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return false;
4845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Everything below needs the name for the type so get it now.
4865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string typeName(getCppName(Ty));
4875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Search the type stack for recursion. If we find it, then generate this
4895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // as an OpaqueType, but make sure not to do this multiple times because
4905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // the type could appear in multiple places on the stack. Once the opaque
4915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // definition is issued, it must not be re-issued. Consequently we have to
4925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // check the UnresolvedTypes list as well.
4935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeList::const_iterator TI = std::find(TypeStack.begin(), TypeStack.end(),
4945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                            Ty);
4955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (TI != TypeStack.end()) {
4965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
4975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I == UnresolvedTypes.end()) {
4985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();";
4995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        UnresolvedTypes[Ty] = typeName;
5015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return true;
5035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We're going to print a derived type which, by definition, contains other
5065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // types. So, push this one we're printing onto the type stack to assist with
5075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // recursive definitions.
5085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.push_back(Ty);
5095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the type definition
5115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (Ty->getTypeID()) {
5125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FunctionTyID:  {
5135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const FunctionType* FT = cast<FunctionType>(Ty);
5145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<const Type*>" << typeName << "_args;";
5155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      FunctionType::param_iterator PI = FT->param_begin();
5175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      FunctionType::param_iterator PE = FT->param_end();
5185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (; PI != PE; ++PI) {
5195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        const Type* argTy = static_cast<const Type*>(*PI);
5205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool isForward = printTypeInternal(argTy);
5215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string argName(getCppName(argTy));
5225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << typeName << "_args.push_back(" << argName;
5235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (isForward)
5245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "_fwd";
5255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
5265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(FT->getReturnType());
5295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string retTypeName(getCppName(FT->getReturnType()));
5305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "FunctionType* " << typeName << " = FunctionType::get(";
5315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      in(); nl(Out) << "/*Result=*/" << retTypeName;
5325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (isForward)
5335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "_fwd";
5345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ",";
5355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "/*Params=*/" << typeName << "_args,";
5365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
5375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out();
5385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::StructTyID: {
5425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const StructType* ST = cast<StructType>(Ty);
5435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<const Type*>" << typeName << "_fields;";
5445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      StructType::element_iterator EI = ST->element_begin();
5465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      StructType::element_iterator EE = ST->element_end();
5475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (; EI != EE; ++EI) {
5485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        const Type* fieldTy = static_cast<const Type*>(*EI);
5495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool isForward = printTypeInternal(fieldTy);
5505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string fieldName(getCppName(fieldTy));
5515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << typeName << "_fields.push_back(" << fieldName;
5525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (isForward)
5535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "_fwd";
5545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
5555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "StructType* " << typeName << " = StructType::get("
5585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << "_fields, /*isPacked=*/"
5595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (ST->isPacked() ? "true" : "false") << ");";
5605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::ArrayTyID: {
5645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ArrayType* AT = cast<ArrayType>(Ty);
5655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = AT->getElementType();
5665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
5675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
5685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ArrayType* " << typeName << " = ArrayType::get("
5695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
5705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(AT->getNumElements()) << ");";
5715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::PointerTyID: {
5755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const PointerType* PT = cast<PointerType>(Ty);
5765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = PT->getElementType();
5775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
5785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
5795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "PointerType* " << typeName << " = PointerType::get("
5805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
5815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(PT->getAddressSpace()) << ");";
5825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VectorTyID: {
5865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const VectorType* PT = cast<VectorType>(Ty);
5875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = PT->getElementType();
5885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
5895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
5905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "VectorType* " << typeName << " = VectorType::get("
5915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
5925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(PT->getNumElements()) << ");";
5935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::OpaqueTyID: {
5975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "OpaqueType* " << typeName << " = OpaqueType::get();";
5985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
6005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:
6025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Invalid TypeID");
6035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // If the type had a name, make sure we recreate it.
6065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const std::string* progTypeName =
6075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      findTypeName(TheModule->getTypeSymbolTable(),Ty);
6085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (progTypeName) {
6095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "mod->addTypeName(\"" << *progTypeName << "\", "
6105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ");";
6115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Pop us off the type stack
6155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.pop_back();
6165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Indicate that this type is now defined.
6185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    DefinedTypes.insert(Ty);
6195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Early resolve as many unresolved types as possible. Search the unresolved
6215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // types map for the type we just printed. Now that its definition is complete
6225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // we can resolve any previous references to it. This prevents a cascade of
6235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // unresolved types.
6245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap::iterator I = UnresolvedTypes.find(Ty);
6255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != UnresolvedTypes.end()) {
6265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "cast<OpaqueType>(" << I->second
6275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");";
6285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << I->second << " = cast<";
6305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (Ty->getTypeID()) {
6315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::FunctionTyID: Out << "FunctionType"; break;
6325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::ArrayTyID:    Out << "ArrayType"; break;
6335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::StructTyID:   Out << "StructType"; break;
6345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::VectorTyID:   Out << "VectorType"; break;
6355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::PointerTyID:  Out << "PointerType"; break;
6365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::OpaqueTyID:   Out << "OpaqueType"; break;
6375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default:                 Out << "NoSuchDerivedType"; break;
6385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
6395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ">(" << I->second << "_fwd.get());";
6405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out); nl(Out);
6415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      UnresolvedTypes.erase(I);
6425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Finally, separate the type definition from other with a newline.
6455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
6465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We weren't a recursive type
6485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return false;
6495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
6505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Prints a type definition. Returns true if it could not resolve all the
6525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // types in the definition but had to use a forward reference.
6535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printType(const Type* Ty) {
6545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    assert(TypeStack.empty());
6555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.clear();
6565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printTypeInternal(Ty);
6575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    assert(TypeStack.empty());
6585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
6595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printTypes(const Module* M) {
6615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Walk the symbol table and print out all its types
6625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const TypeSymbolTable& symtab = M->getTypeSymbolTable();
6635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end();
6645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         TI != TE; ++TI) {
6655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // For primitive types and types already defined, just add a name
6675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      TypeMap::const_iterator TNI = TypeNames.find(TI->second);
6685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (TI->second->isInteger() || TI->second->isPrimitiveType() ||
6695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          TNI != TypeNames.end()) {
6705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "mod->addTypeName(\"";
6715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(TI->first);
6725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "\", " << getCppName(TI->second) << ");";
6735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
6745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // For everything else, define the type
6755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
6765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(TI->second);
6775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
6785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Add all of the global variables to the value table...
6815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
6825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
6835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I->hasInitializer())
6845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(I->getInitializer()->getType());
6855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(I->getType());
6865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Add all the functions to the table
6895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
6905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         FI != FE; ++FI) {
6915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(FI->getReturnType());
6925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(FI->getFunctionType());
6935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all the function arguments
6945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = FI->arg_begin(),
6955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             AE = FI->arg_end(); AI != AE; ++AI) {
6965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(AI->getType());
6975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
6985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all of the basic blocks and instructions
7005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_iterator BB = FI->begin(),
7015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             E = FI->end(); BB != E; ++BB) {
7025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(BB->getType());
7035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
7045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             ++I) {
7055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printType(I->getType());
7065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          for (unsigned i = 0; i < I->getNumOperands(); ++i)
7075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            printType(I->getOperand(i)->getType());
7085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
7115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
7125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printConstant - Print out a constant pool entry...
7155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printConstant(const Constant *CV) {
7165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // First, if the constant is actually a GlobalValue (variable or function)
7175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // or its already in the constant list then we've printed it already and we
7185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // can just return.
7195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
7205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
7215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string constName(getCppName(CV));
7235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string typeName(getCppName(CV->getType()));
7245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (CV->isNullValue()) {
7255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = Constant::getNullValue("
7265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ");";
7275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
7285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
7295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
7305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (isa<GlobalValue>(CV)) {
7315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Skip variables and functions, we emit them elsewhere
7325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
7335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
7345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
7355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt("
7365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << cast<IntegerType>(CI->getType())->getBitWidth() << ", "
7375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " \"" << CI->getValue().toStringSigned(10)  << "\", 10));";
7385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<ConstantAggregateZero>(CV)) {
7395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantAggregateZero* " << constName
7405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = ConstantAggregateZero::get(" << typeName << ");";
7415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<ConstantPointerNull>(CV)) {
7425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantPointerNull* " << constName
7435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = ConstanPointerNull::get(" << typeName << ");";
7445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
7455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantFP* " << constName << " = ";
7465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCFP(CFP);
7475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ";";
7485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
7495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (CA->isString() && CA->getType()->getElementType() == Type::Int8Ty) {
7505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantArray::get(\"";
7515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string tmp = CA->getAsString();
7525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool nullTerminate = false;
7535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (tmp[tmp.length()-1] == 0) {
7545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tmp.erase(tmp.length()-1);
7555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nullTerminate = true;
7565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(tmp);
7585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Determine if we want null termination or not.
7595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (nullTerminate)
7605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "\", true"; // Indicate that the null terminator should be
7615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                             // added.
7625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
7635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "\", false";// No null terminator
7645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
7655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
7665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Constant*> " << constName << "_elems;";
7675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
7685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned N = CA->getNumOperands();
7695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < N; ++i) {
7705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CA->getOperand(i)); // recurse to print operands
7715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << constName << "_elems.push_back("
7725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << getCppName(CA->getOperand(i)) << ");";
7735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
7745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantArray::get("
7765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << typeName << ", " << constName << "_elems);";
7775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
7795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Constant*> " << constName << "_fields;";
7805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
7815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned N = CS->getNumOperands();
7825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < N; i++) {
7835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CS->getOperand(i));
7845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << constName << "_fields.push_back("
7855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CS->getOperand(i)) << ");";
7865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
7875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = ConstantStruct::get("
7895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ", " << constName << "_fields);";
7905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
7915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Constant*> " << constName << "_elems;";
7925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
7935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned N = CP->getNumOperands();
7945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < N; ++i) {
7955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CP->getOperand(i));
7965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << constName << "_elems.push_back("
7975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CP->getOperand(i)) << ");";
7985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
7995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
8005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = ConstantVector::get("
8015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ", " << constName << "_elems);";
8025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<UndefValue>(CV)) {
8035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "UndefValue* " << constName << " = UndefValue::get("
8045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ");";
8055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
8065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (CE->getOpcode() == Instruction::GetElementPtr) {
8075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Constant*> " << constName << "_indices;";
8085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
8095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CE->getOperand(0));
8105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
8115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CE->getOperand(i));
8125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << constName << "_indices.push_back("
8135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << getCppName(CE->getOperand(i)) << ");";
8145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
8155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName
8175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << " = ConstantExpr::getGetElementPtr("
8185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CE->getOperand(0)) << ", "
8195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << "&" << constName << "_indices[0], "
8205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << constName << "_indices.size()"
8215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << " );";
8225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (CE->isCast()) {
8235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CE->getOperand(0));
8245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantExpr::getCast(";
8255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        switch (CE->getOpcode()) {
8265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        default: assert(0 && "Invalid cast opcode");
8275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Trunc: Out << "Instruction::Trunc"; break;
8285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ZExt:  Out << "Instruction::ZExt"; break;
8295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SExt:  Out << "Instruction::SExt"; break;
8305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPTrunc:  Out << "Instruction::FPTrunc"; break;
8315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPExt:  Out << "Instruction::FPExt"; break;
8325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPToUI:  Out << "Instruction::FPToUI"; break;
8335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPToSI:  Out << "Instruction::FPToSI"; break;
8345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::UIToFP:  Out << "Instruction::UIToFP"; break;
8355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SIToFP:  Out << "Instruction::SIToFP"; break;
8365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::PtrToInt:  Out << "Instruction::PtrToInt"; break;
8375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::IntToPtr:  Out << "Instruction::IntToPtr"; break;
8385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::BitCast:  Out << "Instruction::BitCast"; break;
8395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ", " << getCppName(CE->getOperand(0)) << ", "
8415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CE->getType()) << ");";
8425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
8435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned N = CE->getNumOperands();
8445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < N; ++i ) {
8455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CE->getOperand(i));
8465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantExpr::";
8485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        switch (CE->getOpcode()) {
8495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Add:    Out << "getAdd(";  break;
8505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Sub:    Out << "getSub("; break;
8515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Mul:    Out << "getMul("; break;
8525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::UDiv:   Out << "getUDiv("; break;
8535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SDiv:   Out << "getSDiv("; break;
8545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FDiv:   Out << "getFDiv("; break;
8555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::URem:   Out << "getURem("; break;
8565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SRem:   Out << "getSRem("; break;
8575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FRem:   Out << "getFRem("; break;
8585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::And:    Out << "getAnd("; break;
8595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Or:     Out << "getOr("; break;
8605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Xor:    Out << "getXor("; break;
8615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ICmp:
8625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "getICmp(ICmpInst::ICMP_";
8635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          switch (CE->getPredicate()) {
8645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_EQ:  Out << "EQ"; break;
8655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_NE:  Out << "NE"; break;
8665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SLT: Out << "SLT"; break;
8675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_ULT: Out << "ULT"; break;
8685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SGT: Out << "SGT"; break;
8695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_UGT: Out << "UGT"; break;
8705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SLE: Out << "SLE"; break;
8715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_ULE: Out << "ULE"; break;
8725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SGE: Out << "SGE"; break;
8735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_UGE: Out << "UGE"; break;
8745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          default: error("Invalid ICmp Predicate");
8755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
8765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
8775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FCmp:
8785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "getFCmp(FCmpInst::FCMP_";
8795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          switch (CE->getPredicate()) {
8805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
8815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ORD:   Out << "ORD"; break;
8825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UNO:   Out << "UNO"; break;
8835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OEQ:   Out << "OEQ"; break;
8845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UEQ:   Out << "UEQ"; break;
8855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ONE:   Out << "ONE"; break;
8865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UNE:   Out << "UNE"; break;
8875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OLT:   Out << "OLT"; break;
8885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ULT:   Out << "ULT"; break;
8895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OGT:   Out << "OGT"; break;
8905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UGT:   Out << "UGT"; break;
8915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OLE:   Out << "OLE"; break;
8925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ULE:   Out << "ULE"; break;
8935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OGE:   Out << "OGE"; break;
8945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UGE:   Out << "UGE"; break;
8955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_TRUE:  Out << "TRUE"; break;
8965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          default: error("Invalid FCmp Predicate");
8975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
8985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
8995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Shl:     Out << "getShl("; break;
9005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::LShr:    Out << "getLShr("; break;
9015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::AShr:    Out << "getAShr("; break;
9025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Select:  Out << "getSelect("; break;
9035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ExtractElement: Out << "getExtractElement("; break;
9045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::InsertElement:  Out << "getInsertElement("; break;
9055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ShuffleVector:  Out << "getShuffleVector("; break;
9065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        default:
9075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          error("Invalid constant expression");
9085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
9095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
9105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << getCppName(CE->getOperand(0));
9115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < CE->getNumOperands(); ++i)
9125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << ", " << getCppName(CE->getOperand(i));
9135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
9145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else {
9165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Bad Constant");
9175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = 0; ";
9185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
9205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printConstants(const Module* M) {
9235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Traverse all the global variables looking for constant initializers
9245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
9255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I)
9265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I->hasInitializer())
9275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(I->getInitializer());
9285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Traverse the LLVM functions looking for constants
9305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
9315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         FI != FE; ++FI) {
9325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all of the basic blocks and instructions
9335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_iterator BB = FI->begin(),
9345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             E = FI->end(); BB != E; ++BB) {
9355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
9365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             ++I) {
9375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          for (unsigned i = 0; i < I->getNumOperands(); ++i) {
9385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
9395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              printConstant(C);
9405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            }
9415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
9425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
9435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableUses(const GlobalVariable *GV) {
9485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions";
9495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
9505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printType(GV->getType());
9515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
9525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Constant* Init = GV->getInitializer();
9535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(Init->getType());
9545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (Function* F = dyn_cast<Function>(Init)) {
9555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out)<< "/ Function Declarations"; nl(Out);
9565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunctionHead(F);
9575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
9585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Global Variable Declarations"; nl(Out);
9595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableHead(gv);
9605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else  {
9615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Constant Definitions"; nl(Out);
9625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(gv);
9635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
9655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Global Variable Definitions"; nl(Out);
9665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableBody(gv);
9675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableHead(const GlobalVariable *GV) {
9725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "GlobalVariable* " << getCppName(GV);
9735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
9745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << " = mod->getGlobalVariable(";
9755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(GV->getName());
9765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
9775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "if (!" << getCppName(GV) << ") {";
9785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      in(); nl(Out) << getCppName(GV);
9795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << " = new GlobalVariable(";
9815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Type=*/";
9825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(GV->getType()->getElementType());
9835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
9845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
9855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
9865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Linkage=*/";
9875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printLinkageType(GV->getLinkage());
9885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
9895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Initializer=*/0, ";
9905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
9915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "// has initializer, specified below";
9925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Name=*/\"";
9945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(GV->getName());
9955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\",";
9965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "mod);";
9975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
9985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasSection()) {
10005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setSection(\"";
10025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(GV->getSection());
10035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\");";
10045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->getAlignment()) {
10075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
10095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
10125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setVisibility(";
10145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVisibilityType(GV->getVisibility());
10155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
10165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
10195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out(); Out << "}"; nl(Out);
10205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableBody(const GlobalVariable *GV) {
10245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
10255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setInitializer(";
10275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << getCppName(GV->getInitializer()) << ");";
10285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getOpName(Value* V) {
10335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
10345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return getCppName(V);
10355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // See if its alread in the map of forward references, if so just return the
10375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // name we already set up for it
10385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefMap::const_iterator I = ForwardRefs.find(V);
10395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != ForwardRefs.end())
10405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return I->second;
10415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // This is a new forward reference. Generate a unique name for it
10435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string result(std::string("fwdref_") + utostr(uniqueNum++));
10445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Yes, this is a hack. An Argument is the smallest instantiable value that
10465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // we can make as a placeholder for the real value. We'll replace these
10475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Argument instances later.
10485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "Argument* " << result << " = new Argument("
10495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        << getCppName(V->getType()) << ");";
10505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
10515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefs[V] = result;
10525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return result;
10535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printInstruction - This member is called for each Instruction in a function.
10565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printInstruction(const Instruction *I,
10575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                   const std::string& bbname) {
10585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string iName(getCppName(I));
10595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Before we emit this instruction, we need to take care of generating any
10615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // forward references. So, we get the names of all the operands in advance
10625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string* opNames = new std::string[I->getNumOperands()];
10635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (unsigned i = 0; i < I->getNumOperands(); i++) {
10645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      opNames[i] = getOpName(I->getOperand(i));
10655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (I->getOpcode()) {
106826825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman    default:
106926825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman      error("Invalid instruction");
107026825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman      break;
107126825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman
10725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Ret: {
10735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ReturnInst* ret =  cast<ReturnInst>(I);
10745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ReturnInst::Create("
10755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
10765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
10775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Br: {
10795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const BranchInst* br = cast<BranchInst>(I);
10805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "BranchInst::Create(" ;
10815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (br->getNumOperands() == 3 ) {
10825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", "
10835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[1] << ", "
10845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[2] << ", ";
10855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (br->getNumOperands() == 1) {
10875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", ";
10885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
10895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        error("Branch with 2 operands?");
10905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
10915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << bbname << ");";
10925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
10935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Switch: {
10955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const SwitchInst* sw = cast<SwitchInst>(I);
10965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "SwitchInst* " << iName << " = SwitchInst::Create("
10975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
10985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
10995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << sw->getNumCases() << ", " << bbname << ");";
11005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
11015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) {
11025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "->addCase("
11035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ", "
11045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i+1] << ");";
11055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
11065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Invoke: {
11105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const InvokeInst* inv = cast<InvokeInst>(I);
11115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Value*> " << iName << "_params;";
11125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
11135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 3; i < inv->getNumOperands(); ++i) {
11145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "_params.push_back("
11155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ");";
11165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
11175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "InvokeInst *" << iName << " = InvokeInst::Create("
11195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
11205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
11215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[2] << ", "
11225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << iName << "_params.begin(), " << iName << "_params.end(), \"";
11235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(inv->getName());
11245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
11255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setCallingConv(";
11265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCallingConv(inv->getCallingConv());
11275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
11285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printParamAttrs(inv->getParamAttrs(), iName);
11295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << iName << "->setParamAttrs(" << iName << "_PAL);";
11305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
11315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Unwind: {
11345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "new UnwindInst("
11355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << bbname << ");";
11365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Unreachable:{
11395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "new UnreachableInst("
11405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << bbname << ");";
11415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Add:
11445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Sub:
11455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Mul:
11465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UDiv:
11475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SDiv:
11485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FDiv:
11495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::URem:
11505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SRem:
11515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FRem:
11525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::And:
11535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Or:
11545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Xor:
11555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Shl:
11565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::LShr:
11575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::AShr:{
11587cbd8a3e92221437048b484d5ef9c0a22d0f8c58Gabor Greif      Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
11595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (I->getOpcode()) {
11605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Add: Out << "Instruction::Add"; break;
11615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Sub: Out << "Instruction::Sub"; break;
11625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Mul: Out << "Instruction::Mul"; break;
11635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::UDiv:Out << "Instruction::UDiv"; break;
11645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SDiv:Out << "Instruction::SDiv"; break;
11655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FDiv:Out << "Instruction::FDiv"; break;
11665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::URem:Out << "Instruction::URem"; break;
11675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SRem:Out << "Instruction::SRem"; break;
11685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FRem:Out << "Instruction::FRem"; break;
11695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::And: Out << "Instruction::And"; break;
11705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Or:  Out << "Instruction::Or";  break;
11715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Xor: Out << "Instruction::Xor"; break;
11725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Shl: Out << "Instruction::Shl"; break;
11735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::LShr:Out << "Instruction::LShr"; break;
11745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::AShr:Out << "Instruction::AShr"; break;
11755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "Instruction::BadOpCode"; break;
11765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
11785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
11795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
11805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FCmp: {
11835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "FCmpInst* " << iName << " = new FCmpInst(";
11845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (cast<FCmpInst>(I)->getPredicate()) {
11855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
11865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
11875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
11885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
11895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
11905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
11915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
11925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
11935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
11945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
11955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
11965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
11975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
11985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
11995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
12005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
12015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
12025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
12045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
12055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ICmp: {
12095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ICmpInst* " << iName << " = new ICmpInst(";
12105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (cast<ICmpInst>(I)->getPredicate()) {
12115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
12125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
12135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
12145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
12155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
12165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
12175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
12185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
12195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
12205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
12215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
12225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
12245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
12255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Malloc: {
12295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const MallocInst* mallocI = cast<MallocInst>(I);
12305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "MallocInst* " << iName << " = new MallocInst("
12315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(mallocI->getAllocatedType()) << ", ";
12325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (mallocI->isArrayAllocation())
12335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", " ;
12345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\"";
12355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(mallocI->getName());
12365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (mallocI->getAlignment())
12385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << iName << "->setAlignment("
12395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << mallocI->getAlignment() << ");";
12405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Free: {
12435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "FreeInst* " << iName << " = new FreeInst("
12445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(I->getOperand(0)) << ", " << bbname << ");";
12455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Alloca: {
12485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const AllocaInst* allocaI = cast<AllocaInst>(I);
12495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "AllocaInst* " << iName << " = new AllocaInst("
12505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(allocaI->getAllocatedType()) << ", ";
12515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (allocaI->isArrayAllocation())
12525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", ";
12535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\"";
12545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(allocaI->getName());
12555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (allocaI->getAlignment())
12575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << iName << "->setAlignment("
12585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << allocaI->getAlignment() << ");";
12595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Load:{
12625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const LoadInst* load = cast<LoadInst>(I);
12635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "LoadInst* " << iName << " = new LoadInst("
12645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", \"";
12655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(load->getName());
12665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << (load->isVolatile() ? "true" : "false" )
12675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << bbname << ");";
12685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Store: {
12715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const StoreInst* store = cast<StoreInst>(I);
12725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "StoreInst* " << iName << " = new StoreInst("
12735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
12745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
12755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (store->isVolatile() ? "true" : "false")
12765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << bbname << ");";
12775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::GetElementPtr: {
12805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
12815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (gep->getNumOperands() <= 2) {
12825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
12835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0];
12845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (gep->getNumOperands() == 2)
12855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << ", " << opNames[1];
12865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
12875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Value*> " << iName << "_indices;";
12885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
12895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
12905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << iName << "_indices.push_back("
12915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << opNames[i] << ");";
12925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
12935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
12945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
12955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << iName << "_indices.begin(), "
12965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << iName << "_indices.end()";
12975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", \"";
12995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(gep->getName());
13005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::PHI: {
13045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const PHINode* phi = cast<PHINode>(I);
13055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
13065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "PHINode* " << iName << " = PHINode::Create("
13075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(phi->getType()) << ", \"";
13085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(phi->getName());
13095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->reserveOperandSpace("
13115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        << phi->getNumIncomingValues()
13125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ");";
13135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
13145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
13155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "->addIncoming("
13165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ", " << opNames[i+1] << ");";
13175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Trunc:
13225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ZExt:
13235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SExt:
13245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPTrunc:
13255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPExt:
13265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPToUI:
13275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPToSI:
13285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UIToFP:
13295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SIToFP:
13305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::PtrToInt:
13315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::IntToPtr:
13325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::BitCast: {
13335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const CastInst* cst = cast<CastInst>(I);
13345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "CastInst* " << iName << " = new ";
13355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (I->getOpcode()) {
13365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Trunc:    Out << "TruncInst"; break;
13375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::ZExt:     Out << "ZExtInst"; break;
13385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SExt:     Out << "SExtInst"; break;
13395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
13405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPExt:    Out << "FPExtInst"; break;
13415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPToUI:   Out << "FPToUIInst"; break;
13425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPToSI:   Out << "FPToSIInst"; break;
13435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::UIToFP:   Out << "UIToFPInst"; break;
13445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SIToFP:   Out << "SIToFPInst"; break;
13455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
13465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
13475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::BitCast:  Out << "BitCastInst"; break;
13485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: assert(!"Unreachable"); break;
13495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "(" << opNames[0] << ", "
13515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(cst->getType()) << ", \"";
13525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(cst->getName());
13535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Call:{
13575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const CallInst* call = cast<CallInst>(I);
13585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (InlineAsm* ila = dyn_cast<InlineAsm>(call->getOperand(0))) {
13595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
13605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(ila->getFunctionType()) << ", \""
13615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ila->getAsmString() << "\", \""
13625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ila->getConstraintString() << "\","
13635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (ila->hasSideEffects() ? "true" : "false") << ");";
13645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (call->getNumOperands() > 2) {
13675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Value*> " << iName << "_params;";
13685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < call->getNumOperands(); ++i) {
13705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << iName << "_params.push_back(" << opNames[i] << ");";
13715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
13725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
13735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create("
13745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << iName << "_params.begin(), "
13755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << iName << "_params.end(), \"";
13765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (call->getNumOperands() == 2) {
13775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create("
13785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << opNames[1] << ", \"";
13795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
13805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create(" << opNames[0]
13815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ", \"";
13825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(call->getName());
13845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setCallingConv(";
13865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCallingConv(call->getCallingConv());
13875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
13885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setTailCall("
13895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (call->isTailCall() ? "true":"false");
13905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
13915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printParamAttrs(call->getParamAttrs(), iName);
13925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << iName << "->setParamAttrs(" << iName << "_PAL);";
13935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
13945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Select: {
13975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const SelectInst* sel = cast<SelectInst>(I);
13985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
13995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(sel->getName());
14015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UserOp1:
14055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      /// FALL THROUGH
14065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UserOp2: {
14075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      /// FIXME: What should be done here?
14085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::VAArg: {
14115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const VAArgInst* va = cast<VAArgInst>(I);
14125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
14135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
14145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(va->getName());
14155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ExtractElement: {
14195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ExtractElementInst* eei = cast<ExtractElementInst>(I);
14205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ExtractElementInst* " << getCppName(eei)
14215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = new ExtractElementInst(" << opNames[0]
14225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", \"";
14235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(eei->getName());
14245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::InsertElement: {
14285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const InsertElementInst* iei = cast<InsertElementInst>(I);
14295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "InsertElementInst* " << getCppName(iei)
14305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = InsertElementInst::Create(" << opNames[0]
14315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(iei->getName());
14335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ShuffleVector: {
14375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
14385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ShuffleVectorInst* " << getCppName(svi)
14395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = new ShuffleVectorInst(" << opNames[0]
14405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(svi->getName());
14425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
144575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    case Instruction::ExtractValue: {
144675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      const ExtractValueInst *evi = cast<ExtractValueInst>(I);
144775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "std::vector<unsigned> " << iName << "_indices;";
144875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      nl(Out);
144975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
145075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        Out << iName << "_indices.push_back("
145175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman            << evi->idx_begin()[i] << ");";
145275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        nl(Out);
145375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      }
145475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "ExtractValueInst* " << getCppName(evi)
145575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << " = ExtractValueInst::Create(" << opNames[0]
145675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << ", "
145775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
145875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      printEscapedString(evi->getName());
145975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "\", " << bbname << ");";
146075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      break;
146175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    }
146275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    case Instruction::InsertValue: {
146375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      const InsertValueInst *ivi = cast<InsertValueInst>(I);
146475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "std::vector<unsigned> " << iName << "_indices;";
146575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      nl(Out);
146675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
146775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        Out << iName << "_indices.push_back("
146875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman            << ivi->idx_begin()[i] << ");";
146975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        nl(Out);
147075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      }
147175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "InsertValueInst* " << getCppName(ivi)
147275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << " = InsertValueInst::Create(" << opNames[0]
147375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << ", " << opNames[1] << ", "
147475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
147575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      printEscapedString(ivi->getName());
147675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "\", " << bbname << ");";
147775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      break;
147875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    }
14795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
14805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  DefinedValues.insert(I);
14815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  nl(Out);
14825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  delete [] opNames;
14835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
14845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
14855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Print out the types, constants and declarations needed by one function
14865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionUses(const Function* F) {
14875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions"; nl(Out);
14885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!is_inline) {
14895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the function's return type
14905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(F->getReturnType());
14915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
14925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the function's function type
14935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(F->getFunctionType());
14945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
14955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the types of each of the function's arguments
14965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
14975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           AI != AE; ++AI) {
14985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(AI->getType());
14995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print type definitions for every type referenced by an instruction and
15035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // make a note of any global values or constants that are referenced
15045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    SmallPtrSet<GlobalValue*,64> gvs;
15055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    SmallPtrSet<Constant*,64> consts;
15065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BB = F->begin(), BE = F->end();
15075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BB != BE; ++BB){
15085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
15095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           I != E; ++I) {
15105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Print the type of the instruction itself
15115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(I->getType());
15125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Print the type of each of the instruction's operands
15145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < I->getNumOperands(); ++i) {
15155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Value* operand = I->getOperand(i);
15165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printType(operand->getType());
15175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          // If the operand references a GVal or Constant, make a note of it
15195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
15205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            gvs.insert(GV);
15215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
15225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              if (GVar->hasInitializer())
15235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                consts.insert(GVar->getInitializer());
15245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          } else if (Constant* C = dyn_cast<Constant>(operand))
15255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            consts.insert(C);
15265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
15275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the function declarations for any functions encountered
15315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Declarations"; nl(Out);
15325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (Function* Fun = dyn_cast<Function>(*I)) {
15355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (!is_inline || Fun != F)
15365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printFunctionHead(Fun);
15375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the global variable declarations for any variables encountered
15415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Declarations"; nl(Out);
15425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
15455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableHead(F);
15465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Print the constants found
15495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Constant Definitions"; nl(Out);
15505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(),
15515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = consts.end(); I != E; ++I) {
15525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printConstant(*I);
15535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables definitions now that all the constants have
15565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // been emitted. These definitions just couple the gvars with their constant
15575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // initializers.
15585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Definitions"; nl(Out);
15595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
15625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableBody(GV);
15635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
15655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionHead(const Function* F) {
15675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "Function* " << getCppName(F);
15685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
15695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << " = mod->getFunction(\"";
15705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(F->getName());
15715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << getCppName(F->getFunctionType()) << ");";
15725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "if (!" << getCppName(F) << ") {";
15735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << getCppName(F);
15745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out<< " = Function::Create(";
15765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
15775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Linkage=*/";
15785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printLinkageType(F->getLinkage());
15795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
15805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Name=*/\"";
15815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(F->getName());
15825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
15835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,-1);
15845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(F);
15855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "->setCallingConv(";
15865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCallingConv(F->getCallingConv());
15875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ");";
15885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
15895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->hasSection()) {
15905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
15915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setSection(\"" << F->getSection() << "\");";
15925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
15935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->getAlignment()) {
15955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
15965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setAlignment(" << F->getAlignment() << ");";
15975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
15985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->getVisibility() != GlobalValue::DefaultVisibility) {
16005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setVisibility(";
16025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVisibilityType(F->getVisibility());
16035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
16045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->hasCollector()) {
16075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setCollector(\"" << F->getCollector() << "\");";
16095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
16125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "}";
16135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printParamAttrs(F->getParamAttrs(), getCppName(F));
16165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(F);
16175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "->setParamAttrs(" << getCppName(F) << "_PAL);";
16185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
16195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
16205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionBody(const Function *F) {
16225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->isDeclaration())
16235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return; // external functions have no bodies.
16245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Clear the DefinedValues and ForwardRefs maps because we can't have
16265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // cross-function forward refs
16275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefs.clear();
16285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    DefinedValues.clear();
16295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Create all the argument values
16315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!is_inline) {
16325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!F->arg_empty()) {
16335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Function::arg_iterator args = " << getCppName(F)
16345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << "->arg_begin();";
16355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
16365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
16385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           AI != AE; ++AI) {
16395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Value* " << getCppName(AI) << " = args++;";
16405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
16415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (AI->hasName()) {
16425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
16435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
16445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
16455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Create all the basic blocks
16495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
16505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BI = F->begin(), BE = F->end();
16515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BI != BE; ++BI) {
16525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string bbname(getCppName(BI));
16535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "BasicBlock* " << bbname << " = BasicBlock::Create(\"";
16545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (BI->hasName())
16555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(BI->getName());
16565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\"," << getCppName(BI->getParent()) << ",0);";
16575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Output all of its basic blocks... for the function
16615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BI = F->begin(), BE = F->end();
16625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BI != BE; ++BI) {
16635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string bbname(getCppName(BI));
16645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
16655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Output all of the instructions in the basic block...
16685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
16695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           I != E; ++I) {
16705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printInstruction(I,bbname);
16715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Loop over the ForwardRefs and resolve them now that all instructions
16755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // are generated.
16765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!ForwardRefs.empty()) {
16775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "// Resolve Forward References";
16785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    while (!ForwardRefs.empty()) {
16825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ForwardRefMap::iterator I = ForwardRefs.begin();
16835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << I->second << "->replaceAllUsesWith("
16845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(I->first) << "); delete " << I->second << ";";
16855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ForwardRefs.erase(I);
16875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
16895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printInline(const std::string& fname,
16915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                              const std::string& func) {
16925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Function* F = TheModule->getFunction(func);
16935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!F) {
16945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + func + "' not found in input module");
16955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
16965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->isDeclaration()) {
16985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + func + "' is external!");
16995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
17005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
17025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(F);
17035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    unsigned arg_count = 1;
17045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
17055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         AI != AE; ++AI) {
17065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", Value* arg_" << arg_count;
17075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ") {";
17095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
17105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    is_inline = true;
17115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionUses(F);
17125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionBody(F);
17135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    is_inline = false;
17145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(F->begin()) << ";";
17155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "}";
17165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
17175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
17185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printModuleBody() {
17205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print out all the type definitions
17215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions"; nl(Out);
17225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printTypes(TheModule);
17235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Functions can call each other and global variables can reference them so
17255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // define all the functions first before emitting their function bodies.
17265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Declarations"; nl(Out);
17275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
17285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I)
17295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunctionHead(I);
17305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables declarations. We can't initialze them until
17325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // after the constants are printed so just print a header for each global
17335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Declarations\n"; nl(Out);
17345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
17355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
17365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariableHead(I);
17375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print out all the constants definitions. Constants don't recurse except
17405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // through GlobalValues. All GlobalValues have been declared at this point
17415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // so we can proceed to generate the constants.
17425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Constant Definitions"; nl(Out);
17435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printConstants(TheModule);
17445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables definitions now that all the constants have
17465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // been emitted. These definitions just couple the gvars with their constant
17475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // initializers.
17485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Definitions"; nl(Out);
17495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
17505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
17515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariableBody(I);
17525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Finally, we can safely put out all of the function bodies.
17555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Definitions"; nl(Out);
17565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
17575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
17585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!I->isDeclaration()) {
17595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
17605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                << ")";
17615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "{";
17625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out,1);
17635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunctionBody(I);
17645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out,-1) << "}";
17655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
17665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
17675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
17695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printProgram(const std::string& fname,
17715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                               const std::string& mName) {
17725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Module.h>\n";
17735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/DerivedTypes.h>\n";
17745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Constants.h>\n";
17755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/GlobalVariable.h>\n";
17765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Function.h>\n";
17775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/CallingConv.h>\n";
17785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/BasicBlock.h>\n";
17795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Instructions.h>\n";
17805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/InlineAsm.h>\n";
17815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Support/MathExtras.h>\n";
17825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Pass.h>\n";
17835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/PassManager.h>\n";
17849474ede38b7f991347c48b467397c88cbe99c163Nicolas Geoffray    Out << "#include <llvm/ADT/SmallVector.h>\n";
17855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Analysis/Verifier.h>\n";
17865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
17875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <algorithm>\n";
17885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <iostream>\n\n";
17895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "using namespace llvm;\n\n";
17905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "Module* " << fname << "();\n\n";
17915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "int main(int argc, char**argv) {\n";
17925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  Module* Mod = " << fname << "();\n";
17935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  verifyModule(*Mod, PrintMessageAction);\n";
17945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  std::cerr.flush();\n";
17955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  std::cout.flush();\n";
17965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  PassManager PM;\n";
17975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  PM.add(new PrintModulePass(&llvm::cout));\n";
17985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  PM.run(*Mod);\n";
17995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  return 0;\n";
18005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n\n";
18015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModule(fname,mName);
18025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printModule(const std::string& fname,
18055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                              const std::string& mName) {
18065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "Module* " << fname << "() {";
18075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,1) << "// Module Construction";
18085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "Module* mod = new Module(\"" << mName << "\");";
18095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getTargetTriple().empty()) {
18105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
18115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getTargetTriple().empty()) {
18135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
18145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << "\");";
18155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getModuleInlineAsm().empty()) {
18185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setModuleInlineAsm(\"";
18195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(TheModule->getModuleInlineAsm());
18205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\");";
18215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
18235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Loop over the dependent libraries and emit them.
18255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::lib_iterator LI = TheModule->lib_begin();
18265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::lib_iterator LE = TheModule->lib_end();
18275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    while (LI != LE) {
18285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "mod->addLibrary(\"" << *LI << "\");";
18295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
18305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ++LI;
18315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModuleBody();
18335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "return mod;";
18345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,-1) << "}";
18355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
18365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printContents(const std::string& fname,
18395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& mName) {
18405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nModule* " << fname << "(Module *mod) {\n";
18415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n";
18425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModuleBody();
18435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nreturn mod;\n";
18445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\n}\n";
18455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunction(const std::string& fname,
18485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& funcName) {
18495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Function* F = TheModule->getFunction(funcName);
18505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!F) {
18515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + funcName + "' not found in input module");
18525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
18535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nFunction* " << fname << "(Module *mod) {\n";
18555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionUses(F);
18565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionHead(F);
18575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionBody(F);
18585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(F) << ";\n";
18595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
18605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctions() {
18635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Module::FunctionListType &funcs = TheModule->getFunctionList();
18645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::const_iterator I  = funcs.begin();
18655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::const_iterator IE = funcs.end();
18665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (; I != IE; ++I) {
18685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Function &func = *I;
18695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!func.isDeclaration()) {
18705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string name("define_");
18715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name += func.getName();
18725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunction(name, func.getName());
18735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
18745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariable(const std::string& fname,
18785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& varName) {
18795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
18805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!GV) {
18825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Variable '") + varName + "' not found in input module");
18835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
18845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
18865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableUses(GV);
18875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableHead(GV);
18885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableBody(GV);
18895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(GV) << ";\n";
18905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
18915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printType(const std::string& fname,
18945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                            const std::string& typeName) {
18955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Type* Ty = TheModule->getTypeByName(typeName);
18965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!Ty) {
18975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Type '") + typeName + "' not found in input module");
18985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
18995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nType* " << fname << "(Module *mod) {\n";
19015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printType(Ty);
19025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(Ty) << ";\n";
19035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
19045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
19055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  bool CppWriter::runOnModule(Module &M) {
19075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TheModule = &M;
19085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Emit a header
19105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
19115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Get the name of the function we're supposed to generate
19135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string fname = FuncName.getValue();
19145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Get the name of the thing we are to generate
19165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string tgtname = NameToGenerate.getValue();
19175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GenerationType == GenModule ||
19185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenContents ||
19195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenProgram ||
19205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenFunctions) {
19215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (tgtname == "!bad!") {
19225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (M.getModuleIdentifier() == "-")
19235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tgtname = "<stdin>";
19245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
19255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tgtname = M.getModuleIdentifier();
19265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
19275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (tgtname == "!bad!")
19285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("You must use the -for option with -gen-{function,variable,type}");
19295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (WhatToGenerate(GenerationType)) {
19315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenProgram:
19325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModule";
19345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printProgram(fname,tgtname);
19355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenModule:
19375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModule";
19395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printModule(fname,tgtname);
19405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenContents:
19425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModuleContents";
19445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printContents(fname,tgtname);
19455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenFunction:
19475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMFunction";
19495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunction(fname,tgtname);
19505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenFunctions:
19525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunctions();
19535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenInline:
19555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMInline";
19575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printInline(fname,tgtname);
19585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenVariable:
19605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMVariable";
19625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariable(fname,tgtname);
19635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenType:
19655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMType";
19675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(fname,tgtname);
19685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     default:
19705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Invalid generation option");
19715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return false;
19745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
19755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
19765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovchar CppWriter::ID = 0;
19785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
19805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//                       External Interface declaration
19815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
19825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovbool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
19845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                                std::ostream &o,
19855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                                CodeGenFileType FileType,
19865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                                bool Fast) {
19875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  if (FileType != TargetMachine::AssemblyFile) return true;
19885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  PM.add(new CppWriter(o));
19895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  return false;
19905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
1991