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, BasicNote) { 71 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 72 printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None); 73 74 EXPECT_EQ("file.in:1:5: note: message\n" 75 "aaa bbb\n" 76 " ^\n", 77 Output); 78 } 79 80 TEST_F(SourceMgrTest, LocationAtEndOfLine) { 81 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 82 printMessage(getLoc(6), SourceMgr::DK_Error, "message", None, None); 83 84 EXPECT_EQ("file.in:1:7: error: message\n" 85 "aaa bbb\n" 86 " ^\n", 87 Output); 88 } 89 90 TEST_F(SourceMgrTest, LocationAtNewline) { 91 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 92 printMessage(getLoc(7), SourceMgr::DK_Error, "message", None, None); 93 94 EXPECT_EQ("file.in:1:8: error: message\n" 95 "aaa bbb\n" 96 " ^\n", 97 Output); 98 } 99 100 TEST_F(SourceMgrTest, BasicRange) { 101 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 102 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3), None); 103 104 EXPECT_EQ("file.in:1:5: error: message\n" 105 "aaa bbb\n" 106 " ^~~\n", 107 Output); 108 } 109 110 TEST_F(SourceMgrTest, RangeWithTab) { 111 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 112 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), None); 113 114 EXPECT_EQ("file.in:1:5: error: message\n" 115 "aaa bbb\n" 116 " ~~~~~^~\n", 117 Output); 118 } 119 120 TEST_F(SourceMgrTest, MultiLineRange) { 121 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 122 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None); 123 124 EXPECT_EQ("file.in:1:5: error: message\n" 125 "aaa bbb\n" 126 " ^~~\n", 127 Output); 128 } 129 130 TEST_F(SourceMgrTest, MultipleRanges) { 131 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 132 SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) }; 133 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 134 135 EXPECT_EQ("file.in:1:5: error: message\n" 136 "aaa bbb\n" 137 "~~~ ^~~\n", 138 Output); 139 } 140 141 TEST_F(SourceMgrTest, OverlappingRanges) { 142 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 143 SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) }; 144 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 145 146 EXPECT_EQ("file.in:1:5: error: message\n" 147 "aaa bbb\n" 148 "~~~~^~\n", 149 Output); 150 } 151 152 TEST_F(SourceMgrTest, BasicFixit) { 153 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 154 printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, 155 makeArrayRef(SMFixIt(getRange(4, 3), "zzz"))); 156 157 EXPECT_EQ("file.in:1:5: error: message\n" 158 "aaa bbb\n" 159 " ^~~\n" 160 " zzz\n", 161 Output); 162 } 163 164 TEST_F(SourceMgrTest, FixitForTab) { 165 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 166 printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, 167 makeArrayRef(SMFixIt(getRange(3, 1), "zzz"))); 168 169 EXPECT_EQ("file.in:1:4: error: message\n" 170 "aaa bbb\n" 171 " ^^^^^\n" 172 " zzz\n", 173 Output); 174 } 175 176