[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
This commit is contained in:
Jonas Devlieghere 2020-03-12 09:51:59 -07:00
parent adb290d974
commit bc9b6b33a0
6 changed files with 97 additions and 2 deletions

View 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

View 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

View 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 {};
}

View 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;
}

View 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);
}

View 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);
}