From bc9b6b33a0d5760370e72ae06c520c25aa8d61c6 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 12 Mar 2020 09:51:59 -0700 Subject: [PATCH] [lldb/Utility] Add YAML traits for ConstString and FileSpec. 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 | 15 +++++++++++++-- lldb/include/lldb/Utility/FileSpec.h | 15 +++++++++++++++ lldb/source/Utility/ConstString.cpp | 12 ++++++++++++ lldb/source/Utility/FileSpec.cpp | 16 ++++++++++++++++ lldb/unittests/Utility/ConstStringTest.cpp | 20 ++++++++++++++++++++ lldb/unittests/Utility/FileSpecTest.cpp | 21 +++++++++++++++++++++ 6 files changed, 97 insertions(+), 2 deletions(-) diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h index ee605dad9493a..c2419407f2f6e 100644 --- a/lldb/include/lldb/Utility/ConstString.h +++ b/lldb/include/lldb/Utility/ConstString.h @@ -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 @@ -481,6 +482,16 @@ template <> struct DenseMapInfo { } }; /// \} -} + +namespace yaml { +template <> struct ScalarTraits { + 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 diff --git a/lldb/include/lldb/Utility/FileSpec.h b/lldb/include/lldb/Utility/FileSpec.h index 119b33d54d4e2..f7cbeb247100d 100644 --- a/lldb/include/lldb/Utility/FileSpec.h +++ b/lldb/include/lldb/Utility/FileSpec.h @@ -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 #include @@ -397,6 +398,8 @@ class FileSpec { ConstString GetLastPathComponent() const; protected: + friend struct llvm::yaml::MappingTraits; + // Convenience method for setting the file without changing the style. void SetFile(llvm::StringRef path); @@ -410,6 +413,8 @@ class FileSpec { /// 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 { static void format(const lldb_private::FileSpec &F, llvm::raw_ostream &Stream, StringRef Style); }; + +namespace yaml { +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, lldb_private::FileSpecStyle &style); +}; + +template <> struct MappingTraits { + static void mapping(IO &io, lldb_private::FileSpec &f); +}; +} // namespace yaml } // namespace llvm #endif // LLDB_UTILITY_FILESPEC_H diff --git a/lldb/source/Utility/ConstString.cpp b/lldb/source/Utility/ConstString.cpp index 8911a06218bcc..62f79b3df7a5a 100644 --- a/lldb/source/Utility/ConstString.cpp +++ b/lldb/source/Utility/ConstString.cpp @@ -337,3 +337,15 @@ void llvm::format_provider::format(const ConstString &CS, llvm::StringRef Options) { format_provider::format(CS.GetStringRef(), OS, Options); } + +void llvm::yaml::ScalarTraits::output(const ConstString &Val, + void *, raw_ostream &Out) { + Out << Val.GetStringRef(); +} + +llvm::StringRef +llvm::yaml::ScalarTraits::input(llvm::StringRef Scalar, void *, + ConstString &Val) { + Val = ConstString(Scalar); + return {}; +} diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp index f732b43f700ec..1ec5d60e27804 100644 --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -537,3 +537,19 @@ void llvm::format_provider::format(const FileSpec &F, if (!file.empty()) Stream << file; } + +void llvm::yaml::ScalarEnumerationTraits::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::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; +} diff --git a/lldb/unittests/Utility/ConstStringTest.cpp b/lldb/unittests/Utility/ConstStringTest.cpp index 9affa927570a5..96624b3913089 100644 --- a/lldb/unittests/Utility/ConstStringTest.cpp +++ b/lldb/unittests/Utility/ConstStringTest.cpp @@ -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(nullptr)); EXPECT_TRUE(null != "bar"); } + +TEST(ConstStringTest, YAML) { + std::string buffer; + llvm::raw_string_ostream os(buffer); + + // Serialize. + std::vector strings = {ConstString("foo"), ConstString("bar"), + ConstString("")}; + llvm::yaml::Output yout(os); + yout << strings; + os.flush(); + + // Deserialize. + std::vector deserialized; + llvm::yaml::Input yin(buffer); + yin >> deserialized; + + EXPECT_EQ(strings, deserialized); +} diff --git a/lldb/unittests/Utility/FileSpecTest.cpp b/lldb/unittests/Utility/FileSpecTest.cpp index 7e9fcfec99f7d..c66edc4447978 100644 --- a/lldb/unittests/Utility/FileSpecTest.cpp +++ b/lldb/unittests/Utility/FileSpecTest.cpp @@ -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); +}