xref: /llvm-project/llvm/unittests/Remarks/YAMLRemarksSerializerTest.cpp (revision 38818b60c58c76ba89b990978cdfd2d7b6799260)
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/RemarkParser.h"
11 #include "llvm/Remarks/YAMLRemarkSerializer.h"
12 #include "llvm/Support/Error.h"
13 #include "gtest/gtest.h"
14 
15 // We need to supprt Windows paths as well. In order to have paths with the same
16 // length, use a different path according to the platform.
17 #ifdef _WIN32
18 #define EXTERNALFILETESTPATH "C:/externalfi"
19 #else
20 #define EXTERNALFILETESTPATH "/externalfile"
21 #endif
22 
23 using namespace llvm;
24 
check(remarks::Format SerializerFormat,remarks::SerializerMode Mode,ArrayRef<remarks::Remark> Rs,StringRef ExpectedR,std::optional<StringRef> ExpectedMeta,std::optional<remarks::StringTable> StrTab=std::nullopt)25 static void check(remarks::Format SerializerFormat,
26                   remarks::SerializerMode Mode, ArrayRef<remarks::Remark> Rs,
27                   StringRef ExpectedR, std::optional<StringRef> ExpectedMeta,
28                   std::optional<remarks::StringTable> StrTab = std::nullopt) {
29   std::string Buf;
30   raw_string_ostream OS(Buf);
31   Expected<std::unique_ptr<remarks::RemarkSerializer>> MaybeS = [&] {
32     if (StrTab)
33       return createRemarkSerializer(SerializerFormat, Mode, OS,
34                                     std::move(*StrTab));
35     else
36       return createRemarkSerializer(SerializerFormat, Mode, OS);
37   }();
38   EXPECT_FALSE(errorToBool(MaybeS.takeError()));
39   std::unique_ptr<remarks::RemarkSerializer> S = std::move(*MaybeS);
40 
41   for (const remarks::Remark &R : Rs)
42     S->emit(R);
43   EXPECT_EQ(OS.str(), ExpectedR);
44 
45   if (ExpectedMeta) {
46     Buf.clear();
47     std::unique_ptr<remarks::MetaSerializer> MS =
48         S->metaSerializer(OS, StringRef(EXTERNALFILETESTPATH));
49     MS->emit();
50     EXPECT_EQ(OS.str(), *ExpectedMeta);
51   }
52 }
53 
check(remarks::Format SerializerFormat,const remarks::Remark & R,StringRef ExpectedR,StringRef ExpectedMeta,std::optional<remarks::StringTable> StrTab=std::nullopt)54 static void check(remarks::Format SerializerFormat, const remarks::Remark &R,
55                   StringRef ExpectedR, StringRef ExpectedMeta,
56                   std::optional<remarks::StringTable> StrTab = std::nullopt) {
57   return check(SerializerFormat, remarks::SerializerMode::Separate,
58                ArrayRef(&R, &R + 1), ExpectedR, ExpectedMeta,
59                std::move(StrTab));
60 }
61 
62 static void
checkStandalone(remarks::Format SerializerFormat,const remarks::Remark & R,StringRef ExpectedR,std::optional<remarks::StringTable> StrTab=std::nullopt)63 checkStandalone(remarks::Format SerializerFormat, const remarks::Remark &R,
64                 StringRef ExpectedR,
65                 std::optional<remarks::StringTable> StrTab = std::nullopt) {
66   return check(SerializerFormat, remarks::SerializerMode::Standalone,
67                ArrayRef(&R, &R + 1), ExpectedR,
68                /*ExpectedMeta=*/std::nullopt, std::move(StrTab));
69 }
70 
TEST(YAMLRemarks,SerializerRemark)71 TEST(YAMLRemarks, SerializerRemark) {
72   remarks::Remark R;
73   R.RemarkType = remarks::Type::Missed;
74   R.PassName = "pass";
75   R.RemarkName = "name";
76   R.FunctionName = "func";
77   R.Loc = remarks::RemarkLocation{"path", 3, 4};
78   R.Hotness = 5;
79   R.Args.emplace_back();
80   R.Args.back().Key = "key";
81   R.Args.back().Val = "value";
82   R.Args.emplace_back();
83   R.Args.back().Key = "keydebug";
84   R.Args.back().Val = "valuedebug";
85   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
86   check(remarks::Format::YAML, R,
87         "--- !Missed\n"
88         "Pass:            pass\n"
89         "Name:            name\n"
90         "DebugLoc:        { File: path, Line: 3, Column: 4 }\n"
91         "Function:        func\n"
92         "Hotness:         5\n"
93         "Args:\n"
94         "  - key:             value\n"
95         "  - keydebug:        valuedebug\n"
96         "    DebugLoc:        { File: argpath, Line: 6, Column: 7 }\n"
97         "...\n",
98         StringRef("REMARKS\0"
99                   "\0\0\0\0\0\0\0\0"
100                   "\0\0\0\0\0\0\0\0" EXTERNALFILETESTPATH "\0",
101                   38));
102 }
103 
TEST(YAMLRemarks,SerializerRemarkStandalone)104 TEST(YAMLRemarks, SerializerRemarkStandalone) {
105   remarks::Remark R;
106   R.RemarkType = remarks::Type::Missed;
107   R.PassName = "pass";
108   R.RemarkName = "name";
109   R.FunctionName = "func";
110   R.Loc = remarks::RemarkLocation{"path", 3, 4};
111   R.Hotness = 5;
112   R.Args.emplace_back();
113   R.Args.back().Key = "key";
114   R.Args.back().Val = "value";
115   R.Args.emplace_back();
116   R.Args.back().Key = "keydebug";
117   R.Args.back().Val = "valuedebug";
118   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
119   checkStandalone(
120       remarks::Format::YAML, R,
121       StringRef("--- !Missed\n"
122                 "Pass:            pass\n"
123                 "Name:            name\n"
124                 "DebugLoc:        { File: path, Line: 3, Column: 4 }\n"
125                 "Function:        func\n"
126                 "Hotness:         5\n"
127                 "Args:\n"
128                 "  - key:             value\n"
129                 "  - keydebug:        valuedebug\n"
130                 "    DebugLoc:        { File: argpath, Line: 6, Column: 7 }\n"
131                 "...\n"));
132 }
133 
TEST(YAMLRemarks,SerializerRemarkStrTab)134 TEST(YAMLRemarks, SerializerRemarkStrTab) {
135   remarks::Remark R;
136   R.RemarkType = remarks::Type::Missed;
137   R.PassName = "pass";
138   R.RemarkName = "name";
139   R.FunctionName = "func";
140   R.Loc = remarks::RemarkLocation{"path", 3, 4};
141   R.Hotness = 5;
142   R.Args.emplace_back();
143   R.Args.back().Key = "key";
144   R.Args.back().Val = "value";
145   R.Args.emplace_back();
146   R.Args.back().Key = "keydebug";
147   R.Args.back().Val = "valuedebug";
148   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
149   check(remarks::Format::YAMLStrTab, R,
150         "--- !Missed\n"
151         "Pass:            0\n"
152         "Name:            1\n"
153         "DebugLoc:        { File: 3, Line: 3, Column: 4 }\n"
154         "Function:        2\n"
155         "Hotness:         5\n"
156         "Args:\n"
157         "  - key:             4\n"
158         "  - keydebug:        5\n"
159         "    DebugLoc:        { File: 6, Line: 6, Column: 7 }\n"
160         "...\n",
161         StringRef("REMARKS\0"
162                   "\0\0\0\0\0\0\0\0"
163                   "\x2d\0\0\0\0\0\0\0"
164                   "pass\0name\0func\0path\0value\0valuedebug\0argpath"
165                   "\0" EXTERNALFILETESTPATH "\0",
166                   83));
167 }
168 
TEST(YAMLRemarks,SerializerRemarkParsedStrTab)169 TEST(YAMLRemarks, SerializerRemarkParsedStrTab) {
170   StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
171   remarks::Remark R;
172   R.RemarkType = remarks::Type::Missed;
173   R.PassName = "pass";
174   R.RemarkName = "name";
175   R.FunctionName = "func";
176   R.Loc = remarks::RemarkLocation{"path", 3, 4};
177   R.Hotness = 5;
178   R.Args.emplace_back();
179   R.Args.back().Key = "key";
180   R.Args.back().Val = "value";
181   R.Args.emplace_back();
182   R.Args.back().Key = "keydebug";
183   R.Args.back().Val = "valuedebug";
184   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
185   check(remarks::Format::YAMLStrTab, R,
186         "--- !Missed\n"
187         "Pass:            0\n"
188         "Name:            1\n"
189         "DebugLoc:        { File: 3, Line: 3, Column: 4 }\n"
190         "Function:        2\n"
191         "Hotness:         5\n"
192         "Args:\n"
193         "  - key:             4\n"
194         "  - keydebug:        5\n"
195         "    DebugLoc:        { File: 6, Line: 6, Column: 7 }\n"
196         "...\n",
197         StringRef("REMARKS\0"
198                   "\0\0\0\0\0\0\0\0"
199                   "\x2d\0\0\0\0\0\0\0"
200                   "pass\0name\0func\0path\0value\0valuedebug\0argpath"
201                   "\0" EXTERNALFILETESTPATH "\0",
202                   83),
203         remarks::StringTable(remarks::ParsedStringTable(StrTab)));
204 }
205 
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandaloneNoStrTab)206 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneNoStrTab) {
207   // Check that we don't use the string table even if it was provided.
208   StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
209   remarks::ParsedStringTable ParsedStrTab(StrTab);
210   remarks::StringTable PreFilledStrTab(ParsedStrTab);
211   remarks::Remark R;
212   R.RemarkType = remarks::Type::Missed;
213   R.PassName = "pass";
214   R.RemarkName = "name";
215   R.FunctionName = "func";
216   R.Loc = remarks::RemarkLocation{"path", 3, 4};
217   R.Hotness = 5;
218   R.Args.emplace_back();
219   R.Args.back().Key = "key";
220   R.Args.back().Val = "value";
221   R.Args.emplace_back();
222   R.Args.back().Key = "keydebug";
223   R.Args.back().Val = "valuedebug";
224   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
225   checkStandalone(
226       remarks::Format::YAML, R,
227       StringRef("--- !Missed\n"
228                 "Pass:            pass\n"
229                 "Name:            name\n"
230                 "DebugLoc:        { File: path, Line: 3, Column: 4 }\n"
231                 "Function:        func\n"
232                 "Hotness:         5\n"
233                 "Args:\n"
234                 "  - key:             value\n"
235                 "  - keydebug:        valuedebug\n"
236                 "    DebugLoc:        { File: argpath, Line: 6, Column: 7 }\n"
237                 "...\n"),
238       std::move(PreFilledStrTab));
239 }
240 
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandalone)241 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandalone) {
242   StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
243   remarks::ParsedStringTable ParsedStrTab(StrTab);
244   remarks::StringTable PreFilledStrTab(ParsedStrTab);
245   remarks::Remark R;
246   R.RemarkType = remarks::Type::Missed;
247   R.PassName = "pass";
248   R.RemarkName = "name";
249   R.FunctionName = "func";
250   R.Loc = remarks::RemarkLocation{"path", 3, 4};
251   R.Hotness = 5;
252   R.Args.emplace_back();
253   R.Args.back().Key = "key";
254   R.Args.back().Val = "value";
255   R.Args.emplace_back();
256   R.Args.back().Key = "keydebug";
257   R.Args.back().Val = "valuedebug";
258   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
259   checkStandalone(
260       remarks::Format::YAMLStrTab, R,
261       StringRef("REMARKS\0"
262                 "\0\0\0\0\0\0\0\0"
263                 "\x2d\0\0\0\0\0\0\0"
264                 "pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
265                 "--- !Missed\n"
266                 "Pass:            0\n"
267                 "Name:            1\n"
268                 "DebugLoc:        { File: 3, Line: 3, Column: 4 }\n"
269                 "Function:        2\n"
270                 "Hotness:         5\n"
271                 "Args:\n"
272                 "  - key:             4\n"
273                 "  - keydebug:        5\n"
274                 "    DebugLoc:        { File: 6, Line: 6, Column: 7 }\n"
275                 "...\n",
276                 315),
277       std::move(PreFilledStrTab));
278 }
279 
TEST(YAMLRemarks,SerializerRemarkParsedStrTabStandaloneMultipleRemarks)280 TEST(YAMLRemarks, SerializerRemarkParsedStrTabStandaloneMultipleRemarks) {
281   StringRef StrTab("pass\0name\0func\0path\0value\0valuedebug\0argpath\0", 45);
282   remarks::ParsedStringTable ParsedStrTab(StrTab);
283   remarks::StringTable PreFilledStrTab(ParsedStrTab);
284   SmallVector<remarks::Remark, 2> Rs;
285   remarks::Remark R;
286   R.RemarkType = remarks::Type::Missed;
287   R.PassName = "pass";
288   R.RemarkName = "name";
289   R.FunctionName = "func";
290   R.Loc = remarks::RemarkLocation{"path", 3, 4};
291   R.Hotness = 5;
292   R.Args.emplace_back();
293   R.Args.back().Key = "key";
294   R.Args.back().Val = "value";
295   R.Args.emplace_back();
296   R.Args.back().Key = "keydebug";
297   R.Args.back().Val = "valuedebug";
298   R.Args.back().Loc = remarks::RemarkLocation{"argpath", 6, 7};
299   Rs.emplace_back(R.clone());
300   Rs.emplace_back(std::move(R));
301   check(remarks::Format::YAMLStrTab, remarks::SerializerMode::Standalone, Rs,
302         StringRef("REMARKS\0"
303                   "\0\0\0\0\0\0\0\0"
304                   "\x2d\0\0\0\0\0\0\0"
305                   "pass\0name\0func\0path\0value\0valuedebug\0argpath\0"
306                   "--- !Missed\n"
307                   "Pass:            0\n"
308                   "Name:            1\n"
309                   "DebugLoc:        { File: 3, Line: 3, Column: 4 }\n"
310                   "Function:        2\n"
311                   "Hotness:         5\n"
312                   "Args:\n"
313                   "  - key:             4\n"
314                   "  - keydebug:        5\n"
315                   "    DebugLoc:        { File: 6, Line: 6, Column: 7 }\n"
316                   "...\n"
317                   "--- !Missed\n"
318                   "Pass:            0\n"
319                   "Name:            1\n"
320                   "DebugLoc:        { File: 3, Line: 3, Column: 4 }\n"
321                   "Function:        2\n"
322                   "Hotness:         5\n"
323                   "Args:\n"
324                   "  - key:             4\n"
325                   "  - keydebug:        5\n"
326                   "    DebugLoc:        { File: 6, Line: 6, Column: 7 }\n"
327                   "...\n",
328                   561),
329         /*ExpectedMeta=*/std::nullopt, std::move(PreFilledStrTab));
330 }
331