Index: llvm/include/llvm/Support/YAMLTraits.h
===================================================================
--- llvm/include/llvm/Support/YAMLTraits.h
+++ llvm/include/llvm/Support/YAMLTraits.h
@@ -902,24 +902,7 @@
   template <typename T, typename Context>
   void processKeyWithDefault(const char *Key, Optional<T> &Val,
                              const Optional<T> &DefaultValue, bool Required,
-                             Context &Ctx) {
-    assert(DefaultValue.hasValue() == false &&
-           "Optional<T> shouldn't have a value!");
-    void *SaveInfo;
-    bool UseDefault = true;
-    const bool sameAsDefault = outputting() && !Val.hasValue();
-    if (!outputting() && !Val.hasValue())
-      Val = T();
-    if (Val.hasValue() &&
-        this->preflightKey(Key, Required, sameAsDefault, UseDefault,
-                           SaveInfo)) {
-      yamlize(*this, Val.getValue(), Required, Ctx);
-      this->postflightKey(SaveInfo);
-    } else {
-      if (UseDefault)
-        Val = DefaultValue;
-    }
-  }
+                             Context &Ctx);
 
   template <typename T, typename Context>
   void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
@@ -1625,6 +1608,40 @@
   StringRef PaddingBeforeContainer;
 };
 
+template <typename T, typename Context>
+void IO::processKeyWithDefault(const char *Key, Optional<T> &Val,
+                               const Optional<T> &DefaultValue, bool Required,
+                               Context &Ctx) {
+  assert(DefaultValue.hasValue() == false &&
+         "Optional<T> shouldn't have a value!");
+  void *SaveInfo;
+  bool UseDefault = true;
+  const bool sameAsDefault = outputting() && !Val.hasValue();
+  if (!outputting() && !Val.hasValue())
+    Val = T();
+  if (Val.hasValue() &&
+      this->preflightKey(Key, Required, sameAsDefault, UseDefault, SaveInfo)) {
+
+    // When reading an Optional<X> key from a YAML description, we allow the
+    // special "<none>" value, which can be used to specify that no value was
+    // requested, i.e. the DefaultValue will be assigned. The DefaultValue is
+    // usually None.
+    bool IsNone = false;
+    if (!outputting())
+      if (auto *Node = dyn_cast<ScalarNode>(((Input *)this)->getCurrentNode()))
+        IsNone = Node->getRawValue() == "<none>";
+
+    if (IsNone)
+      Val = DefaultValue;
+    else
+      yamlize(*this, Val.getValue(), Required, Ctx);
+    this->postflightKey(SaveInfo);
+  } else {
+    if (UseDefault)
+      Val = DefaultValue;
+  }
+}
+
 /// YAML I/O does conversion based on types. But often native data types
 /// are just a typedef of built in intergral types (e.g. int).  But the C++
 /// type matching system sees through the typedef and all the typedefed types
