1 //===- unittest/Support/YAMLRemarksSerializerTest.cpp --------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Remarks/Remark.h" 10 #include "llvm/Remarks/YAMLRemarkSerializer.h" 11 #include "llvm/Support/Error.h" 12 #include "gtest/gtest.h" 13 14 // We need to supprt Windows paths as well. In order to have paths with the same 15 // length, use a different path according to the platform. 16 #ifdef _WIN32 17 #define EXTERNALFILETESTPATH "C:/externalfi" 18 #else 19 #define EXTERNALFILETESTPATH "/externalfile" 20 #endif 21 22 using namespace llvm; 23 24 static void check(remarks::SerializerMode Mode, const remarks::Remark &R, 25 StringRef ExpectedR, Optional<StringRef> ExpectedMeta, 26 bool UseStrTab = false, 27 Optional<remarks::StringTable> StrTab = None) { 28 std::string Buf; 29 raw_string_ostream OS(Buf); 30 Expected<std::unique_ptr<remarks::RemarkSerializer>> MaybeS = [&] { 31 if (UseStrTab) { 32 if (StrTab) 33 return createRemarkSerializer(remarks::Format::YAMLStrTab, Mode, OS, 34 std::move(*StrTab)); 35 else 36 return createRemarkSerializer(remarks::Format::YAMLStrTab, Mode, OS); 37 } else 38 return createRemarkSerializer(remarks::Format::YAML, Mode, OS); 39 }(); 40 EXPECT_FALSE(errorToBool(MaybeS.takeError())); 41 std::unique_ptr<remarks::RemarkSerializer> S = std::move(*MaybeS); 42 43 S->emit(R); 44 EXPECT_EQ(OS.str(), ExpectedR); 45 46 if (ExpectedMeta) { 47 Buf.clear(); 48 std::unique_ptr<remarks::MetaSerializer> MS = 49 S->metaSerializer(OS, StringRef(EXTERNALFILETESTPATH)); 50 MS->emit(); 51 EXPECT_EQ(OS.str(), *ExpectedMeta); 52 } 53 } 54 55 static void check(const remarks::Remark &R, StringRef ExpectedR, 56 StringRef ExpectedMeta, bool UseStrTab = false, 57 Optional<remarks::StringTable> StrTab = None) { 58 return check(remarks::SerializerMode::Separate, R, ExpectedR, ExpectedMeta, 59 UseStrTab, std::move(StrTab)); 60 } 61 62 static void checkStandalone(const remarks::Remark &R, StringRef ExpectedR, 63 Optional<remarks::StringTable> StrTab = None) { 64 bool UseStrTab = StrTab.hasValue(); 65 return check(remarks::SerializerMode::Standalone, R, ExpectedR, 66 /*ExpectedMeta=*/None, UseStrTab, std::move(StrTab)); 67 } 68 69 TEST(YAMLRemarks, SerializerRemark) { 70 remarks::Remark R; 71 R.RemarkType = remarks::Type::Missed; 72 R.PassName = "pass"; 73 R.RemarkName = "name"; 74 R.FunctionName = "func"; 75 R.Loc = remarks::RemarkLocation{"path", 3, 4}; 76 R.Hotness = 5; 77 R.Args.emplace_back(); 78 R.Args.back().Key = "key"; 79 R.Args.back().Val = "value"; 80 R.Args.emplace_back(); 81 R.Args.back().Key = "keydebug"; 82 R.Args.back().Val = "valuedebug"; 83 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; 84 check(R, 85 "--- !Missed\n" 86 "Pass: pass\n" 87 "Name: name\n" 88 "DebugLoc: { File: path, Line: 3, Column: 4 }\n" 89 "Function: func\n" 90 "Hotness: 5\n" 91 "Args:\n" 92 " - key: value\n" 93 " - keydebug: valuedebug\n" 94 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n" 95 "...\n", 96 StringRef("REMARKS\0" 97 "\0\0\0\0\0\0\0\0" 98 "\0\0\0\0\0\0\0\0" 99 EXTERNALFILETESTPATH"\0", 100 38)); 101 } 102 103 TEST(YAMLRemarks, SerializerRemarkStandalone) { 104 remarks::Remark R; 105 R.RemarkType = remarks::Type::Missed; 106 R.PassName = "pass"; 107 R.RemarkName = "name"; 108 R.FunctionName = "func"; 109 R.Loc = remarks::RemarkLocation{"path", 3, 4}; 110 R.Hotness = 5; 111 R.Args.emplace_back(); 112 R.Args.back().Key = "key"; 113 R.Args.back().Val = "value"; 114 R.Args.emplace_back(); 115 R.Args.back().Key = "keydebug"; 116 R.Args.back().Val = "valuedebug"; 117 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; 118 checkStandalone( 119 R, 120 StringRef("REMARKS\0" 121 "\0\0\0\0\0\0\0\0" 122 "\0\0\0\0\0\0\0\0" 123 "--- !Missed\n" 124 "Pass: pass\n" 125 "Name: name\n" 126 "DebugLoc: { File: path, Line: 3, Column: 4 }\n" 127 "Function: func\n" 128 "Hotness: 5\n" 129 "Args:\n" 130 " - key: value\n" 131 " - keydebug: valuedebug\n" 132 " DebugLoc: { File: argpath, Line: 6, Column: 7 }\n" 133 "...\n", 134 301)); 135 } 136 137 TEST(YAMLRemarks, SerializerRemarkStrTab) { 138 remarks::Remark R; 139 R.RemarkType = remarks::Type::Missed; 140 R.PassName = "pass"; 141 R.RemarkName = "name"; 142 R.FunctionName = "func"; 143 R.Loc = remarks::RemarkLocation{"path", 3, 4}; 144 R.Hotness = 5; 145 R.Args.emplace_back(); 146 R.Args.back().Key = "key"; 147 R.Args.back().Val = "value"; 148 R.Args.emplace_back(); 149 R.Args.back().Key = "keydebug"; 150 R.Args.back().Val = "valuedebug"; 151 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; 152 check(R, 153 "--- !Missed\n" 154 "Pass: 0\n" 155 "Name: 1\n" 156 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n" 157 "Function: 2\n" 158 "Hotness: 5\n" 159 "Args:\n" 160 " - key: 4\n" 161 " - keydebug: 5\n" 162 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n" 163 "...\n", 164 StringRef("REMARKS\0" 165 "\0\0\0\0\0\0\0\0" 166 "\x2d\0\0\0\0\0\0\0" 167 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0" 168 EXTERNALFILETESTPATH"\0", 169 83), 170 /*UseStrTab=*/true); 171 } 172 173 TEST(YAMLRemarks, SerializerRemarkParsedStrTab) { 174 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45); 175 remarks::Remark R; 176 R.RemarkType = remarks::Type::Missed; 177 R.PassName = "pass"; 178 R.RemarkName = "name"; 179 R.FunctionName = "func"; 180 R.Loc = remarks::RemarkLocation{"path", 3, 4}; 181 R.Hotness = 5; 182 R.Args.emplace_back(); 183 R.Args.back().Key = "key"; 184 R.Args.back().Val = "value"; 185 R.Args.emplace_back(); 186 R.Args.back().Key = "keydebug"; 187 R.Args.back().Val = "valuedebug"; 188 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; 189 check(R, 190 "--- !Missed\n" 191 "Pass: 0\n" 192 "Name: 1\n" 193 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n" 194 "Function: 2\n" 195 "Hotness: 5\n" 196 "Args:\n" 197 " - key: 4\n" 198 " - keydebug: 5\n" 199 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n" 200 "...\n", 201 StringRef("REMARKS\0" 202 "\0\0\0\0\0\0\0\0" 203 "\x2d\0\0\0\0\0\0\0" 204 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0" 205 EXTERNALFILETESTPATH"\0", 206 83), 207 /*UseStrTab=*/true, 208 remarks::StringTable(remarks::ParsedStringTable(StrTab))); 209 } 210 211 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandalone) { 212 StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45); 213 remarks::ParsedStringTable ParsedStrTab(StrTab); 214 remarks::StringTable PreFilledStrTab(ParsedStrTab); 215 remarks::Remark R; 216 R.RemarkType = remarks::Type::Missed; 217 R.PassName = "pass"; 218 R.RemarkName = "name"; 219 R.FunctionName = "func"; 220 R.Loc = remarks::RemarkLocation{"path", 3, 4}; 221 R.Hotness = 5; 222 R.Args.emplace_back(); 223 R.Args.back().Key = "key"; 224 R.Args.back().Val = "value"; 225 R.Args.emplace_back(); 226 R.Args.back().Key = "keydebug"; 227 R.Args.back().Val = "valuedebug"; 228 R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7}; 229 checkStandalone( 230 R, 231 StringRef("REMARKS\0" 232 "\0\0\0\0\0\0\0\0" 233 "\x2d\0\0\0\0\0\0\0" 234 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0" 235 "--- !Missed\n" 236 "Pass: 0\n" 237 "Name: 1\n" 238 "DebugLoc: { File: 3, Line: 3, Column: 4 }\n" 239 "Function: 2\n" 240 "Hotness: 5\n" 241 "Args:\n" 242 " - key: 4\n" 243 " - keydebug: 5\n" 244 " DebugLoc: { File: 6, Line: 6, Column: 7 }\n" 245 "...\n", 246 315), 247 std::move(PreFilledStrTab)); 248 } 249