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