} // End yaml namespace
} // End llvm namespace
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t)
-
namespace llvm {
namespace yaml {
LLVM_YAML_IS_STRING_MAP(TypeIdSummary)
LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
namespace llvm {
namespace yaml {
} // namespace llvm::DWARFYAML
} // namespace llvm
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint8_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
namespace llvm {
namespace yaml {
/// to/from a YAML sequence. For example:
///
/// template<>
-/// struct SequenceTraits< std::vector<MyType>> {
-/// static size_t size(IO &io, std::vector<MyType> &seq) {
+/// struct SequenceTraits<MyContainer> {
+/// static size_t size(IO &io, MyContainer &seq) {
/// return seq.size();
/// }
-/// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
+/// static MyType& element(IO &, MyContainer &seq, size_t index) {
/// if ( index >= seq.size() )
/// seq.resize(index+1);
/// return seq[index];
/// }
/// };
-template<typename T>
+template<typename T, typename EnableIf = void>
struct SequenceTraits {
// Must provide:
// static size_t size(IO &io, T &seq);
// static const bool flow = true;
};
+/// This class should be specialized by any type for which vectors of that
+/// type need to be converted to/from a YAML sequence.
+template<typename T, typename EnableIf = void>
+struct SequenceElementTraits {
+ // Must provide:
+ // static const bool flow;
+};
+
/// This class should be specialized by any type that needs to be converted
/// to/from a list of YAML documents.
template<typename T>
return yout;
}
-template <typename T> struct SequenceTraitsImpl {
- using _type = typename T::value_type;
+template <bool B> struct IsFlowSequenceBase {};
+template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
+template <typename T, bool Flow>
+struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
+private:
+ using type = typename T::value_type;
+
+public:
static size_t size(IO &io, T &seq) { return seq.size(); }
- static _type &element(IO &io, T &seq, size_t index) {
+ static type &element(IO &io, T &seq, size_t index) {
if (index >= seq.size())
seq.resize(index + 1);
return seq[index];
}
};
+// Simple helper to check an expression can be used as a bool-valued template
+// argument.
+template <bool> struct CheckIsBool { static const bool value = true; };
+
+// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
+// SequenceTraits that do the obvious thing.
+template <typename T>
+struct SequenceTraits<std::vector<T>,
+ typename std::enable_if<CheckIsBool<
+ SequenceElementTraits<T>::flow>::value>::type>
+ : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
+template <typename T, unsigned N>
+struct SequenceTraits<SmallVector<T, N>,
+ typename std::enable_if<CheckIsBool<
+ SequenceElementTraits<T>::flow>::value>::type>
+ : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
+
+// Sequences of fundamental types use flow formatting.
+template <typename T>
+struct SequenceElementTraits<
+ T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
+ static const bool flow = true;
+};
+
+// Sequences of strings use block formatting.
+template<> struct SequenceElementTraits<std::string> {
+ static const bool flow = false;
+};
+template<> struct SequenceElementTraits<StringRef> {
+ static const bool flow = false;
+};
+template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
+ static const bool flow = false;
+};
+
/// Implementation of CustomMappingTraits for std::map<std::string, T>.
template <typename T> struct StdMapStringCustomMappingTraitsImpl {
using map_type = std::map<std::string, T>;
} // end namespace yaml
} // end namespace llvm
-/// Utility for declaring that a std::vector of a particular type
-/// should be considered a YAML sequence.
-#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
+#define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW) \
namespace llvm { \
namespace yaml { \
- template <> \
- struct SequenceTraits<std::vector<_type>> \
- : public SequenceTraitsImpl<std::vector<_type>> {}; \
- template <unsigned N> \
- struct SequenceTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
+ static_assert( \
+ !std::is_fundamental<TYPE>::value && \
+ !std::is_same<TYPE, std::string>::value && \
+ !std::is_same<TYPE, llvm::StringRef>::value, \
+ "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
+ template <> struct SequenceElementTraits<TYPE> { \
+ static const bool flow = FLOW; \
+ }; \
} \
}
+/// Utility for declaring that a std::vector of a particular type
+/// should be considered a YAML sequence.
+#define LLVM_YAML_IS_SEQUENCE_VECTOR(type) \
+ LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
+
/// Utility for declaring that a std::vector of a particular type
/// should be considered a YAML flow sequence.
-/// We need to do a partial specialization on the vector version, not a full.
-/// If this is a full specialization, the compiler is a bit too "smart" and
-/// decides to warn on -Wunused-const-variable. This workaround can be
-/// removed and we can do a full specialization on std::vector<T> once
-/// PR28878 is fixed.
-#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
- namespace llvm { \
- namespace yaml { \
- template <unsigned N> \
- struct SequenceTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> { \
- static const bool flow = true; \
- }; \
- template <typename Allocator> \
- struct SequenceTraits<std::vector<_type, Allocator>> \
- : public SequenceTraitsImpl<std::vector<_type, Allocator>> { \
- static const bool flow = true; \
- }; \
- } \
- }
+#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type) \
+ LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
#define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \
namespace llvm { \
namespace yaml { \
template <unsigned N> \
struct DocumentListTraits<SmallVector<_type, N>> \
- : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
+ : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
template <> \
struct DocumentListTraits<std::vector<_type>> \
- : public SequenceTraitsImpl<std::vector<_type>> {}; \
+ : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
} \
}
LLVM_YAML_IS_SEQUENCE_VECTOR(InlineeInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(CrossModuleExport)
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLCrossModuleImport)
-LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(YAMLFrameData)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
LLVM_YAML_DECLARE_SCALAR_TRAITS(HexFormattedString, false)
LLVM_YAML_DECLARE_ENUM_TRAITS(DebugSubsectionKind)
using namespace llvm::CodeViewYAML::detail;
using namespace llvm::yaml;
-LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
using namespace llvm::yaml;
LLVM_YAML_IS_SEQUENCE_VECTOR(OneMethodRecord)
-LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(VFTableSlotKind)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
using namespace llvm::AMDGPU;
using namespace llvm::AMDGPU::CodeObject;
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Arg::Metadata)
LLVM_YAML_IS_SEQUENCE_VECTOR(Kernel::Metadata)
; CHECK: ---
; CHECK: Version: [ 1, 0 ]
-; CHECK: Printf: [ '1:1:4:%d\n', '2:1:8:%g\n' ]
+; CHECK: Printf:
+; CHECK: - '1:1:4:%d\n'
+; CHECK: - '2:1:8:%g\n'
; CHECK: Kernels:
; CHECK: - Name: test_char
; NOTES-NEXT: Owner Data size Description
; NOTES-NEXT: AMD 0x00000008 Unknown note type: (0x00000001)
; NOTES-NEXT: AMD 0x0000001b Unknown note type: (0x00000003)
-; GFX700: AMD 0x00008b06 Unknown note type: (0x0000000a)
-; GFX800: AMD 0x00008e6a Unknown note type: (0x0000000a)
-; GFX900: AMD 0x00008b06 Unknown note type: (0x0000000a)
+; GFX700: AMD 0x00008b0a Unknown note type: (0x0000000a)
+; GFX800: AMD 0x00008e6e Unknown note type: (0x0000000a)
+; GFX900: AMD 0x00008b0a Unknown note type: (0x0000000a)
; PARSER: AMDGPU Code Object Metadata Parser Test: PASS
// CHECK: .amdgpu_code_object_metadata
// CHECK: Version: [ 1, 0 ]
-// CHECK: Printf: [ '1:1:4:%d\n', '2:1:8:%g\n' ]
+// CHECK: Printf:
+// CHECK: - '1:1:4:%d\n'
+// CHECK: - '2:1:8:%g\n'
// CHECK: Kernels:
// CHECK: - Name: test_kernel
// CHECK: Language: OpenCL C
// CHECK: .amdgpu_code_object_metadata
// CHECK: Version: [ 1, 0 ]
-// CHECK: Printf: [ '1:1:4:%d\n', '2:1:8:%g\n' ]
+// CHECK: Printf:
+// CHECK: - '1:1:4:%d\n'
+// CHECK: - '2:1:8:%g\n'
// CHECK: Kernels:
// CHECK: - Name: test_kernel
// CHECK: Language: OpenCL C
; SUMMARY-NEXT: SizeM1BitWidth: 0
; SUMMARY-NEXT: WPDRes:
-; SUMMARY: CfiFunctionDefs: [ f, g, h ]
-; SUMMARY-NEXT: CfiFunctionDecls: [ external, external_weak ]
+; SUMMARY: CfiFunctionDefs:
+; SUMMARY-NEXT: - f
+; SUMMARY-NEXT: - g
+; SUMMARY-NEXT: - h
+; SUMMARY-NEXT: CfiFunctionDecls:
+; SUMMARY-NEXT: - external
+; SUMMARY-NEXT: - external_weak
; SUMMARY-NEXT: ...
using namespace llvm::pdb::yaml;
using namespace llvm::yaml;
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::NamedStreamMapping)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::PdbDbiModuleInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::pdb::yaml::StreamBlockList)
LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::StringRef)
+LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, MyString)
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyString)
namespace llvm {
namespace yaml {
static bool mustQuote(StringRef) { return false; }
};
+
+ template <> struct ScalarTraits<MyString> {
+ using Impl = ScalarTraits<StringRef>;
+ static void output(const MyString &V, void *Ctx, raw_ostream &OS) {
+ Impl::output(V, Ctx, OS);
+ }
+ static StringRef input(StringRef S, void *Ctx, MyString &V) {
+ return Impl::input(S, Ctx, V.value);
+ }
+ static bool mustQuote(StringRef S) { return Impl::mustQuote(S); }
+ };
}
}
struct NameAndNumbers {
llvm::StringRef name;
- std::vector<llvm::StringRef> strings;
+ std::vector<MyString> strings;
std::vector<MyNumber> single;
std::vector<MyNumber> numbers;
};
EXPECT_FALSE(yin.error());
EXPECT_TRUE(map2.name.equals("hello"));
EXPECT_EQ(map2.strings.size(), 2UL);
- EXPECT_TRUE(map2.strings[0].equals("one"));
- EXPECT_TRUE(map2.strings[1].equals("two"));
+ EXPECT_TRUE(map2.strings[0].value.equals("one"));
+ EXPECT_TRUE(map2.strings[1].value.equals("two"));
EXPECT_EQ(map2.single.size(), 1UL);
EXPECT_EQ(1, map2.single[0]);
EXPECT_EQ(map2.numbers.size(), 3UL);
//
// Test error handling reading built-in uint8_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint8_t)
TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
std::vector<uint8_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in uint16_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint16_t)
TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
std::vector<uint16_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in uint32_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t)
TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
std::vector<uint32_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in uint64_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t)
TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
std::vector<uint64_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in int8_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int8_t)
TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
std::vector<int8_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in int16_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int16_t)
TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
std::vector<int16_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in int32_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int32_t)
TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
std::vector<int32_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in int64_t type
//
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int64_t)
TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
std::vector<int64_t> seq;
Input yin("---\n"
//
// Test error handling reading built-in float type
//
-LLVM_YAML_IS_SEQUENCE_VECTOR(float)
TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
std::vector<float> seq;
Input yin("---\n"
//
// Test error handling reading built-in float type
//
-LLVM_YAML_IS_SEQUENCE_VECTOR(double)
TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
std::vector<double> seq;
Input yin("---\n"