Remove the one-definition-rule version of extern_weak
[oota-llvm.git] / lib / Target / CppBackend / CPPBackend.cpp
index 22dd3058de0a3bdc70110bf75f6b7a395584e7bc..52646f0ce3df355bc59273f41c7e176ce520e0d2 100644 (file)
 #include "llvm/ADT/STLExtras.h"
 #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 <iostream>
 #include <set>
 
 using namespace llvm;
@@ -70,8 +71,16 @@ static cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
   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;
@@ -86,7 +95,7 @@ namespace {
   /// 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;
@@ -101,8 +110,8 @@ namespace {
 
   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"; }
 
@@ -132,7 +141,7 @@ namespace {
     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);
@@ -154,7 +163,7 @@ namespace {
   };
 
   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;
@@ -209,7 +218,7 @@ namespace {
   }
 
   void CppWriter::error(const std::string& msg) {
-    std::cerr << progname << ": " << msg << "\n";
+    cerr << progname << ": " << msg << "\n";
     exit(2);
   }
 
@@ -217,9 +226,10 @@ namespace {
   // 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
@@ -252,13 +262,14 @@ namespace {
         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
     }
@@ -281,10 +292,16 @@ namespace {
     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::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:
@@ -297,8 +314,10 @@ namespace {
       Out << "GlobalValue::ExternalWeakLinkage"; break;
     case GlobalValue::GhostLinkage:
       Out << "GlobalValue::GhostLinkage"; break;
-    case GlobalValue::CommonLinkage:
-      Out << "GlobalValue::CommonLinkage"; break;
+    case GlobalValue::CommonAnyLinkage:
+      Out << "GlobalValue::CommonAnyLinkage"; break;
+    case GlobalValue::CommonODRLinkage:
+      Out << "GlobalValue::CommonODRLinkage"; break;
     }
   }
 
@@ -427,46 +446,43 @@ namespace {
     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);
@@ -721,26 +737,23 @@ namespace {
 
     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().toStringSigned(10)  << "\", 10));";
+          << cast<IntegerType>(CI->getType())->getBitWidth() << ",  \""
+          <<  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);
@@ -1065,6 +1078,10 @@ namespace {
     }
 
     switch (I->getOpcode()) {
+    default:
+      error("Invalid instruction");
+      break;
+
     case Instruction::Ret: {
       const ReturnInst* ret =  cast<ReturnInst>(I);
       Out << "ReturnInst::Create("
@@ -1121,8 +1138,8 @@ namespace {
       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;
     }
@@ -1265,7 +1282,7 @@ namespace {
     }
     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")
@@ -1384,8 +1401,8 @@ namespace {
       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;
     }
@@ -1438,6 +1455,40 @@ namespace {
       Out << "\", " << bbname << ");";
       break;
     }
+    case Instruction::ExtractValue: {
+      const ExtractValueInst *evi = cast<ExtractValueInst>(I);
+      Out << "std::vector<unsigned> " << iName << "_indices;";
+      nl(Out);
+      for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
+        Out << iName << "_indices.push_back("
+            << evi->idx_begin()[i] << ");";
+        nl(Out);
+      }
+      Out << "ExtractValueInst* " << getCppName(evi)
+          << " = ExtractValueInst::Create(" << opNames[0]
+          << ", "
+          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
+      printEscapedString(evi->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
+    case Instruction::InsertValue: {
+      const InsertValueInst *ivi = cast<InsertValueInst>(I);
+      Out << "std::vector<unsigned> " << iName << "_indices;";
+      nl(Out);
+      for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
+        Out << iName << "_indices.push_back("
+            << ivi->idx_begin()[i] << ");";
+        nl(Out);
+      }
+      Out << "InsertValueInst* " << getCppName(ivi)
+          << " = InsertValueInst::Create(" << opNames[0]
+          << ", " << opNames[1] << ", "
+          << iName << "_indices.begin(), " << iName << "_indices.end(), \"";
+      printEscapedString(ivi->getName());
+      Out << "\", " << bbname << ");";
+      break;
+    }
   }
   DefinedValues.insert(I);
   nl(Out);
@@ -1565,18 +1616,18 @@ namespace {
       Out << ");";
       nl(Out);
     }
-    if (F->hasCollector()) {
+    if (F->hasGC()) {
       printCppName(F);
-      Out << "->setCollector(\"" << F->getCollector() << "\");";
+      Out << "->setGC(\"" << F->getGC() << "\");";
       nl(Out);
     }
     if (is_inline) {
       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);
   }
 
@@ -1741,22 +1792,22 @@ namespace {
     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";
@@ -1943,7 +1994,7 @@ char CppWriter::ID = 0;
 //===----------------------------------------------------------------------===//
 
 bool CPPTargetMachine::addPassesToEmitWholeFile(PassManager &PM,
-                                                std::ostream &o,
+                                                raw_ostream &o,
                                                 CodeGenFileType FileType,
                                                 bool Fast) {
   if (FileType != TargetMachine::AssemblyFile) return true;