#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Config/config.h"
#include <algorithm>
#include <set>
cl::desc("Specify the name of the thing to generate"),
cl::init("!bad!"));
+/// CppBackendTargetMachineModule - Note that this is used on hosts
+/// that cannot link in a library unless there are references into the
+/// library. In particular, it seems that it is not possible to get
+/// things to work on Win32 without this. Though it is unused, do not
+/// remove it.
+extern "C" int CppBackendTargetMachineModule;
+int CppBackendTargetMachineModule = 0;
+
// Register the target.
-static RegisterTarget<CPPTargetMachine> X("cpp", " C++ backend");
+static RegisterTarget<CPPTargetMachine> X("cpp", "C++ backend");
namespace {
typedef std::vector<const Type*> TypeList;
/// module to a C++ translation unit.
class CppWriter : public ModulePass {
const char* progname;
- std::ostream &Out;
+ raw_ostream &Out;
const Module *TheModule;
uint64_t uniqueNum;
TypeMap TypeNames;
public:
static char ID;
- explicit CppWriter(std::ostream &o) :
- ModulePass((intptr_t)&ID), Out(o), uniqueNum(0), is_inline(false) {}
+ explicit CppWriter(raw_ostream &o) :
+ ModulePass(&ID), Out(o), uniqueNum(0), is_inline(false) {}
virtual const char *getPassName() const { return "C++ backend"; }
std::string getCppName(const Value* val);
inline void printCppName(const Value* val);
- void printParamAttrs(const PAListPtr &PAL, const std::string &name);
+ void printAttributes(const AttrListPtr &PAL, const std::string &name);
bool printTypeInternal(const Type* Ty);
inline void printType(const Type* Ty);
void printTypes(const Module* M);
};
static unsigned indent_level = 0;
- inline std::ostream& nl(std::ostream& Out, int delta = 0) {
+ inline raw_ostream& nl(raw_ostream& Out, int delta = 0) {
Out << "\n";
if (delta >= 0 || indent_level >= unsigned(-delta))
indent_level += delta;
// 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) {
+ bool ignored;
APFloat APF = APFloat(CFP->getValueAPF()); // copy
if (CFP->getType() == Type::FloatTy)
- APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven);
+ APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
Out << "ConstantFP::get(";
Out << "APFloat(";
#if HAVE_PRINTF_A
else
Out << StrVal << "f";
} else if (CFP->getType() == Type::DoubleTy)
- Out << "BitsToDouble(0x" << std::hex
- << CFP->getValueAPF().convertToAPInt().getZExtValue()
- << std::dec << "ULL) /* " << StrVal << " */";
+ Out << "BitsToDouble(0x"
+ << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
+ << "ULL) /* " << StrVal << " */";
else
- Out << "BitsToFloat(0x" << std::hex
- << (uint32_t)CFP->getValueAPF().convertToAPInt().getZExtValue()
- << std::dec << "U) /* " << StrVal << " */";
+ Out << "BitsToFloat(0x"
+ << utohexstr((uint32_t)CFP->getValueAPF().
+ bitcastToAPInt().getZExtValue())
+ << "U) /* " << StrVal << " */";
Out << ")";
#if HAVE_PRINTF_A
}
switch (LT) {
case GlobalValue::InternalLinkage:
Out << "GlobalValue::InternalLinkage"; break;
+ case GlobalValue::PrivateLinkage:
+ Out << "GlobalValue::PrivateLinkage"; break;
case GlobalValue::LinkOnceLinkage:
Out << "GlobalValue::LinkOnceLinkage "; break;
case GlobalValue::WeakLinkage:
printEscapedString(getCppName(val));
}
- void CppWriter::printParamAttrs(const PAListPtr &PAL,
+ void CppWriter::printAttributes(const AttrListPtr &PAL,
const std::string &name) {
- Out << "PAListPtr " << name << "_PAL;";
+ Out << "AttrListPtr " << name << "_PAL;";
nl(Out);
if (!PAL.isEmpty()) {
Out << '{'; in(); nl(Out);
- Out << "SmallVector<ParamAttrsWithIndex, 4> Attrs;"; nl(Out);
- Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
+ Out << "SmallVector<AttributeWithIndex, 4> Attrs;"; nl(Out);
+ Out << "AttributeWithIndex 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";
+ unsigned index = PAL.getSlot(i).Index;
+ Attributes attrs = PAL.getSlot(i).Attrs;
+ Out << "PAWI.Index = " << index << "U; PAWI.Attrs = 0 ";
+#define HANDLE_ATTR(X) \
+ if (attrs & Attribute::X) \
+ Out << " | Attribute::" #X; \
+ attrs &= ~Attribute::X;
+
+ HANDLE_ATTR(SExt);
+ HANDLE_ATTR(ZExt);
+ HANDLE_ATTR(StructRet);
+ HANDLE_ATTR(InReg);
+ HANDLE_ATTR(NoReturn);
+ HANDLE_ATTR(NoUnwind);
+ HANDLE_ATTR(ByVal);
+ HANDLE_ATTR(NoAlias);
+ HANDLE_ATTR(Nest);
+ HANDLE_ATTR(ReadNone);
+ HANDLE_ATTR(ReadOnly);
+ HANDLE_ATTR(NoCapture);
+#undef HANDLE_ATTR
+ assert(attrs == 0 && "Unhandled attribute!");
Out << ";";
nl(Out);
Out << "Attrs.push_back(PAWI);";
nl(Out);
}
- Out << name << "_PAL = PAListPtr::get(Attrs.begin(), Attrs.end());";
+ Out << name << "_PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());";
nl(Out);
out(); nl(Out);
Out << '}'; nl(Out);
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)) {
+ std::string constValue = CI->getValue().toString(10, true);
Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt("
<< cast<IntegerType>(CI->getType())->getBitWidth() << ", \""
- << CI->getValue() << "\", 10));";
+ << constValue << "\", " << constValue.length() << ", 10));";
} else if (isa<ConstantAggregateZero>(CV)) {
Out << "ConstantAggregateZero* " << constName
<< " = ConstantAggregateZero::get(" << typeName << ");";
} else if (isa<ConstantPointerNull>(CV)) {
Out << "ConstantPointerNull* " << constName
- << " = ConstanPointerNull::get(" << typeName << ");";
+ << " = ConstantPointerNull::get(" << typeName << ");";
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
Out << "ConstantFP* " << constName << " = ";
printCFP(CFP);
nl(Out) << iName << "->setCallingConv(";
printCallingConv(inv->getCallingConv());
Out << ");";
- printParamAttrs(inv->getParamAttrs(), iName);
- Out << iName << "->setParamAttrs(" << iName << "_PAL);";
+ printAttributes(inv->getAttributes(), iName);
+ Out << iName << "->setAttributes(" << iName << "_PAL);";
nl(Out);
break;
}
}
case Instruction::Store: {
const StoreInst* store = cast<StoreInst>(I);
- Out << "StoreInst* " << iName << " = new StoreInst("
+ Out << " new StoreInst("
<< opNames[0] << ", "
<< opNames[1] << ", "
<< (store->isVolatile() ? "true" : "false")
nl(Out) << iName << "->setTailCall("
<< (call->isTailCall() ? "true":"false");
Out << ");";
- printParamAttrs(call->getParamAttrs(), iName);
- Out << iName << "->setParamAttrs(" << iName << "_PAL);";
+ printAttributes(call->getAttributes(), iName);
+ Out << iName << "->setAttributes(" << iName << "_PAL);";
nl(Out);
break;
}
Out << "}";
nl(Out);
}
- printParamAttrs(F->getParamAttrs(), getCppName(F));
+ printAttributes(F->getAttributes(), getCppName(F));
printCppName(F);
- Out << "->setParamAttrs(" << getCppName(F) << "_PAL);";
+ Out << "->setAttributes(" << getCppName(F) << "_PAL);";
nl(Out);
}
Out << "#include <llvm/Instructions.h>\n";
Out << "#include <llvm/InlineAsm.h>\n";
Out << "#include <llvm/Support/MathExtras.h>\n";
+ Out << "#include <llvm/Support/raw_ostream.h>\n";
Out << "#include <llvm/Pass.h>\n";
Out << "#include <llvm/PassManager.h>\n";
Out << "#include <llvm/ADT/SmallVector.h>\n";
Out << "#include <llvm/Analysis/Verifier.h>\n";
Out << "#include <llvm/Assembly/PrintModulePass.h>\n";
Out << "#include <algorithm>\n";
- Out << "#include <iostream>\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 << " errs().flush();\n";
+ Out << " outs().flush();\n";
Out << " PassManager PM;\n";
- Out << " PM.add(new PrintModulePass(&llvm::cout));\n";
+ Out << " PM.add(createPrintModulePass(&outs()));\n";
Out << " PM.run(*Mod);\n";
Out << " return 0;\n";
Out << "}\n\n";
//===----------------------------------------------------------------------===//
bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
- std::ostream &o,
+ raw_ostream &o,
CodeGenFileType FileType,
bool Fast) {
if (FileType != TargetMachine::AssemblyFile) return true;