CPPBackend.cpp revision 211edae4843f5c2ee9c376e88e4cf0ecc8745f03
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/ADT/SmallPtrSet.h"
275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Support/CommandLine.h"
283046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
2971847813bc419f7a0667468136a07429c6d9f164David Greene#include "llvm/Support/FormattedStream.h"
300c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
3123132b188ba651ba172380cd082cc286df73d440Chris Lattner#include "llvm/ADT/StringExtras.h"
325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include "llvm/Config/config.h"
335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include <algorithm>
345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#include <set>
355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovusing namespace llvm;
375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovstatic cl::opt<std::string>
398d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton KorobeynikovFuncName("cppfname", cl::desc("Specify the name of the generated function"),
405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         cl::value_desc("function name"));
415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovenum WhatToGenerate {
435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenProgram,
445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenModule,
455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenContents,
465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenFunction,
475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenFunctions,
485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenInline,
495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenVariable,
505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  GenType
515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov};
525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
538d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikovstatic cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::desc("Choose what kind of output to generate"),
555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::init(GenProgram),
565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::values(
578d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenProgram,  "program",   "Generate a complete program"),
588d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenModule,   "module",    "Generate a module definition"),
598d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenContents, "contents",  "Generate contents of a module"),
608d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenFunction, "function",  "Generate a function definition"),
618d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
628d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenInline,   "inline",    "Generate an inline function"),
638d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenVariable, "variable",  "Generate a variable definition"),
648d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikov    clEnumValN(GenType,     "type",      "Generate a type definition"),
655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    clEnumValEnd
665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  )
675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov);
685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
698d3e74ed49a11cd787d281a4a7afaf0f829c3fcbAnton Korobeynikovstatic cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::desc("Specify the name of the thing to generate"),
715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  cl::init("!bad!"));
725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
730c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbarextern "C" void LLVMInitializeCppBackendTarget() {
740c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar  // Register the target.
75214e22396fe86aa20c587d5c7df9ce63bfd4549eDaniel Dunbar  RegisterTargetMachine<CPPTargetMachine> X(TheCppBackendTarget);
760c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar}
771555a23335400143f2b54a66aedc4b5cbbb79f8dDouglas Gregor
78844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace {
795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::vector<const Type*> TypeList;
805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Type*,std::string> TypeMap;
815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Value*,std::string> ValueMap;
825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<std::string> NameSet;
835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<const Type*> TypeSet;
845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::set<const Value*> ValueSet;
855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  typedef std::map<const Value*,std::string> ForwardRefMap;
865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  /// CppWriter - This class is the main chunk of code that converts an LLVM
885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  /// module to a C++ translation unit.
895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  class CppWriter : public ModulePass {
9071847813bc419f7a0667468136a07429c6d9f164David Greene    formatted_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;
10571847813bc419f7a0667468136a07429c6d9f164David Greene    explicit CppWriter(formatted_raw_ostream &o) :
106ae73dc1448d25b02cabc7c64c86c64371453dda8Dan Gohman      ModulePass(&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);
12665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel    void printCallingConv(CallingConv::ID 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
1360598866c052147c31b808391f58434ce3dbfb838Devang Patel    void printAttributes(const AttrListPtr &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;
15871847813bc419f7a0667468136a07429c6d9f164David Greene  inline formatted_raw_ostream& nl(formatted_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) {
2133046470919e648ff7c011bda9c094163062c83dcTorok Edwin    llvm_report_error(msg);
2145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printCFP - Print a floating point constant .. very carefully :)
2175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // This makes sure that conversion to/from floating yields the same binary
2185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // result so that we don't lose precision.
2195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCFP(const ConstantFP *CFP) {
22023a98551ab65eeb8fe5019df8b7db4891582a4bdDale Johannesen    bool ignored;
2215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    APFloat APF = APFloat(CFP->getValueAPF());  // copy
2221d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson    if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
22323a98551ab65eeb8fe5019df8b7db4891582a4bdDale Johannesen      APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
224d083dfb60bb2778a6414e260d86a8f1e92b6c5d3Anton Korobeynikov    Out << "ConstantFP::get(getGlobalContext(), ";
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)))) {
2331d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson      if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
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())))) {
2511d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson        if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
2525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out <<  StrVal;
2535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
2545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << StrVal << "f";
2551d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson      } else if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
256cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson        Out << "BitsToDouble(0x"
2577111b02c734c992b8c97d9918118768026dad79eDale Johannesen            << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
258cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson            << "ULL) /* " << StrVal << " */";
2595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else
260cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson        Out << "BitsToFloat(0x"
2617111b02c734c992b8c97d9918118768026dad79eDale Johannesen            << utohexstr((uint32_t)CFP->getValueAPF().
2627111b02c734c992b8c97d9918118768026dad79eDale Johannesen                                        bitcastToAPInt().getZExtValue())
263cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson            << "U) /* " << StrVal << " */";
2645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ")";
2655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#if HAVE_PRINTF_A
2665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
2675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov#endif
2685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ")";
2695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
27165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel  void CppWriter::printCallingConv(CallingConv::ID cc){
2725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the calling convention.
2735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (cc) {
2745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::C:     Out << "CallingConv::C"; break;
2755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::Fast:  Out << "CallingConv::Fast"; break;
2765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::Cold:  Out << "CallingConv::Cold"; break;
2775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
2785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:                 Out << cc; break;
2795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
2805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
2815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
2825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
2835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (LT) {
2845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::InternalLinkage:
2855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::InternalLinkage"; break;
286bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola    case GlobalValue::PrivateLinkage:
287bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola      Out << "GlobalValue::PrivateLinkage"; break;
2883d10a5a75794356a0a568ce283713adc3a963200Bill Wendling    case GlobalValue::LinkerPrivateLinkage:
2893d10a5a75794356a0a568ce283713adc3a963200Bill Wendling      Out << "GlobalValue::LinkerPrivateLinkage"; break;
290266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner    case GlobalValue::AvailableExternallyLinkage:
291266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner      Out << "GlobalValue::AvailableExternallyLinkage "; break;
292667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands    case GlobalValue::LinkOnceAnyLinkage:
293667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands      Out << "GlobalValue::LinkOnceAnyLinkage "; break;
294667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands    case GlobalValue::LinkOnceODRLinkage:
295667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands      Out << "GlobalValue::LinkOnceODRLinkage "; break;
296667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands    case GlobalValue::WeakAnyLinkage:
297667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands      Out << "GlobalValue::WeakAnyLinkage"; break;
298667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands    case GlobalValue::WeakODRLinkage:
299667d4b8de6dea70195ff12ef39a4deebffa2f5c7Duncan Sands      Out << "GlobalValue::WeakODRLinkage"; break;
3005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::AppendingLinkage:
3015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::AppendingLinkage"; break;
3025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::ExternalLinkage:
3035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::ExternalLinkage"; break;
3045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DLLImportLinkage:
3055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DLLImportLinkage"; break;
3065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DLLExportLinkage:
3075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DLLExportLinkage"; break;
3085f4ee1fc5d00ae55c30fa2ce450c69be4c6d6e63Duncan Sands    case GlobalValue::ExternalWeakLinkage:
3095f4ee1fc5d00ae55c30fa2ce450c69be4c6d6e63Duncan Sands      Out << "GlobalValue::ExternalWeakLinkage"; break;
3104dc2b39bf89d7c87868008ef8a0f807e0419aca6Duncan Sands    case GlobalValue::CommonLinkage:
3114dc2b39bf89d7c87868008ef8a0f807e0419aca6Duncan Sands      Out << "GlobalValue::CommonLinkage"; break;
3125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
3165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (VisType) {
317c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    default: llvm_unreachable("Unknown GVar visibility");
3185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::DefaultVisibility:
3195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::DefaultVisibility";
3205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::HiddenVisibility:
3225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::HiddenVisibility";
3235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case GlobalValue::ProtectedVisibility:
3255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "GlobalValue::ProtectedVisibility";
3265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
3275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printEscapedString - Print each character of the specified string, escaping
3315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // it if it is not printable or if it is an escape char.
3325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printEscapedString(const std::string &Str) {
3335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (unsigned i = 0, e = Str.size(); i != e; ++i) {
3345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned char C = Str[i];
3355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (isprint(C) && C != '"' && C != '\\') {
3365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << C;
3375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
3385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "\\x"
3395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (char) ((C/16  < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
3405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
3415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
3425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getCppName(const Type* Ty) {
3465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // First, handle the primitive types .. easy
3475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (Ty->isPrimitiveType() || Ty->isInteger()) {
3485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (Ty->getTypeID()) {
349ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      case Type::VoidTyID:   return "Type::getVoidTy(getGlobalContext())";
3505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::IntegerTyID: {
3515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
352267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson        return "IntegerType::get(getGlobalContext(), " + utostr(BitWidth) + ")";
3535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
354ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      case Type::X86_FP80TyID: return "Type::getX86_FP80Ty(getGlobalContext())";
355ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      case Type::FloatTyID:    return "Type::getFloatTy(getGlobalContext())";
356ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      case Type::DoubleTyID:   return "Type::getDoubleTy(getGlobalContext())";
357ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      case Type::LabelTyID:    return "Type::getLabelTy(getGlobalContext())";
3585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default:
3595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        error("Invalid primitive type");
3605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        break;
3615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
362ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      // shouldn't be returned, but make it sensible
363ab2a663af1a696872d042d1a91f93ab9f8194fd6Nicolas Geoffray      return "Type::getVoidTy(getGlobalContext())";
3645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Now, see if we've seen the type before and return that
3675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap::iterator I = TypeNames.find(Ty);
3685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != TypeNames.end())
3695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return I->second;
3705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Okay, let's build a new name for this type. Start with a prefix
3725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const char* prefix = 0;
3735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (Ty->getTypeID()) {
3745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FunctionTyID:    prefix = "FuncTy_"; break;
3755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::StructTyID:      prefix = "StructTy_"; break;
3765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::ArrayTyID:       prefix = "ArrayTy_"; break;
3775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::PointerTyID:     prefix = "PointerTy_"; break;
3785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::OpaqueTyID:      prefix = "OpaqueTy_"; break;
3795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VectorTyID:      prefix = "VectorTy_"; break;
3805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:                    prefix = "OtherTy_"; break; // prevent breakage
3815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
3825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // See if the type has a name in the symboltable and build accordingly
3845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty);
3855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string name;
3865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (tName)
3875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string(prefix) + *tName;
3885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    else
3895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string(prefix) + utostr(uniqueNum++);
3905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    sanitize(name);
3915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Save the name
3935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return TypeNames[Ty] = name;
3945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
3965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCppName(const Type* Ty) {
3975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(getCppName(Ty));
3985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
3995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getCppName(const Value* val) {
4015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string name;
4025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ValueMap::iterator I = ValueNames.find(val);
4035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != ValueNames.end() && I->first == val)
4045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return  I->second;
4055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
4075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("gvar_") +
4085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        getTypePrefix(GV->getType()->getElementType());
4095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<Function>(val)) {
4105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("func_");
4115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const Constant* C = dyn_cast<Constant>(val)) {
4125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = std::string("const_") + getTypePrefix(C->getType());
4135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
4145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (is_inline) {
4155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
4165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                        Function::const_arg_iterator(Arg)) + 1;
4175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name = std::string("arg_") + utostr(argNum);
4185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        NameSet::iterator NI = UsedNames.find(name);
4195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (NI != UsedNames.end())
4205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          name += std::string("_") + utostr(uniqueNum++);
4215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        UsedNames.insert(name);
4225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        return ValueNames[val] = name;
4235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
4245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name = getTypePrefix(val->getType());
4255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
4265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else {
4275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name = getTypePrefix(val->getType());
4285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
4298f60302ee5e45c90fba7b8c771986106e3618129Daniel Dunbar    if (val->hasName())
4308f60302ee5e45c90fba7b8c771986106e3618129Daniel Dunbar      name += val->getName();
4318f60302ee5e45c90fba7b8c771986106e3618129Daniel Dunbar    else
4328f60302ee5e45c90fba7b8c771986106e3618129Daniel Dunbar      name += utostr(uniqueNum++);
4335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    sanitize(name);
4345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    NameSet::iterator NI = UsedNames.find(name);
4355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (NI != UsedNames.end())
4365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      name += std::string("_") + utostr(uniqueNum++);
4375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    UsedNames.insert(name);
4385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return ValueNames[val] = name;
4395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printCppName(const Value* val) {
4425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(getCppName(val));
4435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4450598866c052147c31b808391f58434ce3dbfb838Devang Patel  void CppWriter::printAttributes(const AttrListPtr &PAL,
4465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                  const std::string &name) {
4470598866c052147c31b808391f58434ce3dbfb838Devang Patel    Out << "AttrListPtr " << name << "_PAL;";
4485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
4495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!PAL.isEmpty()) {
4505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << '{'; in(); nl(Out);
4510598866c052147c31b808391f58434ce3dbfb838Devang Patel      Out << "SmallVector<AttributeWithIndex, 4> Attrs;"; nl(Out);
4520598866c052147c31b808391f58434ce3dbfb838Devang Patel      Out << "AttributeWithIndex PAWI;"; nl(Out);
4535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
454d9afb4d08a0143c9b9266001175c1b03e33663b6Nicolas Geoffray        unsigned index = PAL.getSlot(i).Index;
455eaf42abab6d465c38891345d999255871cf03943Devang Patel        Attributes attrs = PAL.getSlot(i).Attrs;
456d9afb4d08a0143c9b9266001175c1b03e33663b6Nicolas Geoffray        Out << "PAWI.Index = " << index << "U; PAWI.Attrs = 0 ";
457acca9559f4fdf99de62537592d7d63409229857bChris Lattner#define HANDLE_ATTR(X)                 \
458acca9559f4fdf99de62537592d7d63409229857bChris Lattner        if (attrs & Attribute::X)      \
459acca9559f4fdf99de62537592d7d63409229857bChris Lattner          Out << " | Attribute::" #X;  \
460acca9559f4fdf99de62537592d7d63409229857bChris Lattner        attrs &= ~Attribute::X;
461acca9559f4fdf99de62537592d7d63409229857bChris Lattner
462acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(SExt);
463acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(ZExt);
464acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(NoReturn);
4652d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(InReg);
4662d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(StructRet);
467acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(NoUnwind);
468acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(NoAlias);
4692d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(ByVal);
470acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(Nest);
471acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(ReadNone);
472acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(ReadOnly);
4732d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(NoInline);
4742d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(AlwaysInline);
4752d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(OptimizeForSize);
4762d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(StackProtect);
4772d92c71668a96dcad806b4f0ed4ecce2bec2d2deJeffrey Yasskin        HANDLE_ATTR(StackProtectReq);
478acca9559f4fdf99de62537592d7d63409229857bChris Lattner        HANDLE_ATTR(NoCapture);
479acca9559f4fdf99de62537592d7d63409229857bChris Lattner#undef HANDLE_ATTR
480acca9559f4fdf99de62537592d7d63409229857bChris Lattner        assert(attrs == 0 && "Unhandled attribute!");
4815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ";";
4825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
4835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Attrs.push_back(PAWI);";
4845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
4855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
4860598866c052147c31b808391f58434ce3dbfb838Devang Patel      Out << name << "_PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());";
4875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
4885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out(); nl(Out);
4895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << '}'; nl(Out);
4905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
4915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
4925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  bool CppWriter::printTypeInternal(const Type* Ty) {
4945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We don't print definitions for primitive types
4955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (Ty->isPrimitiveType() || Ty->isInteger())
4965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return false;
4975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
4985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // If we already defined this type, we don't need to define it again.
4995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (DefinedTypes.find(Ty) != DefinedTypes.end())
5005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return false;
5015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Everything below needs the name for the type so get it now.
5035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string typeName(getCppName(Ty));
5045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Search the type stack for recursion. If we find it, then generate this
5065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // as an OpaqueType, but make sure not to do this multiple times because
5075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // the type could appear in multiple places on the stack. Once the opaque
5085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // definition is issued, it must not be re-issued. Consequently we have to
5095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // check the UnresolvedTypes list as well.
5105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeList::const_iterator TI = std::find(TypeStack.begin(), TypeStack.end(),
5115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                            Ty);
5125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (TI != TypeStack.end()) {
5135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      TypeMap::const_iterator I = UnresolvedTypes.find(Ty);
5145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I == UnresolvedTypes.end()) {
515bad9defac851d5cf04def7906345812ec270a63aNicolas Geoffray        Out << "PATypeHolder " << typeName;
516bad9defac851d5cf04def7906345812ec270a63aNicolas Geoffray        Out << "_fwd = OpaqueType::get(getGlobalContext());";
5175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        UnresolvedTypes[Ty] = typeName;
5195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return true;
5215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We're going to print a derived type which, by definition, contains other
5245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // types. So, push this one we're printing onto the type stack to assist with
5255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // recursive definitions.
5265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.push_back(Ty);
5275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
5285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the type definition
5295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (Ty->getTypeID()) {
5305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::FunctionTyID:  {
5315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const FunctionType* FT = cast<FunctionType>(Ty);
5325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<const Type*>" << typeName << "_args;";
5335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      FunctionType::param_iterator PI = FT->param_begin();
5355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      FunctionType::param_iterator PE = FT->param_end();
5365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (; PI != PE; ++PI) {
5375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        const Type* argTy = static_cast<const Type*>(*PI);
5385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool isForward = printTypeInternal(argTy);
5395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string argName(getCppName(argTy));
5405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << typeName << "_args.push_back(" << argName;
5415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (isForward)
5425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "_fwd";
5435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
5445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(FT->getReturnType());
5475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string retTypeName(getCppName(FT->getReturnType()));
5485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "FunctionType* " << typeName << " = FunctionType::get(";
5495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      in(); nl(Out) << "/*Result=*/" << retTypeName;
5505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (isForward)
5515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "_fwd";
5525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ",";
5535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "/*Params=*/" << typeName << "_args,";
5545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
5555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out();
5565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::StructTyID: {
5605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const StructType* ST = cast<StructType>(Ty);
5615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<const Type*>" << typeName << "_fields;";
5625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      StructType::element_iterator EI = ST->element_begin();
5645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      StructType::element_iterator EE = ST->element_end();
5655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (; EI != EE; ++EI) {
5665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        const Type* fieldTy = static_cast<const Type*>(*EI);
5675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool isForward = printTypeInternal(fieldTy);
5685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string fieldName(getCppName(fieldTy));
5695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << typeName << "_fields.push_back(" << fieldName;
5705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (isForward)
5715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "_fwd";
5725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
5735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
5745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
5755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "StructType* " << typeName << " = StructType::get("
5766f62cffd63ba698fafe8a89470b0c02c4586d991Nicolas Geoffray          << "mod->getContext(), "
5775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << "_fields, /*isPacked=*/"
5785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (ST->isPacked() ? "true" : "false") << ");";
5795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::ArrayTyID: {
5835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ArrayType* AT = cast<ArrayType>(Ty);
5845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = AT->getElementType();
5855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
5865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
5875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ArrayType* " << typeName << " = ArrayType::get("
5885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
5895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(AT->getNumElements()) << ");";
5905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
5915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
5925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
5935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::PointerTyID: {
5945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const PointerType* PT = cast<PointerType>(Ty);
5955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = PT->getElementType();
5965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
5975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
5985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "PointerType* " << typeName << " = PointerType::get("
5995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
6005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(PT->getAddressSpace()) << ");";
6015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
6035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::VectorTyID: {
6055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const VectorType* PT = cast<VectorType>(Ty);
6065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Type* ET = PT->getElementType();
6075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      bool isForward = printTypeInternal(ET);
6085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string elemName(getCppName(ET));
6095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "VectorType* " << typeName << " = VectorType::get("
6105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << elemName << (isForward ? "_fwd" : "")
6115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << utostr(PT->getNumElements()) << ");";
6125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
6145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Type::OpaqueTyID: {
616bad9defac851d5cf04def7906345812ec270a63aNicolas Geoffray      Out << "OpaqueType* " << typeName;
617bad9defac851d5cf04def7906345812ec270a63aNicolas Geoffray      Out << " = OpaqueType::get(getGlobalContext());";
6185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
6205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    default:
6225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Invalid TypeID");
6235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // If the type had a name, make sure we recreate it.
6265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const std::string* progTypeName =
6275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      findTypeName(TheModule->getTypeSymbolTable(),Ty);
6285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (progTypeName) {
6295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "mod->addTypeName(\"" << *progTypeName << "\", "
6305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ");";
6315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Pop us off the type stack
6355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.pop_back();
6365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Indicate that this type is now defined.
6385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    DefinedTypes.insert(Ty);
6395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Early resolve as many unresolved types as possible. Search the unresolved
6415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // types map for the type we just printed. Now that its definition is complete
6425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // we can resolve any previous references to it. This prevents a cascade of
6435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // unresolved types.
6445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeMap::iterator I = UnresolvedTypes.find(Ty);
6455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != UnresolvedTypes.end()) {
6465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "cast<OpaqueType>(" << I->second
6475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");";
6485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
6495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << I->second << " = cast<";
6505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (Ty->getTypeID()) {
6515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::FunctionTyID: Out << "FunctionType"; break;
6525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::ArrayTyID:    Out << "ArrayType"; break;
6535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::StructTyID:   Out << "StructType"; break;
6545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::VectorTyID:   Out << "VectorType"; break;
6555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::PointerTyID:  Out << "PointerType"; break;
6565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Type::OpaqueTyID:   Out << "OpaqueType"; break;
6575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default:                 Out << "NoSuchDerivedType"; break;
6585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
6595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ">(" << I->second << "_fwd.get());";
6605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out); nl(Out);
6615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      UnresolvedTypes.erase(I);
6625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Finally, separate the type definition from other with a newline.
6655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
6665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // We weren't a recursive type
6685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return false;
6695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
6705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Prints a type definition. Returns true if it could not resolve all the
6725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // types in the definition but had to use a forward reference.
6735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printType(const Type* Ty) {
6745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    assert(TypeStack.empty());
6755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TypeStack.clear();
6765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printTypeInternal(Ty);
6775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    assert(TypeStack.empty());
6785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
6795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printTypes(const Module* M) {
6815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Walk the symbol table and print out all its types
6825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const TypeSymbolTable& symtab = M->getTypeSymbolTable();
6835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end();
6845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         TI != TE; ++TI) {
6855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
6865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // For primitive types and types already defined, just add a name
6875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      TypeMap::const_iterator TNI = TypeNames.find(TI->second);
6885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (TI->second->isInteger() || TI->second->isPrimitiveType() ||
6895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          TNI != TypeNames.end()) {
6905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "mod->addTypeName(\"";
6915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(TI->first);
6925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "\", " << getCppName(TI->second) << ");";
6935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
6945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // For everything else, define the type
6955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
6965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(TI->second);
6975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
6985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
6995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Add all of the global variables to the value table...
7015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
7025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
7035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I->hasInitializer())
7045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(I->getInitializer()->getType());
7055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(I->getType());
7065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
7075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Add all the functions to the table
7095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
7105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         FI != FE; ++FI) {
7115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(FI->getReturnType());
7125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(FI->getFunctionType());
7135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all the function arguments
7145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = FI->arg_begin(),
7155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             AE = FI->arg_end(); AI != AE; ++AI) {
7165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(AI->getType());
7175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all of the basic blocks and instructions
7205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_iterator BB = FI->begin(),
7215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             E = FI->end(); BB != E; ++BB) {
7225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(BB->getType());
7235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
7245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             ++I) {
7255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printType(I->getType());
7265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          for (unsigned i = 0; i < I->getNumOperands(); ++i)
7275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            printType(I->getOperand(i)->getType());
7285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
7315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
7325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printConstant - Print out a constant pool entry...
7355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printConstant(const Constant *CV) {
7365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // First, if the constant is actually a GlobalValue (variable or function)
7375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // or its already in the constant list then we've printed it already and we
7385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // can just return.
7395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
7405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
7415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
7425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string constName(getCppName(CV));
7435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string typeName(getCppName(CV->getType()));
744ff4ca2e0883d95cbd97e09e56bee8c73fa384e6aAnton Korobeynikov
7455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (isa<GlobalValue>(CV)) {
7465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Skip variables and functions, we emit them elsewhere
7475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
7485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
749ff4ca2e0883d95cbd97e09e56bee8c73fa384e6aAnton Korobeynikov
7505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
75170053c340e41a1a7086ecef218395489b3c8cbc6Anton Korobeynikov      std::string constValue = CI->getValue().toString(10, true);
752267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson      Out << "ConstantInt* " << constName
753267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson          << " = ConstantInt::get(getGlobalContext(), APInt("
754267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson          << cast<IntegerType>(CI->getType())->getBitWidth()
7556d5f0f041f38c25983d576d5288f3e13c76f13e0Benjamin Kramer          << ", StringRef(\"" <<  constValue << "\"), 10));";
7565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<ConstantAggregateZero>(CV)) {
7575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantAggregateZero* " << constName
7585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = ConstantAggregateZero::get(" << typeName << ");";
7595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<ConstantPointerNull>(CV)) {
7605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantPointerNull* " << constName
761ff4ca2e0883d95cbd97e09e56bee8c73fa384e6aAnton Korobeynikov          << " = ConstantPointerNull::get(" << typeName << ");";
7625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
7635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ConstantFP* " << constName << " = ";
7645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCFP(CFP);
7655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ";";
7665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
7671d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson      if (CA->isString() &&
7681d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson          CA->getType()->getElementType() ==
7691d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson              Type::getInt8Ty(CA->getContext())) {
770267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson        Out << "Constant* " << constName <<
771267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson               " = ConstantArray::get(getGlobalContext(), \"";
7725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string tmp = CA->getAsString();
7735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        bool nullTerminate = false;
7745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (tmp[tmp.length()-1] == 0) {
7755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tmp.erase(tmp.length()-1);
7765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nullTerminate = true;
7775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(tmp);
7795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Determine if we want null termination or not.
7805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (nullTerminate)
7815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "\", true"; // Indicate that the null terminator should be
7825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                             // added.
7835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
7845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "\", false";// No null terminator
7855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
7865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
7875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Constant*> " << constName << "_elems;";
7885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
7895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned N = CA->getNumOperands();
7905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < N; ++i) {
7915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CA->getOperand(i)); // recurse to print operands
7925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << constName << "_elems.push_back("
7935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << getCppName(CA->getOperand(i)) << ");";
7945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
7955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
7965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantArray::get("
7975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << typeName << ", " << constName << "_elems);";
7985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
7995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
8005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Constant*> " << constName << "_fields;";
8015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
8025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned N = CS->getNumOperands();
8035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < N; i++) {
8045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CS->getOperand(i));
8055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << constName << "_fields.push_back("
8065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CS->getOperand(i)) << ");";
8075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
8085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
8095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = ConstantStruct::get("
8105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ", " << constName << "_fields);";
8115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) {
8125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Constant*> " << constName << "_elems;";
8135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
8145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      unsigned N = CP->getNumOperands();
8155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < N; ++i) {
8165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CP->getOperand(i));
8175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << constName << "_elems.push_back("
8185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CP->getOperand(i)) << ");";
8195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
8205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
8215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = ConstantVector::get("
8225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ", " << constName << "_elems);";
8235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (isa<UndefValue>(CV)) {
8245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "UndefValue* " << constName << " = UndefValue::get("
8255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << typeName << ");";
8265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
8275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (CE->getOpcode() == Instruction::GetElementPtr) {
8285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Constant*> " << constName << "_indices;";
8295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
8305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CE->getOperand(0));
8315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
8325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CE->getOperand(i));
8335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << constName << "_indices.push_back("
8345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << getCppName(CE->getOperand(i)) << ");";
8355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
8365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName
8385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << " = ConstantExpr::getGetElementPtr("
8395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CE->getOperand(0)) << ", "
8405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << "&" << constName << "_indices[0], "
8415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << constName << "_indices.size()"
8426d5f0f041f38c25983d576d5288f3e13c76f13e0Benjamin Kramer            << ");";
8435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (CE->isCast()) {
8445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(CE->getOperand(0));
8455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantExpr::getCast(";
8465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        switch (CE->getOpcode()) {
847c23197a26f34f559ea9797de51e187087c039c42Torok Edwin        default: llvm_unreachable("Invalid cast opcode");
8485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Trunc: Out << "Instruction::Trunc"; break;
8495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ZExt:  Out << "Instruction::ZExt"; break;
8505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SExt:  Out << "Instruction::SExt"; break;
8515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPTrunc:  Out << "Instruction::FPTrunc"; break;
8525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPExt:  Out << "Instruction::FPExt"; break;
8535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPToUI:  Out << "Instruction::FPToUI"; break;
8545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FPToSI:  Out << "Instruction::FPToSI"; break;
8555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::UIToFP:  Out << "Instruction::UIToFP"; break;
8565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SIToFP:  Out << "Instruction::SIToFP"; break;
8575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::PtrToInt:  Out << "Instruction::PtrToInt"; break;
8585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::IntToPtr:  Out << "Instruction::IntToPtr"; break;
8595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::BitCast:  Out << "Instruction::BitCast"; break;
8605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ", " << getCppName(CE->getOperand(0)) << ", "
8625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(CE->getType()) << ");";
8635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
8645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        unsigned N = CE->getNumOperands();
8655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < N; ++i ) {
8665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printConstant(CE->getOperand(i));
8675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
8685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Constant* " << constName << " = ConstantExpr::";
8695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        switch (CE->getOpcode()) {
8705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Add:    Out << "getAdd(";  break;
871ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman        case Instruction::FAdd:   Out << "getFAdd(";  break;
8725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Sub:    Out << "getSub("; break;
873ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman        case Instruction::FSub:   Out << "getFSub("; break;
8745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Mul:    Out << "getMul("; break;
875ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman        case Instruction::FMul:   Out << "getFMul("; break;
8765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::UDiv:   Out << "getUDiv("; break;
8775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SDiv:   Out << "getSDiv("; break;
8785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FDiv:   Out << "getFDiv("; break;
8795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::URem:   Out << "getURem("; break;
8805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::SRem:   Out << "getSRem("; break;
8815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FRem:   Out << "getFRem("; break;
8825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::And:    Out << "getAnd("; break;
8835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Or:     Out << "getOr("; break;
8845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Xor:    Out << "getXor("; break;
8855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ICmp:
8865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "getICmp(ICmpInst::ICMP_";
8875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          switch (CE->getPredicate()) {
8885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_EQ:  Out << "EQ"; break;
8895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_NE:  Out << "NE"; break;
8905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SLT: Out << "SLT"; break;
8915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_ULT: Out << "ULT"; break;
8925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SGT: Out << "SGT"; break;
8935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_UGT: Out << "UGT"; break;
8945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SLE: Out << "SLE"; break;
8955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_ULE: Out << "ULE"; break;
8965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_SGE: Out << "SGE"; break;
8975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case ICmpInst::ICMP_UGE: Out << "UGE"; break;
8985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          default: error("Invalid ICmp Predicate");
8995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
9005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
9015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::FCmp:
9025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << "getFCmp(FCmpInst::FCMP_";
9035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          switch (CE->getPredicate()) {
9045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
9055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ORD:   Out << "ORD"; break;
9065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UNO:   Out << "UNO"; break;
9075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OEQ:   Out << "OEQ"; break;
9085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UEQ:   Out << "UEQ"; break;
9095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ONE:   Out << "ONE"; break;
9105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UNE:   Out << "UNE"; break;
9115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OLT:   Out << "OLT"; break;
9125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ULT:   Out << "ULT"; break;
9135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OGT:   Out << "OGT"; break;
9145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UGT:   Out << "UGT"; break;
9155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OLE:   Out << "OLE"; break;
9165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_ULE:   Out << "ULE"; break;
9175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_OGE:   Out << "OGE"; break;
9185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_UGE:   Out << "UGE"; break;
9195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          case FCmpInst::FCMP_TRUE:  Out << "TRUE"; break;
9205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          default: error("Invalid FCmp Predicate");
9215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
9225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
9235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Shl:     Out << "getShl("; break;
9245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::LShr:    Out << "getLShr("; break;
9255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::AShr:    Out << "getAShr("; break;
9265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::Select:  Out << "getSelect("; break;
9275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ExtractElement: Out << "getExtractElement("; break;
9285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::InsertElement:  Out << "getInsertElement("; break;
9295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        case Instruction::ShuffleVector:  Out << "getShuffleVector("; break;
9305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        default:
9315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          error("Invalid constant expression");
9325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          break;
9335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
9345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << getCppName(CE->getOperand(0));
9355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < CE->getNumOperands(); ++i)
9365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << ", " << getCppName(CE->getOperand(i));
9375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << ");";
9385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else {
9405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Bad Constant");
9415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "Constant* " << constName << " = 0; ";
9425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
9445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printConstants(const Module* M) {
9475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Traverse all the global variables looking for constant initializers
9485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
9495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I)
9505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (I->hasInitializer())
9515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printConstant(I->getInitializer());
9525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Traverse the LLVM functions looking for constants
9545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
9555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         FI != FE; ++FI) {
9565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Add all of the basic blocks and instructions
9575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_iterator BB = FI->begin(),
9585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             E = FI->end(); BB != E; ++BB) {
9595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
9605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov             ++I) {
9615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          for (unsigned i = 0; i < I->getNumOperands(); ++i) {
9625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
9635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              printConstant(C);
9645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            }
9655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          }
9665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
9675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableUses(const GlobalVariable *GV) {
9725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions";
9735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
9745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printType(GV->getType());
9755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
976cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner      Constant *Init = GV->getInitializer();
9775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(Init->getType());
978cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner      if (Function *F = dyn_cast<Function>(Init)) {
9795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out)<< "/ Function Declarations"; nl(Out);
9805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunctionHead(F);
9815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
9825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Global Variable Declarations"; nl(Out);
9835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableHead(gv);
984cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner
9855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Global Variable Definitions"; nl(Out);
9865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableBody(gv);
987cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner      } else  {
988cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner        nl(Out) << "// Constant Definitions"; nl(Out);
989cdfb30287689346f3fbb466f1ea62bbb9df73333Chris Lattner        printConstant(Init);
9905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
9915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
9925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
9935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
9945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableHead(const GlobalVariable *GV) {
9955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "GlobalVariable* " << getCppName(GV);
9965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
997267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson      Out << " = mod->getGlobalVariable(getGlobalContext(), ";
9985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(GV->getName());
9995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
10005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "if (!" << getCppName(GV) << ") {";
10015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      in(); nl(Out) << getCppName(GV);
10025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
1003267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson    Out << " = new GlobalVariable(/*Module=*/*mod, ";
10045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Type=*/";
10055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(GV->getType()->getElementType());
10065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
10075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
10085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
10095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Linkage=*/";
10105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printLinkageType(GV->getLinkage());
10115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
10125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Initializer=*/0, ";
10135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
10145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "// has initializer, specified below";
10155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Name=*/\"";
10175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(GV->getName());
101816a412edb6d279bb5fbffba3ff1a6c914e478aafOwen Anderson    Out << "\");";
10195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
10205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasSection()) {
10225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setSection(\"";
10245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(GV->getSection());
10255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\");";
10265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->getAlignment()) {
10295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");";
10315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
10345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setVisibility(";
10365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVisibilityType(GV->getVisibility());
10375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
10385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
10415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      out(); Out << "}"; nl(Out);
10425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariableBody(const GlobalVariable *GV) {
10465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GV->hasInitializer()) {
10475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(GV);
10485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setInitializer(";
10495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << getCppName(GV->getInitializer()) << ");";
10505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
10515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  std::string CppWriter::getOpName(Value* V) {
10555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
10565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return getCppName(V);
10575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // See if its alread in the map of forward references, if so just return the
10595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // name we already set up for it
10605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefMap::const_iterator I = ForwardRefs.find(V);
10615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (I != ForwardRefs.end())
10625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return I->second;
10635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // This is a new forward reference. Generate a unique name for it
10655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string result(std::string("fwdref_") + utostr(uniqueNum++));
10665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Yes, this is a hack. An Argument is the smallest instantiable value that
10685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // we can make as a placeholder for the real value. We'll replace these
10695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Argument instances later.
10705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "Argument* " << result << " = new Argument("
10715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        << getCppName(V->getType()) << ");";
10725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
10735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefs[V] = result;
10745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return result;
10755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
10765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // printInstruction - This member is called for each Instruction in a function.
10785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printInstruction(const Instruction *I,
10795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                   const std::string& bbname) {
10805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string iName(getCppName(I));
10815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Before we emit this instruction, we need to take care of generating any
10835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // forward references. So, we get the names of all the operands in advance
10845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string* opNames = new std::string[I->getNumOperands()];
10855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (unsigned i = 0; i < I->getNumOperands(); i++) {
10865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      opNames[i] = getOpName(I->getOperand(i));
10875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
10885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
10895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (I->getOpcode()) {
109026825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman    default:
109126825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman      error("Invalid instruction");
109226825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman      break;
109326825a84e97790adaffc55c6101b9fe2524fe1b7Dan Gohman
10945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Ret: {
10955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ReturnInst* ret =  cast<ReturnInst>(I);
1096267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson      Out << "ReturnInst::Create(getGlobalContext(), "
10975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
10985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
10995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Br: {
11015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const BranchInst* br = cast<BranchInst>(I);
11025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "BranchInst::Create(" ;
11035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (br->getNumOperands() == 3 ) {
1104cffb5284f12afdfa5ba9cb6dbddcf0699ec11d84Anton Korobeynikov        Out << opNames[2] << ", "
11055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[1] << ", "
1106cffb5284f12afdfa5ba9cb6dbddcf0699ec11d84Anton Korobeynikov            << opNames[0] << ", ";
11075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
11085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (br->getNumOperands() == 1) {
11095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", ";
11105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
11115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        error("Branch with 2 operands?");
11125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << bbname << ");";
11145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Switch: {
1117627b470981a833f847005556bea04e71f94da260Chris Lattner      const SwitchInst *SI = cast<SwitchInst>(I);
11185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "SwitchInst* " << iName << " = SwitchInst::Create("
11195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
11205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
1121627b470981a833f847005556bea04e71f94da260Chris Lattner          << SI->getNumCases() << ", " << bbname << ");";
11225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
1123627b470981a833f847005556bea04e71f94da260Chris Lattner      for (unsigned i = 2; i != SI->getNumOperands(); i += 2) {
11245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "->addCase("
11255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ", "
11265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i+1] << ");";
11275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
11285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
1131ab21db79ef1d2530880ad11f21f0b87ffca02dd4Chris Lattner    case Instruction::IndirectBr: {
1132ab21db79ef1d2530880ad11f21f0b87ffca02dd4Chris Lattner      const IndirectBrInst *IBI = cast<IndirectBrInst>(I);
1133ab21db79ef1d2530880ad11f21f0b87ffca02dd4Chris Lattner      Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create("
1134627b470981a833f847005556bea04e71f94da260Chris Lattner          << opNames[0] << ", " << IBI->getNumDestinations() << ");";
1135627b470981a833f847005556bea04e71f94da260Chris Lattner      nl(Out);
1136627b470981a833f847005556bea04e71f94da260Chris Lattner      for (unsigned i = 1; i != IBI->getNumOperands(); ++i) {
1137627b470981a833f847005556bea04e71f94da260Chris Lattner        Out << iName << "->addDestination(" << opNames[i] << ");";
1138627b470981a833f847005556bea04e71f94da260Chris Lattner        nl(Out);
1139627b470981a833f847005556bea04e71f94da260Chris Lattner      }
1140627b470981a833f847005556bea04e71f94da260Chris Lattner      break;
1141627b470981a833f847005556bea04e71f94da260Chris Lattner    }
11425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Invoke: {
11435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const InvokeInst* inv = cast<InvokeInst>(I);
11445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "std::vector<Value*> " << iName << "_params;";
11455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
11465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 3; i < inv->getNumOperands(); ++i) {
11475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "_params.push_back("
11485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ");";
11495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
11505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
11515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "InvokeInst *" << iName << " = InvokeInst::Create("
11525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
11535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
11545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[2] << ", "
11555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << iName << "_params.begin(), " << iName << "_params.end(), \"";
11565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(inv->getName());
11575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
11585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setCallingConv(";
11595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCallingConv(inv->getCallingConv());
11605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
11610598866c052147c31b808391f58434ce3dbfb838Devang Patel      printAttributes(inv->getAttributes(), iName);
11620598866c052147c31b808391f58434ce3dbfb838Devang Patel      Out << iName << "->setAttributes(" << iName << "_PAL);";
11635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
11645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Unwind: {
11675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "new UnwindInst("
11685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << bbname << ");";
11695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
1171781c2b8c4901435c374549afb50adb0ea96b7b2bReid Kleckner    case Instruction::Unreachable: {
11725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "new UnreachableInst("
1173781c2b8c4901435c374549afb50adb0ea96b7b2bReid Kleckner          << "getGlobalContext(), "
11745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << bbname << ");";
11755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
11765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
11775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Add:
1178ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman    case Instruction::FAdd:
11795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Sub:
1180ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman    case Instruction::FSub:
11815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Mul:
1182ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman    case Instruction::FMul:
11835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UDiv:
11845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SDiv:
11855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FDiv:
11865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::URem:
11875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SRem:
11885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FRem:
11895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::And:
11905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Or:
11915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Xor:
11925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Shl:
11935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::LShr:
11945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::AShr:{
11957cbd8a3e92221437048b484d5ef9c0a22d0f8c58Gabor Greif      Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
11965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (I->getOpcode()) {
11975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Add: Out << "Instruction::Add"; break;
1198ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman      case Instruction::FAdd: Out << "Instruction::FAdd"; break;
11995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Sub: Out << "Instruction::Sub"; break;
1200ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman      case Instruction::FSub: Out << "Instruction::FSub"; break;
12015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Mul: Out << "Instruction::Mul"; break;
1202ae3a0be92e33bc716722aa600983fc1535acb122Dan Gohman      case Instruction::FMul: Out << "Instruction::FMul"; break;
12035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::UDiv:Out << "Instruction::UDiv"; break;
12045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SDiv:Out << "Instruction::SDiv"; break;
12055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FDiv:Out << "Instruction::FDiv"; break;
12065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::URem:Out << "Instruction::URem"; break;
12075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SRem:Out << "Instruction::SRem"; break;
12085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FRem:Out << "Instruction::FRem"; break;
12095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::And: Out << "Instruction::And"; break;
12105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Or:  Out << "Instruction::Or";  break;
12115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Xor: Out << "Instruction::Xor"; break;
12125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Shl: Out << "Instruction::Shl"; break;
12135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::LShr:Out << "Instruction::LShr"; break;
12145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::AShr:Out << "Instruction::AShr"; break;
12155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "Instruction::BadOpCode"; break;
12165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
12185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
12195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FCmp: {
1223d083dfb60bb2778a6414e260d86a8f1e92b6c5d3Anton Korobeynikov      Out << "FCmpInst* " << iName << " = new FCmpInst(*" << bbname << ", ";
12245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (cast<FCmpInst>(I)->getPredicate()) {
12255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
12265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OEQ  : Out << "FCmpInst::FCMP_OEQ"; break;
12275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OGT  : Out << "FCmpInst::FCMP_OGT"; break;
12285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OGE  : Out << "FCmpInst::FCMP_OGE"; break;
12295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OLT  : Out << "FCmpInst::FCMP_OLT"; break;
12305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_OLE  : Out << "FCmpInst::FCMP_OLE"; break;
12315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ONE  : Out << "FCmpInst::FCMP_ONE"; break;
12325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ORD  : Out << "FCmpInst::FCMP_ORD"; break;
12335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UNO  : Out << "FCmpInst::FCMP_UNO"; break;
12345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UEQ  : Out << "FCmpInst::FCMP_UEQ"; break;
12355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UGT  : Out << "FCmpInst::FCMP_UGT"; break;
12365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UGE  : Out << "FCmpInst::FCMP_UGE"; break;
12375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ULT  : Out << "FCmpInst::FCMP_ULT"; break;
12385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_ULE  : Out << "FCmpInst::FCMP_ULE"; break;
12395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_UNE  : Out << "FCmpInst::FCMP_UNE"; break;
12405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
12415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
12425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
12445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
1245d083dfb60bb2778a6414e260d86a8f1e92b6c5d3Anton Korobeynikov      Out << "\");";
12465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ICmp: {
1249781c2b8c4901435c374549afb50adb0ea96b7b2bReid Kleckner      Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
12505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (cast<ICmpInst>(I)->getPredicate()) {
12515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_EQ:  Out << "ICmpInst::ICMP_EQ";  break;
12525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_NE:  Out << "ICmpInst::ICMP_NE";  break;
12535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
12545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
12555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
12565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
12575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
12585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
12595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
12605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
12615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
12625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
12635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
12645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(I->getName());
1265781c2b8c4901435c374549afb50adb0ea96b7b2bReid Kleckner      Out << "\");";
12665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Alloca: {
12695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const AllocaInst* allocaI = cast<AllocaInst>(I);
12705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "AllocaInst* " << iName << " = new AllocaInst("
12715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(allocaI->getAllocatedType()) << ", ";
12725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (allocaI->isArrayAllocation())
12735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << opNames[0] << ", ";
12745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\"";
12755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(allocaI->getName());
12765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
12775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (allocaI->getAlignment())
12785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << iName << "->setAlignment("
12795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << allocaI->getAlignment() << ");";
12805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Load:{
12835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const LoadInst* load = cast<LoadInst>(I);
12845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "LoadInst* " << iName << " = new LoadInst("
12855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", \"";
12865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(load->getName());
12875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << (load->isVolatile() ? "true" : "false" )
12885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << bbname << ");";
12895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
12915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Store: {
12925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const StoreInst* store = cast<StoreInst>(I);
1293b0714dbc0dc1cfc942790930871967572c1e360dAnton Korobeynikov      Out << " new StoreInst("
12945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", "
12955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[1] << ", "
12965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (store->isVolatile() ? "true" : "false")
12975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << bbname << ");";
12985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
12995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::GetElementPtr: {
13015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
13025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (gep->getNumOperands() <= 2) {
13035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
13045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0];
13055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (gep->getNumOperands() == 2)
13065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << ", " << opNames[1];
13075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
13085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Value*> " << iName << "_indices;";
13095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
13115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << iName << "_indices.push_back("
13125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << opNames[i] << ");";
13135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
13145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
13155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Instruction* " << iName << " = GetElementPtrInst::Create("
13165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << iName << "_indices.begin(), "
13175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << iName << "_indices.end()";
13185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", \"";
13205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(gep->getName());
13215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::PHI: {
13255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const PHINode* phi = cast<PHINode>(I);
13265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
13275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "PHINode* " << iName << " = PHINode::Create("
13285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(phi->getType()) << ", \"";
13295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(phi->getName());
13305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->reserveOperandSpace("
13325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        << phi->getNumIncomingValues()
13335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ");";
13345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
13355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (unsigned i = 0; i < phi->getNumOperands(); i+=2) {
13365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << iName << "->addIncoming("
13375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[i] << ", " << opNames[i+1] << ");";
13385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Trunc:
13435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ZExt:
13445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SExt:
13455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPTrunc:
13465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPExt:
13475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPToUI:
13485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::FPToSI:
13495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UIToFP:
13505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::SIToFP:
13515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::PtrToInt:
13525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::IntToPtr:
13535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::BitCast: {
13545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const CastInst* cst = cast<CastInst>(I);
13555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "CastInst* " << iName << " = new ";
13565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      switch (I->getOpcode()) {
13575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::Trunc:    Out << "TruncInst"; break;
13585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::ZExt:     Out << "ZExtInst"; break;
13595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SExt:     Out << "SExtInst"; break;
13605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPTrunc:  Out << "FPTruncInst"; break;
13615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPExt:    Out << "FPExtInst"; break;
13625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPToUI:   Out << "FPToUIInst"; break;
13635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::FPToSI:   Out << "FPToSIInst"; break;
13645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::UIToFP:   Out << "UIToFPInst"; break;
13655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::SIToFP:   Out << "SIToFPInst"; break;
13665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
13675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
13685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      case Instruction::BitCast:  Out << "BitCastInst"; break;
13695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      default: assert(!"Unreachable"); break;
13705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "(" << opNames[0] << ", "
13725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(cst->getType()) << ", \"";
13735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(cst->getName());
13745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
13755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
13765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
13775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Call:{
13785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const CallInst* call = cast<CallInst>(I);
13790c8f7dc67cebcb1eef5984baaa4802cb46f72797Gabor Greif      if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
13805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
13815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(ila->getFunctionType()) << ", \""
13825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ila->getAsmString() << "\", \""
13835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ila->getConstraintString() << "\","
13845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << (ila->hasSideEffects() ? "true" : "false") << ");";
13855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
13875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (call->getNumOperands() > 2) {
13885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "std::vector<Value*> " << iName << "_params;";
13895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
13905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 1; i < call->getNumOperands(); ++i) {
13915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << iName << "_params.push_back(" << opNames[i] << ");";
13925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
13935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
13945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create("
13955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << iName << "_params.begin(), "
13965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << iName << "_params.end(), \"";
13975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else if (call->getNumOperands() == 2) {
13985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create("
13995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << opNames[0] << ", " << opNames[1] << ", \"";
14005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      } else {
14015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "CallInst* " << iName << " = CallInst::Create(" << opNames[0]
14025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << ", \"";
14035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
14045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(call->getName());
14055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setCallingConv(";
14075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCallingConv(call->getCallingConv());
14085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
14095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << iName << "->setTailCall("
14105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << (call->isTailCall() ? "true":"false");
14115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
14120598866c052147c31b808391f58434ce3dbfb838Devang Patel      printAttributes(call->getAttributes(), iName);
14130598866c052147c31b808391f58434ce3dbfb838Devang Patel      Out << iName << "->setAttributes(" << iName << "_PAL);";
14145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
14155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::Select: {
14185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const SelectInst* sel = cast<SelectInst>(I);
14195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
14205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(sel->getName());
14225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UserOp1:
14265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      /// FALL THROUGH
14275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::UserOp2: {
14285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      /// FIXME: What should be done here?
14295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::VAArg: {
14325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const VAArgInst* va = cast<VAArgInst>(I);
14335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
14345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
14355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(va->getName());
14365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ExtractElement: {
14405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ExtractElementInst* eei = cast<ExtractElementInst>(I);
14415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ExtractElementInst* " << getCppName(eei)
14425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = new ExtractElementInst(" << opNames[0]
14435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", \"";
14445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(eei->getName());
14455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::InsertElement: {
14495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const InsertElementInst* iei = cast<InsertElementInst>(I);
14505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "InsertElementInst* " << getCppName(iei)
14515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = InsertElementInst::Create(" << opNames[0]
14525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(iei->getName());
14545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
14575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    case Instruction::ShuffleVector: {
14585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
14595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "ShuffleVectorInst* " << getCppName(svi)
14605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << " = new ShuffleVectorInst(" << opNames[0]
14615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << ", " << opNames[1] << ", " << opNames[2] << ", \"";
14625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(svi->getName());
14635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << bbname << ");";
14645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
14655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
146675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    case Instruction::ExtractValue: {
146775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      const ExtractValueInst *evi = cast<ExtractValueInst>(I);
146875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "std::vector<unsigned> " << iName << "_indices;";
146975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      nl(Out);
147075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
147175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        Out << iName << "_indices.push_back("
147275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman            << evi->idx_begin()[i] << ");";
147375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        nl(Out);
147475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      }
147575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "ExtractValueInst* " << getCppName(evi)
147675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << " = ExtractValueInst::Create(" << opNames[0]
147775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << ", "
147875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
147975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      printEscapedString(evi->getName());
148075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "\", " << bbname << ");";
148175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      break;
148275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    }
148375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    case Instruction::InsertValue: {
148475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      const InsertValueInst *ivi = cast<InsertValueInst>(I);
148575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "std::vector<unsigned> " << iName << "_indices;";
148675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      nl(Out);
148775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
148875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        Out << iName << "_indices.push_back("
148975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman            << ivi->idx_begin()[i] << ");";
149075146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman        nl(Out);
149175146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      }
149275146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "InsertValueInst* " << getCppName(ivi)
149375146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << " = InsertValueInst::Create(" << opNames[0]
149475146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << ", " << opNames[1] << ", "
149575146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
149675146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      printEscapedString(ivi->getName());
149775146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      Out << "\", " << bbname << ");";
149875146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman      break;
149975146a6725739fe11ca183f1c4c5518eb164b2e5Dan Gohman    }
15005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
15015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  DefinedValues.insert(I);
15025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  nl(Out);
15035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  delete [] opNames;
15045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
15055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Print out the types, constants and declarations needed by one function
15075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionUses(const Function* F) {
15085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions"; nl(Out);
15095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!is_inline) {
15105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the function's return type
15115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(F->getReturnType());
15125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the function's function type
15145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(F->getFunctionType());
15155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Print the types of each of the function's arguments
15175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
15185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           AI != AE; ++AI) {
15195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(AI->getType());
15205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print type definitions for every type referenced by an instruction and
15245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // make a note of any global values or constants that are referenced
15255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    SmallPtrSet<GlobalValue*,64> gvs;
15265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    SmallPtrSet<Constant*,64> consts;
15275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BB = F->begin(), BE = F->end();
15285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BB != BE; ++BB){
15295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
15305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           I != E; ++I) {
15315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Print the type of the instruction itself
15325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printType(I->getType());
15335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        // Print the type of each of the instruction's operands
15355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        for (unsigned i = 0; i < I->getNumOperands(); ++i) {
15365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Value* operand = I->getOperand(i);
15375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printType(operand->getType());
15385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          // If the operand references a GVal or Constant, make a note of it
15405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
15415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            gvs.insert(GV);
15425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
15435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              if (GVar->hasInitializer())
15445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                consts.insert(GVar->getInitializer());
15455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          } else if (Constant* C = dyn_cast<Constant>(operand))
15465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            consts.insert(C);
15475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
15485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the function declarations for any functions encountered
15525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Declarations"; nl(Out);
15535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (Function* Fun = dyn_cast<Function>(*I)) {
15565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (!is_inline || Fun != F)
15575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          printFunctionHead(Fun);
15585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
15595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print the global variable declarations for any variables encountered
15625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Declarations"; nl(Out);
15635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (GlobalVariable* F = dyn_cast<GlobalVariable>(*I))
15665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableHead(F);
15675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  // Print the constants found
15705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Constant Definitions"; nl(Out);
15715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<Constant*,64>::iterator I = consts.begin(),
15725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = consts.end(); I != E; ++I) {
15735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printConstant(*I);
15745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables definitions now that all the constants have
15775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // been emitted. These definitions just couple the gvars with their constant
15785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // initializers.
15795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Definitions"; nl(Out);
15805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (SmallPtrSet<GlobalValue*,64>::iterator I = gvs.begin(), E = gvs.end();
15815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
15825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (GlobalVariable* GV = dyn_cast<GlobalVariable>(*I))
15835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printVariableBody(GV);
15845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
15865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
15875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionHead(const Function* F) {
15885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "Function* " << getCppName(F);
15895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
15905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << " = mod->getFunction(\"";
15915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(F->getName());
15925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\", " << getCppName(F->getFunctionType()) << ");";
15935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "if (!" << getCppName(F) << ") {";
15945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << getCppName(F);
15955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
15965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out<< " = Function::Create(";
15975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
15985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Linkage=*/";
15995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printLinkageType(F->getLinkage());
16005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ",";
16015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "/*Name=*/\"";
16025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printEscapedString(F->getName());
16035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
16045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,-1);
16055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(F);
16065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "->setCallingConv(";
16075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCallingConv(F->getCallingConv());
16085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ");";
16095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
16105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->hasSection()) {
16115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setSection(\"" << F->getSection() << "\");";
16135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->getAlignment()) {
16165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setAlignment(" << F->getAlignment() << ");";
16185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->getVisibility() != GlobalValue::DefaultVisibility) {
16215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "->setVisibility(";
16235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVisibilityType(F->getVisibility());
16245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ");";
16255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16275eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen    if (F->hasGC()) {
16285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printCppName(F);
16295eca075b74d62c621b160aa216b4cd50829a2cc7Gordon Henriksen      Out << "->setGC(\"" << F->getGC() << "\");";
16305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (is_inline) {
16335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "}";
16345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16360598866c052147c31b808391f58434ce3dbfb838Devang Patel    printAttributes(F->getAttributes(), getCppName(F));
16375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printCppName(F);
16380598866c052147c31b808391f58434ce3dbfb838Devang Patel    Out << "->setAttributes(" << getCppName(F) << "_PAL);";
16395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
16405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
16415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctionBody(const Function *F) {
16435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->isDeclaration())
16445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return; // external functions have no bodies.
16455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Clear the DefinedValues and ForwardRefs maps because we can't have
16475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // cross-function forward refs
16485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    ForwardRefs.clear();
16495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    DefinedValues.clear();
16505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Create all the argument values
16525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!is_inline) {
16535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!F->arg_empty()) {
16545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Function::arg_iterator args = " << getCppName(F)
16555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << "->arg_begin();";
16565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
16575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
16595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           AI != AE; ++AI) {
16605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        Out << "Value* " << getCppName(AI) << " = args++;";
16615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
16625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (AI->hasName()) {
16635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");";
16645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          nl(Out);
16655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        }
16665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Create all the basic blocks
16705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
16715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BI = F->begin(), BE = F->end();
16725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BI != BE; ++BI) {
16735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string bbname(getCppName(BI));
1674267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson      Out << "BasicBlock* " << bbname <<
1675267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson             " = BasicBlock::Create(getGlobalContext(), \"";
16765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (BI->hasName())
16775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printEscapedString(BI->getName());
16785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\"," << getCppName(BI->getParent()) << ",0);";
16795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Output all of its basic blocks... for the function
16835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_iterator BI = F->begin(), BE = F->end();
16845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         BI != BE; ++BI) {
16855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      std::string bbname(getCppName(BI));
16865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")";
16875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
16885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      // Output all of the instructions in the basic block...
16905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
16915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           I != E; ++I) {
16925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printInstruction(I,bbname);
16935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
16945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
16955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
16965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Loop over the ForwardRefs and resolve them now that all instructions
16975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // are generated.
16985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!ForwardRefs.empty()) {
16995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "// Resolve Forward References";
17005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
17015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    while (!ForwardRefs.empty()) {
17045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ForwardRefMap::iterator I = ForwardRefs.begin();
17055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << I->second << "->replaceAllUsesWith("
17065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          << getCppName(I->first) << "); delete " << I->second << ";";
17075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
17085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ForwardRefs.erase(I);
17095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
17115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printInline(const std::string& fname,
17135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                              const std::string& func) {
17145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Function* F = TheModule->getFunction(func);
17155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!F) {
17165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + func + "' not found in input module");
17175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
17185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (F->isDeclaration()) {
17205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + func + "' is external!");
17215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
17225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
17245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov            << getCppName(F);
17255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    unsigned arg_count = 1;
17265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
17275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         AI != AE; ++AI) {
17285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << ", Value* arg_" << arg_count;
17295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << ") {";
17315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
17325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    is_inline = true;
17335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionUses(F);
17345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionBody(F);
17355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    is_inline = false;
17365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(F->begin()) << ";";
17375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "}";
17385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
17395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
17405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printModuleBody() {
17425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print out all the type definitions
17435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Type Definitions"; nl(Out);
17445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printTypes(TheModule);
17455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Functions can call each other and global variables can reference them so
17475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // define all the functions first before emitting their function bodies.
17485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Declarations"; nl(Out);
17495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
17505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I)
17515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunctionHead(I);
17525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables declarations. We can't initialze them until
17545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // after the constants are printed so just print a header for each global
17555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Declarations\n"; nl(Out);
17565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
17575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
17585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariableHead(I);
17595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Print out all the constants definitions. Constants don't recurse except
17625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // through GlobalValues. All GlobalValues have been declared at this point
17635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // so we can proceed to generate the constants.
17645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Constant Definitions"; nl(Out);
17655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printConstants(TheModule);
17665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Process the global variables definitions now that all the constants have
17685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // been emitted. These definitions just couple the gvars with their constant
17695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // initializers.
17705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Global Variable Definitions"; nl(Out);
17715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_global_iterator I = TheModule->global_begin(),
17725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov           E = TheModule->global_end(); I != E; ++I) {
17735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariableBody(I);
17745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Finally, we can safely put out all of the function bodies.
17775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "// Function Definitions"; nl(Out);
17785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
17795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov         I != E; ++I) {
17805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!I->isDeclaration()) {
17815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I)
17825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                << ")";
17835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out) << "{";
17845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out,1);
17855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunctionBody(I);
17865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out,-1) << "}";
17875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        nl(Out);
17885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
17895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
17905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
17915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
17925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printProgram(const std::string& fname,
17935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                               const std::string& mName) {
1794267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson    Out << "#include <llvm/LLVMContext.h>\n";
17955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Module.h>\n";
17965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/DerivedTypes.h>\n";
17975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Constants.h>\n";
17985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/GlobalVariable.h>\n";
17995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Function.h>\n";
18005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/CallingConv.h>\n";
18015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/BasicBlock.h>\n";
18025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Instructions.h>\n";
18035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/InlineAsm.h>\n";
180471847813bc419f7a0667468136a07429c6d9f164David Greene    Out << "#include <llvm/Support/FormattedStream.h>\n";
18055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Support/MathExtras.h>\n";
18065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Pass.h>\n";
18075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/PassManager.h>\n";
18089474ede38b7f991347c48b467397c88cbe99c163Nicolas Geoffray    Out << "#include <llvm/ADT/SmallVector.h>\n";
18095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Analysis/Verifier.h>\n";
18105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
18115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "#include <algorithm>\n";
18125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "using namespace llvm;\n\n";
18135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "Module* " << fname << "();\n\n";
18145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "int main(int argc, char**argv) {\n";
18155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  Module* Mod = " << fname << "();\n";
18165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  verifyModule(*Mod, PrintMessageAction);\n";
18175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  PassManager PM;\n";
1818f923129fc30a8a2c2c0948131dd6458af4ae10eeDan Gohman    Out << "  PM.add(createPrintModulePass(&outs()));\n";
18195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  PM.run(*Mod);\n";
18205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "  return 0;\n";
18215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n\n";
18225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModule(fname,mName);
18235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printModule(const std::string& fname,
18265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                              const std::string& mName) {
18275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "Module* " << fname << "() {";
18285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,1) << "// Module Construction";
1829b8b7347c101367ca6c22843db3ad60702330ec05Nick Lewycky    nl(Out) << "Module* mod = new Module(\"";
1830b8b7347c101367ca6c22843db3ad60702330ec05Nick Lewycky    printEscapedString(mName);
1831267a0ff04519e04b5f74b233201c21258a3609f8Owen Anderson    Out << "\", getGlobalContext());";
18325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getTargetTriple().empty()) {
18335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
18345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getTargetTriple().empty()) {
18365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
18375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov              << "\");";
18385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!TheModule->getModuleInlineAsm().empty()) {
18415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out) << "mod->setModuleInlineAsm(\"";
18425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printEscapedString(TheModule->getModuleInlineAsm());
18435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "\");";
18445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
18465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Loop over the dependent libraries and emit them.
18485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::lib_iterator LI = TheModule->lib_begin();
18495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::lib_iterator LE = TheModule->lib_end();
18505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    while (LI != LE) {
18515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      Out << "mod->addLibrary(\"" << *LI << "\");";
18525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      nl(Out);
18535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      ++LI;
18545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModuleBody();
18565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out) << "return mod;";
18575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out,-1) << "}";
18585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    nl(Out);
18595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printContents(const std::string& fname,
18625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& mName) {
18635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nModule* " << fname << "(Module *mod) {\n";
1864b8b7347c101367ca6c22843db3ad60702330ec05Nick Lewycky    Out << "\nmod->setModuleIdentifier(\"";
1865b8b7347c101367ca6c22843db3ad60702330ec05Nick Lewycky    printEscapedString(mName);
1866b8b7347c101367ca6c22843db3ad60702330ec05Nick Lewycky    Out << "\");\n";
18675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printModuleBody();
18685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nreturn mod;\n";
18695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\n}\n";
18705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunction(const std::string& fname,
18735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& funcName) {
18745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Function* F = TheModule->getFunction(funcName);
18755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!F) {
18765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Function '") + funcName + "' not found in input module");
18775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
18785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
18795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nFunction* " << fname << "(Module *mod) {\n";
18805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionUses(F);
18815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionHead(F);
18825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printFunctionBody(F);
18835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(F) << ";\n";
18845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
18855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
18865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printFunctions() {
18885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Module::FunctionListType &funcs = TheModule->getFunctionList();
18895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::const_iterator I  = funcs.begin();
18905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Module::const_iterator IE = funcs.end();
18915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
18925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    for (; I != IE; ++I) {
18935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      const Function &func = *I;
18945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (!func.isDeclaration()) {
18955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        std::string name("define_");
18965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        name += func.getName();
18975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        printFunction(name, func.getName());
18985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
18995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
19015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printVariable(const std::string& fname,
19035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                const std::string& varName) {
19045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
19055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!GV) {
19075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Variable '") + varName + "' not found in input module");
19085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
19095027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
19115027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableUses(GV);
19125027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableHead(GV);
19135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printVariableBody(GV);
19145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(GV) << ";\n";
19155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
19165027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
19175027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19185027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  void CppWriter::printType(const std::string& fname,
19195027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                            const std::string& typeName) {
19205027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    const Type* Ty = TheModule->getTypeByName(typeName);
19215027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (!Ty) {
19225027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error(std::string("Type '") + typeName + "' not found in input module");
19235027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      return;
19245027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19255027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "\nType* " << fname << "(Module *mod) {\n";
19265027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    printType(Ty);
19275027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "return " << getCppName(Ty) << ";\n";
19285027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "}\n";
19295027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
19305027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19315027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  bool CppWriter::runOnModule(Module &M) {
19325027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    TheModule = &M;
19335027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19345027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Emit a header
19355027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
19365027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19375027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Get the name of the function we're supposed to generate
19385027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string fname = FuncName.getValue();
19395027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19405027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    // Get the name of the thing we are to generate
19415027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    std::string tgtname = NameToGenerate.getValue();
19425027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (GenerationType == GenModule ||
19435027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenContents ||
19445027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenProgram ||
19455027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        GenerationType == GenFunctions) {
19465027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (tgtname == "!bad!") {
19475027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        if (M.getModuleIdentifier() == "-")
19485027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tgtname = "<stdin>";
19495027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        else
19505027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov          tgtname = M.getModuleIdentifier();
19515027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      }
19525027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else if (tgtname == "!bad!")
19535027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("You must use the -for option with -gen-{function,variable,type}");
19545027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    switch (WhatToGenerate(GenerationType)) {
19565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenProgram:
19575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModule";
19595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printProgram(fname,tgtname);
19605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenModule:
19625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModule";
19645027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printModule(fname,tgtname);
19655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenContents:
19675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMModuleContents";
19695027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printContents(fname,tgtname);
19705027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19715027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenFunction:
19725027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19735027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMFunction";
19745027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunction(fname,tgtname);
19755027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19765027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenFunctions:
19775027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printFunctions();
19785027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19795027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenInline:
19805027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19815027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMInline";
19825027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printInline(fname,tgtname);
19835027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19845027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenVariable:
19855027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19865027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMVariable";
19875027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printVariable(fname,tgtname);
19885027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19895027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     case GenType:
19905027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (fname.empty())
19915027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        fname = "makeLLVMType";
19925027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      printType(fname,tgtname);
19935027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      break;
19945027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov     default:
19955027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      error("Invalid generation option");
19965027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    }
19975027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
19985027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    return false;
19995027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  }
20005027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
20015027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
20025027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovchar CppWriter::ID = 0;
20035027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
20045027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
20055027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//                       External Interface declaration
20065027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov//===----------------------------------------------------------------------===//
20075027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov
20085027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikovbool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
200971847813bc419f7a0667468136a07429c6d9f164David Greene                                                formatted_raw_ostream &o,
20105027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov                                                CodeGenFileType FileType,
201198a366d547772010e94609e4584489b3e5ce0043Bill Wendling                                                CodeGenOpt::Level OptLevel) {
2012211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
20135027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  PM.add(new CppWriter(o));
20145027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov  return false;
20155027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov}
2016