blob: a28820ffb7f39a3637f9afa5ed53768cc03d21ac [file] [log] [blame]
Francis Visoiu Mistrih057784a2018-10-10 17:58:09 +00001//===- unittest/Support/OptRemarksParsingTest.cpp - OptTable tests --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm-c/OptRemarks.h"
11#include "gtest/gtest.h"
12
13using namespace llvm;
14
15template <size_t N> bool tryParse(const char (&Buf)[N]) {
16 LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
17 LLVMOptRemarkEntry *Remark = nullptr;
18 while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
19 EXPECT_TRUE(Remark == nullptr); // Only one remark per test.
20 Remark = NewRemark;
21 }
22 EXPECT_TRUE(Remark != nullptr); // We need *exactly* one remark per test.
23 bool HasError = LLVMOptRemarkParserHasError(Parser);
24 LLVMOptRemarkParserDispose(Parser);
25 return !HasError;
26}
27
28template <size_t N>
29bool parseExpectError(const char (&Buf)[N], const char *Error) {
30 LLVMOptRemarkParserRef Parser = LLVMOptRemarkParserCreate(Buf, N - 1);
31 LLVMOptRemarkEntry *Remark = nullptr;
32 while (LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser)) {
33 EXPECT_FALSE(NewRemark);
34 }
35 EXPECT_TRUE(Remark == nullptr); // We are parsing only one malformed remark.
36 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
37 bool MatchesError =
38 StringRef(LLVMOptRemarkParserGetErrorMessage(Parser)).contains(Error);
39 LLVMOptRemarkParserDispose(Parser);
40
41 return MatchesError;
42}
43
44TEST(OptRemarks, OptRemarksParsingEmpty) {
45 StringRef Buf = R"YAML(
46)YAML";
47 LLVMOptRemarkParserRef Parser =
48 LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
49 LLVMOptRemarkEntry *NewRemark = LLVMOptRemarkParserGetNext(Parser);
50 EXPECT_TRUE(NewRemark == nullptr); // No remark expected.
51 EXPECT_TRUE(LLVMOptRemarkParserHasError(Parser));
52 EXPECT_TRUE(StringRef(LLVMOptRemarkParserGetErrorMessage(Parser))
53 .contains("document root is not of mapping type."));
54 LLVMOptRemarkParserDispose(Parser);
55}
56
57TEST(OptRemarks, OptRemarksParsingGood) {
58 EXPECT_TRUE(tryParse(R"YAML(
59--- !Missed
60Pass: inline
61Name: NoDefinition
62DebugLoc: { File: file.c, Line: 3, Column: 12 }
63Function: foo
64Args:
65 - Callee: bar
66 - String: ' will not be inlined into '
67 - Caller: foo
68 DebugLoc: { File: file.c, Line: 2, Column: 0 }
69 - String: ' because its definition is unavailable'
70)YAML"));
71
72 // No debug loc should also pass.
73 EXPECT_TRUE(tryParse(R"YAML(
74--- !Missed
75Pass: inline
76Name: NoDefinition
77Function: foo
78Args:
79 - Callee: bar
80 - String: ' will not be inlined into '
81 - Caller: foo
82 DebugLoc: { File: file.c, Line: 2, Column: 0 }
83 - String: ' because its definition is unavailable'
84)YAML"));
85
86 // No args is also ok.
87 EXPECT_TRUE(tryParse(R"YAML(
88--- !Missed
89Pass: inline
90Name: NoDefinition
91DebugLoc: { File: file.c, Line: 3, Column: 12 }
92Function: foo
93)YAML"));
94
95 // Different order.
96 EXPECT_TRUE(tryParse(R"YAML(
97--- !Missed
98DebugLoc: { Line: 3, Column: 12, File: file.c }
99Function: foo
100Name: NoDefinition
101Args:
102 - Callee: bar
103 - String: ' will not be inlined into '
104 - Caller: foo
105 DebugLoc: { File: file.c, Line: 2, Column: 0 }
106 - String: ' because its definition is unavailable'
107Pass: inline
108)YAML"));
109}
110
111// Mandatory common part of a remark.
112#define COMMON_REMARK "\nPass: inline\nName: NoDefinition\nFunction: foo\n"
113// Test all the types.
114TEST(OptRemarks, OptRemarksParsingTypes) {
115 // Type: Passed
116 EXPECT_TRUE(tryParse("--- !Passed" COMMON_REMARK));
117 // Type: Missed
118 EXPECT_TRUE(tryParse("--- !Missed" COMMON_REMARK));
119 // Type: Analysis
120 EXPECT_TRUE(tryParse("--- !Analysis" COMMON_REMARK));
121 // Type: AnalysisFPCompute
122 EXPECT_TRUE(tryParse("--- !AnalysisFPCompute" COMMON_REMARK));
123 // Type: AnalysisAliasing
124 EXPECT_TRUE(tryParse("--- !AnalysisAliasing" COMMON_REMARK));
125 // Type: Failure
126 EXPECT_TRUE(tryParse("--- !Failure" COMMON_REMARK));
127}
128#undef COMMON_REMARK
129
130TEST(OptRemarks, OptRemarksParsingMissingFields) {
131 // No type.
132 EXPECT_TRUE(parseExpectError(R"YAML(
133---
134Pass: inline
135Name: NoDefinition
136Function: foo
137)YAML",
138 "error: Type, Pass, Name or Function missing."));
139 // No pass.
140 EXPECT_TRUE(parseExpectError(R"YAML(
141--- !Missed
142Name: NoDefinition
143Function: foo
144)YAML",
145 "error: Type, Pass, Name or Function missing."));
146 // No name.
147 EXPECT_TRUE(parseExpectError(R"YAML(
148--- !Missed
149Pass: inline
150Function: foo
151)YAML",
152 "error: Type, Pass, Name or Function missing."));
153 // No function.
154 EXPECT_TRUE(parseExpectError(R"YAML(
155--- !Missed
156Pass: inline
157Name: NoDefinition
158)YAML",
159 "error: Type, Pass, Name or Function missing."));
160 // Debug loc but no file.
161 EXPECT_TRUE(parseExpectError(R"YAML(
162--- !Missed
163Pass: inline
164Name: NoDefinition
165Function: foo
166DebugLoc: { Line: 3, Column: 12 }
167)YAML",
168 "DebugLoc node incomplete."));
169 // Debug loc but no line.
170 EXPECT_TRUE(parseExpectError(R"YAML(
171--- !Missed
172Pass: inline
173Name: NoDefinition
174Function: foo
175DebugLoc: { File: file.c, Column: 12 }
176)YAML",
177 "DebugLoc node incomplete."));
178 // Debug loc but no column.
179 EXPECT_TRUE(parseExpectError(R"YAML(
180--- !Missed
181Pass: inline
182Name: NoDefinition
183Function: foo
184DebugLoc: { File: file.c, Line: 3 }
185)YAML",
186 "DebugLoc node incomplete."));
187}
188
189TEST(OptRemarks, OptRemarksParsingWrongTypes) {
190 // Wrong debug loc type.
191 EXPECT_TRUE(parseExpectError(R"YAML(
192--- !Missed
193Pass: inline
194Name: NoDefinition
195Function: foo
196DebugLoc: foo
197)YAML",
198 "expected a value of mapping type."));
199 // Wrong line type.
200 EXPECT_TRUE(parseExpectError(R"YAML(
201--- !Missed
202Pass: inline
203Name: NoDefinition
204Function: foo
205DebugLoc: { File: file.c, Line: b, Column: 12 }
206)YAML",
207 "expected a value of integer type."));
208 // Wrong column type.
209 EXPECT_TRUE(parseExpectError(R"YAML(
210--- !Missed
211Pass: inline
212Name: NoDefinition
213Function: foo
214DebugLoc: { File: file.c, Line: 3, Column: c }
215)YAML",
216 "expected a value of integer type."));
217 // Wrong args type.
218 EXPECT_TRUE(parseExpectError(R"YAML(
219--- !Missed
220Pass: inline
221Name: NoDefinition
222Function: foo
223Args: foo
224)YAML",
225 "wrong value type for key."));
226 // Wrong key type.
227 EXPECT_TRUE(parseExpectError(R"YAML(
228--- !Missed
229{ A: a }: inline
230Name: NoDefinition
231Function: foo
232)YAML",
233 "key is not a string."));
234 // Debug loc with unknown entry.
235 EXPECT_TRUE(parseExpectError(R"YAML(
236--- !Missed
237Pass: inline
238Name: NoDefinition
239Function: foo
240DebugLoc: { File: file.c, Column: 12, Unknown: 12 }
241)YAML",
242 "unknown entry in DebugLoc map."));
243 // Unknown entry.
244 EXPECT_TRUE(parseExpectError(R"YAML(
245--- !Missed
246Unknown: inline
247)YAML",
248 "unknown key."));
249 // Not a scalar.
250 EXPECT_TRUE(parseExpectError(R"YAML(
251--- !Missed
252Pass: { File: a, Line: 1, Column: 2 }
253Name: NoDefinition
254Function: foo
255)YAML",
256 "expected a value of scalar type."));
257 // Not a string file in debug loc.
258 EXPECT_TRUE(parseExpectError(R"YAML(
259--- !Missed
260Pass: inline
261Name: NoDefinition
262Function: foo
263DebugLoc: { File: { a: b }, Column: 12, Line: 12 }
264)YAML",
265 "expected a value of scalar type."));
266 // Not a integer column in debug loc.
267 EXPECT_TRUE(parseExpectError(R"YAML(
268--- !Missed
269Pass: inline
270Name: NoDefinition
271Function: foo
272DebugLoc: { File: file.c, Column: { a: b }, Line: 12 }
273)YAML",
274 "expected a value of scalar type."));
275 // Not a integer line in debug loc.
276 EXPECT_TRUE(parseExpectError(R"YAML(
277--- !Missed
278Pass: inline
279Name: NoDefinition
280Function: foo
281DebugLoc: { File: file.c, Column: 12, Line: { a: b } }
282)YAML",
283 "expected a value of scalar type."));
284 // Not a mapping type value for args.
285 EXPECT_TRUE(parseExpectError(R"YAML(
286--- !Missed
287Pass: inline
288Name: NoDefinition
289Function: foo
290DebugLoc: { File: file.c, Column: 12, Line: { a: b } }
291)YAML",
292 "expected a value of scalar type."));
293}
294
295TEST(OptRemarks, OptRemarksParsingWrongArgs) {
296 // Multiple debug locs per arg.
297 EXPECT_TRUE(
298 parseExpectError(R"YAML(
299--- !Missed
300Pass: inline
301Name: NoDefinition
302Function: foo
303Args:
304 - Str: string
305 DebugLoc: { File: a, Line: 1, Column: 2 }
306 DebugLoc: { File: a, Line: 1, Column: 2 }
307)YAML",
308 "only one DebugLoc entry is allowed per argument."));
309 // Multiple strings per arg.
310 EXPECT_TRUE(
311 parseExpectError(R"YAML(
312--- !Missed
313Pass: inline
314Name: NoDefinition
315Function: foo
316Args:
317 - Str: string
318 Str2: string
319 DebugLoc: { File: a, Line: 1, Column: 2 }
320)YAML",
321 "only one string entry is allowed per argument."));
322 // No arg value.
323 EXPECT_TRUE(parseExpectError(R"YAML(
324--- !Missed
325Pass: inline
326Name: NoDefinition
327Function: foo
328Args:
329 - Callee: ''
330 - DebugLoc: { File: a, Line: 1, Column: 2 }
331)YAML",
332 "argument value is missing."));
333 // No arg value.
334 EXPECT_TRUE(parseExpectError(R"YAML(
335--- !Missed
336Pass: inline
337Name: NoDefinition
338Function: foo
339Args:
340 - DebugLoc: { File: a, Line: 1, Column: 2 }
341)YAML",
342 "argument key is missing."));
343
344}
345
346TEST(OptRemarks, OptRemarksGoodStruct) {
347 StringRef Buf = R"YAML(
348--- !Missed
349Pass: inline
350Name: NoDefinition
351DebugLoc: { File: file.c, Line: 3, Column: 12 }
352Function: foo
353Args:
354 - Callee: bar
355 - String: ' will not be inlined into '
356 - Caller: foo
357 DebugLoc: { File: file.c, Line: 2, Column: 0 }
358 - String: ' because its definition is unavailable'
359)YAML";
360
361 LLVMOptRemarkParserRef Parser =
362 LLVMOptRemarkParserCreate(Buf.data(), Buf.size());
363 LLVMOptRemarkEntry *Remark = LLVMOptRemarkParserGetNext(Parser);
364 EXPECT_FALSE(Remark == nullptr);
365 EXPECT_EQ(StringRef(Remark->RemarkType.Str, 7), "!Missed");
366 EXPECT_EQ(Remark->RemarkType.Len, 7U);
367 EXPECT_EQ(StringRef(Remark->PassName.Str, 6), "inline");
368 EXPECT_EQ(Remark->PassName.Len, 6U);
369 EXPECT_EQ(StringRef(Remark->RemarkName.Str, 12), "NoDefinition");
370 EXPECT_EQ(Remark->RemarkName.Len, 12U);
371 EXPECT_EQ(StringRef(Remark->FunctionName.Str, 3), "foo");
372 EXPECT_EQ(Remark->FunctionName.Len, 3U);
373 EXPECT_EQ(StringRef(Remark->DebugLoc.SourceFile.Str, 6), "file.c");
374 EXPECT_EQ(Remark->DebugLoc.SourceFile.Len, 6U);
375 EXPECT_EQ(Remark->DebugLoc.SourceLineNumber, 3U);
376 EXPECT_EQ(Remark->DebugLoc.SourceColumnNumber, 12U);
377 EXPECT_EQ(Remark->Hotness, 0U);
378 EXPECT_EQ(Remark->NumArgs, 4U);
379 // Arg 0
380 {
381 LLVMOptRemarkArg &Arg = Remark->Args[0];
382 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Callee");
383 EXPECT_EQ(Arg.Key.Len, 6U);
384 EXPECT_EQ(StringRef(Arg.Value.Str, 3), "bar");
385 EXPECT_EQ(Arg.Value.Len, 3U);
386 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
387 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
388 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
389 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
390 }
391 // Arg 1
392 {
393 LLVMOptRemarkArg &Arg = Remark->Args[1];
394 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
395 EXPECT_EQ(Arg.Key.Len, 6U);
396 EXPECT_EQ(StringRef(Arg.Value.Str, 26), " will not be inlined into ");
397 EXPECT_EQ(Arg.Value.Len, 26U);
398 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
399 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
400 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
401 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
402 }
403 // Arg 2
404 {
405 LLVMOptRemarkArg &Arg = Remark->Args[2];
406 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "Caller");
407 EXPECT_EQ(Arg.Key.Len, 6U);
408 EXPECT_EQ(StringRef(Arg.Value.Str, 3), "foo");
409 EXPECT_EQ(Arg.Value.Len, 3U);
410 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 6), "file.c");
411 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 6U);
412 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 2U);
413 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
414 }
415 // Arg 3
416 {
417 LLVMOptRemarkArg &Arg = Remark->Args[3];
418 EXPECT_EQ(StringRef(Arg.Key.Str, 6), "String");
419 EXPECT_EQ(Arg.Key.Len, 6U);
420 EXPECT_EQ(StringRef(Arg.Value.Str, 38),
421 " because its definition is unavailable");
422 EXPECT_EQ(Arg.Value.Len, 38U);
423 EXPECT_EQ(StringRef(Arg.DebugLoc.SourceFile.Str, 0), "");
424 EXPECT_EQ(Arg.DebugLoc.SourceFile.Len, 0U);
425 EXPECT_EQ(Arg.DebugLoc.SourceLineNumber, 0U);
426 EXPECT_EQ(Arg.DebugLoc.SourceColumnNumber, 0U);
427 }
428
429 EXPECT_EQ(LLVMOptRemarkParserGetNext(Parser), nullptr);
430
431 EXPECT_FALSE(LLVMOptRemarkParserHasError(Parser));
432 LLVMOptRemarkParserDispose(Parser);
433}