From a9d9ca469fd2442e1352028a7a69d23de0a4cbd5 Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Sun, 4 May 2008 06:16:50 +0000 Subject: [PATCH] Drop llvm2cpp, it's now a llc target git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50614 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/CommandGuide/llvm2cpp.pod | 217 ---- tools/llvm2cpp/CppWriter.cpp | 1968 -------------------------------- tools/llvm2cpp/CppWriter.h | 18 - tools/llvm2cpp/Makefile | 15 - tools/llvm2cpp/llvm2cpp.cpp | 122 -- 5 files changed, 2340 deletions(-) delete mode 100644 docs/CommandGuide/llvm2cpp.pod delete mode 100644 tools/llvm2cpp/CppWriter.cpp delete mode 100644 tools/llvm2cpp/CppWriter.h delete mode 100644 tools/llvm2cpp/Makefile delete mode 100644 tools/llvm2cpp/llvm2cpp.cpp diff --git a/docs/CommandGuide/llvm2cpp.pod b/docs/CommandGuide/llvm2cpp.pod deleted file mode 100644 index 4b86ae0fea6..00000000000 --- a/docs/CommandGuide/llvm2cpp.pod +++ /dev/null @@ -1,217 +0,0 @@ -=pod - -=head1 NAME - -llvm2xpp - LLVM bitcode to LLVM C++ IR translator - -=head1 SYNOPSIS - -B [I] [I] - -=head1 DESCRIPTION - -B translates from LLVM bitcode (.bc files) to a -corresponding C++ source file that will make calls against the LLVM C++ API to -build the same module as the input. By default, the C++ output is a complete -program that builds the module, verifies it and then emits the module as -LLVM assembly. This technique assists with testing because the input to -B and the output of the generated C++ program should be identical. - -If F is omitted or is C<->, then B reads its input from -standard input. - -If an output file is not specified with the B<-o> option, then -B sends its output to a file or standard output by following -these rules: - -=over - -=item * - -If the input is standard input, then the output is standard output. - -=item * - -If the input is a file that ends with C<.bc>, then the output file is of -the same name, except that the suffix is changed to C<.cpp>. - -=item * - -If the input is a file that does not end with the C<.bc> suffix, then the -output file has the same name as the input file, except that the C<.cpp> -suffix is appended. - -=back - -=head1 OPTIONS - -=over - -=item B<-f> - -Force overwrite. Normally, B will refuse to overwrite an -output file that already exists. With this option, B -will overwrite the output file and replace it with new C++ source code. - -=item B<--help> - -Print a summary of command line options. - -=item B<-f> - -Normally, B will not overwrite an existing output file. With this -option, that default behavior is changed and the program will overwrite existing -output files. - -=item B<-o> F - -Specify the output file name. If F is C<->, then B -sends its output to standard output. - -=item B<-funcname> F - -Specify the name of the function to be generated. The generated code contains a -single function that produces the input module. By default its name is -I. The B<-funcname> option overrides this default and allows -you to control the name of the generated function. This is handy in conjunction -with the B<-fragment> option when you only want B to generate a -single function that produces the module. With both options, such generated code -could be I<#included> into another program. - -=item B<-for> - -Specify the name of the thing for which C++ code should be generated. By default -the entire input module is re-generated. However, use of the various B<-gen-*> -options can restrict what is produced. This option indicates what that -restriction is. - -=item B<-gen-program> - -Specify that the output should be a complete program. Such program will recreate -B's input as an LLVM module, verify that module, and then write out -the module in LLVM assembly format. This is useful for doing identity tests -where the output of the generated program is identical to the input to -B. The LLVM DejaGnu test suite can make use of this fact. This is the -default form of generated output. - -If the B<-for> option is given with this option, it specifies the module -identifier to use for the module created. - -=item B<-gen-module> - -Specify that the output should be a function that regenerates the module. It is -assumed that this output will be #included into another program that has already -arranged for the correct header files to be #included. The function generated -takes no arguments and returns a I. - -If the B<-for> option is given with this option, it specifies the module -identifier to use in creating the module returned by the generated function. - -=item B<-gen-contents> - -Specify that the output should be a function that adds the contents of the input -module to another module. It is assumed that the output will be #included into -another program that has already arranged for the correct header files to be -#included. The function generated takes a single argument of type I and -returns that argument. Note that Module level attributes such as endianess, -pointer size, target triple and inline asm are not passed on from the input -module to the destination module. Only the sub-elements of the module (types, -constants, functions, global variables) will be added to the input module. - -If the B<-for> option is given with this option, it specifies the module -identifier to set in the input module by the generated function. - -=item B<-gen-function> - -Specify that the output should be a function that produces the definitions -necessary for a specific function to be added to a module. It is assumed that -the output will be #included into another program that has already arranged -for the correct header files to be #included. The function generated takes a -single argument of type I and returns the I that it added to -the module. Note that only those things (types, constants, etc.) directly -needed in the definition of the function will be placed in the generated -function. - -The B<-for> option must be given with this option or an error will be produced. -The value of the option must be the name of a function in the input module for -which code should be generated. If the named function does not exist an error -will be produced. - -=item B<-gen-inline> - -This option is very analagous to B<-gen-function> except that the generated -function will not re-produce the target function's definition. Instead, the body -of the target function is inserted into some other function passed as an -argument to the generated function. Similarly any arguments to the function must -be passed to the generated function. The result of the generated function is the -first basic block of the target function. - -The B<-for> option works the same way as it does for B<-gen-function>. - -=item B<-gen-variable> - -Specify that the output should be a function that produces the definitions -necessary for a specific global variable to be added to a module. It is assumed -that the output will be #included into another program that has already arranged -for the correct header files to be #included. The function generated takes a -single argument of type I and returns the I that it -added to the module. Note that only those things (types, constants, etc.) -directly needed in the definition of the global variable will be placed in the -generated function. - -The B<-for> option must be given with this option or an error will be produced. -THe value of the option must be the name of a global variable in the input -module for which code should be generated. If the named global variable does not -exist an error will be produced. - -=item B<-gen-type> - -Specify that the output should be a function that produces the definitions -necessary for specific type to be added to a module. It is assumed that the -otuput will be #included into another program that has already arranged for the -correct header files to be #included. The function generated take a single -argument of type I and returns the I that it added to the -module. Note that the generated function will only add the necessary type -definitions to (possibly recursively) define the requested type. - -The B<-for> option must be given with this option or an error will be produced. -The value of the option must be the name of a global type in the input module -for which code should be generated. If the named type does not exist an error -will be produced. - -=item B<-stats> - -Show pass statistics (not interesting in this program). - -=item B<-time-passes> - -Show pass timing statistics (not interesting in this program). - -=item B<-version> - -Show the version number of this program. - -=back - - -=head1 EXIT STATUS - -If B succeeds, it will exit with 0. Otherwise, if an error -occurs, it will exit with a non-zero value. - -=head1 SEE ALSO - -L L - -=head1 NOTES - -This tool may be removed from a future version of LLVM. Instead, its -functionality may be incorporated into the llc tool. It would then act similarly -to other targets except its output would be C++ source that could be compiled to -construct the input program. - -=head1 AUTHORS - -Written by Reid Spencer (L). - -=cut diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp deleted file mode 100644 index b724b9c8718..00000000000 --- a/tools/llvm2cpp/CppWriter.cpp +++ /dev/null @@ -1,1968 +0,0 @@ -//===-- CppWriter.cpp - Printing LLVM IR as a C++ Source File -------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the writing of the LLVM IR as a set of C++ calls to the -// LLVM IR interface. The input module is assumed to be verified. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CallingConv.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instruction.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/TypeSymbolTable.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/CFG.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MathExtras.h" -#include "llvm/Config/config.h" -#include -#include -#include - -using namespace llvm; - -static cl::opt -FuncName("funcname", cl::desc("Specify the name of the generated function"), - cl::value_desc("function name")); - -enum WhatToGenerate { - GenProgram, - GenModule, - GenContents, - GenFunction, - GenFunctions, - GenInline, - GenVariable, - GenType -}; - -static cl::opt GenerationType(cl::Optional, - cl::desc("Choose what kind of output to generate"), - cl::init(GenProgram), - cl::values( - clEnumValN(GenProgram, "gen-program", "Generate a complete program"), - clEnumValN(GenModule, "gen-module", "Generate a module definition"), - clEnumValN(GenContents, "gen-contents", "Generate contents of a module"), - clEnumValN(GenFunction, "gen-function", "Generate a function definition"), - clEnumValN(GenFunctions,"gen-functions", "Generate all function definitions"), - clEnumValN(GenInline, "gen-inline", "Generate an inline function"), - clEnumValN(GenVariable, "gen-variable", "Generate a variable definition"), - clEnumValN(GenType, "gen-type", "Generate a type definition"), - clEnumValEnd - ) -); - -static cl::opt NameToGenerate("for", cl::Optional, - cl::desc("Specify the name of the thing to generate"), - cl::init("!bad!")); - -namespace { -typedef std::vector TypeList; -typedef std::map TypeMap; -typedef std::map ValueMap; -typedef std::set NameSet; -typedef std::set TypeSet; -typedef std::set ValueSet; -typedef std::map ForwardRefMap; - -class CppWriter { - const char* progname; - std::ostream &Out; - const Module *TheModule; - uint64_t uniqueNum; - TypeMap TypeNames; - ValueMap ValueNames; - TypeMap UnresolvedTypes; - TypeList TypeStack; - NameSet UsedNames; - TypeSet DefinedTypes; - ValueSet DefinedValues; - ForwardRefMap ForwardRefs; - bool is_inline; - -public: - inline CppWriter(std::ostream &o, const Module *M, const char* pn="llvm2cpp") - : progname(pn), Out(o), TheModule(M), uniqueNum(0), TypeNames(), - ValueNames(), UnresolvedTypes(), TypeStack(), is_inline(false) { } - - const Module* getModule() { return TheModule; } - - void printProgram(const std::string& fname, const std::string& modName ); - void printModule(const std::string& fname, const std::string& modName ); - void printContents(const std::string& fname, const std::string& modName ); - void printFunction(const std::string& fname, const std::string& funcName ); - void printFunctions(); - void printInline(const std::string& fname, const std::string& funcName ); - void printVariable(const std::string& fname, const std::string& varName ); - void printType(const std::string& fname, const std::string& typeName ); - - void error(const std::string& msg); - -private: - void printLinkageType(GlobalValue::LinkageTypes LT); - void printVisibilityType(GlobalValue::VisibilityTypes VisTypes); - void printCallingConv(unsigned cc); - void printEscapedString(const std::string& str); - void printCFP(const ConstantFP* CFP); - - std::string getCppName(const Type* val); - inline void printCppName(const Type* val); - - std::string getCppName(const Value* val); - inline void printCppName(const Value* val); - - void printParamAttrs(const PAListPtr &PAL, const std::string &name); - bool printTypeInternal(const Type* Ty); - inline void printType(const Type* Ty); - void printTypes(const Module* M); - - void printConstant(const Constant *CPV); - void printConstants(const Module* M); - - void printVariableUses(const GlobalVariable *GV); - void printVariableHead(const GlobalVariable *GV); - void printVariableBody(const GlobalVariable *GV); - - void printFunctionUses(const Function *F); - void printFunctionHead(const Function *F); - void printFunctionBody(const Function *F); - void printInstruction(const Instruction *I, const std::string& bbname); - std::string getOpName(Value*); - - void printModuleBody(); - -}; - -static unsigned indent_level = 0; -inline std::ostream& nl(std::ostream& Out, int delta = 0) { - Out << "\n"; - if (delta >= 0 || indent_level >= unsigned(-delta)) - indent_level += delta; - for (unsigned i = 0; i < indent_level; ++i) - Out << " "; - return Out; -} - -inline void in() { indent_level++; } -inline void out() { if (indent_level >0) indent_level--; } - -inline void -sanitize(std::string& str) { - for (size_t i = 0; i < str.length(); ++i) - if (!isalnum(str[i]) && str[i] != '_') - str[i] = '_'; -} - -inline std::string -getTypePrefix(const Type* Ty ) { - switch (Ty->getTypeID()) { - case Type::VoidTyID: return "void_"; - case Type::IntegerTyID: - return std::string("int") + utostr(cast(Ty)->getBitWidth()) + - "_"; - case Type::FloatTyID: return "float_"; - case Type::DoubleTyID: return "double_"; - case Type::LabelTyID: return "label_"; - case Type::FunctionTyID: return "func_"; - case Type::StructTyID: return "struct_"; - case Type::ArrayTyID: return "array_"; - case Type::PointerTyID: return "ptr_"; - case Type::VectorTyID: return "packed_"; - case Type::OpaqueTyID: return "opaque_"; - default: return "other_"; - } - return "unknown_"; -} - -// Looks up the type in the symbol table and returns a pointer to its name or -// a null pointer if it wasn't found. Note that this isn't the same as the -// Mode::getTypeName function which will return an empty string, not a null -// pointer if the name is not found. -inline const std::string* -findTypeName(const TypeSymbolTable& ST, const Type* Ty) -{ - TypeSymbolTable::const_iterator TI = ST.begin(); - TypeSymbolTable::const_iterator TE = ST.end(); - for (;TI != TE; ++TI) - if (TI->second == Ty) - return &(TI->first); - return 0; -} - -void -CppWriter::error(const std::string& msg) { - std::cerr << progname << ": " << msg << "\n"; - exit(2); -} - -// printCFP - Print a floating point constant .. very carefully :) -// This makes sure that conversion to/from floating yields the same binary -// result so that we don't lose precision. -void -CppWriter::printCFP(const ConstantFP *CFP) { - APFloat APF = APFloat(CFP->getValueAPF()); // copy - if (CFP->getType() == Type::FloatTy) - APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven); - Out << "ConstantFP::get("; - if (CFP->getType() == Type::DoubleTy) - Out << "Type::DoubleTy, "; - else - Out << "Type::FloatTy, "; - Out << "APFloat("; -#if HAVE_PRINTF_A - char Buffer[100]; - sprintf(Buffer, "%A", APF.convertToDouble()); - if ((!strncmp(Buffer, "0x", 2) || - !strncmp(Buffer, "-0x", 3) || - !strncmp(Buffer, "+0x", 3)) && - APF.bitwiseIsEqual(APFloat(atof(Buffer)))) { - if (CFP->getType() == Type::DoubleTy) - Out << "BitsToDouble(" << Buffer << ")"; - else - Out << "BitsToFloat((float)" << Buffer << ")"; - Out << ")"; - } else { -#endif - std::string StrVal = ftostr(CFP->getValueAPF()); - - while (StrVal[0] == ' ') - StrVal.erase(StrVal.begin()); - - // Check to make sure that the stringized number is not some string like - // "Inf" or NaN. Check that the string matches the "[-+]?[0-9]" regex. - if (((StrVal[0] >= '0' && StrVal[0] <= '9') || - ((StrVal[0] == '-' || StrVal[0] == '+') && - (StrVal[1] >= '0' && StrVal[1] <= '9'))) && - (CFP->isExactlyValue(atof(StrVal.c_str())))) { - if (CFP->getType() == Type::DoubleTy) - Out << StrVal; - else - Out << StrVal << "f"; - } - else if (CFP->getType() == Type::DoubleTy) - Out << "BitsToDouble(0x" << std::hex - << CFP->getValueAPF().convertToAPInt().getZExtValue() - << std::dec << "ULL) /* " << StrVal << " */"; - else - Out << "BitsToFloat(0x" << std::hex - << (uint32_t)CFP->getValueAPF().convertToAPInt().getZExtValue() - << std::dec << "U) /* " << StrVal << " */"; - Out << ")"; -#if HAVE_PRINTF_A - } -#endif - Out << ")"; -} - -void -CppWriter::printCallingConv(unsigned cc){ - // Print the calling convention. - switch (cc) { - case CallingConv::C: Out << "CallingConv::C"; break; - case CallingConv::Fast: Out << "CallingConv::Fast"; break; - case CallingConv::Cold: Out << "CallingConv::Cold"; break; - case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break; - default: Out << cc; break; - } -} - -void -CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { - switch (LT) { - case GlobalValue::InternalLinkage: - Out << "GlobalValue::InternalLinkage"; break; - case GlobalValue::LinkOnceLinkage: - Out << "GlobalValue::LinkOnceLinkage "; break; - case GlobalValue::WeakLinkage: - Out << "GlobalValue::WeakLinkage"; break; - case GlobalValue::AppendingLinkage: - Out << "GlobalValue::AppendingLinkage"; break; - case GlobalValue::ExternalLinkage: - Out << "GlobalValue::ExternalLinkage"; break; - case GlobalValue::DLLImportLinkage: - Out << "GlobalValue::DLLImportLinkage"; break; - case GlobalValue::DLLExportLinkage: - Out << "GlobalValue::DLLExportLinkage"; break; - case GlobalValue::ExternalWeakLinkage: - Out << "GlobalValue::ExternalWeakLinkage"; break; - case GlobalValue::GhostLinkage: - Out << "GlobalValue::GhostLinkage"; break; - } -} - -void -CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) { - switch (VisType) { - default: assert(0 && "Unknown GVar visibility"); - case GlobalValue::DefaultVisibility: - Out << "GlobalValue::DefaultVisibility"; - break; - case GlobalValue::HiddenVisibility: - Out << "GlobalValue::HiddenVisibility"; - break; - case GlobalValue::ProtectedVisibility: - Out << "GlobalValue::ProtectedVisibility"; - break; - } -} - -// printEscapedString - Print each character of the specified string, escaping -// it if it is not printable or if it is an escape char. -void -CppWriter::printEscapedString(const std::string &Str) { - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char C = Str[i]; - if (isprint(C) && C != '"' && C != '\\') { - Out << C; - } else { - Out << "\\x" - << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) - << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); - } - } -} - -std::string -CppWriter::getCppName(const Type* Ty) -{ - // First, handle the primitive types .. easy - if (Ty->isPrimitiveType() || Ty->isInteger()) { - switch (Ty->getTypeID()) { - case Type::VoidTyID: return "Type::VoidTy"; - case Type::IntegerTyID: { - unsigned BitWidth = cast(Ty)->getBitWidth(); - return "IntegerType::get(" + utostr(BitWidth) + ")"; - } - case Type::FloatTyID: return "Type::FloatTy"; - case Type::DoubleTyID: return "Type::DoubleTy"; - case Type::LabelTyID: return "Type::LabelTy"; - default: - error("Invalid primitive type"); - break; - } - return "Type::VoidTy"; // shouldn't be returned, but make it sensible - } - - // Now, see if we've seen the type before and return that - TypeMap::iterator I = TypeNames.find(Ty); - if (I != TypeNames.end()) - return I->second; - - // Okay, let's build a new name for this type. Start with a prefix - const char* prefix = 0; - switch (Ty->getTypeID()) { - case Type::FunctionTyID: prefix = "FuncTy_"; break; - case Type::StructTyID: prefix = "StructTy_"; break; - case Type::ArrayTyID: prefix = "ArrayTy_"; break; - case Type::PointerTyID: prefix = "PointerTy_"; break; - case Type::OpaqueTyID: prefix = "OpaqueTy_"; break; - case Type::VectorTyID: prefix = "VectorTy_"; break; - default: prefix = "OtherTy_"; break; // prevent breakage - } - - // See if the type has a name in the symboltable and build accordingly - const std::string* tName = findTypeName(TheModule->getTypeSymbolTable(), Ty); - std::string name; - if (tName) - name = std::string(prefix) + *tName; - else - name = std::string(prefix) + utostr(uniqueNum++); - sanitize(name); - - // Save the name - return TypeNames[Ty] = name; -} - -void -CppWriter::printCppName(const Type* Ty) -{ - printEscapedString(getCppName(Ty)); -} - -std::string -CppWriter::getCppName(const Value* val) { - std::string name; - ValueMap::iterator I = ValueNames.find(val); - if (I != ValueNames.end() && I->first == val) - return I->second; - - if (const GlobalVariable* GV = dyn_cast(val)) { - name = std::string("gvar_") + - getTypePrefix(GV->getType()->getElementType()); - } else if (isa(val)) { - name = std::string("func_"); - } else if (const Constant* C = dyn_cast(val)) { - name = std::string("const_") + getTypePrefix(C->getType()); - } else if (const Argument* Arg = dyn_cast(val)) { - if (is_inline) { - unsigned argNum = std::distance(Arg->getParent()->arg_begin(), - Function::const_arg_iterator(Arg)) + 1; - name = std::string("arg_") + utostr(argNum); - NameSet::iterator NI = UsedNames.find(name); - if (NI != UsedNames.end()) - name += std::string("_") + utostr(uniqueNum++); - UsedNames.insert(name); - return ValueNames[val] = name; - } else { - name = getTypePrefix(val->getType()); - } - } else { - name = getTypePrefix(val->getType()); - } - name += (val->hasName() ? val->getName() : utostr(uniqueNum++)); - sanitize(name); - NameSet::iterator NI = UsedNames.find(name); - if (NI != UsedNames.end()) - name += std::string("_") + utostr(uniqueNum++); - UsedNames.insert(name); - return ValueNames[val] = name; -} - -void -CppWriter::printCppName(const Value* val) { - printEscapedString(getCppName(val)); -} - -void -CppWriter::printParamAttrs(const PAListPtr &PAL, const std::string &name) { - Out << "PAListPtr " << name << "_PAL = 0;"; - nl(Out); - if (!PAL.isEmpty()) { - Out << '{'; in(); nl(Out); - Out << "SmallVector Attrs;"; nl(Out); - Out << "ParamAttrsWithIndex PAWI;"; nl(Out); - for (unsigned i = 0; i < PAL.getNumSlots(); ++i) { - uint16_t index = PAL.getSlot(i).Index; - ParameterAttributes attrs = PAL.getSlot(i).Attrs; - Out << "PAWI.index = " << index << "; PAWI.attrs = 0 "; - if (attrs & ParamAttr::SExt) - Out << " | ParamAttr::SExt"; - if (attrs & ParamAttr::ZExt) - Out << " | ParamAttr::ZExt"; - if (attrs & ParamAttr::StructRet) - Out << " | ParamAttr::StructRet"; - if (attrs & ParamAttr::InReg) - Out << " | ParamAttr::InReg"; - if (attrs & ParamAttr::NoReturn) - Out << " | ParamAttr::NoReturn"; - if (attrs & ParamAttr::NoUnwind) - Out << " | ParamAttr::NoUnwind"; - if (attrs & ParamAttr::ByVal) - Out << " | ParamAttr::ByVal"; - if (attrs & ParamAttr::NoAlias) - Out << " | ParamAttr::NoAlias"; - if (attrs & ParamAttr::Nest) - Out << " | ParamAttr::Nest"; - if (attrs & ParamAttr::ReadNone) - Out << " | ParamAttr::ReadNone"; - if (attrs & ParamAttr::ReadOnly) - Out << " | ParamAttr::ReadOnly"; - Out << ";"; - nl(Out); - Out << "Attrs.push_back(PAWI);"; - nl(Out); - } - Out << name << "_PAL = PAListPtr::get(Attrs.begin(), Attrs.end());"; - nl(Out); - out(); nl(Out); - Out << '}'; nl(Out); - } -} - -bool -CppWriter::printTypeInternal(const Type* Ty) { - // We don't print definitions for primitive types - if (Ty->isPrimitiveType() || Ty->isInteger()) - return false; - - // If we already defined this type, we don't need to define it again. - if (DefinedTypes.find(Ty) != DefinedTypes.end()) - return false; - - // Everything below needs the name for the type so get it now. - std::string typeName(getCppName(Ty)); - - // Search the type stack for recursion. If we find it, then generate this - // as an OpaqueType, but make sure not to do this multiple times because - // the type could appear in multiple places on the stack. Once the opaque - // definition is issued, it must not be re-issued. Consequently we have to - // check the UnresolvedTypes list as well. - TypeList::const_iterator TI = std::find(TypeStack.begin(),TypeStack.end(),Ty); - if (TI != TypeStack.end()) { - TypeMap::const_iterator I = UnresolvedTypes.find(Ty); - if (I == UnresolvedTypes.end()) { - Out << "PATypeHolder " << typeName << "_fwd = OpaqueType::get();"; - nl(Out); - UnresolvedTypes[Ty] = typeName; - } - return true; - } - - // We're going to print a derived type which, by definition, contains other - // types. So, push this one we're printing onto the type stack to assist with - // recursive definitions. - TypeStack.push_back(Ty); - - // Print the type definition - switch (Ty->getTypeID()) { - case Type::FunctionTyID: { - const FunctionType* FT = cast(Ty); - Out << "std::vector" << typeName << "_args;"; - nl(Out); - FunctionType::param_iterator PI = FT->param_begin(); - FunctionType::param_iterator PE = FT->param_end(); - for (; PI != PE; ++PI) { - const Type* argTy = static_cast(*PI); - bool isForward = printTypeInternal(argTy); - std::string argName(getCppName(argTy)); - Out << typeName << "_args.push_back(" << argName; - if (isForward) - Out << "_fwd"; - Out << ");"; - nl(Out); - } - bool isForward = printTypeInternal(FT->getReturnType()); - std::string retTypeName(getCppName(FT->getReturnType())); - Out << "FunctionType* " << typeName << " = FunctionType::get("; - in(); nl(Out) << "/*Result=*/" << retTypeName; - if (isForward) - Out << "_fwd"; - Out << ","; - nl(Out) << "/*Params=*/" << typeName << "_args,"; - nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");"; - out(); - nl(Out); - break; - } - case Type::StructTyID: { - const StructType* ST = cast(Ty); - Out << "std::vector" << typeName << "_fields;"; - nl(Out); - StructType::element_iterator EI = ST->element_begin(); - StructType::element_iterator EE = ST->element_end(); - for (; EI != EE; ++EI) { - const Type* fieldTy = static_cast(*EI); - bool isForward = printTypeInternal(fieldTy); - std::string fieldName(getCppName(fieldTy)); - Out << typeName << "_fields.push_back(" << fieldName; - if (isForward) - Out << "_fwd"; - Out << ");"; - nl(Out); - } - Out << "StructType* " << typeName << " = StructType::get(" - << typeName << "_fields, /*isPacked=*/" - << (ST->isPacked() ? "true" : "false") << ");"; - nl(Out); - break; - } - case Type::ArrayTyID: { - const ArrayType* AT = cast(Ty); - const Type* ET = AT->getElementType(); - bool isForward = printTypeInternal(ET); - std::string elemName(getCppName(ET)); - Out << "ArrayType* " << typeName << " = ArrayType::get(" - << elemName << (isForward ? "_fwd" : "") - << ", " << utostr(AT->getNumElements()) << ");"; - nl(Out); - break; - } - case Type::PointerTyID: { - const PointerType* PT = cast(Ty); - const Type* ET = PT->getElementType(); - bool isForward = printTypeInternal(ET); - std::string elemName(getCppName(ET)); - Out << "PointerType* " << typeName << " = PointerType::get(" - << elemName << (isForward ? "_fwd" : "") - << ", " << utostr(PT->getAddressSpace()) << ");"; - nl(Out); - break; - } - case Type::VectorTyID: { - const VectorType* PT = cast(Ty); - const Type* ET = PT->getElementType(); - bool isForward = printTypeInternal(ET); - std::string elemName(getCppName(ET)); - Out << "VectorType* " << typeName << " = VectorType::get(" - << elemName << (isForward ? "_fwd" : "") - << ", " << utostr(PT->getNumElements()) << ");"; - nl(Out); - break; - } - case Type::OpaqueTyID: { - Out << "OpaqueType* " << typeName << " = OpaqueType::get();"; - nl(Out); - break; - } - default: - error("Invalid TypeID"); - } - - // If the type had a name, make sure we recreate it. - const std::string* progTypeName = - findTypeName(TheModule->getTypeSymbolTable(),Ty); - if (progTypeName) { - Out << "mod->addTypeName(\"" << *progTypeName << "\", " - << typeName << ");"; - nl(Out); - } - - // Pop us off the type stack - TypeStack.pop_back(); - - // Indicate that this type is now defined. - DefinedTypes.insert(Ty); - - // Early resolve as many unresolved types as possible. Search the unresolved - // types map for the type we just printed. Now that its definition is complete - // we can resolve any previous references to it. This prevents a cascade of - // unresolved types. - TypeMap::iterator I = UnresolvedTypes.find(Ty); - if (I != UnresolvedTypes.end()) { - Out << "cast(" << I->second - << "_fwd.get())->refineAbstractTypeTo(" << I->second << ");"; - nl(Out); - Out << I->second << " = cast<"; - switch (Ty->getTypeID()) { - case Type::FunctionTyID: Out << "FunctionType"; break; - case Type::ArrayTyID: Out << "ArrayType"; break; - case Type::StructTyID: Out << "StructType"; break; - case Type::VectorTyID: Out << "VectorType"; break; - case Type::PointerTyID: Out << "PointerType"; break; - case Type::OpaqueTyID: Out << "OpaqueType"; break; - default: Out << "NoSuchDerivedType"; break; - } - Out << ">(" << I->second << "_fwd.get());"; - nl(Out); nl(Out); - UnresolvedTypes.erase(I); - } - - // Finally, separate the type definition from other with a newline. - nl(Out); - - // We weren't a recursive type - return false; -} - -// Prints a type definition. Returns true if it could not resolve all the types -// in the definition but had to use a forward reference. -void -CppWriter::printType(const Type* Ty) { - assert(TypeStack.empty()); - TypeStack.clear(); - printTypeInternal(Ty); - assert(TypeStack.empty()); -} - -void -CppWriter::printTypes(const Module* M) { - - // Walk the symbol table and print out all its types - const TypeSymbolTable& symtab = M->getTypeSymbolTable(); - for (TypeSymbolTable::const_iterator TI = symtab.begin(), TE = symtab.end(); - TI != TE; ++TI) { - - // For primitive types and types already defined, just add a name - TypeMap::const_iterator TNI = TypeNames.find(TI->second); - if (TI->second->isInteger() || TI->second->isPrimitiveType() || - TNI != TypeNames.end()) { - Out << "mod->addTypeName(\""; - printEscapedString(TI->first); - Out << "\", " << getCppName(TI->second) << ");"; - nl(Out); - // For everything else, define the type - } else { - printType(TI->second); - } - } - - // Add all of the global variables to the value table... - for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) { - if (I->hasInitializer()) - printType(I->getInitializer()->getType()); - printType(I->getType()); - } - - // Add all the functions to the table - for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end(); - FI != FE; ++FI) { - printType(FI->getReturnType()); - printType(FI->getFunctionType()); - // Add all the function arguments - for(Function::const_arg_iterator AI = FI->arg_begin(), - AE = FI->arg_end(); AI != AE; ++AI) { - printType(AI->getType()); - } - - // Add all of the basic blocks and instructions - for (Function::const_iterator BB = FI->begin(), - E = FI->end(); BB != E; ++BB) { - printType(BB->getType()); - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; - ++I) { - printType(I->getType()); - for (unsigned i = 0; i < I->getNumOperands(); ++i) - printType(I->getOperand(i)->getType()); - } - } - } -} - - -// printConstant - Print out a constant pool entry... -void CppWriter::printConstant(const Constant *CV) { - // First, if the constant is actually a GlobalValue (variable or function) or - // its already in the constant list then we've printed it already and we can - // just return. - if (isa(CV) || ValueNames.find(CV) != ValueNames.end()) - return; - - std::string constName(getCppName(CV)); - std::string typeName(getCppName(CV->getType())); - if (CV->isNullValue()) { - Out << "Constant* " << constName << " = Constant::getNullValue(" - << typeName << ");"; - nl(Out); - return; - } - if (isa(CV)) { - // Skip variables and functions, we emit them elsewhere - return; - } - if (const ConstantInt *CI = dyn_cast(CV)) { - Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt(" - << cast(CI->getType())->getBitWidth() << ", " - << " \"" << CI->getValue().toStringSigned(10) << "\", 10));"; - } else if (isa(CV)) { - Out << "ConstantAggregateZero* " << constName - << " = ConstantAggregateZero::get(" << typeName << ");"; - } else if (isa(CV)) { - Out << "ConstantPointerNull* " << constName - << " = ConstanPointerNull::get(" << typeName << ");"; - } else if (const ConstantFP *CFP = dyn_cast(CV)) { - Out << "ConstantFP* " << constName << " = "; - printCFP(CFP); - Out << ";"; - } else if (const ConstantArray *CA = dyn_cast(CV)) { - if (CA->isString() && CA->getType()->getElementType() == Type::Int8Ty) { - Out << "Constant* " << constName << " = ConstantArray::get(\""; - std::string tmp = CA->getAsString(); - bool nullTerminate = false; - if (tmp[tmp.length()-1] == 0) { - tmp.erase(tmp.length()-1); - nullTerminate = true; - } - printEscapedString(tmp); - // Determine if we want null termination or not. - if (nullTerminate) - Out << "\", true"; // Indicate that the null terminator should be added. - else - Out << "\", false";// No null terminator - Out << ");"; - } else { - Out << "std::vector " << constName << "_elems;"; - nl(Out); - unsigned N = CA->getNumOperands(); - for (unsigned i = 0; i < N; ++i) { - printConstant(CA->getOperand(i)); // recurse to print operands - Out << constName << "_elems.push_back(" - << getCppName(CA->getOperand(i)) << ");"; - nl(Out); - } - Out << "Constant* " << constName << " = ConstantArray::get(" - << typeName << ", " << constName << "_elems);"; - } - } else if (const ConstantStruct *CS = dyn_cast(CV)) { - Out << "std::vector " << constName << "_fields;"; - nl(Out); - unsigned N = CS->getNumOperands(); - for (unsigned i = 0; i < N; i++) { - printConstant(CS->getOperand(i)); - Out << constName << "_fields.push_back(" - << getCppName(CS->getOperand(i)) << ");"; - nl(Out); - } - Out << "Constant* " << constName << " = ConstantStruct::get(" - << typeName << ", " << constName << "_fields);"; - } else if (const ConstantVector *CP = dyn_cast(CV)) { - Out << "std::vector " << constName << "_elems;"; - nl(Out); - unsigned N = CP->getNumOperands(); - for (unsigned i = 0; i < N; ++i) { - printConstant(CP->getOperand(i)); - Out << constName << "_elems.push_back(" - << getCppName(CP->getOperand(i)) << ");"; - nl(Out); - } - Out << "Constant* " << constName << " = ConstantVector::get(" - << typeName << ", " << constName << "_elems);"; - } else if (isa(CV)) { - Out << "UndefValue* " << constName << " = UndefValue::get(" - << typeName << ");"; - } else if (const ConstantExpr *CE = dyn_cast(CV)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - Out << "std::vector " << constName << "_indices;"; - nl(Out); - printConstant(CE->getOperand(0)); - for (unsigned i = 1; i < CE->getNumOperands(); ++i ) { - printConstant(CE->getOperand(i)); - Out << constName << "_indices.push_back(" - << getCppName(CE->getOperand(i)) << ");"; - nl(Out); - } - Out << "Constant* " << constName - << " = ConstantExpr::getGetElementPtr(" - << getCppName(CE->getOperand(0)) << ", " - << "&" << constName << "_indices[0], " - << constName << "_indices.size()" - << " );"; - } else if (CE->isCast()) { - printConstant(CE->getOperand(0)); - Out << "Constant* " << constName << " = ConstantExpr::getCast("; - switch (CE->getOpcode()) { - default: assert(0 && "Invalid cast opcode"); - case Instruction::Trunc: Out << "Instruction::Trunc"; break; - case Instruction::ZExt: Out << "Instruction::ZExt"; break; - case Instruction::SExt: Out << "Instruction::SExt"; break; - case Instruction::FPTrunc: Out << "Instruction::FPTrunc"; break; - case Instruction::FPExt: Out << "Instruction::FPExt"; break; - case Instruction::FPToUI: Out << "Instruction::FPToUI"; break; - case Instruction::FPToSI: Out << "Instruction::FPToSI"; break; - case Instruction::UIToFP: Out << "Instruction::UIToFP"; break; - case Instruction::SIToFP: Out << "Instruction::SIToFP"; break; - case Instruction::PtrToInt: Out << "Instruction::PtrToInt"; break; - case Instruction::IntToPtr: Out << "Instruction::IntToPtr"; break; - case Instruction::BitCast: Out << "Instruction::BitCast"; break; - } - Out << ", " << getCppName(CE->getOperand(0)) << ", " - << getCppName(CE->getType()) << ");"; - } else { - unsigned N = CE->getNumOperands(); - for (unsigned i = 0; i < N; ++i ) { - printConstant(CE->getOperand(i)); - } - Out << "Constant* " << constName << " = ConstantExpr::"; - switch (CE->getOpcode()) { - case Instruction::Add: Out << "getAdd("; break; - case Instruction::Sub: Out << "getSub("; break; - case Instruction::Mul: Out << "getMul("; break; - case Instruction::UDiv: Out << "getUDiv("; break; - case Instruction::SDiv: Out << "getSDiv("; break; - case Instruction::FDiv: Out << "getFDiv("; break; - case Instruction::URem: Out << "getURem("; break; - case Instruction::SRem: Out << "getSRem("; break; - case Instruction::FRem: Out << "getFRem("; break; - case Instruction::And: Out << "getAnd("; break; - case Instruction::Or: Out << "getOr("; break; - case Instruction::Xor: Out << "getXor("; break; - case Instruction::ICmp: - Out << "getICmp(ICmpInst::ICMP_"; - switch (CE->getPredicate()) { - case ICmpInst::ICMP_EQ: Out << "EQ"; break; - case ICmpInst::ICMP_NE: Out << "NE"; break; - case ICmpInst::ICMP_SLT: Out << "SLT"; break; - case ICmpInst::ICMP_ULT: Out << "ULT"; break; - case ICmpInst::ICMP_SGT: Out << "SGT"; break; - case ICmpInst::ICMP_UGT: Out << "UGT"; break; - case ICmpInst::ICMP_SLE: Out << "SLE"; break; - case ICmpInst::ICMP_ULE: Out << "ULE"; break; - case ICmpInst::ICMP_SGE: Out << "SGE"; break; - case ICmpInst::ICMP_UGE: Out << "UGE"; break; - default: error("Invalid ICmp Predicate"); - } - break; - case Instruction::FCmp: - Out << "getFCmp(FCmpInst::FCMP_"; - switch (CE->getPredicate()) { - case FCmpInst::FCMP_FALSE: Out << "FALSE"; break; - case FCmpInst::FCMP_ORD: Out << "ORD"; break; - case FCmpInst::FCMP_UNO: Out << "UNO"; break; - case FCmpInst::FCMP_OEQ: Out << "OEQ"; break; - case FCmpInst::FCMP_UEQ: Out << "UEQ"; break; - case FCmpInst::FCMP_ONE: Out << "ONE"; break; - case FCmpInst::FCMP_UNE: Out << "UNE"; break; - case FCmpInst::FCMP_OLT: Out << "OLT"; break; - case FCmpInst::FCMP_ULT: Out << "ULT"; break; - case FCmpInst::FCMP_OGT: Out << "OGT"; break; - case FCmpInst::FCMP_UGT: Out << "UGT"; break; - case FCmpInst::FCMP_OLE: Out << "OLE"; break; - case FCmpInst::FCMP_ULE: Out << "ULE"; break; - case FCmpInst::FCMP_OGE: Out << "OGE"; break; - case FCmpInst::FCMP_UGE: Out << "UGE"; break; - case FCmpInst::FCMP_TRUE: Out << "TRUE"; break; - default: error("Invalid FCmp Predicate"); - } - break; - case Instruction::Shl: Out << "getShl("; break; - case Instruction::LShr: Out << "getLShr("; break; - case Instruction::AShr: Out << "getAShr("; break; - case Instruction::Select: Out << "getSelect("; break; - case Instruction::ExtractElement: Out << "getExtractElement("; break; - case Instruction::InsertElement: Out << "getInsertElement("; break; - case Instruction::ShuffleVector: Out << "getShuffleVector("; break; - default: - error("Invalid constant expression"); - break; - } - Out << getCppName(CE->getOperand(0)); - for (unsigned i = 1; i < CE->getNumOperands(); ++i) - Out << ", " << getCppName(CE->getOperand(i)); - Out << ");"; - } - } else { - error("Bad Constant"); - Out << "Constant* " << constName << " = 0; "; - } - nl(Out); -} - -void -CppWriter::printConstants(const Module* M) { - // Traverse all the global variables looking for constant initializers - for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) - if (I->hasInitializer()) - printConstant(I->getInitializer()); - - // Traverse the LLVM functions looking for constants - for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end(); - FI != FE; ++FI) { - // Add all of the basic blocks and instructions - for (Function::const_iterator BB = FI->begin(), - E = FI->end(); BB != E; ++BB) { - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; - ++I) { - for (unsigned i = 0; i < I->getNumOperands(); ++i) { - if (Constant* C = dyn_cast(I->getOperand(i))) { - printConstant(C); - } - } - } - } - } -} - -void CppWriter::printVariableUses(const GlobalVariable *GV) { - nl(Out) << "// Type Definitions"; - nl(Out); - printType(GV->getType()); - if (GV->hasInitializer()) { - Constant* Init = GV->getInitializer(); - printType(Init->getType()); - if (Function* F = dyn_cast(Init)) { - nl(Out)<< "/ Function Declarations"; nl(Out); - printFunctionHead(F); - } else if (GlobalVariable* gv = dyn_cast(Init)) { - nl(Out) << "// Global Variable Declarations"; nl(Out); - printVariableHead(gv); - } else { - nl(Out) << "// Constant Definitions"; nl(Out); - printConstant(gv); - } - if (GlobalVariable* gv = dyn_cast(Init)) { - nl(Out) << "// Global Variable Definitions"; nl(Out); - printVariableBody(gv); - } - } -} - -void CppWriter::printVariableHead(const GlobalVariable *GV) { - nl(Out) << "GlobalVariable* " << getCppName(GV); - if (is_inline) { - Out << " = mod->getGlobalVariable("; - printEscapedString(GV->getName()); - Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)"; - nl(Out) << "if (!" << getCppName(GV) << ") {"; - in(); nl(Out) << getCppName(GV); - } - Out << " = new GlobalVariable("; - nl(Out) << "/*Type=*/"; - printCppName(GV->getType()->getElementType()); - Out << ","; - nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false"); - Out << ","; - nl(Out) << "/*Linkage=*/"; - printLinkageType(GV->getLinkage()); - Out << ","; - nl(Out) << "/*Initializer=*/0, "; - if (GV->hasInitializer()) { - Out << "// has initializer, specified below"; - } - nl(Out) << "/*Name=*/\""; - printEscapedString(GV->getName()); - Out << "\","; - nl(Out) << "mod);"; - nl(Out); - - if (GV->hasSection()) { - printCppName(GV); - Out << "->setSection(\""; - printEscapedString(GV->getSection()); - Out << "\");"; - nl(Out); - } - if (GV->getAlignment()) { - printCppName(GV); - Out << "->setAlignment(" << utostr(GV->getAlignment()) << ");"; - nl(Out); - }; - if (GV->getVisibility() != GlobalValue::DefaultVisibility) { - printCppName(GV); - Out << "->setVisibility("; - printVisibilityType(GV->getVisibility()); - Out << ");"; - nl(Out); - } - if (is_inline) { - out(); Out << "}"; nl(Out); - } -} - -void -CppWriter::printVariableBody(const GlobalVariable *GV) { - if (GV->hasInitializer()) { - printCppName(GV); - Out << "->setInitializer("; - //if (!isagetInitializer())) - //else - Out << getCppName(GV->getInitializer()) << ");"; - nl(Out); - } -} - -std::string -CppWriter::getOpName(Value* V) { - if (!isa(V) || DefinedValues.find(V) != DefinedValues.end()) - return getCppName(V); - - // See if its alread in the map of forward references, if so just return the - // name we already set up for it - ForwardRefMap::const_iterator I = ForwardRefs.find(V); - if (I != ForwardRefs.end()) - return I->second; - - // This is a new forward reference. Generate a unique name for it - std::string result(std::string("fwdref_") + utostr(uniqueNum++)); - - // Yes, this is a hack. An Argument is the smallest instantiable value that - // we can make as a placeholder for the real value. We'll replace these - // Argument instances later. - Out << "Argument* " << result << " = new Argument(" - << getCppName(V->getType()) << ");"; - nl(Out); - ForwardRefs[V] = result; - return result; -} - -// printInstruction - This member is called for each Instruction in a function. -void -CppWriter::printInstruction(const Instruction *I, const std::string& bbname) { - std::string iName(getCppName(I)); - - // Before we emit this instruction, we need to take care of generating any - // forward references. So, we get the names of all the operands in advance - std::string* opNames = new std::string[I->getNumOperands()]; - for (unsigned i = 0; i < I->getNumOperands(); i++) { - opNames[i] = getOpName(I->getOperand(i)); - } - - switch (I->getOpcode()) { - case Instruction::Ret: { - const ReturnInst* ret = cast(I); - Out << "ReturnInst::Create(" - << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");"; - break; - } - case Instruction::Br: { - const BranchInst* br = cast(I); - Out << "BranchInst::Create(" ; - if (br->getNumOperands() == 3 ) { - Out << opNames[0] << ", " - << opNames[1] << ", " - << opNames[2] << ", "; - - } else if (br->getNumOperands() == 1) { - Out << opNames[0] << ", "; - } else { - error("Branch with 2 operands?"); - } - Out << bbname << ");"; - break; - } - case Instruction::Switch: { - const SwitchInst* sw = cast(I); - Out << "SwitchInst* " << iName << " = SwitchInst::Create(" - << opNames[0] << ", " - << opNames[1] << ", " - << sw->getNumCases() << ", " << bbname << ");"; - nl(Out); - for (unsigned i = 2; i < sw->getNumOperands(); i += 2 ) { - Out << iName << "->addCase(" - << opNames[i] << ", " - << opNames[i+1] << ");"; - nl(Out); - } - break; - } - case Instruction::Invoke: { - const InvokeInst* inv = cast(I); - Out << "std::vector " << iName << "_params;"; - nl(Out); - for (unsigned i = 3; i < inv->getNumOperands(); ++i) { - Out << iName << "_params.push_back(" - << opNames[i] << ");"; - nl(Out); - } - Out << "InvokeInst *" << iName << " = InvokeInst::Create(" - << opNames[0] << ", " - << opNames[1] << ", " - << opNames[2] << ", " - << iName << "_params.begin(), " << iName << "_params.end(), \""; - printEscapedString(inv->getName()); - Out << "\", " << bbname << ");"; - nl(Out) << iName << "->setCallingConv("; - printCallingConv(inv->getCallingConv()); - Out << ");"; - printParamAttrs(inv->getParamAttrs(), iName); - Out << iName << "->setParamAttrs(" << iName << "_PAL);"; - nl(Out); - break; - } - case Instruction::Unwind: { - Out << "new UnwindInst(" - << bbname << ");"; - break; - } - case Instruction::Unreachable:{ - Out << "new UnreachableInst(" - << bbname << ");"; - break; - } - case Instruction::Add: - case Instruction::Sub: - case Instruction::Mul: - case Instruction::UDiv: - case Instruction::SDiv: - case Instruction::FDiv: - case Instruction::URem: - case Instruction::SRem: - case Instruction::FRem: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr:{ - Out << "BinaryOperator* " << iName << " = BinaryOperator::create("; - switch (I->getOpcode()) { - case Instruction::Add: Out << "Instruction::Add"; break; - case Instruction::Sub: Out << "Instruction::Sub"; break; - case Instruction::Mul: Out << "Instruction::Mul"; break; - case Instruction::UDiv:Out << "Instruction::UDiv"; break; - case Instruction::SDiv:Out << "Instruction::SDiv"; break; - case Instruction::FDiv:Out << "Instruction::FDiv"; break; - case Instruction::URem:Out << "Instruction::URem"; break; - case Instruction::SRem:Out << "Instruction::SRem"; break; - case Instruction::FRem:Out << "Instruction::FRem"; break; - case Instruction::And: Out << "Instruction::And"; break; - case Instruction::Or: Out << "Instruction::Or"; break; - case Instruction::Xor: Out << "Instruction::Xor"; break; - case Instruction::Shl: Out << "Instruction::Shl"; break; - case Instruction::LShr:Out << "Instruction::LShr"; break; - case Instruction::AShr:Out << "Instruction::AShr"; break; - default: Out << "Instruction::BadOpCode"; break; - } - Out << ", " << opNames[0] << ", " << opNames[1] << ", \""; - printEscapedString(I->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::FCmp: { - Out << "FCmpInst* " << iName << " = new FCmpInst("; - switch (cast(I)->getPredicate()) { - case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break; - case FCmpInst::FCMP_OEQ : Out << "FCmpInst::FCMP_OEQ"; break; - case FCmpInst::FCMP_OGT : Out << "FCmpInst::FCMP_OGT"; break; - case FCmpInst::FCMP_OGE : Out << "FCmpInst::FCMP_OGE"; break; - case FCmpInst::FCMP_OLT : Out << "FCmpInst::FCMP_OLT"; break; - case FCmpInst::FCMP_OLE : Out << "FCmpInst::FCMP_OLE"; break; - case FCmpInst::FCMP_ONE : Out << "FCmpInst::FCMP_ONE"; break; - case FCmpInst::FCMP_ORD : Out << "FCmpInst::FCMP_ORD"; break; - case FCmpInst::FCMP_UNO : Out << "FCmpInst::FCMP_UNO"; break; - case FCmpInst::FCMP_UEQ : Out << "FCmpInst::FCMP_UEQ"; break; - case FCmpInst::FCMP_UGT : Out << "FCmpInst::FCMP_UGT"; break; - case FCmpInst::FCMP_UGE : Out << "FCmpInst::FCMP_UGE"; break; - case FCmpInst::FCMP_ULT : Out << "FCmpInst::FCMP_ULT"; break; - case FCmpInst::FCMP_ULE : Out << "FCmpInst::FCMP_ULE"; break; - case FCmpInst::FCMP_UNE : Out << "FCmpInst::FCMP_UNE"; break; - case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break; - default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break; - } - Out << ", " << opNames[0] << ", " << opNames[1] << ", \""; - printEscapedString(I->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::ICmp: { - Out << "ICmpInst* " << iName << " = new ICmpInst("; - switch (cast(I)->getPredicate()) { - case ICmpInst::ICMP_EQ: Out << "ICmpInst::ICMP_EQ"; break; - case ICmpInst::ICMP_NE: Out << "ICmpInst::ICMP_NE"; break; - case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break; - case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break; - case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break; - case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break; - case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break; - case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break; - case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break; - case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break; - default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break; - } - Out << ", " << opNames[0] << ", " << opNames[1] << ", \""; - printEscapedString(I->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::Malloc: { - const MallocInst* mallocI = cast(I); - Out << "MallocInst* " << iName << " = new MallocInst(" - << getCppName(mallocI->getAllocatedType()) << ", "; - if (mallocI->isArrayAllocation()) - Out << opNames[0] << ", " ; - Out << "\""; - printEscapedString(mallocI->getName()); - Out << "\", " << bbname << ");"; - if (mallocI->getAlignment()) - nl(Out) << iName << "->setAlignment(" - << mallocI->getAlignment() << ");"; - break; - } - case Instruction::Free: { - Out << "FreeInst* " << iName << " = new FreeInst(" - << getCppName(I->getOperand(0)) << ", " << bbname << ");"; - break; - } - case Instruction::Alloca: { - const AllocaInst* allocaI = cast(I); - Out << "AllocaInst* " << iName << " = new AllocaInst(" - << getCppName(allocaI->getAllocatedType()) << ", "; - if (allocaI->isArrayAllocation()) - Out << opNames[0] << ", "; - Out << "\""; - printEscapedString(allocaI->getName()); - Out << "\", " << bbname << ");"; - if (allocaI->getAlignment()) - nl(Out) << iName << "->setAlignment(" - << allocaI->getAlignment() << ");"; - break; - } - case Instruction::Load:{ - const LoadInst* load = cast(I); - Out << "LoadInst* " << iName << " = new LoadInst(" - << opNames[0] << ", \""; - printEscapedString(load->getName()); - Out << "\", " << (load->isVolatile() ? "true" : "false" ) - << ", " << bbname << ");"; - break; - } - case Instruction::Store: { - const StoreInst* store = cast(I); - Out << "StoreInst* " << iName << " = new StoreInst(" - << opNames[0] << ", " - << opNames[1] << ", " - << (store->isVolatile() ? "true" : "false") - << ", " << bbname << ");"; - break; - } - case Instruction::GetElementPtr: { - const GetElementPtrInst* gep = cast(I); - if (gep->getNumOperands() <= 2) { - Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create(" - << opNames[0]; - if (gep->getNumOperands() == 2) - Out << ", " << opNames[1]; - } else { - Out << "std::vector " << iName << "_indices;"; - nl(Out); - for (unsigned i = 1; i < gep->getNumOperands(); ++i ) { - Out << iName << "_indices.push_back(" - << opNames[i] << ");"; - nl(Out); - } - Out << "Instruction* " << iName << " = GetElementPtrInst::Create(" - << opNames[0] << ", " << iName << "_indices.begin(), " - << iName << "_indices.end()"; - } - Out << ", \""; - printEscapedString(gep->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::PHI: { - const PHINode* phi = cast(I); - - Out << "PHINode* " << iName << " = PHINode::Create(" - << getCppName(phi->getType()) << ", \""; - printEscapedString(phi->getName()); - Out << "\", " << bbname << ");"; - nl(Out) << iName << "->reserveOperandSpace(" - << phi->getNumIncomingValues() - << ");"; - nl(Out); - for (unsigned i = 0; i < phi->getNumOperands(); i+=2) { - Out << iName << "->addIncoming(" - << opNames[i] << ", " << opNames[i+1] << ");"; - nl(Out); - } - break; - } - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::PtrToInt: - case Instruction::IntToPtr: - case Instruction::BitCast: { - const CastInst* cst = cast(I); - Out << "CastInst* " << iName << " = new "; - switch (I->getOpcode()) { - case Instruction::Trunc: Out << "TruncInst"; break; - case Instruction::ZExt: Out << "ZExtInst"; break; - case Instruction::SExt: Out << "SExtInst"; break; - case Instruction::FPTrunc: Out << "FPTruncInst"; break; - case Instruction::FPExt: Out << "FPExtInst"; break; - case Instruction::FPToUI: Out << "FPToUIInst"; break; - case Instruction::FPToSI: Out << "FPToSIInst"; break; - case Instruction::UIToFP: Out << "UIToFPInst"; break; - case Instruction::SIToFP: Out << "SIToFPInst"; break; - case Instruction::PtrToInt: Out << "PtrToIntInst"; break; - case Instruction::IntToPtr: Out << "IntToPtrInst"; break; - case Instruction::BitCast: Out << "BitCastInst"; break; - default: assert(!"Unreachable"); break; - } - Out << "(" << opNames[0] << ", " - << getCppName(cst->getType()) << ", \""; - printEscapedString(cst->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::Call:{ - const CallInst* call = cast(I); - if (InlineAsm* ila = dyn_cast(call->getOperand(0))) { - Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get(" - << getCppName(ila->getFunctionType()) << ", \"" - << ila->getAsmString() << "\", \"" - << ila->getConstraintString() << "\"," - << (ila->hasSideEffects() ? "true" : "false") << ");"; - nl(Out); - } - if (call->getNumOperands() > 2) { - Out << "std::vector " << iName << "_params;"; - nl(Out); - for (unsigned i = 1; i < call->getNumOperands(); ++i) { - Out << iName << "_params.push_back(" << opNames[i] << ");"; - nl(Out); - } - Out << "CallInst* " << iName << " = CallInst::Create(" - << opNames[0] << ", " << iName << "_params.begin(), " - << iName << "_params.end(), \""; - } else if (call->getNumOperands() == 2) { - Out << "CallInst* " << iName << " = CallInst::Create(" - << opNames[0] << ", " << opNames[1] << ", \""; - } else { - Out << "CallInst* " << iName << " = CallInst::Create(" << opNames[0] - << ", \""; - } - printEscapedString(call->getName()); - Out << "\", " << bbname << ");"; - nl(Out) << iName << "->setCallingConv("; - printCallingConv(call->getCallingConv()); - Out << ");"; - nl(Out) << iName << "->setTailCall(" - << (call->isTailCall() ? "true":"false"); - Out << ");"; - printParamAttrs(call->getParamAttrs(), iName); - Out << iName << "->setParamAttrs(" << iName << "_PAL);"; - nl(Out); - break; - } - case Instruction::Select: { - const SelectInst* sel = cast(I); - Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create("; - Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \""; - printEscapedString(sel->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::UserOp1: - /// FALL THROUGH - case Instruction::UserOp2: { - /// FIXME: What should be done here? - break; - } - case Instruction::VAArg: { - const VAArgInst* va = cast(I); - Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst(" - << opNames[0] << ", " << getCppName(va->getType()) << ", \""; - printEscapedString(va->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::ExtractElement: { - const ExtractElementInst* eei = cast(I); - Out << "ExtractElementInst* " << getCppName(eei) - << " = new ExtractElementInst(" << opNames[0] - << ", " << opNames[1] << ", \""; - printEscapedString(eei->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::InsertElement: { - const InsertElementInst* iei = cast(I); - Out << "InsertElementInst* " << getCppName(iei) - << " = InsertElementInst::Create(" << opNames[0] - << ", " << opNames[1] << ", " << opNames[2] << ", \""; - printEscapedString(iei->getName()); - Out << "\", " << bbname << ");"; - break; - } - case Instruction::ShuffleVector: { - const ShuffleVectorInst* svi = cast(I); - Out << "ShuffleVectorInst* " << getCppName(svi) - << " = new ShuffleVectorInst(" << opNames[0] - << ", " << opNames[1] << ", " << opNames[2] << ", \""; - printEscapedString(svi->getName()); - Out << "\", " << bbname << ");"; - break; - } - } - DefinedValues.insert(I); - nl(Out); - delete [] opNames; -} - -// Print out the types, constants and declarations needed by one function -void CppWriter::printFunctionUses(const Function* F) { - - nl(Out) << "// Type Definitions"; nl(Out); - if (!is_inline) { - // Print the function's return type - printType(F->getReturnType()); - - // Print the function's function type - printType(F->getFunctionType()); - - // Print the types of each of the function's arguments - for(Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) { - printType(AI->getType()); - } - } - - // Print type definitions for every type referenced by an instruction and - // make a note of any global values or constants that are referenced - SmallPtrSet gvs; - SmallPtrSet consts; - for (Function::const_iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB){ - for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); - I != E; ++I) { - // Print the type of the instruction itself - printType(I->getType()); - - // Print the type of each of the instruction's operands - for (unsigned i = 0; i < I->getNumOperands(); ++i) { - Value* operand = I->getOperand(i); - printType(operand->getType()); - - // If the operand references a GVal or Constant, make a note of it - if (GlobalValue* GV = dyn_cast(operand)) { - gvs.insert(GV); - if (GlobalVariable *GVar = dyn_cast(GV)) - if (GVar->hasInitializer()) - consts.insert(GVar->getInitializer()); - } else if (Constant* C = dyn_cast(operand)) - consts.insert(C); - } - } - } - - // Print the function declarations for any functions encountered - nl(Out) << "// Function Declarations"; nl(Out); - for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); - I != E; ++I) { - if (Function* Fun = dyn_cast(*I)) { - if (!is_inline || Fun != F) - printFunctionHead(Fun); - } - } - - // Print the global variable declarations for any variables encountered - nl(Out) << "// Global Variable Declarations"; nl(Out); - for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); - I != E; ++I) { - if (GlobalVariable* F = dyn_cast(*I)) - printVariableHead(F); - } - - // Print the constants found - nl(Out) << "// Constant Definitions"; nl(Out); - for (SmallPtrSet::iterator I = consts.begin(), E = consts.end(); - I != E; ++I) { - printConstant(*I); - } - - // Process the global variables definitions now that all the constants have - // been emitted. These definitions just couple the gvars with their constant - // initializers. - nl(Out) << "// Global Variable Definitions"; nl(Out); - for (SmallPtrSet::iterator I = gvs.begin(), E = gvs.end(); - I != E; ++I) { - if (GlobalVariable* GV = dyn_cast(*I)) - printVariableBody(GV); - } -} - -void CppWriter::printFunctionHead(const Function* F) { - nl(Out) << "Function* " << getCppName(F); - if (is_inline) { - Out << " = mod->getFunction(\""; - printEscapedString(F->getName()); - Out << "\", " << getCppName(F->getFunctionType()) << ");"; - nl(Out) << "if (!" << getCppName(F) << ") {"; - nl(Out) << getCppName(F); - } - Out<< " = Function::Create("; - nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ","; - nl(Out) << "/*Linkage=*/"; - printLinkageType(F->getLinkage()); - Out << ","; - nl(Out) << "/*Name=*/\""; - printEscapedString(F->getName()); - Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : ""); - nl(Out,-1); - printCppName(F); - Out << "->setCallingConv("; - printCallingConv(F->getCallingConv()); - Out << ");"; - nl(Out); - if (F->hasSection()) { - printCppName(F); - Out << "->setSection(\"" << F->getSection() << "\");"; - nl(Out); - } - if (F->getAlignment()) { - printCppName(F); - Out << "->setAlignment(" << F->getAlignment() << ");"; - nl(Out); - } - if (F->getVisibility() != GlobalValue::DefaultVisibility) { - printCppName(F); - Out << "->setVisibility("; - printVisibilityType(F->getVisibility()); - Out << ");"; - nl(Out); - } - if (F->hasCollector()) { - printCppName(F); - Out << "->setCollector(\"" << F->getCollector() << "\");"; - nl(Out); - } - if (is_inline) { - Out << "}"; - nl(Out); - } - printParamAttrs(F->getParamAttrs(), getCppName(F)); - printCppName(F); - Out << "->setParamAttrs(" << getCppName(F) << "_PAL);"; - nl(Out); -} - -void CppWriter::printFunctionBody(const Function *F) { - if (F->isDeclaration()) - return; // external functions have no bodies. - - // Clear the DefinedValues and ForwardRefs maps because we can't have - // cross-function forward refs - ForwardRefs.clear(); - DefinedValues.clear(); - - // Create all the argument values - if (!is_inline) { - if (!F->arg_empty()) { - Out << "Function::arg_iterator args = " << getCppName(F) - << "->arg_begin();"; - nl(Out); - } - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) { - Out << "Value* " << getCppName(AI) << " = args++;"; - nl(Out); - if (AI->hasName()) { - Out << getCppName(AI) << "->setName(\"" << AI->getName() << "\");"; - nl(Out); - } - } - } - - // Create all the basic blocks - nl(Out); - for (Function::const_iterator BI = F->begin(), BE = F->end(); - BI != BE; ++BI) { - std::string bbname(getCppName(BI)); - Out << "BasicBlock* " << bbname << " = BasicBlock::Create(\""; - if (BI->hasName()) - printEscapedString(BI->getName()); - Out << "\"," << getCppName(BI->getParent()) << ",0);"; - nl(Out); - } - - // Output all of its basic blocks... for the function - for (Function::const_iterator BI = F->begin(), BE = F->end(); - BI != BE; ++BI) { - std::string bbname(getCppName(BI)); - nl(Out) << "// Block " << BI->getName() << " (" << bbname << ")"; - nl(Out); - - // Output all of the instructions in the basic block... - for (BasicBlock::const_iterator I = BI->begin(), E = BI->end(); - I != E; ++I) { - printInstruction(I,bbname); - } - } - - // Loop over the ForwardRefs and resolve them now that all instructions - // are generated. - if (!ForwardRefs.empty()) { - nl(Out) << "// Resolve Forward References"; - nl(Out); - } - - while (!ForwardRefs.empty()) { - ForwardRefMap::iterator I = ForwardRefs.begin(); - Out << I->second << "->replaceAllUsesWith(" - << getCppName(I->first) << "); delete " << I->second << ";"; - nl(Out); - ForwardRefs.erase(I); - } -} - -void CppWriter::printInline(const std::string& fname, const std::string& func) { - const Function* F = TheModule->getFunction(func); - if (!F) { - error(std::string("Function '") + func + "' not found in input module"); - return; - } - if (F->isDeclaration()) { - error(std::string("Function '") + func + "' is external!"); - return; - } - nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *" - << getCppName(F); - unsigned arg_count = 1; - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) { - Out << ", Value* arg_" << arg_count; - } - Out << ") {"; - nl(Out); - is_inline = true; - printFunctionUses(F); - printFunctionBody(F); - is_inline = false; - Out << "return " << getCppName(F->begin()) << ";"; - nl(Out) << "}"; - nl(Out); -} - -void CppWriter::printModuleBody() { - // Print out all the type definitions - nl(Out) << "// Type Definitions"; nl(Out); - printTypes(TheModule); - - // Functions can call each other and global variables can reference them so - // define all the functions first before emitting their function bodies. - nl(Out) << "// Function Declarations"; nl(Out); - for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); - I != E; ++I) - printFunctionHead(I); - - // Process the global variables declarations. We can't initialze them until - // after the constants are printed so just print a header for each global - nl(Out) << "// Global Variable Declarations\n"; nl(Out); - for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) { - printVariableHead(I); - } - - // Print out all the constants definitions. Constants don't recurse except - // through GlobalValues. All GlobalValues have been declared at this point - // so we can proceed to generate the constants. - nl(Out) << "// Constant Definitions"; nl(Out); - printConstants(TheModule); - - // Process the global variables definitions now that all the constants have - // been emitted. These definitions just couple the gvars with their constant - // initializers. - nl(Out) << "// Global Variable Definitions"; nl(Out); - for (Module::const_global_iterator I = TheModule->global_begin(), - E = TheModule->global_end(); I != E; ++I) { - printVariableBody(I); - } - - // Finally, we can safely put out all of the function bodies. - nl(Out) << "// Function Definitions"; nl(Out); - for (Module::const_iterator I = TheModule->begin(), E = TheModule->end(); - I != E; ++I) { - if (!I->isDeclaration()) { - nl(Out) << "// Function: " << I->getName() << " (" << getCppName(I) - << ")"; - nl(Out) << "{"; - nl(Out,1); - printFunctionBody(I); - nl(Out,-1) << "}"; - nl(Out); - } - } -} - -void CppWriter::printProgram( - const std::string& fname, - const std::string& mName -) { - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n"; - Out << "#include \n\n"; - Out << "using namespace llvm;\n\n"; - Out << "Module* " << fname << "();\n\n"; - Out << "int main(int argc, char**argv) {\n"; - Out << " Module* Mod = " << fname << "();\n"; - Out << " verifyModule(*Mod, PrintMessageAction);\n"; - Out << " std::cerr.flush();\n"; - Out << " std::cout.flush();\n"; - Out << " PassManager PM;\n"; - Out << " PM.add(new PrintModulePass(&llvm::cout));\n"; - Out << " PM.run(*Mod);\n"; - Out << " return 0;\n"; - Out << "}\n\n"; - printModule(fname,mName); -} - -void CppWriter::printModule( - const std::string& fname, - const std::string& mName -) { - nl(Out) << "Module* " << fname << "() {"; - nl(Out,1) << "// Module Construction"; - nl(Out) << "Module* mod = new Module(\"" << mName << "\");"; - if (!TheModule->getTargetTriple().empty()) { - nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");"; - } - if (!TheModule->getTargetTriple().empty()) { - nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple() - << "\");"; - } - - if (!TheModule->getModuleInlineAsm().empty()) { - nl(Out) << "mod->setModuleInlineAsm(\""; - printEscapedString(TheModule->getModuleInlineAsm()); - Out << "\");"; - } - nl(Out); - - // Loop over the dependent libraries and emit them. - Module::lib_iterator LI = TheModule->lib_begin(); - Module::lib_iterator LE = TheModule->lib_end(); - while (LI != LE) { - Out << "mod->addLibrary(\"" << *LI << "\");"; - nl(Out); - ++LI; - } - printModuleBody(); - nl(Out) << "return mod;"; - nl(Out,-1) << "}"; - nl(Out); -} - -void CppWriter::printContents( - const std::string& fname, // Name of generated function - const std::string& mName // Name of module generated module -) { - Out << "\nModule* " << fname << "(Module *mod) {\n"; - Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n"; - printModuleBody(); - Out << "\nreturn mod;\n"; - Out << "\n}\n"; -} - -void CppWriter::printFunction( - const std::string& fname, // Name of generated function - const std::string& funcName // Name of function to generate -) { - const Function* F = TheModule->getFunction(funcName); - if (!F) { - error(std::string("Function '") + funcName + "' not found in input module"); - return; - } - Out << "\nFunction* " << fname << "(Module *mod) {\n"; - printFunctionUses(F); - printFunctionHead(F); - printFunctionBody(F); - Out << "return " << getCppName(F) << ";\n"; - Out << "}\n"; -} - -void CppWriter::printFunctions() { - const Module::FunctionListType &funcs = TheModule->getFunctionList(); - Module::const_iterator I = funcs.begin(); - Module::const_iterator IE = funcs.end(); - - for (; I != IE; ++I) { - const Function &func = *I; - if (!func.isDeclaration()) { - std::string name("define_"); - name += func.getName(); - printFunction(name, func.getName()); - } - } -} - -void CppWriter::printVariable( - const std::string& fname, /// Name of generated function - const std::string& varName // Name of variable to generate -) { - const GlobalVariable* GV = TheModule->getNamedGlobal(varName); - - if (!GV) { - error(std::string("Variable '") + varName + "' not found in input module"); - return; - } - Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n"; - printVariableUses(GV); - printVariableHead(GV); - printVariableBody(GV); - Out << "return " << getCppName(GV) << ";\n"; - Out << "}\n"; -} - -void CppWriter::printType( - const std::string& fname, /// Name of generated function - const std::string& typeName // Name of type to generate -) { - const Type* Ty = TheModule->getTypeByName(typeName); - if (!Ty) { - error(std::string("Type '") + typeName + "' not found in input module"); - return; - } - Out << "\nType* " << fname << "(Module *mod) {\n"; - printType(Ty); - Out << "return " << getCppName(Ty) << ";\n"; - Out << "}\n"; -} - -} // end anonymous llvm - -namespace llvm { - -void WriteModuleToCppFile(Module* mod, std::ostream& o) { - // Initialize a CppWriter for us to use - CppWriter W(o, mod); - - // Emit a header - o << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n"; - - // Get the name of the function we're supposed to generate - std::string fname = FuncName.getValue(); - - // Get the name of the thing we are to generate - std::string tgtname = NameToGenerate.getValue(); - if (GenerationType == GenModule || - GenerationType == GenContents || - GenerationType == GenProgram || - GenerationType == GenFunctions) { - if (tgtname == "!bad!") { - if (mod->getModuleIdentifier() == "-") - tgtname = ""; - else - tgtname = mod->getModuleIdentifier(); - } - } else if (tgtname == "!bad!") { - W.error("You must use the -for option with -gen-{function,variable,type}"); - } - - switch (WhatToGenerate(GenerationType)) { - case GenProgram: - if (fname.empty()) - fname = "makeLLVMModule"; - W.printProgram(fname,tgtname); - break; - case GenModule: - if (fname.empty()) - fname = "makeLLVMModule"; - W.printModule(fname,tgtname); - break; - case GenContents: - if (fname.empty()) - fname = "makeLLVMModuleContents"; - W.printContents(fname,tgtname); - break; - case GenFunction: - if (fname.empty()) - fname = "makeLLVMFunction"; - W.printFunction(fname,tgtname); - break; - case GenFunctions: - W.printFunctions(); - break; - case GenInline: - if (fname.empty()) - fname = "makeLLVMInline"; - W.printInline(fname,tgtname); - break; - case GenVariable: - if (fname.empty()) - fname = "makeLLVMVariable"; - W.printVariable(fname,tgtname); - break; - case GenType: - if (fname.empty()) - fname = "makeLLVMType"; - W.printType(fname,tgtname); - break; - default: - W.error("Invalid generation option"); - } -} - -} diff --git a/tools/llvm2cpp/CppWriter.h b/tools/llvm2cpp/CppWriter.h deleted file mode 100644 index 4fd35db512b..00000000000 --- a/tools/llvm2cpp/CppWriter.h +++ /dev/null @@ -1,18 +0,0 @@ -//===--- CppWriter.h - Generate C++ IR to C++ Source Interface ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares a function, WriteModuleToCppFile that will convert a -// Module into the corresponding C++ code to construct the same module. -// -//===------------------------------------------------------------------------=== -#include -namespace llvm { -class Module; -void WriteModuleToCppFile(Module* mod, std::ostream& out); -} diff --git a/tools/llvm2cpp/Makefile b/tools/llvm2cpp/Makefile deleted file mode 100644 index 33fd972d199..00000000000 --- a/tools/llvm2cpp/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- tools/llvm2cpp/Makefile -----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. -TOOLNAME = llvm2cpp -LINK_COMPONENTS = bitreader - -include $(LEVEL)/Makefile.common - -CompileCommonOpts := $(CompileCommonOpts) -Wno-format diff --git a/tools/llvm2cpp/llvm2cpp.cpp b/tools/llvm2cpp/llvm2cpp.cpp deleted file mode 100644 index bf88da1acb2..00000000000 --- a/tools/llvm2cpp/llvm2cpp.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//===--- llvm2cpp.cpp - LLVM IR to C++ Translator -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This program converts an input LLVM assembly file (.ll) into a C++ source -// file that makes calls to the LLVM C++ API to produce the same module. The -// generated program verifies what it built and then runs the PrintAssemblyPass -// to reproduce the input originally given to llvm2cpp. -// -// Use the --help option for help with command line options. -// -//===------------------------------------------------------------------------=== - -#include "llvm/Module.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/System/Signals.h" -#include "CppWriter.h" -#include -#include -#include -using namespace llvm; - -static cl::opt -InputFilename(cl::Positional, cl::desc(""), - cl::init("-")); - -static cl::opt -OutputFilename("o", cl::desc("Override output filename"), - cl::value_desc("filename")); - -static cl::opt -Force("f", cl::desc("Overwrite output files")); - -int main(int argc, char **argv) { - llvm_shutdown_obj X; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .cpp assembler\n"); - sys::PrintStackTraceOnErrorSignal(); - - int exitCode = 0; - std::ostream *Out = 0; - std::string ErrorMessage; - - std::auto_ptr M; - std::auto_ptr Buffer( - MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)); - if (Buffer.get()) - M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage)); - if (M.get() == 0) { - std::cerr << argv[0] << ": "; - if (ErrorMessage.size()) - std::cerr << ErrorMessage << "\n"; - else - std::cerr << "bitcode didn't read correctly.\n"; - return 1; - } - - if (OutputFilename != "") { // Specified an output filename? - if (OutputFilename != "-") { // Not stdout? - if (!Force && std::ifstream(OutputFilename.c_str())) { - // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists!\n" - << "Use -f command line argument to force output\n"; - return 1; - } - Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | - std::ios::trunc | std::ios::binary); - } else { // Specified stdout - Out = &std::cout; - } - } else { - if (InputFilename == "-") { - OutputFilename = "-"; - Out = &std::cout; - } else { - std::string IFN = InputFilename; - int Len = IFN.length(); - if (IFN[Len-3] == '.' && IFN[Len-2] == 'l' && IFN[Len-1] == 'l') { - // Source ends in .ll - OutputFilename = std::string(IFN.begin(), IFN.end()-3); - } else { - OutputFilename = IFN; // Append a .cpp to it - } - OutputFilename += ".cpp"; - - if (!Force && std::ifstream(OutputFilename.c_str())) { - // If force is not specified, make sure not to overwrite a file! - std::cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists!\n" - << "Use -f command line argument to force output\n"; - return 1; - } - - Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | - std::ios::trunc | std::ios::binary); - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - } - } - - if (!Out->good()) { - std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; - return 1; - } - - WriteModuleToCppFile(M.get(), *Out); - - if (Out != &std::cout) delete Out; - return exitCode; -} - -- 2.34.1