MIR Serialization: print and parse machine function names.

This commit introduces a serializable structure called
'llvm::yaml::MachineFunction' that stores the machine
function's name. This structure will mirror the machine 
function's state in the future.

This commit prints machine functions as YAML documents
containing a YAML mapping that stores the state of a machine
function. This commit also parses the YAML documents
that contain the machine functions.

Reviewers: Duncan P. N. Exon Smith

Differential Revision: http://reviews.llvm.org/D9841

llvm-svn: 238519
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 8a048c1..a0de371 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/AsmParser/Parser.h"
+#include "llvm/CodeGen/MIRYamlMapping.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/SMLoc.h"
 #include "llvm/Support/SourceMgr.h"
@@ -38,10 +39,16 @@
   MIRParserImpl(std::unique_ptr<MemoryBuffer> Contents, StringRef Filename,
                 LLVMContext &Context);
 
-  /// Try to parse the optional LLVM module in the MIR file.
+  /// Try to parse the optional LLVM module and the machine functions in the MIR
+  /// file.
   ///
-  /// Return null if an error occurred while parsing the LLVM module.
-  std::unique_ptr<Module> parseLLVMModule(SMDiagnostic &Error);
+  /// Return null if an error occurred.
+  std::unique_ptr<Module> parse(SMDiagnostic &Error);
+
+  /// Parse the machine function in the current YAML document.
+  ///
+  /// Return true if an error occurred.
+  bool parseMachineFunction(yaml::Input &In);
 };
 
 } // end anonymous namespace
@@ -52,21 +59,56 @@
   SM.AddNewSourceBuffer(std::move(Contents), SMLoc());
 }
 
-std::unique_ptr<Module> MIRParserImpl::parseLLVMModule(SMDiagnostic &Error) {
-  yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer());
+static void handleYAMLDiag(const SMDiagnostic &Diag, void *Context) {
+  *reinterpret_cast<SMDiagnostic *>(Context) = Diag;
+}
 
-  // Parse the block scalar manually so that we can return unique pointer
-  // without having to go trough YAML traits.
-  if (In.setCurrentDocument()) {
-    if (const auto *BSN =
-            dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
-      return parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
-                           Context);
-    }
+std::unique_ptr<Module> MIRParserImpl::parse(SMDiagnostic &Error) {
+  yaml::Input In(SM.getMemoryBuffer(SM.getMainFileID())->getBuffer(),
+                 /*Ctxt=*/nullptr, handleYAMLDiag, &Error);
+
+  if (!In.setCurrentDocument()) {
+    if (!Error.getMessage().empty())
+      return nullptr;
+    // Create an empty module when the MIR file is empty.
+    return llvm::make_unique<Module>(Filename, Context);
   }
 
-  // Create an new, empty module.
-  return llvm::make_unique<Module>(Filename, Context);
+  std::unique_ptr<Module> M;
+  // Parse the block scalar manually so that we can return unique pointer
+  // without having to go trough YAML traits.
+  if (const auto *BSN =
+          dyn_cast_or_null<yaml::BlockScalarNode>(In.getCurrentNode())) {
+    M = parseAssembly(MemoryBufferRef(BSN->getValue(), Filename), Error,
+                      Context);
+    if (!M)
+      return M;
+    In.nextDocument();
+    if (!In.setCurrentDocument())
+      return M;
+  } else {
+    // Create an new, empty module.
+    M = llvm::make_unique<Module>(Filename, Context);
+  }
+
+  // Parse the machine functions.
+  do {
+    if (parseMachineFunction(In))
+      return nullptr;
+    In.nextDocument();
+  } while (In.setCurrentDocument());
+
+  return M;
+}
+
+bool MIRParserImpl::parseMachineFunction(yaml::Input &In) {
+  yaml::MachineFunction MF;
+  yaml::yamlize(In, MF, false);
+  if (In.error())
+    return true;
+  // TODO: Initialize the real machine function with the state in the yaml
+  // machine function later on.
+  return false;
 }
 
 std::unique_ptr<Module> llvm::parseMIRFile(StringRef Filename,
@@ -86,5 +128,5 @@
                                        LLVMContext &Context) {
   auto Filename = Contents->getBufferIdentifier();
   MIRParserImpl Parser(std::move(Contents), Filename, Context);
-  return Parser.parseLLVMModule(Error);
+  return Parser.parse(Error);
 }