clarify: stub emission depends on the version of the linker you use, it has nothing
[oota-llvm.git] / lib / VMCore / AsmWriter.cpp
index b9ed8aff381405626402655aca4c3470a7ebf179..cbf7070d17eda74a9e711905a9bdc7c47fe31589 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/InlineAsm.h"
 #include "llvm/Instruction.h"
 #include "llvm/Instructions.h"
+#include "llvm/MDNode.h"
 #include "llvm/Module.h"
 #include "llvm/ValueSymbolTable.h"
 #include "llvm/TypeSymbolTable.h"
@@ -34,6 +35,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cctype>
+#include <map>
 using namespace llvm;
 
 // Make virtual table appear in this compilation unit.
@@ -98,7 +100,7 @@ static void PrintLLVMName(raw_ostream &OS, const char *NameStr,
   case GlobalPrefix: OS << '@'; break;
   case LabelPrefix:  break;
   case LocalPrefix:  OS << '%'; break;
-  }      
+  }
   
   // Scan the name to see if it needs quotes first.
   bool NeedsQuotes = isdigit(NameStr[0]);
@@ -169,7 +171,7 @@ void TypePrinting::CalcTypeName(const Type *Ty,
                                 raw_ostream &OS, bool IgnoreTopLevelName) {
   // Check to see if the type is named.
   if (!IgnoreTopLevelName) {
-    DenseMap<const Type*, std::string> &TM = getTypeNamesMap(TypeNames);
+    DenseMap<const Type *, std::string> &TM = getTypeNamesMap(TypeNames);
     DenseMap<const Type *, std::string>::iterator I = TM.find(Ty);
     if (I != TM.end()) {
       OS << I->second;
@@ -199,6 +201,7 @@ void TypePrinting::CalcTypeName(const Type *Ty,
   case Type::FP128TyID:     OS << "fp128"; break;
   case Type::PPC_FP128TyID: OS << "ppc_fp128"; break;
   case Type::LabelTyID:     OS << "label"; break;
+  case Type::MetadataTyID:  OS << "metadata"; break;
   case Type::IntegerTyID:
     OS << 'i' << cast<IntegerType>(Ty)->getBitWidth();
     break;
@@ -361,8 +364,8 @@ namespace {
         return;
       
       // If this is a structure or opaque type, add a name for the type.
-      if ((isa<StructType>(Ty) || isa<OpaqueType>(Ty))
-          && !TP.hasTypeName(Ty)) {
+      if (((isa<StructType>(Ty) && cast<StructType>(Ty)->getNumElements())
+            || isa<OpaqueType>(Ty)) && !TP.hasTypeName(Ty)) {
         TP.addTypeName(Ty, "%"+utostr(unsigned(NumberedTypes.size())));
         NumberedTypes.push_back(Ty);
       }
@@ -797,9 +800,29 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     // Some form of long double.  These appear as a magic letter identifying
     // the type, then a fixed number of hex digits.
     Out << "0x";
-    if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended)
+    if (&CFP->getValueAPF().getSemantics() == &APFloat::x87DoubleExtended) {
       Out << 'K';
-    else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
+      // api needed to prevent premature destruction
+      APInt api = CFP->getValueAPF().bitcastToAPInt();
+      const uint64_t* p = api.getRawData();
+      uint64_t word = p[1];
+      int shiftcount=12;
+      int width = api.getBitWidth();
+      for (int j=0; j<width; j+=4, shiftcount-=4) {
+        unsigned int nibble = (word>>shiftcount) & 15;
+        if (nibble < 10)
+          Out << (unsigned char)(nibble + '0');
+        else
+          Out << (unsigned char)(nibble - 10 + 'A');
+        if (shiftcount == 0 && j+4 < width) {
+          word = *p;
+          shiftcount = 64;
+          if (width-j-4 < 64)
+            shiftcount = width-j-4;
+        }
+      }
+      return;
+    } else if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEquad)
       Out << 'L';
     else if (&CFP->getValueAPF().getSemantics() == &APFloat::PPCDoubleDouble)
       Out << 'M';
@@ -915,6 +938,13 @@ static void WriteConstantInt(raw_ostream &Out, const Constant *CV,
     Out << "undef";
     return;
   }
+  
+  if (const MDString *S = dyn_cast<MDString>(CV)) {
+    Out << "!\"";
+    PrintEscapedString(S->begin(), S->size(), Out);
+    Out << '"';
+    return;
+  }
 
   if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
     Out << CE->getOpcodeName();
@@ -1044,10 +1074,14 @@ class AssemblyWriter {
   TypePrinting TypePrinter;
   AssemblyAnnotationWriter *AnnotationWriter;
   std::vector<const Type*> NumberedTypes;
+
+  // Each MDNode is assigned unique MetadataIDNo.
+  std::map<const MDNode *, unsigned> MDNodes;
+  unsigned MetadataIDNo;
 public:
   inline AssemblyWriter(raw_ostream &o, SlotTracker &Mac, const Module *M,
                         AssemblyAnnotationWriter *AAW)
-    : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW) {
+    : Out(o), Machine(Mac), TheModule(M), AnnotationWriter(AAW), MetadataIDNo(0) {
     AddModuleTypesToPrinter(TypePrinter, NumberedTypes, M);
   }
 
@@ -1069,6 +1103,7 @@ public:
 
   void writeOperand(const Value *Op, bool PrintType);
   void writeParamOperand(const Value *Operand, Attributes Attrs);
+  void printMDNode(const MDNode *Node, bool StandAlone);
 
   const Module* getModule() { return TheModule; }
 
@@ -1185,6 +1220,9 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, raw_ostream &Out) {
   switch (LT) {
   case GlobalValue::PrivateLinkage:     Out << "private "; break;
   case GlobalValue::InternalLinkage:    Out << "internal "; break;
+  case GlobalValue::AvailableExternallyLinkage:
+    Out << "available_externally ";
+    break;
   case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break;
   case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break;
   case GlobalValue::WeakAnyLinkage:     Out << "weak "; break;
@@ -1213,6 +1251,28 @@ static void PrintVisibility(GlobalValue::VisibilityTypes Vis,
 }
 
 void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
+  if (GV->hasInitializer())
+    // If GV is initialized using Metadata then separate out metadata
+    // operands used by the initializer. Note, MDNodes are not cyclic.
+    if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer())) {
+      SmallVector<const MDNode *, 4> WorkList;
+      // Collect MDNodes used by the initializer.
+      for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end();
+          I != E; ++I) {
+       const Value *TV = *I;
+       if (TV)
+         if (const MDNode *NN = dyn_cast<MDNode>(TV))
+           WorkList.push_back(NN);
+      }
+
+      // Print MDNodes used by the initializer.
+      while (!WorkList.empty()) {
+       const MDNode *N = WorkList.back(); WorkList.pop_back();
+       printMDNode(N, true);
+       Out << '\n';
+      }
+    }
+
   if (GV->hasName()) {
     PrintLLVMName(Out, GV);
     Out << " = ";
@@ -1232,7 +1292,10 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
 
   if (GV->hasInitializer()) {
     Out << ' ';
-    writeOperand(GV->getInitializer(), false);
+    if (MDNode *N = dyn_cast<MDNode>(GV->getInitializer()))
+      printMDNode(N, false);
+    else
+      writeOperand(GV->getInitializer(), false);
   }
     
   if (GV->hasSection())
@@ -1244,6 +1307,47 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   Out << '\n';
 }
 
+void AssemblyWriter::printMDNode(const MDNode *Node,
+                                bool StandAlone) {
+  std::map<const MDNode *, unsigned>::iterator MI = MDNodes.find(Node);
+  // If this node is already printed then just refer it using its Metadata
+  // id number.
+  if (MI != MDNodes.end()) {
+    if (!StandAlone)
+      Out << "!" << MI->second;
+    return;
+  }
+  
+  if (StandAlone) {
+    // Print standalone MDNode.
+    // !42 = !{ ... }
+    Out << "!" << MetadataIDNo << " = ";
+    Out << "constant metadata ";
+  }
+
+  Out << "!{";
+  for (MDNode::const_elem_iterator I = Node->elem_begin(), E = Node->elem_end();
+       I != E;) {
+    const Value *TV = *I;
+    if (!TV)
+      Out << "null";
+    else if (const MDNode *N = dyn_cast<MDNode>(TV)) {
+      TypePrinter.print(N->getType(), Out);
+      Out << ' ';
+      printMDNode(N, StandAlone);
+    }
+    else if (!*I)
+      Out << "null";
+    else 
+      writeOperand(*I, true);
+    if (++I != E)
+      Out << ", ";
+  }
+  Out << "}";
+
+  MDNodes[Node] = MetadataIDNo++;
+}
+
 void AssemblyWriter::printAlias(const GlobalAlias *GA) {
   // Don't crash when dumping partially built GA
   if (!GA->hasName())
@@ -1274,12 +1378,12 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) {
     Out << ' ';
     PrintLLVMName(Out, GA);
   } else {
-    const ConstantExpr *CE = 0;
-    if ((CE = dyn_cast<ConstantExpr>(Aliasee)) &&
-        (CE->getOpcode() == Instruction::BitCast)) {
-      writeOperand(CE, false);    
-    } else
-      assert(0 && "Unsupported aliasee");
+    const ConstantExpr *CE = cast<ConstantExpr>(Aliasee);
+    // The only valid GEP is an all zero GEP.
+    assert((CE->getOpcode() == Instruction::BitCast ||
+            CE->getOpcode() == Instruction::GetElementPtr) &&
+           "Unsupported aliasee");
+    writeOperand(CE, false);
   }
   
   printInfoComment(*GA);
@@ -1333,7 +1437,10 @@ void AssemblyWriter::printFunction(const Function *F) {
   case CallingConv::Fast:         Out << "fastcc "; break;
   case CallingConv::Cold:         Out << "coldcc "; break;
   case CallingConv::X86_StdCall:  Out << "x86_stdcallcc "; break;
-  case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break; 
+  case CallingConv::X86_FastCall: Out << "x86_fastcallcc "; break;
+  case CallingConv::ARM_APCS:     Out << "arm_apcscc "; break;
+  case CallingConv::ARM_AAPCS:    Out << "arm_aapcscc "; break;
+  case CallingConv::ARM_AAPCS_VFP:Out << "arm_aapcs_vfpcc "; break;
   default: Out << "cc" << F->getCallingConv() << " "; break;
   }
 
@@ -1589,7 +1696,10 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     case CallingConv::Fast:  Out << " fastcc"; break;
     case CallingConv::Cold:  Out << " coldcc"; break;
     case CallingConv::X86_StdCall:  Out << " x86_stdcallcc"; break;
-    case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break; 
+    case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
+    case CallingConv::ARM_APCS:     Out << " arm_apcscc "; break;
+    case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
+    case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     default: Out << " cc" << CI->getCallingConv(); break;
     }
 
@@ -1637,6 +1747,9 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     case CallingConv::Cold:  Out << " coldcc"; break;
     case CallingConv::X86_StdCall:  Out << " x86_stdcallcc"; break;
     case CallingConv::X86_FastCall: Out << " x86_fastcallcc"; break;
+    case CallingConv::ARM_APCS:     Out << " arm_apcscc "; break;
+    case CallingConv::ARM_AAPCS:    Out << " arm_aapcscc "; break;
+    case CallingConv::ARM_AAPCS_VFP:Out << " arm_aapcs_vfpcc "; break;
     default: Out << " cc" << II->getCallingConv(); break;
     }
 
@@ -1790,8 +1903,16 @@ void Value::print(raw_ostream &OS, AssemblyAnnotationWriter *AAW) const {
     W.write(BB);
   } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(this)) {
     SlotTracker SlotTable(GV->getParent());
-    AssemblyWriter W(OS, SlotTable, GV->getParent(), 0);
+    AssemblyWriter W(OS, SlotTable, GV->getParent(), AAW);
     W.write(GV);
+  } else if (const MDNode *N = dyn_cast<MDNode>(this)) {
+    TypePrinting TypePrinter;
+    TypePrinter.print(N->getType(), OS);
+    OS << ' ';
+    // FIXME: Do we need a slot tracker for metadata ?
+    SlotTracker SlotTable((const Function *)NULL);
+    AssemblyWriter W(OS, SlotTable, NULL, AAW);
+    W.printMDNode(N, false);
   } else if (const Constant *C = dyn_cast<Constant>(this)) {
     TypePrinting TypePrinter;
     TypePrinter.print(C->getType(), OS);
@@ -1813,18 +1934,17 @@ void Value::print(std::ostream &O, AssemblyAnnotationWriter *AAW) const {
 }
 
 // Value::dump - allow easy printing of Values from the debugger.
-void Value::dump() const { print(errs()); errs() << '\n'; errs().flush(); }
+void Value::dump() const { print(errs()); errs() << '\n'; }
 
 // Type::dump - allow easy printing of Types from the debugger.
 // This one uses type names from the given context module
 void Type::dump(const Module *Context) const {
   WriteTypeSymbolic(errs(), this, Context);
   errs() << '\n';
-  errs().flush();
 }
 
 // Type::dump - allow easy printing of Types from the debugger.
 void Type::dump() const { dump(0); }
 
 // Module::dump() - Allow printing of Modules from the debugger.
-void Module::dump() const { print(errs(), 0); errs().flush(); }
+void Module::dump() const { print(errs(), 0); }