Index: llvm/test/tools/yaml2obj/ELF/none-value.yaml
===================================================================
--- /dev/null
+++ llvm/test/tools/yaml2obj/ELF/none-value.yaml
@@ -0,0 +1,262 @@
+## We have a special "<none>" value for all keys that are implemented
+## as Optional<> in the code. Setting a key to "<none>" means no-op and
+## works in the same way as when a value was not set at all.
+
+# RUN: yaml2obj %s --docnum=1 -o %t-none
+# RUN: yaml2obj %s --docnum=2 -o %t-base
+# RUN: cmp %t-none %t-base
+
+## Test all keys for which the "<none>" value is supported.
+
+## We do not use the TEST macro. It is exist to
+## demonstrate the expected use case for the <none> word.
+--- !ELF
+FileHeader:
+  Class:      ELFCLASS64
+  Data:       ELFDATA2LSB
+  Type:       ET_REL
+  Machine:    EM_X86_64
+  EShEntSize: [[TEST=<none>]]
+  EShOff:     [[TEST=<none>]]
+  EShNum:     [[TEST=<none>]]
+  EShStrNdx:  [[TEST=<none>]]
+  EPhOff:     [[TEST=<none>]]
+  EPhEntSize: [[TEST=<none>]]
+  EPhNum:     [[TEST=<none>]]
+Sections:
+  - Name:         .bar
+    Type:         SHT_PROGBITS
+    Offset:       [[TEST=<none>]]
+    Address:      [[TEST=<none>]]
+    Content:      [[TEST=<none>]]
+    Size:         [[TEST=<none>]]
+    ContentArray: [[TEST=<none>]]
+    Info:         [[TEST=<none>]]
+    EntSize:      [[TEST=<none>]]
+    ShName:       [[TEST=<none>]]
+    ShOffset:     [[TEST=<none>]]
+    ShSize:       [[TEST=<none>]]
+    ShFlags:      [[TEST=<none>]]
+  - Type:    Fill
+    Pattern: [[TEST=<none>]]
+    Size:    0x3
+  - Name:    .cgp
+    Type:    SHT_LLVM_CALL_GRAPH_PROFILE
+    Content: [[TEST=<none>]]
+    Entries: [[TEST=<none>]]
+  - Name:    .dynamic
+    Type:    SHT_DYNAMIC
+    Content: [[TEST=<none>]]
+## Note: for SHT_NOTE sections, one of "Content", "Size" or "Notes" must be specified.
+  - Name:    .note.1
+    Type:    SHT_NOTE
+    Content: [[TEST=<none>]]
+    Size:    1
+    Notes:   [[TEST=<none>]]
+  - Name:    .note.2
+    Type:    SHT_NOTE
+    Content: "1122"
+    Size:    [[TEST=<none>]]
+## Note: for SHT_HASH sections, one of "Content", "Size", "Bucket" or "Chain" must be specified.
+  - Name:    .hash.1
+    Type:    SHT_HASH
+    Content: [[TEST=<none>]]
+    Size:    1
+    Bucket:  [[TEST=<none>]]
+    Chain:   [[TEST=<none>]]
+    NBucket: [[TEST=<none>]]
+    NChain:  [[TEST=<none>]]
+  - Name:    .hash.2
+    Type:    SHT_HASH
+    Content: "1122"
+    Size:    [[TEST=<none>]]
+## Note: for SHT_GNU_HASH sections either "Content" or "Header", "BloomFilter", "HashBuckets" and
+## "HashBuckets" must be specified.
+  - Name:        .gnu.hash.1
+    Type:        SHT_GNU_HASH
+    Content:     "00"
+    Header:      [[TEST=<none>]]
+    BloomFilter: [[TEST=<none>]]
+    HashBuckets: [[TEST=<none>]]
+    HashValues:  [[TEST=<none>]]
+  - Name:        .gnu.hash.2
+    Type:        SHT_GNU_HASH
+    Content:     [[TEST=<none>]]
+    BloomFilter: []
+    HashBuckets: []
+    HashValues:  []
+    Header:
+      SymNdx: 0x0
+      Shift2: 0x0
+  - Name:         .gnu.version_r
+    Type:         SHT_GNU_verneed
+    Info:         0x0
+    Dependencies: [[TEST=<none>]]
+    Content:      [[TEST=<none>]]
+  - Name:    .gnu.version_d
+    Info:    0x0
+    Type:    SHT_GNU_verdef
+    Entries: [[TEST=<none>]]
+    Content: [[TEST=<none>]]
+## Note: for SHT_LLVM_ADDRSIG sections one of "Content", "Size" or "Symbols" must be specified.
+  - Name:    .llvm_addrsig.1
+    Type:    SHT_LLVM_ADDRSIG
+    Content: "1122"
+    Size:    [[TEST=<none>]]
+    Symbols: [[TEST=<none>]]
+  - Name:    .llvm_addrsig.2
+    Type:    SHT_LLVM_ADDRSIG
+    Content: [[TEST=<none>]]
+    Size:    1
+  - Name:    .linker-options
+    Type:    SHT_LLVM_LINKER_OPTIONS
+    Content: [[TEST=<none>]]
+    Options: [[TEST=<none>]]
+  - Name:      .deplibs
+    Type:      SHT_LLVM_DEPENDENT_LIBRARIES
+    Libraries: [[TEST=<none>]]
+    Content:   [[TEST=<none>]]
+  - Name:    .group
+    Type:    SHT_GROUP
+    Info:    [[TEST=<none>]]
+    Members: []
+  - Name: .rela
+    Type: SHT_RELA
+    Relocations:
+      - Type:   R_X86_64_NONE
+        Symbol: [[TEST=<none>]]
+  - Name:    .relr
+    Type:    SHT_RELR
+    Entries: [[TEST=<none>]]
+    Content: [[TEST=<none>]]
+ProgramHeaders:
+  - Type:     PT_LOAD
+    Align:    [[TEST=<none>]]
+    FileSize: [[TEST=<none>]]
+    MemSize:  [[TEST=<none>]]
+    Offset:   [[TEST=<none>]]
+Symbols:
+  - Name:   foo
+    Other:  [[TEST=<none>]]
+    StName: [[TEST=<none>]]
+SectionHeaderTable:
+  Sections:
+    - Name: .bar
+    - Name: .cgp
+    - Name: .symtab
+    - Name: .strtab
+    - Name: .shstrtab
+    - Name: .dynamic
+    - Name: .note.1
+    - Name: .note.2
+    - Name: .hash.1
+    - Name: .hash.2
+    - Name: .gnu.hash.1
+    - Name: .gnu.hash.2
+    - Name: .gnu.version_r
+    - Name: .gnu.version_d
+    - Name: .llvm_addrsig.1
+    - Name: .llvm_addrsig.2
+    - Name: .linker-options
+    - Name: .deplibs
+    - Name: .group
+    - Name: .rela
+    - Name: .relr
+  NoHeaders: [[TEST=<none>]]
+
+## The same document, but all fields that were set to <none> are removed.
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .bar
+    Type: SHT_PROGBITS
+  - Type: Fill
+    Size: 0x3
+  - Name: .cgp
+    Type: SHT_LLVM_CALL_GRAPH_PROFILE
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+## Note: for SHT_NOTE sections, one of "Content", "Size" or "Notes" must be specified.
+  - Name: .note.1
+    Type: SHT_NOTE
+    Size: 1
+  - Name:    .note.2
+    Type:    SHT_NOTE
+    Content: "1122"
+## Note: for SHT_HASH sections, one of "Content", "Size", "Bucket" or "Chain" must be specified.
+  - Name: .hash.1
+    Type: SHT_HASH
+    Size: 1
+  - Name:    .hash.2
+    Type:    SHT_HASH
+    Content: "1122"
+## Note: for SHT_GNU_HASH sections either "Content" or "Header", "BloomFilter", "HashBuckets" and
+## "HashBuckets" must be specified.
+  - Name:    .gnu.hash.1
+    Type:    SHT_GNU_HASH
+    Content: "00"
+  - Name:        .gnu.hash.2
+    Type:        SHT_GNU_HASH
+    BloomFilter: []
+    HashBuckets: []
+    HashValues:  []
+    Header:
+      SymNdx: 0x0
+      Shift2: 0x0
+  - Name: .gnu.version_r
+    Type: SHT_GNU_verneed
+    Info: 0x0
+  - Name: .gnu.version_d
+    Info: 0x0
+    Type: SHT_GNU_verdef
+## Note: for SHT_LLVM_ADDRSIG sections one of "Content", "Size" or "Symbols" must be specified.
+  - Name:    .llvm_addrsig.1
+    Type:    SHT_LLVM_ADDRSIG
+    Content: "1122"
+  - Name: .llvm_addrsig.2
+    Type: SHT_LLVM_ADDRSIG
+    Size: 1
+  - Name: .linker-options
+    Type: SHT_LLVM_LINKER_OPTIONS
+  - Name: .deplibs
+    Type: SHT_LLVM_DEPENDENT_LIBRARIES
+  - Name:    .group
+    Type:    SHT_GROUP
+    Members: []
+  - Name: .rela
+    Type: SHT_RELA
+    Relocations:
+      - Type: R_X86_64_NONE
+  - Name: .relr
+    Type: SHT_RELR
+ProgramHeaders:
+  - Type: PT_LOAD
+Symbols:
+  - Name: foo
+SectionHeaderTable:
+  Sections:
+    - Name: .bar
+    - Name: .cgp
+    - Name: .symtab
+    - Name: .strtab
+    - Name: .shstrtab
+    - Name: .dynamic
+    - Name: .note.1
+    - Name: .note.2
+    - Name: .hash.1
+    - Name: .hash.2
+    - Name: .gnu.hash.1
+    - Name: .gnu.hash.2
+    - Name: .gnu.version_r
+    - Name: .gnu.version_d
+    - Name: .llvm_addrsig.1
+    - Name: .llvm_addrsig.2
+    - Name: .linker-options
+    - Name: .deplibs
+    - Name: .group
+    - Name: .rela
+    - Name: .relr