#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Config/config.h"
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");
+// Force static initialization.
+extern "C" void LLVMInitializeCppBackendTarget() { }
+
namespace {
typedef std::vector<const Type*> TypeList;
typedef std::map<const Type*,std::string> TypeMap;
/// CppWriter - This class is the main chunk of code that converts an LLVM
/// module to a C++ translation unit.
class CppWriter : public ModulePass {
- const char* progname;
raw_ostream &Out;
const Module *TheModule;
uint64_t uniqueNum;
}
void CppWriter::error(const std::string& msg) {
- cerr << progname << ": " << msg << "\n";
- exit(2);
+ llvm_report_error(msg);
}
// printCFP - Print a floating point constant .. very carefully :)
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::PrivateLinkage:
+ Out << "GlobalValue::PrivateLinkage"; break;
+ case GlobalValue::AvailableExternallyLinkage:
+ Out << "GlobalValue::AvailableExternallyLinkage "; break;
+ case GlobalValue::LinkOnceAnyLinkage:
+ Out << "GlobalValue::LinkOnceAnyLinkage "; break;
+ case GlobalValue::LinkOnceODRLinkage:
+ Out << "GlobalValue::LinkOnceODRLinkage "; break;
+ case GlobalValue::WeakAnyLinkage:
+ Out << "GlobalValue::WeakAnyLinkage"; break;
+ case GlobalValue::WeakODRLinkage:
+ Out << "GlobalValue::WeakODRLinkage"; break;
case GlobalValue::AppendingLinkage:
Out << "GlobalValue::AppendingLinkage"; break;
case GlobalValue::ExternalLinkage:
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";
+ case Type::X86_FP80TyID: return "Type::X86_FP80Ty";
+ case Type::FloatTyID: return "Type::FloatTy";
+ case Type::DoubleTyID: return "Type::DoubleTy";
+ case Type::LabelTyID: return "Type::LabelTy";
default:
error("Invalid primitive type");
break;
unsigned index = PAL.getSlot(i).Index;
Attributes attrs = PAL.getSlot(i).Attrs;
Out << "PAWI.Index = " << index << "U; PAWI.Attrs = 0 ";
- if (attrs & Attribute::SExt)
- Out << " | Attribute::SExt";
- if (attrs & Attribute::ZExt)
- Out << " | Attribute::ZExt";
- if (attrs & Attribute::StructRet)
- Out << " | Attribute::StructRet";
- if (attrs & Attribute::InReg)
- Out << " | Attribute::InReg";
- if (attrs & Attribute::NoReturn)
- Out << " | Attribute::NoReturn";
- if (attrs & Attribute::NoUnwind)
- Out << " | Attribute::NoUnwind";
- if (attrs & Attribute::ByVal)
- Out << " | Attribute::ByVal";
- if (attrs & Attribute::NoAlias)
- Out << " | Attribute::NoAlias";
- if (attrs & Attribute::Nest)
- Out << " | Attribute::Nest";
- if (attrs & Attribute::ReadNone)
- Out << " | Attribute::ReadNone";
- if (attrs & Attribute::ReadOnly)
- Out << " | Attribute::ReadOnly";
+#define HANDLE_ATTR(X) \
+ if (attrs & Attribute::X) \
+ Out << " | Attribute::" #X; \
+ attrs &= ~Attribute::X;
+
+ HANDLE_ATTR(SExt);
+ HANDLE_ATTR(ZExt);
+ HANDLE_ATTR(NoReturn);
+ HANDLE_ATTR(InReg);
+ HANDLE_ATTR(StructRet);
+ HANDLE_ATTR(NoUnwind);
+ HANDLE_ATTR(NoAlias);
+ HANDLE_ATTR(ByVal);
+ HANDLE_ATTR(Nest);
+ HANDLE_ATTR(ReadNone);
+ HANDLE_ATTR(ReadOnly);
+ HANDLE_ATTR(NoInline);
+ HANDLE_ATTR(AlwaysInline);
+ HANDLE_ATTR(OptimizeForSize);
+ HANDLE_ATTR(StackProtect);
+ HANDLE_ATTR(StackProtectReq);
+ HANDLE_ATTR(NoCapture);
+#undef HANDLE_ATTR
+ assert(attrs == 0 && "Unhandled attribute!");
Out << ";";
nl(Out);
Out << "Attrs.push_back(PAWI);";
Out << "Constant* " << constName << " = ConstantExpr::";
switch (CE->getOpcode()) {
case Instruction::Add: Out << "getAdd("; break;
+ case Instruction::FAdd: Out << "getFAdd("; break;
case Instruction::Sub: Out << "getSub("; break;
+ case Instruction::FSub: Out << "getFSub("; break;
case Instruction::Mul: Out << "getMul("; break;
+ case Instruction::FMul: Out << "getFMul("; break;
case Instruction::UDiv: Out << "getUDiv("; break;
case Instruction::SDiv: Out << "getSDiv("; break;
case Instruction::FDiv: Out << "getFDiv("; break;
const BranchInst* br = cast<BranchInst>(I);
Out << "BranchInst::Create(" ;
if (br->getNumOperands() == 3 ) {
- Out << opNames[0] << ", "
+ Out << opNames[2] << ", "
<< opNames[1] << ", "
- << opNames[2] << ", ";
+ << opNames[0] << ", ";
} else if (br->getNumOperands() == 1) {
Out << opNames[0] << ", ";
break;
}
case Instruction::Add:
+ case Instruction::FAdd:
case Instruction::Sub:
+ case Instruction::FSub:
case Instruction::Mul:
+ case Instruction::FMul:
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::FDiv:
Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
switch (I->getOpcode()) {
case Instruction::Add: Out << "Instruction::Add"; break;
+ case Instruction::FAdd: Out << "Instruction::FAdd"; break;
case Instruction::Sub: Out << "Instruction::Sub"; break;
+ case Instruction::FSub: Out << "Instruction::FSub"; break;
case Instruction::Mul: Out << "Instruction::Mul"; break;
+ case Instruction::FMul: Out << "Instruction::FMul"; break;
case Instruction::UDiv:Out << "Instruction::UDiv"; break;
case Instruction::SDiv:Out << "Instruction::SDiv"; break;
case Instruction::FDiv:Out << "Instruction::FDiv"; break;
}
case Instruction::Call:{
const CallInst* call = cast<CallInst>(I);
- if (InlineAsm* ila = dyn_cast<InlineAsm>(call->getOperand(0))) {
+ if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
<< getCppName(ila->getFunctionType()) << ", \""
<< ila->getAsmString() << "\", \""
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 << " 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";
const std::string& mName) {
nl(Out) << "Module* " << fname << "() {";
nl(Out,1) << "// Module Construction";
- nl(Out) << "Module* mod = new Module(\"" << mName << "\");";
+ nl(Out) << "Module* mod = new Module(\"";
+ printEscapedString(mName);
+ Out << "\");";
if (!TheModule->getTargetTriple().empty()) {
nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayout() << "\");";
}
void CppWriter::printContents(const std::string& fname,
const std::string& mName) {
Out << "\nModule* " << fname << "(Module *mod) {\n";
- Out << "\nmod->setModuleIdentifier(\"" << mName << "\");\n";
+ Out << "\nmod->setModuleIdentifier(\"";
+ printEscapedString(mName);
+ Out << "\");\n";
printModuleBody();
Out << "\nreturn mod;\n";
Out << "\n}\n";
bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
raw_ostream &o,
CodeGenFileType FileType,
- bool Fast) {
+ CodeGenOpt::Level OptLevel) {
if (FileType != TargetMachine::AssemblyFile) return true;
PM.add(new CppWriter(o));
return false;