<div dir="ltr">This is great!<div><br></div><div>-- Sean Silva</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 13, 2013 at 8:00 PM, Nick Kledzik <span dir="ltr"><<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kledzik<br>
Date: Wed Nov 13 18:59:59 2013<br>
New Revision: 194644<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194644&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=194644&view=rev</a><br>
Log:<br>
Add simple support for tags in YAML I/O<br>
<br>
Modified:<br>
    llvm/trunk/docs/YamlIO.rst<br>
    llvm/trunk/include/llvm/Support/YAMLTraits.h<br>
    llvm/trunk/lib/Support/YAMLTraits.cpp<br>
    llvm/trunk/unittests/Support/YAMLIOTest.cpp<br>
<br>
Modified: llvm/trunk/docs/YamlIO.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=194644&r1=194643&r2=194644&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/docs/YamlIO.rst (original)<br>
+++ llvm/trunk/docs/YamlIO.rst Wed Nov 13 18:59:59 2013<br>
@@ -633,6 +633,20 @@ This works for both reading and writing.<br>
     };<br>
<br>
<br>
+Tags<br>
+----<br>
+<br>
+The YAML syntax supports tags as a way to specify the type of a node before<br>
+it is parsed. This allows dynamic types of nodes.  But the YAML I/O model uses<br>
+static typing, so there are limits to how you can use tags with the YAML I/O<br>
+model. Recently, we added support to YAML I/O for checking/setting the optional<br>
+tag on a map. Using this functionality it is even possbile to support differnt<br>
+mappings, as long as they are convertable.<br>
+<br>
+To check a tag, inside your mapping() method you can use io.mapTag() to specify<br>
+what the tag should be.  This will also add that tag when writing yaml.<br>
+<br>
+<br>
 Sequence<br>
 ========<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/Support/YAMLTraits.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=194644&r1=194643&r2=194644&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/include/llvm/Support/YAMLTraits.h (original)<br>
+++ llvm/trunk/include/llvm/Support/YAMLTraits.h Wed Nov 13 18:59:59 2013<br>
@@ -330,6 +330,7 @@ public:<br>
   virtual void postflightFlowElement(void*) = 0;<br>
   virtual void endFlowSequence() = 0;<br>
<br>
+  virtual bool mapTag(StringRef Tag, bool Default=false) = 0;<br>
   virtual void beginMapping() = 0;<br>
   virtual void endMapping() = 0;<br>
   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;<br>
@@ -404,8 +405,7 @@ public:<br>
   void mapOptional(const char* Key, T& Val, const T& Default) {<br>
     this->processKeyWithDefault(Key, Val, Default, false);<br>
   }<br>
-<br>
-<br>
+<br>
 private:<br>
   template <typename T><br>
   void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,<br>
@@ -696,6 +696,7 @@ public:<br>
<br>
 private:<br>
   virtual bool outputting();<br>
+  virtual bool mapTag(StringRef, bool);<br>
   virtual void beginMapping();<br>
   virtual void endMapping();<br>
   virtual bool preflightKey(const char *, bool, bool, bool &, void *&);<br>
@@ -819,6 +820,7 @@ public:<br>
   virtual ~Output();<br>
<br>
   virtual bool outputting();<br>
+  virtual bool mapTag(StringRef, bool);<br>
   virtual void beginMapping();<br>
   virtual void endMapping();<br>
   virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);<br>
