1 //===- unittests/Support/SourceMgrTest.cpp - SourceMgr 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/Support/SourceMgr.h" 11 #include "llvm/Support/MemoryBuffer.h" 12 #include "llvm/Support/raw_ostream.h" 13 #include "gtest/gtest.h" 14 15 using namespace llvm; 16 17 namespace { 18 19 class SourceMgrTest : public testing::Test { 20 public: 21 SourceMgr SM; 22 unsigned MainBufferID; 23 std::string Output; 24 25 void setMainBuffer(StringRef Text, StringRef BufferName) { 26 std::unique_ptr<MemoryBuffer> MainBuffer = 27 MemoryBuffer::getMemBuffer(Text, BufferName); 28 MainBufferID = SM.AddNewSourceBuffer(std::move(MainBuffer), llvm::SMLoc()); 29 } 30 31 SMLoc getLoc(unsigned Offset) { 32 return SMLoc::getFromPointer( 33 SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset); 34 } 35 36 SMRange getRange(unsigned Offset, unsigned Length) { 37 return SMRange(getLoc(Offset), getLoc(Offset + Length)); 38 } 39 40 void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind, 41 const Twine &Msg, ArrayRef<SMRange> Ranges, 42 ArrayRef<SMFixIt> FixIts) { 43 raw_string_ostream OS(Output); 44 SM.PrintMessage(OS, Loc, Kind, Msg, Ranges, FixIts); 45 } 46 }; 47 48 } // unnamed namespace 49 50 TEST_F(SourceMgrTest, BasicError) { 51 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 52 printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None); 53 54 EXPECT_EQ("file.in:1:5: error: message\n" 55 "aaa bbb\n" 56 " ^\n", 57 Output); 58 } 59 60 TEST_F(SourceMgrTest, BasicWarning) { 61 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 62 printMessage(getLoc(4), SourceMgr::DK_Warning, "message", None, None); 63 64 EXPECT_EQ("file.in:1:5: warning: message\n" 65 "aaa bbb\n" 66 " ^\n", 67 Output); 68 } 69 70 TEST_F(SourceMgrTest, BasicRemark) { 71 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 72 printMessage(getLoc(4), SourceMgr::DK_Remark, "message", None, None); 73 74 EXPECT_EQ("file.in:1:5: remark: message\n" 75 "aaa bbb\n" 76 " ^\n", 77 Output); 78 } 79 80 TEST_F(SourceMgrTest, BasicNote) { 81 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 82 printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None); 83 84 EXPECT_EQ("file.in:1:5: note: message\n" 85 "aaa bbb\n" 86 " ^\n", 87 Output); 88 } 89 90 TEST_F(SourceMgrTest, LocationAtEndOfLine) { 91 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 92 printMessage(getLoc(6), SourceMgr::DK_Error, "message", None, None); 93 94 EXPECT_EQ("file.in:1:7: error: message\n" 95 "aaa bbb\n" 96 " ^\n", 97 Output); 98 } 99 100 TEST_F(SourceMgrTest, LocationAtNewline) { 101 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 102 printMessage(getLoc(7), SourceMgr::DK_Error, "message", None, None); 103 104 EXPECT_EQ("file.in:1:8: error: message\n" 105 "aaa bbb\n" 106 " ^\n", 107 Output); 108 } 109 110 TEST_F(SourceMgrTest, LocationAtEmptyBuffer) { 111 setMainBuffer("", "file.in"); 112 printMessage(getLoc(0), SourceMgr::DK_Error, "message", None, None); 113 114 EXPECT_EQ("file.in:1:1: error: message\n" 115 "\n" 116 "^\n", 117 Output); 118 } 119 120 TEST_F(SourceMgrTest, LocationJustOnSoleNewline) { 121 setMainBuffer("\n", "file.in"); 122 printMessage(getLoc(0), SourceMgr::DK_Error, "message", None, None); 123 124 EXPECT_EQ("file.in:1:1: error: message\n" 125 "\n" 126 "^\n", 127 Output); 128 } 129 130 TEST_F(SourceMgrTest, LocationJustAfterSoleNewline) { 131 setMainBuffer("\n", "file.in"); 132 printMessage(getLoc(1), SourceMgr::DK_Error, "message", None, None); 133 134 EXPECT_EQ("file.in:2:1: error: message\n" 135 "\n" 136 "^\n", 137 Output); 138 } 139 140 TEST_F(SourceMgrTest, LocationJustAfterNonNewline) { 141 setMainBuffer("123", "file.in"); 142 printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, None); 143 144 EXPECT_EQ("file.in:1:4: error: message\n" 145 "123\n" 146 " ^\n", 147 Output); 148 } 149 150 TEST_F(SourceMgrTest, LocationOnFirstLineOfMultiline) { 151 setMainBuffer("1234\n6789\n", "file.in"); 152 printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, None); 153 154 EXPECT_EQ("file.in:1:4: error: message\n" 155 "1234\n" 156 " ^\n", 157 Output); 158 } 159 160 TEST_F(SourceMgrTest, LocationOnEOLOfFirstLineOfMultiline) { 161 setMainBuffer("1234\n6789\n", "file.in"); 162 printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None); 163 164 EXPECT_EQ("file.in:1:5: error: message\n" 165 "1234\n" 166 " ^\n", 167 Output); 168 } 169 170 TEST_F(SourceMgrTest, LocationOnSecondLineOfMultiline) { 171 setMainBuffer("1234\n6789\n", "file.in"); 172 printMessage(getLoc(5), SourceMgr::DK_Error, "message", None, None); 173 174 EXPECT_EQ("file.in:2:1: error: message\n" 175 "6789\n" 176 "^\n", 177 Output); 178 } 179 180 TEST_F(SourceMgrTest, LocationOnSecondLineOfMultilineNoSecondEOL) { 181 setMainBuffer("1234\n6789", "file.in"); 182 printMessage(getLoc(5), SourceMgr::DK_Error, "message", None, None); 183 184 EXPECT_EQ("file.in:2:1: error: message\n" 185 "6789\n" 186 "^\n", 187 Output); 188 } 189 190 TEST_F(SourceMgrTest, LocationOnEOLOfSecondSecondLineOfMultiline) { 191 setMainBuffer("1234\n6789\n", "file.in"); 192 printMessage(getLoc(9), SourceMgr::DK_Error, "message", None, None); 193 194 EXPECT_EQ("file.in:2:5: error: message\n" 195 "6789\n" 196 " ^\n", 197 Output); 198 } 199 200 #define STRING_LITERAL_253_BYTES \ 201 "1234567890\n1234567890\n" \ 202 "1234567890\n1234567890\n" \ 203 "1234567890\n1234567890\n" \ 204 "1234567890\n1234567890\n" \ 205 "1234567890\n1234567890\n" \ 206 "1234567890\n1234567890\n" \ 207 "1234567890\n1234567890\n" \ 208 "1234567890\n1234567890\n" \ 209 "1234567890\n1234567890\n" \ 210 "1234567890\n1234567890\n" \ 211 "1234567890\n1234567890\n" \ 212 "1234567890\n" 213 214 //===----------------------------------------------------------------------===// 215 // 255-byte buffer tests 216 //===----------------------------------------------------------------------===// 217 218 TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBuffer) { 219 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 220 "12" // + 2 = 255 bytes 221 , "file.in"); 222 printMessage(getLoc(253), SourceMgr::DK_Error, "message", None, None); 223 EXPECT_EQ("file.in:24:1: error: message\n" 224 "12\n" 225 "^\n", 226 Output); 227 } 228 229 TEST_F(SourceMgrTest, LocationAtEndOf255ByteBuffer) { 230 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 231 "12" // + 2 = 255 bytes 232 , "file.in"); 233 printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None); 234 EXPECT_EQ("file.in:24:2: error: message\n" 235 "12\n" 236 " ^\n", 237 Output); 238 } 239 240 TEST_F(SourceMgrTest, LocationPastEndOf255ByteBuffer) { 241 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 242 "12" // + 2 = 255 bytes 243 , "file.in"); 244 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 245 EXPECT_EQ("file.in:24:3: error: message\n" 246 "12\n" 247 " ^\n", 248 Output); 249 } 250 251 TEST_F(SourceMgrTest, LocationBeforeEndOf255ByteBufferEndingInNewline) { 252 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 253 "1\n" // + 2 = 255 bytes 254 , "file.in"); 255 printMessage(getLoc(253), SourceMgr::DK_Error, "message", None, None); 256 EXPECT_EQ("file.in:24:1: error: message\n" 257 "1\n" 258 "^\n", 259 Output); 260 } 261 262 TEST_F(SourceMgrTest, LocationAtEndOf255ByteBufferEndingInNewline) { 263 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 264 "1\n" // + 2 = 255 bytes 265 , "file.in"); 266 printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None); 267 EXPECT_EQ("file.in:24:2: error: message\n" 268 "1\n" 269 " ^\n", 270 Output); 271 } 272 273 TEST_F(SourceMgrTest, LocationPastEndOf255ByteBufferEndingInNewline) { 274 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 275 "1\n" // + 2 = 255 bytes 276 , "file.in"); 277 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 278 EXPECT_EQ("file.in:25:1: error: message\n" 279 "\n" 280 "^\n", 281 Output); 282 } 283 284 //===----------------------------------------------------------------------===// 285 // 256-byte buffer tests 286 //===----------------------------------------------------------------------===// 287 288 TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBuffer) { 289 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 290 "123" // + 3 = 256 bytes 291 , "file.in"); 292 printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None); 293 EXPECT_EQ("file.in:24:2: error: message\n" 294 "123\n" 295 " ^\n", 296 Output); 297 } 298 299 TEST_F(SourceMgrTest, LocationAtEndOf256ByteBuffer) { 300 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 301 "123" // + 3 = 256 bytes 302 , "file.in"); 303 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 304 EXPECT_EQ("file.in:24:3: error: message\n" 305 "123\n" 306 " ^\n", 307 Output); 308 } 309 310 TEST_F(SourceMgrTest, LocationPastEndOf256ByteBuffer) { 311 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 312 "123" // + 3 = 256 bytes 313 , "file.in"); 314 printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None); 315 EXPECT_EQ("file.in:24:4: error: message\n" 316 "123\n" 317 " ^\n", 318 Output); 319 } 320 321 TEST_F(SourceMgrTest, LocationBeforeEndOf256ByteBufferEndingInNewline) { 322 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 323 "12\n" // + 3 = 256 bytes 324 , "file.in"); 325 printMessage(getLoc(254), SourceMgr::DK_Error, "message", None, None); 326 EXPECT_EQ("file.in:24:2: error: message\n" 327 "12\n" 328 " ^\n", 329 Output); 330 } 331 332 TEST_F(SourceMgrTest, LocationAtEndOf256ByteBufferEndingInNewline) { 333 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 334 "12\n" // + 3 = 256 bytes 335 , "file.in"); 336 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 337 EXPECT_EQ("file.in:24:3: error: message\n" 338 "12\n" 339 " ^\n", 340 Output); 341 } 342 343 TEST_F(SourceMgrTest, LocationPastEndOf256ByteBufferEndingInNewline) { 344 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 345 "12\n" // + 3 = 256 bytes 346 , "file.in"); 347 printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None); 348 EXPECT_EQ("file.in:25:1: error: message\n" 349 "\n" 350 "^\n", 351 Output); 352 } 353 354 //===----------------------------------------------------------------------===// 355 // 257-byte buffer tests 356 //===----------------------------------------------------------------------===// 357 358 TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBuffer) { 359 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 360 "1234" // + 4 = 257 bytes 361 , "file.in"); 362 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 363 EXPECT_EQ("file.in:24:3: error: message\n" 364 "1234\n" 365 " ^\n", 366 Output); 367 } 368 369 TEST_F(SourceMgrTest, LocationAtEndOf257ByteBuffer) { 370 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 371 "1234" // + 4 = 257 bytes 372 , "file.in"); 373 printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None); 374 EXPECT_EQ("file.in:24:4: error: message\n" 375 "1234\n" 376 " ^\n", 377 Output); 378 } 379 380 TEST_F(SourceMgrTest, LocationPastEndOf257ByteBuffer) { 381 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 382 "1234" // + 4 = 257 bytes 383 , "file.in"); 384 printMessage(getLoc(257), SourceMgr::DK_Error, "message", None, None); 385 EXPECT_EQ("file.in:24:5: error: message\n" 386 "1234\n" 387 " ^\n", 388 Output); 389 } 390 391 TEST_F(SourceMgrTest, LocationBeforeEndOf257ByteBufferEndingInNewline) { 392 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 393 "123\n" // + 4 = 257 bytes 394 , "file.in"); 395 printMessage(getLoc(255), SourceMgr::DK_Error, "message", None, None); 396 EXPECT_EQ("file.in:24:3: error: message\n" 397 "123\n" 398 " ^\n", 399 Output); 400 } 401 402 TEST_F(SourceMgrTest, LocationAtEndOf257ByteBufferEndingInNewline) { 403 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 404 "123\n" // + 4 = 257 bytes 405 , "file.in"); 406 printMessage(getLoc(256), SourceMgr::DK_Error, "message", None, None); 407 EXPECT_EQ("file.in:24:4: error: message\n" 408 "123\n" 409 " ^\n", 410 Output); 411 } 412 413 TEST_F(SourceMgrTest, LocationPastEndOf257ByteBufferEndingInNewline) { 414 setMainBuffer(STRING_LITERAL_253_BYTES // first 253 bytes 415 "123\n" // + 4 = 257 bytes 416 , "file.in"); 417 printMessage(getLoc(257), SourceMgr::DK_Error, "message", None, None); 418 EXPECT_EQ("file.in:25:1: error: message\n" 419 "\n" 420 "^\n", 421 Output); 422 } 423 424 TEST_F(SourceMgrTest, BasicRange) { 425 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 426 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3), None); 427 428 EXPECT_EQ("file.in:1:5: error: message\n" 429 "aaa bbb\n" 430 " ^~~\n", 431 Output); 432 } 433 434 TEST_F(SourceMgrTest, RangeWithTab) { 435 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 436 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), None); 437 438 EXPECT_EQ("file.in:1:5: error: message\n" 439 "aaa bbb\n" 440 " ~~~~~^~\n", 441 Output); 442 } 443 444 TEST_F(SourceMgrTest, MultiLineRange) { 445 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 446 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None); 447 448 EXPECT_EQ("file.in:1:5: error: message\n" 449 "aaa bbb\n" 450 " ^~~\n", 451 Output); 452 } 453 454 TEST_F(SourceMgrTest, MultipleRanges) { 455 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 456 SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) }; 457 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 458 459 EXPECT_EQ("file.in:1:5: error: message\n" 460 "aaa bbb\n" 461 "~~~ ^~~\n", 462 Output); 463 } 464 465 TEST_F(SourceMgrTest, OverlappingRanges) { 466 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 467 SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) }; 468 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 469 470 EXPECT_EQ("file.in:1:5: error: message\n" 471 "aaa bbb\n" 472 "~~~~^~\n", 473 Output); 474 } 475 476 TEST_F(SourceMgrTest, BasicFixit) { 477 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 478 printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, 479 makeArrayRef(SMFixIt(getRange(4, 3), "zzz"))); 480 481 EXPECT_EQ("file.in:1:5: error: message\n" 482 "aaa bbb\n" 483 " ^~~\n" 484 " zzz\n", 485 Output); 486 } 487 488 TEST_F(SourceMgrTest, FixitForTab) { 489 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 490 printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, 491 makeArrayRef(SMFixIt(getRange(3, 1), "zzz"))); 492 493 EXPECT_EQ("file.in:1:4: error: message\n" 494 "aaa bbb\n" 495 " ^^^^^\n" 496 " zzz\n", 497 Output); 498 } 499 500