Index: llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h =================================================================== --- llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h +++ llvm/trunk/include/llvm/IR/ModuleSummaryIndexYAML.h @@ -140,8 +140,6 @@ } // End yaml namespace } // End llvm namespace -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) - namespace llvm { namespace yaml { @@ -188,7 +186,6 @@ LLVM_YAML_IS_STRING_MAP(TypeIdSummary) LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml) -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string) namespace llvm { namespace yaml { Index: llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h =================================================================== --- llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h +++ llvm/trunk/include/llvm/ObjectYAML/DWARFYAML.h @@ -161,9 +161,7 @@ } // 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) Index: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h =================================================================== --- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h +++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h @@ -140,7 +140,6 @@ 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) Index: llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h =================================================================== --- llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h +++ llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h @@ -280,7 +280,6 @@ 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 { Index: llvm/trunk/include/llvm/Support/YAMLTraits.h =================================================================== --- llvm/trunk/include/llvm/Support/YAMLTraits.h +++ llvm/trunk/include/llvm/Support/YAMLTraits.h @@ -180,17 +180,17 @@ /// to/from a YAML sequence. For example: /// /// template<> -/// struct SequenceTraits< std::vector> { -/// static size_t size(IO &io, std::vector &seq) { +/// struct SequenceTraits { +/// static size_t size(IO &io, MyContainer &seq) { /// return seq.size(); /// } -/// static MyType& element(IO &, std::vector &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 +template struct SequenceTraits { // Must provide: // static size_t size(IO &io, T &seq); @@ -201,6 +201,14 @@ // 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 +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 @@ -1542,18 +1550,59 @@ return yout; } -template struct SequenceTraitsImpl { - using _type = typename T::value_type; +template struct IsFlowSequenceBase {}; +template <> struct IsFlowSequenceBase { static const bool flow = true; }; +template +struct SequenceTraitsImpl : IsFlowSequenceBase { +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 struct CheckIsBool { static const bool value = true; }; + +// If T has SequenceElementTraits, then vector and SmallVector have +// SequenceTraits that do the obvious thing. +template +struct SequenceTraits, + typename std::enable_if::flow>::value>::type> + : SequenceTraitsImpl, SequenceElementTraits::flow> {}; +template +struct SequenceTraits, + typename std::enable_if::flow>::value>::type> + : SequenceTraitsImpl, SequenceElementTraits::flow> {}; + +// Sequences of fundamental types use flow formatting. +template +struct SequenceElementTraits< + T, typename std::enable_if::value>::type> { + static const bool flow = true; +}; + +// Sequences of strings use block formatting. +template<> struct SequenceElementTraits { + static const bool flow = false; +}; +template<> struct SequenceElementTraits { + static const bool flow = false; +}; +template<> struct SequenceElementTraits> { + static const bool flow = false; +}; + /// Implementation of CustomMappingTraits for std::map. template struct StdMapStringCustomMappingTraitsImpl { using map_type = std::map; @@ -1571,42 +1620,29 @@ } // 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> \ - : public SequenceTraitsImpl> {}; \ - template \ - struct SequenceTraits> \ - : public SequenceTraitsImpl> {}; \ + static_assert( \ + !std::is_fundamental::value && \ + !std::is_same::value && \ + !std::is_same::value, \ + "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \ + template <> struct SequenceElementTraits { \ + 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 once -/// PR28878 is fixed. -#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \ - namespace llvm { \ - namespace yaml { \ - template \ - struct SequenceTraits> \ - : public SequenceTraitsImpl> { \ - static const bool flow = true; \ - }; \ - template \ - struct SequenceTraits> \ - : public SequenceTraitsImpl> { \ - 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 { \ @@ -1653,10 +1689,10 @@ namespace yaml { \ template \ struct DocumentListTraits> \ - : public SequenceTraitsImpl> {}; \ + : public SequenceTraitsImpl, false> {}; \ template <> \ struct DocumentListTraits> \ - : public SequenceTraitsImpl> {}; \ + : public SequenceTraitsImpl, false> {}; \ } \ } Index: llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp +++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLDebugSections.cpp @@ -48,9 +48,7 @@ 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) Index: llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -27,7 +27,6 @@ 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 Index: llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp +++ llvm/trunk/lib/ObjectYAML/CodeViewYAMLTypes.cpp @@ -29,7 +29,6 @@ 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) Index: llvm/trunk/lib/Support/AMDGPUCodeObjectMetadata.cpp =================================================================== --- llvm/trunk/lib/Support/AMDGPUCodeObjectMetadata.cpp +++ llvm/trunk/lib/Support/AMDGPUCodeObjectMetadata.cpp @@ -20,8 +20,6 @@ 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) Index: llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-from-llvm-ir-full.ll =================================================================== --- llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-from-llvm-ir-full.ll +++ llvm/trunk/test/CodeGen/AMDGPU/code-object-metadata-from-llvm-ir-full.ll @@ -16,7 +16,9 @@ ; 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 @@ -1253,8 +1255,8 @@ ; 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 Index: llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-args.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-args.s +++ llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-args.s @@ -4,7 +4,9 @@ // 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 Index: llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-attrs.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-attrs.s +++ llvm/trunk/test/MC/AMDGPU/code-object-metadata-kernel-attrs.s @@ -4,7 +4,9 @@ // 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 Index: llvm/trunk/test/Transforms/LowerTypeTests/export-icall.ll =================================================================== --- llvm/trunk/test/Transforms/LowerTypeTests/export-icall.ll +++ llvm/trunk/test/Transforms/LowerTypeTests/export-icall.ll @@ -60,6 +60,11 @@ ; 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: ... Index: llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp =================================================================== --- llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp +++ llvm/trunk/tools/llvm-pdbutil/PdbYaml.cpp @@ -30,8 +30,6 @@ 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) Index: llvm/trunk/unittests/Support/YAMLIOTest.cpp =================================================================== --- llvm/trunk/unittests/Support/YAMLIOTest.cpp +++ llvm/trunk/unittests/Support/YAMLIOTest.cpp @@ -1029,7 +1029,8 @@ 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 { @@ -1049,12 +1050,23 @@ static bool mustQuote(StringRef) { return false; } }; + + template <> struct ScalarTraits { + using Impl = ScalarTraits; + 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 strings; + std::vector strings; std::vector single; std::vector numbers; }; @@ -1128,8 +1140,8 @@ 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); @@ -1739,7 +1751,6 @@ // // Test error handling reading built-in uint8_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint8_t) TEST(YAMLIO, TestReadBuiltInTypesUint8Error) { std::vector seq; Input yin("---\n" @@ -1758,7 +1769,6 @@ // // Test error handling reading built-in uint16_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint16_t) TEST(YAMLIO, TestReadBuiltInTypesUint16Error) { std::vector seq; Input yin("---\n" @@ -1777,7 +1787,6 @@ // // Test error handling reading built-in uint32_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint32_t) TEST(YAMLIO, TestReadBuiltInTypesUint32Error) { std::vector seq; Input yin("---\n" @@ -1796,7 +1805,6 @@ // // Test error handling reading built-in uint64_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(uint64_t) TEST(YAMLIO, TestReadBuiltInTypesUint64Error) { std::vector seq; Input yin("---\n" @@ -1815,7 +1823,6 @@ // // Test error handling reading built-in int8_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int8_t) TEST(YAMLIO, TestReadBuiltInTypesint8OverError) { std::vector seq; Input yin("---\n" @@ -1853,7 +1860,6 @@ // // Test error handling reading built-in int16_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int16_t) TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) { std::vector seq; Input yin("---\n" @@ -1892,7 +1898,6 @@ // // Test error handling reading built-in int32_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int32_t) TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) { std::vector seq; Input yin("---\n" @@ -1930,7 +1935,6 @@ // // Test error handling reading built-in int64_t type // -LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int64_t) TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) { std::vector seq; Input yin("---\n" @@ -1967,7 +1971,6 @@ // // Test error handling reading built-in float type // -LLVM_YAML_IS_SEQUENCE_VECTOR(float) TEST(YAMLIO, TestReadBuiltInTypesFloatError) { std::vector seq; Input yin("---\n" @@ -1986,7 +1989,6 @@ // // Test error handling reading built-in float type // -LLVM_YAML_IS_SEQUENCE_VECTOR(double) TEST(YAMLIO, TestReadBuiltInTypesDoubleError) { std::vector seq; Input yin("---\n"