Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / Support / SourceMgrTest.cpp
blob75a0cfe35aaf0e3ccfa8f63634fa964719c7925c
1 //===- unittests/Support/SourceMgrTest.cpp - SourceMgr 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/Support/SourceMgr.h"
10 #include "llvm/Support/MemoryBuffer.h"
11 #include "llvm/Support/raw_ostream.h"
12 #include "gtest/gtest.h"
14 using namespace llvm;
16 namespace {
18 class SourceMgrTest : public testing::Test {
19 public:
20 SourceMgr SM;
21 unsigned MainBufferID;
22 std::string Output;
24 void setMainBuffer(StringRef Text, StringRef BufferName) {
25 std::unique_ptr<MemoryBuffer> MainBuffer =
26 MemoryBuffer::getMemBuffer(Text, BufferName);
27 MainBufferID = SM.AddNewSourceBuffer(std::move(MainBuffer), llvm::SMLoc());
30 SMLoc getLoc(unsigned Offset) {
31 return SMLoc::getFromPointer(
32 SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset);
35 SMRange getRange(unsigned Offset, unsigned Length) {
36 return SMRange(getLoc(Offset), getLoc(Offset + Length));
39 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
40 const Twine &Msg, ArrayRef<SMRange> Ranges,
41 ArrayRef<SMFixIt> FixIts) {
42 raw_string_ostream OS(Output);
43 SM.PrintMessage(OS, Loc, Kind, Msg, Ranges, FixIts);
47 } // unnamed namespace
49 TEST_F(SourceMgrTest, BasicError) {
50 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
51 printMessage(getLoc(4), SourceMgr::DK_Error, "message", std::nullopt,
52 std::nullopt);
54 EXPECT_EQ("file.in:1:5: error: message\n"
55 "aaa bbb\n"
56 " ^\n",
57 Output);
60 TEST_F(SourceMgrTest, BasicWarning) {
61 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
62 printMessage(getLoc(4), SourceMgr::DK_Warning, "message", std::nullopt,
63 std::nullopt);
65 EXPECT_EQ("file.in:1:5: warning: message\n"
66 "aaa bbb\n"
67 " ^\n",
68 Output);
71 TEST_F(SourceMgrTest, BasicRemark) {
72 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
73 printMessage(getLoc(4), SourceMgr::DK_Remark, "message", std::nullopt,
74 std::nullopt);
76 EXPECT_EQ("file.in:1:5: remark: message\n"
77 "aaa bbb\n"
78 " ^\n",
79 Output);
82 TEST_F(SourceMgrTest, BasicNote) {
83 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
84 printMessage(getLoc(4), SourceMgr::DK_Note, "message", std::nullopt,
85 std::nullopt);
87 EXPECT_EQ("file.in:1:5: note: message\n"
88 "aaa bbb\n"
89 " ^\n",
90 Output);
93 TEST_F(SourceMgrTest, LocationAtEndOfLine) {
94 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
95 printMessage(getLoc(6), SourceMgr::DK_Error, "message", std::nullopt,
96 std::nullopt);
98 EXPECT_EQ("file.in:1:7: error: message\n"
99 "aaa bbb\n"
100 " ^\n",
101 Output);
104 TEST_F(SourceMgrTest, LocationAtNewline) {
105 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
106 printMessage(getLoc(7), SourceMgr::DK_Error, "message", std::nullopt,
107 std::nullopt);
109 EXPECT_EQ("file.in:1:8: error: message\n"
110 "aaa bbb\n"
111 " ^\n",
112 Output);
115 TEST_F(SourceMgrTest, LocationAtEmptyBuffer) {
116 setMainBuffer("", "file.in");
117 printMessage(getLoc(0), SourceMgr::DK_Error, "message", std::nullopt,
118 std::nullopt);
120 EXPECT_EQ("file.in:1:1: error: message\n"
121 "\n"
122 "^\n",
123 Output);
126 TEST_F(SourceMgrTest, LocationJustOnSoleNewline) {
127 setMainBuffer("\n", "file.in");
128 printMessage(getLoc(0), SourceMgr::DK_Error, "message", std::nullopt,
129 std::nullopt);
131 EXPECT_EQ("file.in:1:1: error: message\n"
132 "\n"
133 "^\n",
134 Output);
137 TEST_F(SourceMgrTest, LocationJustAfterSoleNewline) {
138 setMainBuffer("\n", "file.in");
139 printMessage(getLoc(1), SourceMgr::DK_Error, "message", std::nullopt,
140 std::nullopt);
142 EXPECT_EQ("file.in:2:1: error: message\n"
143 "\n"
144 "^\n",
145 Output);
148 TEST_F(SourceMgrTest, LocationJustAfterNonNewline) {
149 setMainBuffer("123", "file.in");
150 printMessage(getLoc(3), SourceMgr::DK_Error, "message", std::nullopt,
151 std::nullopt);
153 EXPECT_EQ("file.in:1:4: error: message\n"
154 "123\n"
155 " ^\n",
156 Output);
159 TEST_F(SourceMgrTest, LocationOnFirstLineOfMultiline) {
160 setMainBuffer("1234\n6789\n", "file.in");
161 printMessage(getLoc(3), SourceMgr::DK_Error, "message", std::nullopt,
162 std::nullopt);
164 EXPECT_EQ("file.in:1:4: error: message\n"
165 "1234\n"
166 " ^\n",
167 Output);
170 TEST_F(SourceMgrTest, LocationOnEOLOfFirstLineOfMultiline) {
171 setMainBuffer("1234\n6789\n", "file.in");
172 printMessage(getLoc(4), SourceMgr::DK_Error, "message", std::nullopt,
173 std::nullopt);
175 EXPECT_EQ("file.in:1:5: error: message\n"
176 "1234\n"
177 " ^\n",
178 Output);
181 TEST_F(SourceMgrTest, LocationOnSecondLineOfMultiline) {
182 setMainBuffer("1234\n6789\n", "file.in");
183 printMessage(getLoc(5), SourceMgr::DK_Error, "message", std::nullopt,
184 std::nullopt);
186 EXPECT_EQ("file.in:2:1: error: message\n"
187 "6789\n"
188 "^\n",
189 Output);
192 TEST_F(SourceMgrTest, LocationOnSecondLineOfMultilineNoSecondEOL) {
193 setMainBuffer("1234\n6789", "file.in");
194 printMessage(getLoc(5), SourceMgr::DK_Error, "message", std::nullopt,
195 std::nullopt);
197 EXPECT_EQ("file.in:2:1: error: message\n"
198 "6789\n"
199 "^\n",
200 Output);
203 TEST_F(SourceMgrTest, LocationOnEOLOfSecondSecondLineOfMultiline) {
204 setMainBuffer("1234\n6789\n", "file.in");
205 printMessage(getLoc(9), SourceMgr::DK_Error, "message", std::nullopt,
206 std::nullopt);
208 EXPECT_EQ("file.in:2:5: error: message\n"
209 "6789\n"
210 " ^\n",
211 Output);
214 #define STRING_LITERAL_253_BYTES \
215 "1234567890\n1234567890\n" \
216 "1234567890\n1234567890\n" \
217 "1234567890\n1234567890\n" \
218 "1234567890\n1234567890\n" \
219 "1234567890\n1234567890\n" \
220 "1234567890\n1234567890\n" \
221 "1234567890\n1234567890\n" \
222 "1234567890\n1234567890\n" \
223 "1234567890\n1234567890\n" \
224 "1234567890\n1234567890\n" \
225 "1234567890\n1234567890\n" \
226 "1234567890\n"
228 //===----------------------------------------------------------------------===//
229 // 255-byte buffer tests
230 //===----------------------------------------------------------------------===//
232 TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBuffer) {
233 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
234 "12" // + 2 = 255 bytes
235 , "file.in");
236 printMessage(getLoc(253), SourceMgr::DK_Error, "message", std::nullopt,
237 std::nullopt);
238 EXPECT_EQ("file.in:24:1: error: message\n"
239 "12\n"
240 "^\n",
241 Output);
244 TEST_F(SourceMgrTest, LocationAtEndOf255ByteBuffer) {
245 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
246 "12" // + 2 = 255 bytes
247 , "file.in");
248 printMessage(getLoc(254), SourceMgr::DK_Error, "message", std::nullopt,
249 std::nullopt);
250 EXPECT_EQ("file.in:24:2: error: message\n"
251 "12\n"
252 " ^\n",
253 Output);
256 TEST_F(SourceMgrTest, LocationPastEndOf255ByteBuffer) {
257 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
258 "12" // + 2 = 255 bytes
259 , "file.in");
260 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
261 std::nullopt);
262 EXPECT_EQ("file.in:24:3: error: message\n"
263 "12\n"
264 " ^\n",
265 Output);
268 TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBufferEndingInNewline) {
269 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
270 "1\n" // + 2 = 255 bytes
271 , "file.in");
272 printMessage(getLoc(253), SourceMgr::DK_Error, "message", std::nullopt,
273 std::nullopt);
274 EXPECT_EQ("file.in:24:1: error: message\n"
275 "1\n"
276 "^\n",
277 Output);
280 TEST_F(SourceMgrTest, LocationAtEndOf255ByteBufferEndingInNewline) {
281 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
282 "1\n" // + 2 = 255 bytes
283 , "file.in");
284 printMessage(getLoc(254), SourceMgr::DK_Error, "message", std::nullopt,
285 std::nullopt);
286 EXPECT_EQ("file.in:24:2: error: message\n"
287 "1\n"
288 " ^\n",
289 Output);
292 TEST_F(SourceMgrTest, LocationPastEndOf255ByteBufferEndingInNewline) {
293 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
294 "1\n" // + 2 = 255 bytes
295 , "file.in");
296 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
297 std::nullopt);
298 EXPECT_EQ("file.in:25:1: error: message\n"
299 "\n"
300 "^\n",
301 Output);
304 //===----------------------------------------------------------------------===//
305 // 256-byte buffer tests
306 //===----------------------------------------------------------------------===//
308 TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBuffer) {
309 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
310 "123" // + 3 = 256 bytes
311 , "file.in");
312 printMessage(getLoc(254), SourceMgr::DK_Error, "message", std::nullopt,
313 std::nullopt);
314 EXPECT_EQ("file.in:24:2: error: message\n"
315 "123\n"
316 " ^\n",
317 Output);
320 TEST_F(SourceMgrTest, LocationAtEndOf256ByteBuffer) {
321 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
322 "123" // + 3 = 256 bytes
323 , "file.in");
324 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
325 std::nullopt);
326 EXPECT_EQ("file.in:24:3: error: message\n"
327 "123\n"
328 " ^\n",
329 Output);
332 TEST_F(SourceMgrTest, LocationPastEndOf256ByteBuffer) {
333 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
334 "123" // + 3 = 256 bytes
335 , "file.in");
336 printMessage(getLoc(256), SourceMgr::DK_Error, "message", std::nullopt,
337 std::nullopt);
338 EXPECT_EQ("file.in:24:4: error: message\n"
339 "123\n"
340 " ^\n",
341 Output);
344 TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBufferEndingInNewline) {
345 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
346 "12\n" // + 3 = 256 bytes
347 , "file.in");
348 printMessage(getLoc(254), SourceMgr::DK_Error, "message", std::nullopt,
349 std::nullopt);
350 EXPECT_EQ("file.in:24:2: error: message\n"
351 "12\n"
352 " ^\n",
353 Output);
356 TEST_F(SourceMgrTest, LocationAtEndOf256ByteBufferEndingInNewline) {
357 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
358 "12\n" // + 3 = 256 bytes
359 , "file.in");
360 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
361 std::nullopt);
362 EXPECT_EQ("file.in:24:3: error: message\n"
363 "12\n"
364 " ^\n",
365 Output);
368 TEST_F(SourceMgrTest, LocationPastEndOf256ByteBufferEndingInNewline) {
369 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
370 "12\n" // + 3 = 256 bytes
371 , "file.in");
372 printMessage(getLoc(256), SourceMgr::DK_Error, "message", std::nullopt,
373 std::nullopt);
374 EXPECT_EQ("file.in:25:1: error: message\n"
375 "\n"
376 "^\n",
377 Output);
380 //===----------------------------------------------------------------------===//
381 // 257-byte buffer tests
382 //===----------------------------------------------------------------------===//
384 TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBuffer) {
385 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
386 "1234" // + 4 = 257 bytes
387 , "file.in");
388 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
389 std::nullopt);
390 EXPECT_EQ("file.in:24:3: error: message\n"
391 "1234\n"
392 " ^\n",
393 Output);
396 TEST_F(SourceMgrTest, LocationAtEndOf257ByteBuffer) {
397 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
398 "1234" // + 4 = 257 bytes
399 , "file.in");
400 printMessage(getLoc(256), SourceMgr::DK_Error, "message", std::nullopt,
401 std::nullopt);
402 EXPECT_EQ("file.in:24:4: error: message\n"
403 "1234\n"
404 " ^\n",
405 Output);
408 TEST_F(SourceMgrTest, LocationPastEndOf257ByteBuffer) {
409 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
410 "1234" // + 4 = 257 bytes
411 , "file.in");
412 printMessage(getLoc(257), SourceMgr::DK_Error, "message", std::nullopt,
413 std::nullopt);
414 EXPECT_EQ("file.in:24:5: error: message\n"
415 "1234\n"
416 " ^\n",
417 Output);
420 TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBufferEndingInNewline) {
421 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
422 "123\n" // + 4 = 257 bytes
423 , "file.in");
424 printMessage(getLoc(255), SourceMgr::DK_Error, "message", std::nullopt,
425 std::nullopt);
426 EXPECT_EQ("file.in:24:3: error: message\n"
427 "123\n"
428 " ^\n",
429 Output);
432 TEST_F(SourceMgrTest, LocationAtEndOf257ByteBufferEndingInNewline) {
433 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
434 "123\n" // + 4 = 257 bytes
435 , "file.in");
436 printMessage(getLoc(256), SourceMgr::DK_Error, "message", std::nullopt,
437 std::nullopt);
438 EXPECT_EQ("file.in:24:4: error: message\n"
439 "123\n"
440 " ^\n",
441 Output);
444 TEST_F(SourceMgrTest, LocationPastEndOf257ByteBufferEndingInNewline) {
445 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes
446 "123\n" // + 4 = 257 bytes
447 , "file.in");
448 printMessage(getLoc(257), SourceMgr::DK_Error, "message", std::nullopt,
449 std::nullopt);
450 EXPECT_EQ("file.in:25:1: error: message\n"
451 "\n"
452 "^\n",
453 Output);
456 TEST_F(SourceMgrTest, BasicRange) {
457 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
458 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3),
459 std::nullopt);
461 EXPECT_EQ("file.in:1:5: error: message\n"
462 "aaa bbb\n"
463 " ^~~\n",
464 Output);
467 TEST_F(SourceMgrTest, RangeWithTab) {
468 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
469 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3),
470 std::nullopt);
472 EXPECT_EQ("file.in:1:5: error: message\n"
473 "aaa bbb\n"
474 " ~~~~~^~\n",
475 Output);
478 TEST_F(SourceMgrTest, MultiLineRange) {
479 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
480 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7),
481 std::nullopt);
483 EXPECT_EQ("file.in:1:5: error: message\n"
484 "aaa bbb\n"
485 " ^~~\n",
486 Output);
489 TEST_F(SourceMgrTest, MultipleRanges) {
490 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
491 SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) };
492 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, std::nullopt);
494 EXPECT_EQ("file.in:1:5: error: message\n"
495 "aaa bbb\n"
496 "~~~ ^~~\n",
497 Output);
500 TEST_F(SourceMgrTest, OverlappingRanges) {
501 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
502 SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) };
503 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, std::nullopt);
505 EXPECT_EQ("file.in:1:5: error: message\n"
506 "aaa bbb\n"
507 "~~~~^~\n",
508 Output);
511 TEST_F(SourceMgrTest, BasicFixit) {
512 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
513 printMessage(getLoc(4), SourceMgr::DK_Error, "message", std::nullopt,
514 ArrayRef(SMFixIt(getRange(4, 3), "zzz")));
516 EXPECT_EQ("file.in:1:5: error: message\n"
517 "aaa bbb\n"
518 " ^~~\n"
519 " zzz\n",
520 Output);
523 TEST_F(SourceMgrTest, FixitForTab) {
524 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
525 printMessage(getLoc(3), SourceMgr::DK_Error, "message", std::nullopt,
526 ArrayRef(SMFixIt(getRange(3, 1), "zzz")));
528 EXPECT_EQ("file.in:1:4: error: message\n"
529 "aaa bbb\n"
530 " ^^^^^\n"
531 " zzz\n",
532 Output);
535 TEST_F(SourceMgrTest, PrintWithoutLoc) {
536 raw_string_ostream OS(Output);
537 auto Diag =
538 llvm::SMDiagnostic("file.in", llvm::SourceMgr::DK_Error, "message");
539 Diag.print(nullptr, OS);
540 OS.flush();
541 EXPECT_EQ("file.in: error: message\n", Output);
542 Output.clear();
543 Diag.print(nullptr, OS, false, false, false);
544 EXPECT_EQ("message\n", Output);