diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-05-04 06:16:50 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-05-04 06:16:50 +0000 |
commit | a9d9ca469fd2442e1352028a7a69d23de0a4cbd5 (patch) | |
tree | 1cc86a7633ebef71e2d32579d565a88de85c4848 /tools/llvm2cpp/CppWriter.cpp | |
parent | f6055806d4a6a39c49c441215a9a5d3a8e933de0 (diff) |
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
Diffstat (limited to 'tools/llvm2cpp/CppWriter.cpp')
-rw-r--r-- | tools/llvm2cpp/CppWriter.cpp | 1968 |
1 files changed, 0 insertions, 1968 deletions
diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp deleted file mode 100644 index b724b9c871..0000000000 --- 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 <algorithm> -#include <iostream> -#include <set> - -using namespace llvm; - -static cl::opt<std::string> -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<WhatToGenerate> 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<std::string> NameToGenerate("for", cl::Optional, - cl::desc("Specify the name of the thing to generate"), - cl::init("!bad!")); - -namespace { -typedef std::vector<const Type*> TypeList; -typedef std::map<const Type*,std::string> TypeMap; -typedef std::map<const Value*,std::string> ValueMap; -typedef std::set<std::string> NameSet; -typedef std::set<const Type*> TypeSet; -typedef std::set<const Value*> ValueSet; -typedef std::map<const Value*,std::string> 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<IntegerType>(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<IntegerType>(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<GlobalVariable>(val)) { - name = std::string("gvar_") + - getTypePrefix(GV->getType()->getElementType()); - } else if (isa<Function>(val)) { - name = std::string("func_"); - } else if (const Constant* C = dyn_cast<Constant>(val)) { - name = std::string("const_") + getTypePrefix(C->getType()); - } else if (const Argument* Arg = dyn_cast<Argument>(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<ParamAttrsWithIndex, 4> 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<FunctionType>(Ty); - Out << "std::vector<const Type*>" << 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<const Type*>(*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<StructType>(Ty); - Out << "std::vector<const Type*>" << 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<const Type*>(*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<ArrayType>(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<PointerType>(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<VectorType>(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<OpaqueType>(" << 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<GlobalValue>(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<GlobalValue>(CV)) { - // Skip variables and functions, we emit them elsewhere - return; - } - if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { - Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt(" - << cast<IntegerType>(CI->getType())->getBitWidth() << ", " - << " \"" << CI->getValue().toStringSigned(10) << "\", 10));"; - } else if (isa<ConstantAggregateZero>(CV)) { - Out << "ConstantAggregateZero* " << constName - << " = ConstantAggregateZero::get(" << typeName << ");"; - } else if (isa<ConstantPointerNull>(CV)) { - Out << "ConstantPointerNull* " << constName - << " = ConstanPointerNull::get(" << typeName << ");"; - } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { - Out << "ConstantFP* " << constName << " = "; - printCFP(CFP); - Out << ";"; - } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(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<Constant*> " << 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<ConstantStruct>(CV)) { - Out << "std::vector<Constant*> " << 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<ConstantVector>(CV)) { - Out << "std::vector<Constant*> " << 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<UndefValue>(CV)) { - Out << "UndefValue* " << constName << " = UndefValue::get(" - << typeName << ");"; - } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { - if (CE->getOpcode() == Instruction::GetElementPtr) { - Out << "std::vector<Constant*> " << 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;< |