[opaque pointer type] Add textual IR support for explicit type parameter to getelemen...
[oota-llvm.git] / lib / IR / AsmWriter.cpp
index 5bfbe78496a77ed7695a76a439fba12cd54989ee..8f3e5ec92293fce6ee088c7b248459680f1bfa2d 100644 (file)
@@ -606,8 +606,8 @@ private:
   /// Add all of the functions arguments, basic blocks, and instructions.
   void processFunction();
 
-  SlotTracker(const SlotTracker &) LLVM_DELETED_FUNCTION;
-  void operator=(const SlotTracker &) LLVM_DELETED_FUNCTION;
+  SlotTracker(const SlotTracker &) = delete;
+  void operator=(const SlotTracker &) = delete;
 };
 
 SlotTracker *createSlotTracker(const Module *M) {
@@ -1275,14 +1275,15 @@ static void writeMDTuple(raw_ostream &Out, const MDTuple *Node,
 namespace {
 struct FieldSeparator {
   bool Skip;
-  FieldSeparator() : Skip(true) {}
+  const char *Sep;
+  FieldSeparator(const char *Sep = ", ") : Skip(true), Sep(Sep) {}
 };
 raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
   if (FS.Skip) {
     FS.Skip = false;
     return OS;
   }
-  return OS << ", ";
+  return OS << FS.Sep;
 }
 } // end namespace
 
@@ -1361,8 +1362,8 @@ static void writeMDEnumerator(raw_ostream &Out, const MDEnumerator *N,
                               TypePrinting *, SlotTracker *, const Module *) {
   Out << "!MDEnumerator(";
   FieldSeparator FS;
-  Out << FS << "value: " << N->getValue();
   Out << FS << "name: \"" << N->getName() << "\"";
+  Out << FS << "value: " << N->getValue();
   Out << ")";
 }
 
@@ -1387,6 +1388,20 @@ static void writeMDBasicType(raw_ostream &Out, const MDBasicType *N,
   Out << ")";
 }
 
+static void writeDIFlags(raw_ostream &Out, unsigned Flags) {
+  SmallVector<unsigned, 8> SplitFlags;
+  unsigned Extra = DIDescriptor::splitFlags(Flags, SplitFlags);
+
+  FieldSeparator FS(" | ");
+  for (unsigned F : SplitFlags) {
+    const char *StringF = DIDescriptor::getFlagString(F);
+    assert(StringF && "Expected valid flag");
+    Out << FS << StringF;
+  }
+  if (Extra || SplitFlags.empty())
+    Out << FS << Extra;
+}
+
 static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
                                TypePrinting *TypePrinter, SlotTracker *Machine,
                                const Module *Context) {
@@ -1414,8 +1429,10 @@ static void writeMDDerivedType(raw_ostream &Out, const MDDerivedType *N,
     Out << FS << "align: " << N->getAlignInBits();
   if (N->getOffsetInBits())
     Out << FS << "offset: " << N->getOffsetInBits();
-  if (N->getFlags())
-    Out << FS << "flags: " << N->getFlags();
+  if (auto Flags = N->getFlags()) {
+    Out << FS << "flags: ";
+    writeDIFlags(Out, Flags);
+  }
   if (N->getExtraData()) {
     Out << FS << "extraData: ";
     writeMetadataAsOperand(Out, N->getExtraData(), TypePrinter, Machine,
@@ -1454,8 +1471,10 @@ static void writeMDCompositeType(raw_ostream &Out, const MDCompositeType *N,
     Out << FS << "align: " << N->getAlignInBits();
   if (N->getOffsetInBits())
     Out << FS << "offset: " << N->getOffsetInBits();
-  if (N->getFlags())
-    Out << FS << "flags: " << N->getFlags();
+  if (auto Flags = N->getFlags()) {
+    Out << FS << "flags: ";
+    writeDIFlags(Out, Flags);
+  }
   if (N->getElements()) {
     Out << FS << "elements: ";
     writeMetadataAsOperand(Out, N->getElements(), TypePrinter, Machine,
@@ -1489,8 +1508,10 @@ static void writeMDSubroutineType(raw_ostream &Out, const MDSubroutineType *N,
                                   SlotTracker *Machine, const Module *Context) {
   Out << "!MDSubroutineType(";
   FieldSeparator FS;
-  if (N->getFlags())
-    Out << FS << "flags: " << N->getFlags();
+  if (auto Flags = N->getFlags()) {
+    Out << FS << "flags: ";
+    writeDIFlags(Out, Flags);
+  }
   Out << FS << "types: ";
   writeMetadataAsOperand(Out, N->getTypeArray(), TypePrinter, Machine, Context);
   Out << ")";
@@ -1515,11 +1536,8 @@ static void writeMDCompileUnit(raw_ostream &Out, const MDCompileUnit *N,
     Out << Lang;
   else
     Out << N->getSourceLanguage();
-  if (N->getFile()) {
-    Out << FS << "file: ";
-    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine,
-                           Context);
-  }
+  Out << FS << "file: ";
+  writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
   if (!N->getProducer().empty())
     Out << FS << "producer: \"" << N->getProducer() << "\"";
   Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
@@ -1597,8 +1615,10 @@ static void writeMDSubprogram(raw_ostream &Out, const MDSubprogram *N,
   }
   if (N->getVirtualIndex())
     Out << FS << "virtualIndex: " << N->getVirtualIndex();
-  if (N->getFlags())
-    Out << FS << "flags: " << N->getFlags();
+  if (auto Flags = N->getFlags()) {
+    Out << FS << "flags: ";
+    writeDIFlags(Out, Flags);
+  }
   Out << FS << "isOptimized: " << (N->isOptimized() ? "true" : "false");
   if (N->getFunction()) {
     Out << FS << "function: ";
@@ -1685,8 +1705,6 @@ static void writeMDTemplateTypeParameter(raw_ostream &Out,
                                          const Module *Context) {
   Out << "!MDTemplateTypeParameter(";
   FieldSeparator FS;
-  Out << FS << "scope: ";
-  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
   Out << FS << "name: \"" << N->getName() << "\"";
   Out << FS << "type: ";
   writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
@@ -1701,8 +1719,6 @@ static void writeMDTemplateValueParameter(raw_ostream &Out,
   Out << "!MDTemplateValueParameter(";
   FieldSeparator FS;
   writeTag(Out, FS, N);
-  Out << FS << "scope: ";
-  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
   Out << FS << "name: \"" << N->getName() << "\"";
   Out << FS << "type: ";
   writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
@@ -1771,8 +1787,10 @@ static void writeMDLocalVariable(raw_ostream &Out, const MDLocalVariable *N,
   }
   if (N->getTag() == dwarf::DW_TAG_arg_variable || N->getArg())
     Out << FS << "arg: " << N->getArg();
-  if (N->getFlags())
-    Out << FS << "flags: " << N->getFlags();
+  if (auto Flags = N->getFlags()) {
+    Out << FS << "flags: ";
+    writeDIFlags(Out, Flags);
+  }
   if (N->getInlinedAt()) {
     Out << FS << "inlinedAt: ";
     writeMetadataAsOperand(Out, N->getInlinedAt(), TypePrinter, Machine,
@@ -1802,16 +1820,50 @@ static void writeMDExpression(raw_ostream &Out, const MDExpression *N,
   Out << ")";
 }
 
-static void writeMDObjCProperty(raw_ostream &, const MDObjCProperty *,
-                                TypePrinting *, SlotTracker *, const Module *) {
-  llvm_unreachable("write not implemented");
+static void writeMDObjCProperty(raw_ostream &Out, const MDObjCProperty *N,
+                                TypePrinting *TypePrinter, SlotTracker *Machine,
+                                const Module *Context) {
+  Out << "!MDObjCProperty(";
+  FieldSeparator FS;
+  Out << FS << "name: \"" << N->getName() << "\"";
+  if (N->getFile()) {
+    Out << FS << "file: ";
+    writeMetadataAsOperand(Out, N->getFile(), TypePrinter, Machine, Context);
+  }
+  if (N->getLine())
+    Out << FS << "line: " << N->getLine();
+  if (!N->getSetterName().empty())
+    Out << FS << "setter: \"" << N->getSetterName() << "\"";
+  if (!N->getGetterName().empty())
+    Out << FS << "getter: \"" << N->getGetterName() << "\"";
+  if (N->getAttributes())
+    Out << FS << "attributes: " << N->getAttributes();
+  if (N->getType()) {
+    Out << FS << "type: ";
+    writeMetadataAsOperand(Out, N->getType(), TypePrinter, Machine, Context);
+  }
+  Out << ")";
 }
-static void writeMDImportedEntity(raw_ostream &, const MDImportedEntity *,
-                                  TypePrinting *, SlotTracker *,
-                                  const Module *) {
-  llvm_unreachable("write not implemented");
+
+static void writeMDImportedEntity(raw_ostream &Out, const MDImportedEntity *N,
+                                  TypePrinting *TypePrinter,
+                                  SlotTracker *Machine, const Module *Context) {
+  Out << "!MDImportedEntity(";
+  FieldSeparator FS;
+  writeTag(Out, FS, N);
+  Out << FS << "scope: ";
+  writeMetadataAsOperand(Out, N->getScope(), TypePrinter, Machine, Context);
+  if (N->getEntity()) {
+    Out << FS << "entity: ";
+    writeMetadataAsOperand(Out, N->getEntity(), TypePrinter, Machine, Context);
+  }
+  if (N->getLine())
+    Out << FS << "line: " << N->getLine();
+  Out << FS << "name: \"" << N->getName() << "\"";
+  Out << ")";
 }
 
+
 static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
                                     TypePrinting *TypePrinter,
                                     SlotTracker *Machine,
@@ -2846,6 +2898,11 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     Out << ", ";
     TypePrinter.print(I.getType(), Out);
   } else if (Operand) {   // Print the normal way.
+    if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) {
+      Out << ' ';
+      TypePrinter.print(GEP->getSourceElementType(), Out);
+      Out << ',';
+    }
 
     // PrintAllTypes - Instructions who have operands of all the same type
     // omit the type from all but the first operand.  If the instruction has
@@ -2948,6 +3005,7 @@ static void WriteMDNodeComment(const MDNode *Node,
 void AssemblyWriter::writeMDNode(unsigned Slot, const MDNode *Node) {
   Out << '!' << Slot << " = ";
   printMDNodeBody(Node);
+  Out << "\n";
 }
 
 void AssemblyWriter::writeAllMDNodes() {
@@ -2965,7 +3023,6 @@ void AssemblyWriter::writeAllMDNodes() {
 void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
   WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
   WriteMDNodeComment(Node, Out);
-  Out << "\n";
 }
 
 void AssemblyWriter::writeAllAttributeGroups() {
@@ -3162,20 +3219,26 @@ void Metadata::printAsOperand(raw_ostream &ROS, bool PrintType,
 }
 
 // Value::dump - allow easy printing of Values from the debugger.
+LLVM_DUMP_METHOD
 void Value::dump() const { print(dbgs()); dbgs() << '\n'; }
 
 // Type::dump - allow easy printing of Types from the debugger.
+LLVM_DUMP_METHOD
 void Type::dump() const { print(dbgs()); dbgs() << '\n'; }
 
 // Module::dump() - Allow printing of Modules from the debugger.
+LLVM_DUMP_METHOD
 void Module::dump() const { print(dbgs(), nullptr); }
 
 // \brief Allow printing of Comdats from the debugger.
+LLVM_DUMP_METHOD
 void Comdat::dump() const { print(dbgs()); }
 
 // NamedMDNode::dump() - Allow printing of NamedMDNodes from the debugger.
+LLVM_DUMP_METHOD
 void NamedMDNode::dump() const { print(dbgs()); }
 
+LLVM_DUMP_METHOD
 void Metadata::dump() const {
   print(dbgs());
   dbgs() << '\n';