diff --git a/lldb/include/lldb/Utility/ConstString.h b/lldb/include/lldb/Utility/ConstString.h --- 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 @@ } }; /// \} -} + +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 --- 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 @@ 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 @@ /// 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 @@ 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 --- a/lldb/source/Utility/ConstString.cpp +++ b/lldb/source/Utility/ConstString.cpp @@ -337,3 +337,15 @@ 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 --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -537,3 +537,19 @@ 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 --- 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 @@ 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 --- a/lldb/unittests/Utility/FileSpecTest.cpp +++ b/lldb/unittests/Utility/FileSpecTest.cpp @@ -420,3 +420,24 @@ 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); +}