<br>
Modified: llvm/trunk/lib/Support/YAMLTraits.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=194644&r1=194643&r2=194644&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/YAMLTraits.cpp (original)<br>
+++ llvm/trunk/lib/Support/YAMLTraits.cpp Wed Nov 13 18:59:59 2013<br>
@@ -81,6 +81,16 @@ bool Input::setCurrentDocument() {<br>
 void Input::nextDocument() {<br>
   ++DocIterator;<br>
 }<br>
+<br>
+bool Input::mapTag(StringRef Tag, bool Default) {<br>
+  StringRef foundTag = CurrentNode->_node->getVerbatimTag();<br>
+  if (foundTag.empty()) {<br>
+    // If no tag found and 'Tag' is the default, say it was found.<br>
+    return Default;<br>
+  }<br>
+  // Return true iff found tag matches supplied tag.<br>
+  return Tag.equals(foundTag);<br>
+}<br>
<br>
 void Input::beginMapping() {<br>
   if (EC)<br>
@@ -381,6 +391,14 @@ void Output::beginMapping() {<br>
   NeedsNewLine = true;<br>
 }<br>
<br>
+bool Output::mapTag(StringRef Tag, bool Use) {<br>
+  if (Use) {<br>
+    this->output(" ");<br>
+    this->output(Tag);<br>
+  }<br>
+  return Use;<br>
+}<br>
+<br>
 void Output::endMapping() {<br>
   StateStack.pop_back();<br>
 }<br>
<br>
Modified: llvm/trunk/unittests/Support/YAMLIOTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=194644&r1=194643&r2=194644&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/unittests/Support/YAMLIOTest.cpp (original)<br>
+++ llvm/trunk/unittests/Support/YAMLIOTest.cpp Wed Nov 13 18:59:59 2013<br>
@@ -989,6 +989,91 @@ TEST(YAMLIO, TestSequenceDocListWriteAnd<br>
   }<br>
 }<br>
<br>
+//===----------------------------------------------------------------------===//<br>
+//  Test document tags<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+struct MyDouble {<br>
+  MyDouble() : value(0.0) { }<br>
+  MyDouble(double x) : value(x) { }<br>
+  double value;<br>
+};<br>
+<br>
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble);<br>
+<br>
+<br>
+namespace llvm {<br>
+namespace yaml {<br>
+  template <><br>
+  struct MappingTraits<MyDouble> {<br>
+    static void mapping(IO &io, MyDouble &d) {<br>
+      if (io.mapTag("!decimal", true)) {<br>
+        mappingDecimal(io, d);<br>
+      } else if (io.mapTag("!fraction")) {<br>
+        mappingFraction(io, d);<br>
+      }<br>
+    }<br>
+    static void mappingDecimal(IO &io, MyDouble &d) {<br>
+      io.mapRequired("value", d.value);<br>
+    }<br>
+    static void mappingFraction(IO &io, MyDouble &d) {<br>
+        double num, denom;<br>
+        io.mapRequired("numerator",      num);<br>
+        io.mapRequired("denominator",    denom);<br>
+        // convert fraction to double<br>
+        d.value = num/denom;<br>
+    }<br>
+  };<br>
+ }<br>
+}<br>
+<br>
+<br>
+//<br>
+// Test the reading of two different tagged yaml documents.<br>
+//<br>
+TEST(YAMLIO, TestTaggedDocuments) {<br>
+  std::vector<MyDouble> docList;<br>
+  Input yin("--- !decimal\nvalue:  3.0\n"<br>
+            "--- !fraction\nnumerator:  9.0\ndenominator:  2\n...\n");<br>
+  yin >> docList;<br>
+  EXPECT_FALSE(yin.error());<br>
+  EXPECT_EQ(docList.size(), 2UL);<br>
+  EXPECT_EQ(docList[0].value, 3.0);<br>
+  EXPECT_EQ(docList[1].value, 4.5);<br>
+}<br>
+<br>
+<br>
+<br>
+//<br>
+// Test writing then reading back tagged documents<br>
+//<br>
+TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {<br>
+  std::string intermediate;<br>
+  {<br>
+    MyDouble a(10.25);<br>
+    MyDouble b(-3.75);<br>
+    std::vector<MyDouble> docList;<br>
+    docList.push_back(a);<br>
+    docList.push_back(b);<br>
+<br>
+    llvm::raw_string_ostream ostr(intermediate);<br>
+    Output yout(ostr);<br>
+    yout << docList;<br>
+  }<br>
+<br>
+  {<br>
+    Input yin(intermediate);<br>
+    std::vector<MyDouble> docList2;<br>
+    yin >> docList2;<br>
+<br>
+    EXPECT_FALSE(yin.error());<br>
+    EXPECT_EQ(docList2.size(), 2UL);<br>
+    EXPECT_EQ(docList2[0].value, 10.25);<br>
+    EXPECT_EQ(docList2[1].value, -3.75);<br>
+  }<br>
+}<br>
+<br>
+<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 //  Test error handling<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>