[lldb/Utility] Add YAML traits for ConstString and FileSpec.
authorJonas Devlieghere <jonas@devlieghere.com>
Thu, 12 Mar 2020 16:51:59 +0000 (09:51 -0700)
committerJonas Devlieghere <jonas@devlieghere.com>
Thu, 12 Mar 2020 17:28:21 +0000 (10:28 -0700)
Add YAML traits for the ConstString and FileSpec classes so they can be
serialized as part of ProcessInfo. The latter needs to be serializable
for the reproducers.

Differential revision: https://reviews.llvm.org/D76002

lldb/include/lldb/Utility/ConstString.h
lldb/include/lldb/Utility/FileSpec.h
lldb/source/Utility/ConstString.cpp
lldb/source/Utility/FileSpec.cpp
lldb/unittests/Utility/ConstStringTest.cpp
lldb/unittests/Utility/FileSpecTest.cpp

index ee605da..c241940 100644 (file)
@@ -9,9 +9,10 @@
 #ifndef LLDB_UTILITY_CONSTSTRING_H
 #define LLDB_UTILITY_CONSTSTRING_H
 
-#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/YAMLTraits.h"
 
 #include <stddef.h>
 
@@ -481,6 +482,16 @@ template <> struct DenseMapInfo<lldb_private::ConstString> {
   }
 };
 /// \}
-}
+
+namespace yaml {
+template <> struct ScalarTraits<lldb_private::ConstString> {
+  static void output(const lldb_private::ConstString &, void *, raw_ostream &);
+  static StringRef input(StringRef, void *, lldb_private::ConstString &);
+  static QuotingType mustQuote(StringRef S) { return QuotingType::Double; }
+};
+} // namespace yaml
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(lldb_private::ConstString)
 
 #endif // LLDB_UTILITY_CONSTSTRING_H
index 119b33d..f7cbeb2 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLTraits.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -397,6 +398,8 @@ public:
   ConstString GetLastPathComponent() const;
 
 protected:
+  friend struct llvm::yaml::MappingTraits<FileSpec>;
+
   // Convenience method for setting the file without changing the style.
   void SetFile(llvm::StringRef path);
 
@@ -410,6 +413,8 @@ protected:
 /// Dump a FileSpec object to a stream
 Stream &operator<<(Stream &s, const FileSpec &f);
 
+/// Prevent ODR violations with traits for llvm::sys::path::Style.
+LLVM_YAML_STRONG_TYPEDEF(FileSpec::Style, FileSpecStyle)
 } // namespace lldb_private
 
 namespace llvm {
@@ -436,6 +441,16 @@ template <> struct format_provider<lldb_private::FileSpec> {
   static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream,
                      StringRef Style);
 };
+
+namespace yaml {
+template <> struct ScalarEnumerationTraits<lldb_private::FileSpecStyle> {
+  static void enumeration(IO &io, lldb_private::FileSpecStyle &style);
+};
+
+template <> struct MappingTraits<lldb_private::FileSpec> {
+  static void mapping(IO &io, lldb_private::FileSpec &f);
+};
+} // namespace yaml
 } // namespace llvm
 
 #endif // LLDB_UTILITY_FILESPEC_H
index 8911a06..62f79b3 100644 (file)
@@ -337,3 +337,15 @@ void llvm::format_provider<ConstString>::format(const ConstString &CS,
                                                 llvm::StringRef Options) {
   format_provider<StringRef>::format(CS.GetStringRef(), OS, Options);
 }
+
+void llvm::yaml::ScalarTraits<ConstString>::output(const ConstString &Val,
+                                                   void *, raw_ostream &Out) {
+  Out << Val.GetStringRef();
+}
+
+llvm::StringRef
+llvm::yaml::ScalarTraits<ConstString>::input(llvm::StringRef Scalar, void *,
+                                             ConstString &Val) {
+  Val = ConstString(Scalar);
+  return {};
+}
index f732b43..1ec5d60 100644 (file)
@@ -537,3 +537,19 @@ void llvm::format_provider<FileSpec>::format(const FileSpec &F,
   if (!file.empty())
     Stream << file;
 }
+
+void llvm::yaml::ScalarEnumerationTraits<FileSpecStyle>::enumeration(
+    IO &io, FileSpecStyle &value) {
+  io.enumCase(value, "windows", FileSpecStyle(FileSpec::Style::windows));
+  io.enumCase(value, "posix", FileSpecStyle(FileSpec::Style::posix));
+  io.enumCase(value, "native", FileSpecStyle(FileSpec::Style::native));
+}
+
+void llvm::yaml::MappingTraits<FileSpec>::mapping(IO &io, FileSpec &f) {
+  io.mapRequired("directory", f.m_directory);
+  io.mapRequired("file", f.m_filename);
+  io.mapRequired("resolved", f.m_is_resolved);
+  FileSpecStyle style = f.m_style;
+  io.mapRequired("style", style);
+  f.m_style = style;
+}
index 9affa92..96624b3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "lldb/Utility/ConstString.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/YAMLParser.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
@@ -137,3 +138,22 @@ TEST(ConstStringTest, CompareStringRef) {
   EXPECT_TRUE(null == static_cast<const char *>(nullptr));
   EXPECT_TRUE(null != "bar");
 }
+
+TEST(ConstStringTest, YAML) {
+  std::string buffer;
+  llvm::raw_string_ostream os(buffer);
+
+  // Serialize.
+  std::vector<ConstString> strings = {ConstString("foo"), ConstString("bar"),
+                                      ConstString("")};
+  llvm::yaml::Output yout(os);
+  yout << strings;
+  os.flush();
+
+  // Deserialize.
+  std::vector<ConstString> deserialized;
+  llvm::yaml::Input yin(buffer);
+  yin >> deserialized;
+
+  EXPECT_EQ(strings, deserialized);
+}
index 7e9fcfe..c66edc4 100644 (file)
@@ -420,3 +420,24 @@ TEST(FileSpecTest, Match) {
   EXPECT_TRUE(Match("", ""));
 
 }
+
+TEST(FileSpecTest, Yaml) {
+  std::string buffer;
+  llvm::raw_string_ostream os(buffer);
+
+  // Serialize.
+  FileSpec fs_windows("F:\\bar", FileSpec::Style::windows);
+  llvm::yaml::Output yout(os);
+  yout << fs_windows;
+  os.flush();
+
+  // Deserialize.
+  FileSpec deserialized;
+  llvm::yaml::Input yin(buffer);
+  yin >> deserialized;
+
+  EXPECT_EQ(deserialized.GetPathStyle(), fs_windows.GetPathStyle());
+  EXPECT_EQ(deserialized.GetFilename(), fs_windows.GetFilename());
+  EXPECT_EQ(deserialized.GetDirectory(), fs_windows.GetDirectory());
+  EXPECT_EQ(deserialized, fs_windows);
+}