From 15db0fbcc8397960d8ed1e4a2421862875afb980 Mon Sep 17 00:00:00 2001
From: Alex Lorenz <arphaman@gmail.com>
Date: Wed, 17 Jun 2015 23:26:01 +0000
Subject: [PATCH] YAML: Assign a value returned by the default constructor to
 the value in an optional mapping.

This commit ensures that a value that's passed into YAML's IO mapOptional method
is going to be assigned a value returned by the default constructor for that
value's type when the appropriate key is not present in the YAML mapping.

Reviewers: Duncan P. N. Exon Smith

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239972 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/llvm/Support/YAMLTraits.h |  2 ++
 unittests/Support/YAMLIOTest.cpp  | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index c04294a5e87..e06830c37cb 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -647,6 +647,8 @@ private:
     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
       yamlize(*this, Val, Required);
       this->postflightKey(SaveInfo);
+    } else if (UseDefault) {
+      Val = T();
     }
   }
 
diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index e7affa1698d..0c791b7a020 100644
--- a/unittests/Support/YAMLIOTest.cpp
+++ b/unittests/Support/YAMLIOTest.cpp
@@ -68,6 +68,21 @@ namespace yaml {
 }
 }
 
+struct FooBarOptional {
+  int Foo;
+  int Bar;
+};
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<FooBarOptional> {
+  static void mapping(IO &YamlIO, FooBarOptional &Obj) {
+    YamlIO.mapRequired("foo", Obj.Foo);
+    YamlIO.mapOptional("bar", Obj.Bar);
+  }
+};
+}
+}
 
 //
 // Test the reading of a yaml mapping
@@ -93,6 +108,19 @@ TEST(YAMLIO, TestMapRead) {
   }
 }
 
+TEST(YAMLIO, TestMapReadOptional) {
+  FooBarOptional Doc;
+  Doc.Bar = 42;
+  {
+    Input In("---\nfoo:  3\n...\n");
+    In >> Doc;
+
+    EXPECT_FALSE(In.error());
+    EXPECT_EQ(Doc.Foo, 3);
+    EXPECT_EQ(Doc.Bar, 0);
+  }
+}
+
 TEST(YAMLIO, TestMalformedMapRead) {
   FooBar doc;
   Input yin("{foo: 3; bar: 5}", nullptr, suppressErrorMessages);
-- 
2.34.1