Recommit "rL366894: [yaml2obj] - Allow custom fields for the SHT_UNDEF sections."
[llvm-complete.git] / unittests / Remarks / YAMLRemarksParsingTest.cpp
blob967ac965069cb41b1a1925f95b4576685988fcb0
1 //===- unittest/Support/YAMLRemarksParsingTest.cpp - OptTable tests -------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm-c/Remarks.h"
10 #include "llvm/Remarks/Remark.h"
11 #include "llvm/Remarks/RemarkParser.h"
12 #include "gtest/gtest.h"
14 using namespace llvm;
16 template <size_t N> void parseGood(const char (&Buf)[N]) {
17 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
18 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
19 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
20 EXPECT_TRUE(*MaybeParser != nullptr);
22 remarks::RemarkParser &Parser = **MaybeParser;
23 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
24 EXPECT_FALSE(errorToBool(Remark.takeError())); // Check for parsing errors.
25 EXPECT_TRUE(*Remark != nullptr); // At least one remark.
26 Remark = Parser.next();
27 Error E = Remark.takeError();
28 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
29 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
32 template <size_t N>
33 bool parseExpectError(const char (&Buf)[N], const char *Error) {
34 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
35 remarks::createRemarkParser(remarks::Format::YAML, {Buf, N - 1});
36 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
37 EXPECT_TRUE(*MaybeParser != nullptr);
39 remarks::RemarkParser &Parser = **MaybeParser;
40 Expected<std::unique_ptr<remarks::Remark>> Remark = Parser.next();
41 EXPECT_FALSE(Remark); // Check for parsing errors.
43 std::string ErrorStr;
44 raw_string_ostream Stream(ErrorStr);
45 handleAllErrors(Remark.takeError(),
46 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
47 return StringRef(Stream.str()).contains(Error);
50 TEST(YAMLRemarks, ParsingEmpty) {
51 EXPECT_TRUE(parseExpectError("\n\n", "document root is not of mapping type."));
54 TEST(YAMLRemarks, ParsingNotYAML) {
55 EXPECT_TRUE(
56 parseExpectError("\x01\x02\x03\x04\x05\x06", "Got empty plain scalar"));
59 TEST(YAMLRemarks, ParsingGood) {
60 parseGood("\n"
61 "--- !Missed\n"
62 "Pass: inline\n"
63 "Name: NoDefinition\n"
64 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
65 "Function: foo\n"
66 "Args:\n"
67 " - Callee: bar\n"
68 " - String: ' will not be inlined into '\n"
69 " - Caller: foo\n"
70 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
71 " - String: ' because its definition is unavailable'\n"
72 "");
74 // No debug loc should also pass.
75 parseGood("\n"
76 "--- !Missed\n"
77 "Pass: inline\n"
78 "Name: NoDefinition\n"
79 "Function: foo\n"
80 "Args:\n"
81 " - Callee: bar\n"
82 " - String: ' will not be inlined into '\n"
83 " - Caller: foo\n"
84 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
85 " - String: ' because its definition is unavailable'\n"
86 "");
88 // No args is also ok.
89 parseGood("\n"
90 "--- !Missed\n"
91 "Pass: inline\n"
92 "Name: NoDefinition\n"
93 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
94 "Function: foo\n"
95 "");
97 // Different order.
98 parseGood("\n"
99 "--- !Missed\n"
100 "DebugLoc: { Line: 3, Column: 12, File: file.c }\n"
101 "Function: foo\n"
102 "Name: NoDefinition\n"
103 "Args:\n"
104 " - Callee: bar\n"
105 " - String: ' will not be inlined into '\n"
106 " - Caller: foo\n"
107 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
108 " - String: ' because its definition is unavailable'\n"
109 "Pass: inline\n"
110 "");
113 // Mandatory common part of a remark.
114 #define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n\n"
115 // Test all the types.
116 TEST(YAMLRemarks, ParsingTypes) {
117 // Type: Passed
118 parseGood("--- !Passed" COMMON_REMARK);
119 // Type: Missed
120 parseGood("--- !Missed" COMMON_REMARK);
121 // Type: Analysis
122 parseGood("--- !Analysis" COMMON_REMARK);
123 // Type: AnalysisFPCommute
124 parseGood("--- !AnalysisFPCommute" COMMON_REMARK);
125 // Type: AnalysisAliasing
126 parseGood("--- !AnalysisAliasing" COMMON_REMARK);
127 // Type: Failure
128 parseGood("--- !Failure" COMMON_REMARK);
130 #undef COMMON_REMARK
132 TEST(YAMLRemarks, ParsingMissingFields) {
133 // No type.
134 EXPECT_TRUE(parseExpectError("\n"
135 "---\n"
136 "Pass: inline\n"
137 "Name: NoDefinition\n"
138 "Function: foo\n"
140 "expected a remark tag."));
141 // No pass.
142 EXPECT_TRUE(parseExpectError("\n"
143 "--- !Missed\n"
144 "Name: NoDefinition\n"
145 "Function: foo\n"
147 "Type, Pass, Name or Function missing."));
148 // No name.
149 EXPECT_TRUE(parseExpectError("\n"
150 "--- !Missed\n"
151 "Pass: inline\n"
152 "Function: foo\n"
154 "Type, Pass, Name or Function missing."));
155 // No function.
156 EXPECT_TRUE(parseExpectError("\n"
157 "--- !Missed\n"
158 "Pass: inline\n"
159 "Name: NoDefinition\n"
161 "Type, Pass, Name or Function missing."));
162 // Debug loc but no file.
163 EXPECT_TRUE(parseExpectError("\n"
164 "--- !Missed\n"
165 "Pass: inline\n"
166 "Name: NoDefinition\n"
167 "Function: foo\n"
168 "DebugLoc: { Line: 3, Column: 12 }\n"
170 "DebugLoc node incomplete."));
171 // Debug loc but no line.
172 EXPECT_TRUE(parseExpectError("\n"
173 "--- !Missed\n"
174 "Pass: inline\n"
175 "Name: NoDefinition\n"
176 "Function: foo\n"
177 "DebugLoc: { File: file.c, Column: 12 }\n"
179 "DebugLoc node incomplete."));
180 // Debug loc but no column.
181 EXPECT_TRUE(parseExpectError("\n"
182 "--- !Missed\n"
183 "Pass: inline\n"
184 "Name: NoDefinition\n"
185 "Function: foo\n"
186 "DebugLoc: { File: file.c, Line: 3 }\n"
188 "DebugLoc node incomplete."));
191 TEST(YAMLRemarks, ParsingWrongTypes) {
192 // Wrong debug loc type.
193 EXPECT_TRUE(parseExpectError("\n"
194 "--- !Missed\n"
195 "Pass: inline\n"
196 "Name: NoDefinition\n"
197 "Function: foo\n"
198 "DebugLoc: foo\n"
200 "expected a value of mapping type."));
201 // Wrong line type.
202 EXPECT_TRUE(parseExpectError("\n"
203 "--- !Missed\n"
204 "Pass: inline\n"
205 "Name: NoDefinition\n"
206 "Function: foo\n"
207 "DebugLoc: { File: file.c, Line: b, Column: 12 }\n"
209 "expected a value of integer type."));
210 // Wrong column type.
211 EXPECT_TRUE(parseExpectError("\n"
212 "--- !Missed\n"
213 "Pass: inline\n"
214 "Name: NoDefinition\n"
215 "Function: foo\n"
216 "DebugLoc: { File: file.c, Line: 3, Column: c }\n"
218 "expected a value of integer type."));
219 // Wrong args type.
220 EXPECT_TRUE(parseExpectError("\n"
221 "--- !Missed\n"
222 "Pass: inline\n"
223 "Name: NoDefinition\n"
224 "Function: foo\n"
225 "Args: foo\n"
227 "wrong value type for key."));
228 // Wrong key type.
229 EXPECT_TRUE(parseExpectError("\n"
230 "--- !Missed\n"
231 "{ A: a }: inline\n"
232 "Name: NoDefinition\n"
233 "Function: foo\n"
235 "key is not a string."));
236 // Debug loc with unknown entry.
237 EXPECT_TRUE(parseExpectError("\n"
238 "--- !Missed\n"
239 "Pass: inline\n"
240 "Name: NoDefinition\n"
241 "Function: foo\n"
242 "DebugLoc: { File: file.c, Column: 12, Unknown: 12 }\n"
244 "unknown entry in DebugLoc map."));
245 // Unknown entry.
246 EXPECT_TRUE(parseExpectError("\n"
247 "--- !Missed\n"
248 "Unknown: inline\n"
250 "unknown key."));
251 // Not a scalar.
252 EXPECT_TRUE(parseExpectError("\n"
253 "--- !Missed\n"
254 "Pass: { File: a, Line: 1, Column: 2 }\n"
255 "Name: NoDefinition\n"
256 "Function: foo\n"
258 "expected a value of scalar type."));
259 // Not a string file in debug loc.
260 EXPECT_TRUE(parseExpectError("\n"
261 "--- !Missed\n"
262 "Pass: inline\n"
263 "Name: NoDefinition\n"
264 "Function: foo\n"
265 "DebugLoc: { File: { a: b }, Column: 12, Line: 12 }\n"
267 "expected a value of scalar type."));
268 // Not a integer column in debug loc.
269 EXPECT_TRUE(parseExpectError("\n"
270 "--- !Missed\n"
271 "Pass: inline\n"
272 "Name: NoDefinition\n"
273 "Function: foo\n"
274 "DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }\n"
276 "expected a value of scalar type."));
277 // Not a integer line in debug loc.
278 EXPECT_TRUE(parseExpectError("\n"
279 "--- !Missed\n"
280 "Pass: inline\n"
281 "Name: NoDefinition\n"
282 "Function: foo\n"
283 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
285 "expected a value of scalar type."));
286 // Not a mapping type value for args.
287 EXPECT_TRUE(parseExpectError("\n"
288 "--- !Missed\n"
289 "Pass: inline\n"
290 "Name: NoDefinition\n"
291 "Function: foo\n"
292 "DebugLoc: { File: file.c, Column: 12, Line: { a: b } }\n"
294 "expected a value of scalar type."));
297 TEST(YAMLRemarks, ParsingWrongArgs) {
298 // Multiple debug locs per arg.
299 EXPECT_TRUE(parseExpectError("\n"
300 "--- !Missed\n"
301 "Pass: inline\n"
302 "Name: NoDefinition\n"
303 "Function: foo\n"
304 "Args:\n"
305 " - Str: string\n"
306 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
307 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
309 "only one DebugLoc entry is allowed per argument."));
310 // Multiple strings per arg.
311 EXPECT_TRUE(parseExpectError("\n"
312 "--- !Missed\n"
313 "Pass: inline\n"
314 "Name: NoDefinition\n"
315 "Function: foo\n"
316 "Args:\n"
317 " - Str: string\n"
318 " Str2: string\n"
319 " DebugLoc: { File: a, Line: 1, Column: 2 }\n"
321 "only one string entry is allowed per argument."));
322 // No arg value.
323 EXPECT_TRUE(parseExpectError("\n"
324 "--- !Missed\n"
325 "Pass: inline\n"
326 "Name: NoDefinition\n"
327 "Function: foo\n"
328 "Args:\n"
329 " - DebugLoc: { File: a, Line: 1, Column: 2 }\n"
331 "argument key is missing."));
334 static inline StringRef checkStr(StringRef Str, unsigned ExpectedLen) {
335 const char *StrData = Str.data();
336 unsigned StrLen = Str.size();
337 EXPECT_EQ(StrLen, ExpectedLen);
338 return StringRef(StrData, StrLen);
341 TEST(YAMLRemarks, Contents) {
342 StringRef Buf = "\n"
343 "--- !Missed\n"
344 "Pass: inline\n"
345 "Name: NoDefinition\n"
346 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
347 "Function: foo\n"
348 "Hotness: 4\n"
349 "Args:\n"
350 " - Callee: bar\n"
351 " - String: ' will not be inlined into '\n"
352 " - Caller: foo\n"
353 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
354 " - String: ' because its definition is unavailable'\n"
355 "\n";
357 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
358 remarks::createRemarkParser(remarks::Format::YAML, Buf);
359 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
360 EXPECT_TRUE(*MaybeParser != nullptr);
362 remarks::RemarkParser &Parser = **MaybeParser;
363 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
364 EXPECT_FALSE(
365 errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
366 EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
368 const remarks::Remark &Remark = **MaybeRemark;
369 EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
370 EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
371 EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
372 EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
373 EXPECT_TRUE(Remark.Loc);
374 const remarks::RemarkLocation &RL = *Remark.Loc;
375 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
376 EXPECT_EQ(RL.SourceLine, 3U);
377 EXPECT_EQ(RL.SourceColumn, 12U);
378 EXPECT_TRUE(Remark.Hotness);
379 EXPECT_EQ(*Remark.Hotness, 4U);
380 EXPECT_EQ(Remark.Args.size(), 4U);
382 unsigned ArgID = 0;
383 for (const remarks::Argument &Arg : Remark.Args) {
384 switch (ArgID) {
385 case 0:
386 EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
387 EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
388 EXPECT_FALSE(Arg.Loc);
389 break;
390 case 1:
391 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
392 EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
393 EXPECT_FALSE(Arg.Loc);
394 break;
395 case 2: {
396 EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
397 EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
398 EXPECT_TRUE(Arg.Loc);
399 const remarks::RemarkLocation &RL = *Arg.Loc;
400 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
401 EXPECT_EQ(RL.SourceLine, 2U);
402 EXPECT_EQ(RL.SourceColumn, 0U);
403 break;
405 case 3:
406 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
407 EXPECT_EQ(checkStr(Arg.Val, 38),
408 " because its definition is unavailable");
409 EXPECT_FALSE(Arg.Loc);
410 break;
411 default:
412 break;
414 ++ArgID;
417 MaybeRemark = Parser.next();
418 Error E = MaybeRemark.takeError();
419 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
420 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
423 static inline StringRef checkStr(LLVMRemarkStringRef Str,
424 unsigned ExpectedLen) {
425 const char *StrData = LLVMRemarkStringGetData(Str);
426 unsigned StrLen = LLVMRemarkStringGetLen(Str);
427 EXPECT_EQ(StrLen, ExpectedLen);
428 return StringRef(StrData, StrLen);
431 TEST(YAMLRemarks, ContentsCAPI) {
432 StringRef Buf = "\n"
433 "--- !Missed\n"
434 "Pass: inline\n"
435 "Name: NoDefinition\n"
436 "DebugLoc: { File: file.c, Line: 3, Column: 12 }\n"
437 "Function: foo\n"
438 "Args:\n"
439 " - Callee: bar\n"
440 " - String: ' will not be inlined into '\n"
441 " - Caller: foo\n"
442 " DebugLoc: { File: file.c, Line: 2, Column: 0 }\n"
443 " - String: ' because its definition is unavailable'\n"
444 "\n";
446 LLVMRemarkParserRef Parser =
447 LLVMRemarkParserCreateYAML(Buf.data(), Buf.size());
448 LLVMRemarkEntryRef Remark = LLVMRemarkParserGetNext(Parser);
449 EXPECT_FALSE(Remark == nullptr);
450 EXPECT_EQ(LLVMRemarkEntryGetType(Remark), LLVMRemarkTypeMissed);
451 EXPECT_EQ(checkStr(LLVMRemarkEntryGetPassName(Remark), 6), "inline");
452 EXPECT_EQ(checkStr(LLVMRemarkEntryGetRemarkName(Remark), 12), "NoDefinition");
453 EXPECT_EQ(checkStr(LLVMRemarkEntryGetFunctionName(Remark), 3), "foo");
454 LLVMRemarkDebugLocRef DL = LLVMRemarkEntryGetDebugLoc(Remark);
455 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
456 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 3U);
457 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 12U);
458 EXPECT_EQ(LLVMRemarkEntryGetHotness(Remark), 0U);
459 EXPECT_EQ(LLVMRemarkEntryGetNumArgs(Remark), 4U);
461 unsigned ArgID = 0;
462 LLVMRemarkArgRef Arg = LLVMRemarkEntryGetFirstArg(Remark);
463 do {
464 switch (ArgID) {
465 case 0:
466 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Callee");
467 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "bar");
468 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
469 break;
470 case 1:
471 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
472 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 26),
473 " will not be inlined into ");
474 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
475 break;
476 case 2: {
477 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "Caller");
478 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 3), "foo");
479 LLVMRemarkDebugLocRef DL = LLVMRemarkArgGetDebugLoc(Arg);
480 EXPECT_EQ(checkStr(LLVMRemarkDebugLocGetSourceFilePath(DL), 6), "file.c");
481 EXPECT_EQ(LLVMRemarkDebugLocGetSourceLine(DL), 2U);
482 EXPECT_EQ(LLVMRemarkDebugLocGetSourceColumn(DL), 0U);
483 break;
485 case 3:
486 EXPECT_EQ(checkStr(LLVMRemarkArgGetKey(Arg), 6), "String");
487 EXPECT_EQ(checkStr(LLVMRemarkArgGetValue(Arg), 38),
488 " because its definition is unavailable");
489 EXPECT_EQ(LLVMRemarkArgGetDebugLoc(Arg), nullptr);
490 break;
491 default:
492 break;
494 ++ArgID;
495 } while ((Arg = LLVMRemarkEntryGetNextArg(Arg, Remark)));
497 LLVMRemarkEntryDispose(Remark);
499 EXPECT_EQ(LLVMRemarkParserGetNext(Parser), nullptr);
501 EXPECT_FALSE(LLVMRemarkParserHasError(Parser));
502 LLVMRemarkParserDispose(Parser);
505 TEST(YAMLRemarks, ContentsStrTab) {
506 StringRef Buf = "\n"
507 "--- !Missed\n"
508 "Pass: 0\n"
509 "Name: 1\n"
510 "DebugLoc: { File: 2, Line: 3, Column: 12 }\n"
511 "Function: 3\n"
512 "Hotness: 4\n"
513 "Args:\n"
514 " - Callee: 5\n"
515 " - String: 7\n"
516 " - Caller: 3\n"
517 " DebugLoc: { File: 2, Line: 2, Column: 0 }\n"
518 " - String: 8\n"
519 "\n";
521 StringRef StrTabBuf =
522 StringRef("inline\0NoDefinition\0file.c\0foo\0Callee\0bar\0String\0 "
523 "will not be inlined into \0 because its definition is "
524 "unavailable",
525 115);
527 remarks::ParsedStringTable StrTab(StrTabBuf);
528 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
529 remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf,
530 std::move(StrTab));
531 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
532 EXPECT_TRUE(*MaybeParser != nullptr);
534 remarks::RemarkParser &Parser = **MaybeParser;
535 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
536 EXPECT_FALSE(
537 errorToBool(MaybeRemark.takeError())); // Check for parsing errors.
538 EXPECT_TRUE(*MaybeRemark != nullptr); // At least one remark.
540 const remarks::Remark &Remark = **MaybeRemark;
541 EXPECT_EQ(Remark.RemarkType, remarks::Type::Missed);
542 EXPECT_EQ(checkStr(Remark.PassName, 6), "inline");
543 EXPECT_EQ(checkStr(Remark.RemarkName, 12), "NoDefinition");
544 EXPECT_EQ(checkStr(Remark.FunctionName, 3), "foo");
545 EXPECT_TRUE(Remark.Loc);
546 const remarks::RemarkLocation &RL = *Remark.Loc;
547 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
548 EXPECT_EQ(RL.SourceLine, 3U);
549 EXPECT_EQ(RL.SourceColumn, 12U);
550 EXPECT_TRUE(Remark.Hotness);
551 EXPECT_EQ(*Remark.Hotness, 4U);
552 EXPECT_EQ(Remark.Args.size(), 4U);
554 unsigned ArgID = 0;
555 for (const remarks::Argument &Arg : Remark.Args) {
556 switch (ArgID) {
557 case 0:
558 EXPECT_EQ(checkStr(Arg.Key, 6), "Callee");
559 EXPECT_EQ(checkStr(Arg.Val, 3), "bar");
560 EXPECT_FALSE(Arg.Loc);
561 break;
562 case 1:
563 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
564 EXPECT_EQ(checkStr(Arg.Val, 26), " will not be inlined into ");
565 EXPECT_FALSE(Arg.Loc);
566 break;
567 case 2: {
568 EXPECT_EQ(checkStr(Arg.Key, 6), "Caller");
569 EXPECT_EQ(checkStr(Arg.Val, 3), "foo");
570 EXPECT_TRUE(Arg.Loc);
571 const remarks::RemarkLocation &RL = *Arg.Loc;
572 EXPECT_EQ(checkStr(RL.SourceFilePath, 6), "file.c");
573 EXPECT_EQ(RL.SourceLine, 2U);
574 EXPECT_EQ(RL.SourceColumn, 0U);
575 break;
577 case 3:
578 EXPECT_EQ(checkStr(Arg.Key, 6), "String");
579 EXPECT_EQ(checkStr(Arg.Val, 38),
580 " because its definition is unavailable");
581 EXPECT_FALSE(Arg.Loc);
582 break;
583 default:
584 break;
586 ++ArgID;
589 MaybeRemark = Parser.next();
590 Error E = MaybeRemark.takeError();
591 EXPECT_TRUE(E.isA<remarks::EndOfFileError>());
592 EXPECT_TRUE(errorToBool(std::move(E))); // Check for parsing errors.
595 TEST(YAMLRemarks, ParsingBadStringTableIndex) {
596 StringRef Buf = "\n"
597 "--- !Missed\n"
598 "Pass: 50\n"
599 "\n";
601 StringRef StrTabBuf = StringRef("inline");
603 remarks::ParsedStringTable StrTab(StrTabBuf);
604 Expected<std::unique_ptr<remarks::RemarkParser>> MaybeParser =
605 remarks::createRemarkParser(remarks::Format::YAMLStrTab, Buf,
606 std::move(StrTab));
607 EXPECT_FALSE(errorToBool(MaybeParser.takeError()));
608 EXPECT_TRUE(*MaybeParser != nullptr);
610 remarks::RemarkParser &Parser = **MaybeParser;
611 Expected<std::unique_ptr<remarks::Remark>> MaybeRemark = Parser.next();
612 EXPECT_FALSE(MaybeRemark); // Expect an error here.
614 std::string ErrorStr;
615 raw_string_ostream Stream(ErrorStr);
616 handleAllErrors(MaybeRemark.takeError(),
617 [&](const ErrorInfoBase &EIB) { EIB.log(Stream); });
618 EXPECT_TRUE(
619 StringRef(Stream.str())
620 .contains("String with index 50 is out of bounds (size = 1)."));