[llvm] 1b589f4 - Revert "[yaml2obj][ELF] - Simplify the code that performs sections validation."

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 20 05:17:42 PDT 2020


Author: Georgii Rymar
Date: 2020-10-20T15:16:56+03:00
New Revision: 1b589f4d4db27e3fcd81fdc5abeb9407753ab790

URL: https://github.com/llvm/llvm-project/commit/1b589f4d4db27e3fcd81fdc5abeb9407753ab790
DIFF: https://github.com/llvm/llvm-project/commit/1b589f4d4db27e3fcd81fdc5abeb9407753ab790.diff

LOG: Revert "[yaml2obj][ELF] - Simplify the code that performs sections validation."

This reverts commit b9e2b59680ad1bbfd2b9110b3ebf3d2b22cad51b.

Added: 
    

Modified: 
    lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
    llvm/include/llvm/ObjectYAML/DWARFYAML.h
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/include/llvm/ObjectYAML/MachOYAML.h
    llvm/include/llvm/ObjectYAML/MinidumpYAML.h
    llvm/include/llvm/Support/YAMLTraits.h
    llvm/lib/ObjectYAML/DWARFYAML.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/lib/ObjectYAML/MachOYAML.cpp
    llvm/lib/ObjectYAML/MinidumpYAML.cpp
    llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
    llvm/unittests/Support/YAMLIOTest.cpp

Removed: 
    


################################################################################
diff  --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
index 3826e97d62b9..7f53faaeaea3 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
@@ -740,7 +740,9 @@ struct MappingTraits<NormalizedFile> {
     io.mapOptional("exports",          file.exportInfo);
     io.mapOptional("dataInCode",       file.dataInCode);
   }
-  static std::string validate(IO &io, NormalizedFile &file) { return {}; }
+  static StringRef validate(IO &io, NormalizedFile &file) {
+    return StringRef();
+  }
 };
 
 } // namespace llvm

