1 //===- unittests/Support/SourceMgrTest.cpp - SourceMgr tests --------------===//
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
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"
18 class SourceMgrTest
: public testing::Test
{
21 unsigned MainBufferID
;
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
,
54 EXPECT_EQ("file.in:1:5: error: message\n"
60 TEST_F(SourceMgrTest
, BasicWarning
) {
61 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
62 printMessage(getLoc(4), SourceMgr::DK_Warning
, "message", std::nullopt
,
65 EXPECT_EQ("file.in:1:5: warning: message\n"
71 TEST_F(SourceMgrTest
, BasicRemark
) {
72 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
73 printMessage(getLoc(4), SourceMgr::DK_Remark
, "message", std::nullopt
,
76 EXPECT_EQ("file.in:1:5: remark: message\n"
82 TEST_F(SourceMgrTest
, BasicNote
) {
83 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
84 printMessage(getLoc(4), SourceMgr::DK_Note
, "message", std::nullopt
,
87 EXPECT_EQ("file.in:1:5: note: message\n"
93 TEST_F(SourceMgrTest
, LocationAtEndOfLine
) {
94 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
95 printMessage(getLoc(6), SourceMgr::DK_Error
, "message", std::nullopt
,
98 EXPECT_EQ("file.in:1:7: error: message\n"
104 TEST_F(SourceMgrTest
, LocationAtNewline
) {
105 setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
106 printMessage(getLoc(7), SourceMgr::DK_Error
, "message", std::nullopt
,
109 EXPECT_EQ("file.in:1:8: error: message\n"
115 TEST_F(SourceMgrTest
, LocationAtEmptyBuffer
) {
116 setMainBuffer("", "file.in");
117 printMessage(getLoc(0), SourceMgr::DK_Error
, "message", std::nullopt
,
120 EXPECT_EQ("file.in:1:1: error: message\n"
126 TEST_F(SourceMgrTest
, LocationJustOnSoleNewline
) {
127 setMainBuffer("\n", "file.in");
128 printMessage(getLoc(0), SourceMgr::DK_Error
, "message", std::nullopt
,
131 EXPECT_EQ("file.in:1:1: error: message\n"
137 TEST_F(SourceMgrTest
, LocationJustAfterSoleNewline
) {
138 setMainBuffer("\n", "file.in");
139 printMessage(getLoc(1), SourceMgr::DK_Error
, "message", std::nullopt
,
142 EXPECT_EQ("file.in:2:1: error: message\n"
148 TEST_F(SourceMgrTest
, LocationJustAfterNonNewline
) {
149 setMainBuffer("123", "file.in");
150 printMessage(getLoc(3), SourceMgr::DK_Error
, "message", std::nullopt
,
153 EXPECT_EQ("file.in:1:4: error: message\n"
159 TEST_F(SourceMgrTest
, LocationOnFirstLineOfMultiline
) {
160 setMainBuffer("1234\n6789\n", "file.in");
161 printMessage(getLoc(3), SourceMgr::DK_Error
, "message", std::nullopt
,
164 EXPECT_EQ("file.in:1:4: error: message\n"
170 TEST_F(SourceMgrTest
, LocationOnEOLOfFirstLineOfMultiline
) {
171 setMainBuffer("1234\n6789\n", "file.in");
172 printMessage(getLoc(4), SourceMgr::DK_Error
, "message", std::nullopt
,
175 EXPECT_EQ("file.in:1:5: error: message\n"
181 TEST_F(SourceMgrTest
, LocationOnSecondLineOfMultiline
) {
182 setMainBuffer("1234\n6789\n", "file.in");
183 printMessage(getLoc(5), SourceMgr::DK_Error
, "message", std::nullopt
,
186 EXPECT_EQ("file.in:2:1: error: message\n"
192 TEST_F(SourceMgrTest
, LocationOnSecondLineOfMultilineNoSecondEOL
) {
193 setMainBuffer("1234\n6789", "file.in");
194 printMessage(getLoc(5), SourceMgr::DK_Error
, "message", std::nullopt
,
197 EXPECT_EQ("file.in:2:1: error: message\n"
203 TEST_F(SourceMgrTest
, LocationOnEOLOfSecondSecondLineOfMultiline
) {
204 setMainBuffer("1234\n6789\n", "file.in");
205 printMessage(getLoc(9), SourceMgr::DK_Error
, "message", std::nullopt
,
208 EXPECT_EQ("file.in:2:5: error: message\n"
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" \
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
236 printMessage(getLoc(253), SourceMgr::DK_Error
, "message", std::nullopt
,
238 EXPECT_EQ("file.in:24:1: error: message\n"
244 TEST_F(SourceMgrTest
, LocationAtEndOf255ByteBuffer
) {
245 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
246 "12" // + 2 = 255 bytes
248 printMessage(getLoc(254), SourceMgr::DK_Error
, "message", std::nullopt
,
250 EXPECT_EQ("file.in:24:2: error: message\n"
256 TEST_F(SourceMgrTest
, LocationPastEndOf255ByteBuffer
) {
257 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
258 "12" // + 2 = 255 bytes
260 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
262 EXPECT_EQ("file.in:24:3: error: message\n"
268 TEST_F(SourceMgrTest
, LocationBeforeEndOf255ByteBufferEndingInNewline
) {
269 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
270 "1\n" // + 2 = 255 bytes
272 printMessage(getLoc(253), SourceMgr::DK_Error
, "message", std::nullopt
,
274 EXPECT_EQ("file.in:24:1: error: message\n"
280 TEST_F(SourceMgrTest
, LocationAtEndOf255ByteBufferEndingInNewline
) {
281 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
282 "1\n" // + 2 = 255 bytes
284 printMessage(getLoc(254), SourceMgr::DK_Error
, "message", std::nullopt
,
286 EXPECT_EQ("file.in:24:2: error: message\n"
292 TEST_F(SourceMgrTest
, LocationPastEndOf255ByteBufferEndingInNewline
) {
293 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
294 "1\n" // + 2 = 255 bytes
296 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
298 EXPECT_EQ("file.in:25:1: error: message\n"
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
312 printMessage(getLoc(254), SourceMgr::DK_Error
, "message", std::nullopt
,
314 EXPECT_EQ("file.in:24:2: error: message\n"
320 TEST_F(SourceMgrTest
, LocationAtEndOf256ByteBuffer
) {
321 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
322 "123" // + 3 = 256 bytes
324 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
326 EXPECT_EQ("file.in:24:3: error: message\n"
332 TEST_F(SourceMgrTest
, LocationPastEndOf256ByteBuffer
) {
333 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
334 "123" // + 3 = 256 bytes
336 printMessage(getLoc(256), SourceMgr::DK_Error
, "message", std::nullopt
,
338 EXPECT_EQ("file.in:24:4: error: message\n"
344 TEST_F(SourceMgrTest
, LocationBeforeEndOf256ByteBufferEndingInNewline
) {
345 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
346 "12\n" // + 3 = 256 bytes
348 printMessage(getLoc(254), SourceMgr::DK_Error
, "message", std::nullopt
,
350 EXPECT_EQ("file.in:24:2: error: message\n"
356 TEST_F(SourceMgrTest
, LocationAtEndOf256ByteBufferEndingInNewline
) {
357 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
358 "12\n" // + 3 = 256 bytes
360 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
362 EXPECT_EQ("file.in:24:3: error: message\n"
368 TEST_F(SourceMgrTest
, LocationPastEndOf256ByteBufferEndingInNewline
) {
369 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
370 "12\n" // + 3 = 256 bytes
372 printMessage(getLoc(256), SourceMgr::DK_Error
, "message", std::nullopt
,
374 EXPECT_EQ("file.in:25:1: error: message\n"
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
388 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
390 EXPECT_EQ("file.in:24:3: error: message\n"
396 TEST_F(SourceMgrTest
, LocationAtEndOf257ByteBuffer
) {
397 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
398 "1234" // + 4 = 257 bytes
400 printMessage(getLoc(256), SourceMgr::DK_Error
, "message", std::nullopt
,
402 EXPECT_EQ("file.in:24:4: error: message\n"
408 TEST_F(SourceMgrTest
, LocationPastEndOf257ByteBuffer
) {
409 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
410 "1234" // + 4 = 257 bytes
412 printMessage(getLoc(257), SourceMgr::DK_Error
, "message", std::nullopt
,
414 EXPECT_EQ("file.in:24:5: error: message\n"
420 TEST_F(SourceMgrTest
, LocationBeforeEndOf257ByteBufferEndingInNewline
) {
421 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
422 "123\n" // + 4 = 257 bytes
424 printMessage(getLoc(255), SourceMgr::DK_Error
, "message", std::nullopt
,
426 EXPECT_EQ("file.in:24:3: error: message\n"
432 TEST_F(SourceMgrTest
, LocationAtEndOf257ByteBufferEndingInNewline
) {
433 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
434 "123\n" // + 4 = 257 bytes
436 printMessage(getLoc(256), SourceMgr::DK_Error
, "message", std::nullopt
,
438 EXPECT_EQ("file.in:24:4: error: message\n"
444 TEST_F(SourceMgrTest
, LocationPastEndOf257ByteBufferEndingInNewline
) {
445 setMainBuffer(STRING_LITERAL_253_BYTES
// first 253 bytes
446 "123\n" // + 4 = 257 bytes
448 printMessage(getLoc(257), SourceMgr::DK_Error
, "message", std::nullopt
,
450 EXPECT_EQ("file.in:25:1: error: message\n"
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),
461 EXPECT_EQ("file.in:1:5: error: message\n"
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),
472 EXPECT_EQ("file.in:1:5: error: message\n"
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),
483 EXPECT_EQ("file.in:1:5: error: message\n"
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"
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"
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"
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"
535 TEST_F(SourceMgrTest
, PrintWithoutLoc
) {
536 raw_string_ostream
OS(Output
);
538 llvm::SMDiagnostic("file.in", llvm::SourceMgr::DK_Error
, "message");
539 Diag
.print(nullptr, OS
);
541 EXPECT_EQ("file.in: error: message\n", Output
);
543 Diag
.print(nullptr, OS
, false, false, false);
544 EXPECT_EQ("message\n", Output
);