diff  --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 856cea9a1535..edb5f00c5e80 100644
--- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -359,8 +359,8 @@ struct MappingTraits<DWARFYAML::ListTable<EntryType>> {
 template <typename EntryType>
 struct MappingTraits<DWARFYAML::ListEntries<EntryType>> {
   static void mapping(IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries);
-  static std::string validate(IO &IO,
-                              DWARFYAML::ListEntries<EntryType> &ListEntries);
+  static StringRef validate(IO &IO,
+                            DWARFYAML::ListEntries<EntryType> &ListEntries);
 };
 
 template <> struct MappingTraits<DWARFYAML::RnglistEntry> {

diff  --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index 28cbf325ecb6..af6d934d611e 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -193,13 +193,6 @@ struct Section : public Chunk {
 
   static bool classof(const Chunk *S) { return S->Kind != ChunkKind::Fill; }
 
-  // Some derived sections might have their own special entries. This method
-  // returns a vector of <entry name, is used> pairs. It is used for section
-  // validation.
-  virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
-    return {};
-  };
-
   // The following members are used to override section fields which is
   // useful for creating invalid objects.
 
@@ -242,10 +235,6 @@ struct StackSizesSection : Section {
 
   StackSizesSection() : Section(ChunkKind::StackSizes) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::StackSizes;
   }
@@ -260,10 +249,6 @@ struct DynamicSection : Section {
 
   DynamicSection() : Section(ChunkKind::Dynamic) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
 };
 
@@ -291,10 +276,6 @@ struct NoteSection : Section {
 
   NoteSection() : Section(ChunkKind::Note) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Notes", Notes.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
 };
 
@@ -302,10 +283,6 @@ struct HashSection : Section {
   Optional<std::vector<uint32_t>> Bucket;
   Optional<std::vector<uint32_t>> Chain;
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Bucket", Bucket.hasValue()}, {"Chain", Chain.hasValue()}};
-  };
-
   // The following members are used to override section fields.
   // This is useful for creating invalid objects.
   Optional<llvm::yaml::Hex64> NBucket;
@@ -344,13 +321,6 @@ struct GnuHashSection : Section {
 
   GnuHashSection() : Section(ChunkKind::GnuHash) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Header", Header.hasValue()},
-            {"BloomFilter", BloomFilter.hasValue()},
-            {"HashBuckets", HashBuckets.hasValue()},
-            {"HashValues", HashValues.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
 };
 
@@ -373,10 +343,6 @@ struct VerneedSection : Section {
 
   VerneedSection() : Section(ChunkKind::Verneed) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Dependencies", VerneedV.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::Verneed;
   }
@@ -387,10 +353,6 @@ struct AddrsigSection : Section {
 
   AddrsigSection() : Section(ChunkKind::Addrsig) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Symbols", Symbols.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
 };
 
@@ -404,10 +366,6 @@ struct LinkerOptionsSection : Section {
 
   LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Options", Options.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::LinkerOptions;
   }
@@ -418,10 +376,6 @@ struct DependentLibrariesSection : Section {
 
   DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Libraries", Libs.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::DependentLibraries;
   }
@@ -442,10 +396,6 @@ struct CallGraphProfileSection : Section {
 
   CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::CallGraphProfile;
   }
@@ -456,10 +406,6 @@ struct SymverSection : Section {
 
   SymverSection() : Section(ChunkKind::Symver) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
 };
 
@@ -478,10 +424,6 @@ struct VerdefSection : Section {
 
   VerdefSection() : Section(ChunkKind::Verdef) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
 };
 
@@ -493,10 +435,6 @@ struct GroupSection : Section {
 
   GroupSection() : Section(ChunkKind::Group) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Members", Members.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
 };
 
@@ -513,10 +451,6 @@ struct RelocationSection : Section {
 
   RelocationSection() : Section(ChunkKind::Relocation) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Relocations", Relocations.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::Relocation;
   }
@@ -527,10 +461,6 @@ struct RelrSection : Section {
 
   RelrSection() : Section(ChunkKind::Relr) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::Relr;
   }
@@ -541,10 +471,6 @@ struct SymtabShndxSection : Section {
 
   SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::SymtabShndxSection;
   }
@@ -560,10 +486,6 @@ struct ARMIndexTableSection : Section {
 
   ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
 
-  std::vector<std::pair<StringRef, bool>> getEntries() const override {
-    return {{"Entries", Entries.hasValue()}};
-  };
-
   static bool classof(const Chunk *S) {
     return S->Kind == ChunkKind::ARMIndexTable;
   }
@@ -777,7 +699,7 @@ struct MappingTraits<ELFYAML::FileHeader> {
 
 template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
   static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
-  static std::string validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
+  static StringRef validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
 };
 
 template <> struct MappingTraits<ELFYAML::SectionHeader> {
@@ -791,7 +713,7 @@ template <> struct MappingTraits<ELFYAML::ProgramHeader> {
 template <>
 struct MappingTraits<ELFYAML::Symbol> {
   static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
-  static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
+  static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
 };
 
 template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
@@ -840,7 +762,7 @@ template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
 
 template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
   static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
-  static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
+  static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
 };
 
 template <>

diff  --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h
index 94e66c5ae787..fb6780b6d0ed 100644
--- a/llvm/include/llvm/ObjectYAML/MachOYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h
@@ -220,7 +220,7 @@ template <> struct MappingTraits<MachOYAML::Relocation> {
 
 template <> struct MappingTraits<MachOYAML::Section> {
   static void mapping(IO &IO, MachOYAML::Section &Section);
-  static std::string validate(IO &io, MachOYAML::Section &Section);
+  static StringRef validate(IO &io, MachOYAML::Section &Section);
 };
 
 template <> struct MappingTraits<MachOYAML::NListEntry> {

diff  --git a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
index b0cee541cef2..c1711a28dd84 100644
--- a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -236,7 +236,7 @@ template <> struct BlockScalarTraits<MinidumpYAML::BlockStringRef> {
 
 template <> struct MappingTraits<std::unique_ptr<MinidumpYAML::Stream>> {
   static void mapping(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
-  static std::string validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
+  static StringRef validate(IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S);
 };
 
 template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {

diff  --git a/llvm/include/llvm/Support/YAMLTraits.h b/llvm/include/llvm/Support/YAMLTraits.h
index bdfe7f7cbfcb..f32a6ca92d29 100644
--- a/llvm/include/llvm/Support/YAMLTraits.h
+++ b/llvm/include/llvm/Support/YAMLTraits.h
@@ -61,7 +61,7 @@ struct MappingTraits {
   // Must provide:
   // static void mapping(IO &io, T &fields);
   // Optionally may provide:
-  // static std::string validate(IO &io, T &fields);
+  // static StringRef validate(IO &io, T &fields);
   //
   // The optional flow flag will cause generated YAML to use a flow mapping
   // (e.g. { a: 0, b: 1 }):
@@ -83,7 +83,7 @@ template <class T, class Context> struct MappingContextTraits {
   // Must provide:
   // static void mapping(IO &io, T &fields, Context &Ctx);
   // Optionally may provide:
-  // static std::string validate(IO &io, T &fields, Context &Ctx);
+  // static StringRef validate(IO &io, T &fields, Context &Ctx);
   //
   // The optional flow flag will cause generated YAML to use a flow mapping
   // (e.g. { a: 0, b: 1 }):
@@ -421,7 +421,7 @@ template <class T> struct has_MappingTraits<T, EmptyContext> {
 
 // Test if MappingContextTraits<T>::validate() is defined on type T.
 template <class T, class Context> struct has_MappingValidateTraits {
-  using Signature_validate = std::string (*)(class IO &, T &, Context &);
+  using Signature_validate = StringRef (*)(class IO &, T &, Context &);
 
   template <typename U>
   static char test(SameType<Signature_validate, &U::validate>*);
@@ -435,7 +435,7 @@ template <class T, class Context> struct has_MappingValidateTraits {
 
 // Test if MappingTraits<T>::validate() is defined on type T.
 template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
-  using Signature_validate = std::string (*)(class IO &, T &);
+  using Signature_validate = StringRef (*)(class IO &, T &);
 
   template <typename U>
   static char test(SameType<Signature_validate, &U::validate> *);
@@ -1041,7 +1041,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
   else
     io.beginMapping();
   if (io.outputting()) {
-    std::string Err = MappingTraits<T>::validate(io, Val);
+    StringRef Err = MappingTraits<T>::validate(io, Val);
     if (!Err.empty()) {
       errs() << Err << "\n";
       assert(Err.empty() && "invalid struct trying to be written as yaml");
@@ -1049,7 +1049,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
   }
   detail::doMapping(io, Val, Ctx);
   if (!io.outputting()) {
-    std::string Err = MappingTraits<T>::validate(io, Val);
+    StringRef Err = MappingTraits<T>::validate(io, Val);
     if (!Err.empty())
       io.setError(Err);
   }

diff  --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp
index 2591bf4d5af4..36da74f904ce 100644
--- a/llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -304,11 +304,11 @@ void MappingTraits<DWARFYAML::ListEntries<EntryType>>::mapping(
 }
 
 template <typename EntryType>
-std::string MappingTraits<DWARFYAML::ListEntries<EntryType>>::validate(
+StringRef MappingTraits<DWARFYAML::ListEntries<EntryType>>::validate(
     IO &IO, DWARFYAML::ListEntries<EntryType> &ListEntries) {
   if (ListEntries.Entries && ListEntries.Content)
     return "Entries and Content can't be used together";
-  return "";
+  return StringRef();
 }
 
 template <typename EntryType>

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 978c4968dc64..b3dfd7f73945 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -864,14 +864,14 @@ void MappingTraits<ELFYAML::SectionHeaderTable>::mapping(
   IO.mapOptional("NoHeaders", SectionHeader.NoHeaders);
 }
 
-std::string MappingTraits<ELFYAML::SectionHeaderTable>::validate(
+StringRef MappingTraits<ELFYAML::SectionHeaderTable>::validate(
     IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable) {
   if (SecHdrTable.NoHeaders && (SecHdrTable.Sections || SecHdrTable.Excluded))
     return "NoHeaders can't be used together with Sections/Excluded";
   if (!SecHdrTable.NoHeaders && !SecHdrTable.Sections && !SecHdrTable.Excluded)
     return "SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the "
            "section header table";
-  return "";
+  return StringRef();
 }
 
 void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
@@ -1089,11 +1089,11 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
   IO.mapOptional("Other", Keys->Other);
 }
 
-std::string MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
-                                                     ELFYAML::Symbol &Symbol) {
+StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
+                                                   ELFYAML::Symbol &Symbol) {
   if (Symbol.Index && Symbol.Section.data())
     return "Index and Section cannot both be specified for Symbol";
-  return "";
+  return StringRef();
 }
 
 static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
@@ -1422,12 +1422,12 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
   }
 }
 
-std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
+StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
     IO &io, std::unique_ptr<ELFYAML::Chunk> &C) {
   if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
     if (F->Pattern && F->Pattern->binary_size() != 0 && !F->Size)
       return "\"Size\" can't be 0 when \"Pattern\" is not empty";
-    return "";
+    return {};
   }
 
   const ELFYAML::Section &Sec = *cast<ELFYAML::Section>(C.get());
@@ -1435,43 +1435,130 @@ std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
       (uint64_t)(*Sec.Size) < Sec.Content->binary_size())
     return "Section size must be greater than or equal to the content size";
 
-  auto BuildErrPrefix = [](ArrayRef<std::pair<StringRef, bool>> EntV) {
-    std::string Msg;
-    for (size_t I = 0, E = EntV.size(); I != E; ++I) {
-      StringRef Name = EntV[I].first;
-      if (I == 0) {
-        Msg = "\"" + Name.str() + "\"";
-        continue;
-      }
-      if (I != EntV.size() - 1)
-        Msg += ", \"" + Name.str() + "\"";
-      else
-        Msg += " and \"" + Name.str() + "\"";
-    }
-    return Msg;
-  };
+  if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
+    if (RawSection->Flags && RawSection->ShFlags)
+      return "ShFlags and Flags cannot be used together";
+    return {};
+  }
+
+  if (const auto *SS = dyn_cast<ELFYAML::StackSizesSection>(C.get())) {
+    if ((SS->Content || SS->Size) && SS->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *HS = dyn_cast<ELFYAML::HashSection>(C.get())) {
+    if ((HS->Content || HS->Size) && (HS->Bucket || HS->Chain))
+      return "\"Bucket\" and \"Chain\" cannot be used with \"Content\" or "
+             "\"Size\"";
+    if ((HS->Bucket && !HS->Chain) || (!HS->Bucket && HS->Chain))
+      return "\"Bucket\" and \"Chain\" must be used together";
+    return {};
+  }
 
-  std::vector<std::pair<StringRef, bool>> Entries = Sec.getEntries();
-  const size_t NumUsedEntries = llvm::count_if(
-      Entries, [](const std::pair<StringRef, bool> &P) { return P.second; });
+  if (const auto *Sec = dyn_cast<ELFYAML::AddrsigSection>(C.get())) {
+    if ((Sec->Content || Sec->Size) && Sec->Symbols)
+      return "\"Symbols\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
 
-  if ((Sec.Size || Sec.Content) && NumUsedEntries > 0)
-    return BuildErrPrefix(Entries) +
-           " cannot be used with \"Content\" or \"Size\"";
+  if (const auto *NS = dyn_cast<ELFYAML::NoteSection>(C.get())) {
+    if ((NS->Content || NS->Size) && NS->Notes)
+      return "\"Notes\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
 
-  if (NumUsedEntries > 0 && Entries.size() != NumUsedEntries)
-    return BuildErrPrefix(Entries) + " must be used together";
+  if (const auto *Sec = dyn_cast<ELFYAML::GnuHashSection>(C.get())) {
+    const bool HasSpecialFields =
+        Sec->Header || Sec->BloomFilter || Sec->HashBuckets || Sec->HashValues;
+    if (HasSpecialFields && (Sec->Content || Sec->Size))
+      return "\"Header\", \"BloomFilter\", "
+             "\"HashBuckets\" and \"HashValues\" can't be used together with "
+             "\"Content\" or \"Size\"";
+
+    if (HasSpecialFields && (!Sec->Header || !Sec->BloomFilter ||
+                             !Sec->HashBuckets || !Sec->HashValues))
+      return "\"Header\", \"BloomFilter\", "
+             "\"HashBuckets\" and \"HashValues\" must be used together";
+    return {};
+  }
 
-  if (const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(C.get())) {
-    if (RawSection->Flags && RawSection->ShFlags)
-      return "ShFlags and Flags cannot be used together";
-    return "";
+  if (const auto *Sec = dyn_cast<ELFYAML::LinkerOptionsSection>(C.get())) {
+    if ((Sec->Content || Sec->Size) && Sec->Options)
+      return "\"Options\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *Sec = dyn_cast<ELFYAML::DependentLibrariesSection>(C.get())) {
+    if ((Sec->Content || Sec->Size) && Sec->Libs)
+      return "\"Libraries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *VD = dyn_cast<ELFYAML::VerdefSection>(C.get())) {
+    if ((VD->Content || VD->Size) && VD->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *VN = dyn_cast<ELFYAML::VerneedSection>(C.get())) {
+    if ((VN->Content || VN->Size) && VN->VerneedV)
+      return "\"Dependencies\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *SV = dyn_cast<ELFYAML::SymverSection>(C.get())) {
+    if ((SV->Content || SV->Size) && SV->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *RS = dyn_cast<ELFYAML::RelrSection>(C.get())) {
+    if ((RS->Content || RS->Size) && RS->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *CGP = dyn_cast<ELFYAML::CallGraphProfileSection>(C.get())) {
+    if ((CGP->Content || CGP->Size) && CGP->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *IT = dyn_cast<ELFYAML::ARMIndexTableSection>(C.get())) {
+    if ((IT->Content || IT->Size) && IT->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *RS = dyn_cast<ELFYAML::RelocationSection>(C.get())) {
+    if ((RS->Content || RS->Size) && RS->Relocations)
+      return "\"Relocations\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *SS = dyn_cast<ELFYAML::SymtabShndxSection>(C.get())) {
+    if ((SS->Content || SS->Size) && SS->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
+  }
+
+  if (const auto *GS = dyn_cast<ELFYAML::GroupSection>(C.get())) {
+    if ((GS->Content || GS->Size) && GS->Members)
+      return "\"Members\" cannot be used with \"Content\" or \"Size\"";
+    return {};
   }
 
   if (const auto *NB = dyn_cast<ELFYAML::NoBitsSection>(C.get())) {
     if (NB->Content)
       return "SHT_NOBITS section cannot have \"Content\"";
-    return "";
+    return {};
+  }
+
+  if (const auto *DS = dyn_cast<ELFYAML::DynamicSection>(C.get())) {
+    if ((DS->Content || DS->Size) && DS->Entries)
+      return "\"Entries\" cannot be used with \"Content\" or \"Size\"";
+    return {};
   }
 
   if (const auto *MF = dyn_cast<ELFYAML::MipsABIFlags>(C.get())) {
@@ -1480,10 +1567,10 @@ std::string MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
              "sections";
     if (MF->Size)
       return "\"Size\" key is not implemented for SHT_MIPS_ABIFLAGS sections";
-    return "";
+    return {};
   }
 
-  return "";
+  return {};
 }
 
 namespace {

diff  --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp
index 5a27d37cb726..86aad0233767 100644
--- a/llvm/lib/ObjectYAML/MachOYAML.cpp
+++ b/llvm/lib/ObjectYAML/MachOYAML.cpp
@@ -305,12 +305,12 @@ void MappingTraits<MachOYAML::Section>::mapping(IO &IO,
   IO.mapOptional("relocations", Section.relocations);
 }
 
-std::string
+StringRef
 MappingTraits<MachOYAML::Section>::validate(IO &IO,
                                             MachOYAML::Section &Section) {
   if (Section.content && Section.size < Section.content->binary_size())
     return "Section size must be greater than or equal to the content size";
-  return "";
+  return {};
 }
 
 void MappingTraits<MachO::build_tool_version>::mapping(

diff  --git a/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
index e1a80b98e449..77ea42c41a4c 100644
--- a/llvm/lib/ObjectYAML/MinidumpYAML.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -292,7 +292,7 @@ static void streamMapping(yaml::IO &IO, RawContentStream &Stream) {
   IO.mapOptional("Size", Stream.Size, Stream.Content.binary_size());
 }
 
-static std::string streamValidate(RawContentStream &Stream) {
+static StringRef streamValidate(RawContentStream &Stream) {
   if (Stream.Size.value < Stream.Content.binary_size())
     return "Stream size must be greater or equal to the content size";
   return "";
@@ -434,7 +434,7 @@ void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
   }
 }
 
-std::string yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
+StringRef yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
     yaml::IO &IO, std::unique_ptr<MinidumpYAML::Stream> &S) {
   switch (S->Kind) {
   case MinidumpYAML::Stream::StreamKind::RawContent:

diff  --git a/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml b/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
index 607336a4cc84..3b58fa8ce407 100644
--- a/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml
@@ -231,7 +231,7 @@ Sections:
 
 # RUN: not yaml2obj --docnum=11 -DCONTENT="" %s 2>&1 | FileCheck %s --check-prefix=TOGETHER
 # RUN: not yaml2obj --docnum=11 -DSIZE=0 %s 2>&1 | FileCheck %s --check-prefix=TOGETHER
-# TOGETHER: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" cannot be used with "Content" or "Size"
+# TOGETHER: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content" or "Size"
 
 --- !ELF
 FileHeader:

diff  --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index c7df4b919a27..492d854ef812 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1782,10 +1782,10 @@ namespace yaml {
     static void mapping(IO &io, MyValidation &d) {
         io.mapRequired("value", d.value);
     }
-    static std::string validate(IO &io, MyValidation &d) {
+    static StringRef validate(IO &io, MyValidation &d) {
         if (d.value < 0)
           return "negative value";
-        return {};
+        return StringRef();
     }
   };
  }


        


More information about the llvm-commits mailing list