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, BasicRange) { 111 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 112 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 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, RangeWithTab) { 121 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 122 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), 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, MultiLineRange) { 131 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 132 printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None); 133 134 EXPECT_EQ("file.in:1:5: error: message\n" 135 "aaa bbb\n" 136 " ^~~\n", 137 Output); 138 } 139 140 TEST_F(SourceMgrTest, MultipleRanges) { 141 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 142 SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) }; 143 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 144 145 EXPECT_EQ("file.in:1:5: error: message\n" 146 "aaa bbb\n" 147 "~~~ ^~~\n", 148 Output); 149 } 150 151 TEST_F(SourceMgrTest, OverlappingRanges) { 152 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 153 SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) }; 154 printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None); 155 156 EXPECT_EQ("file.in:1:5: error: message\n" 157 "aaa bbb\n" 158 "~~~~^~\n", 159 Output); 160 } 161 162 TEST_F(SourceMgrTest, BasicFixit) { 163 setMainBuffer("aaa bbb\nccc ddd\n", "file.in"); 164 printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, 165 makeArrayRef(SMFixIt(getRange(4, 3), "zzz"))); 166 167 EXPECT_EQ("file.in:1:5: error: message\n" 168 "aaa bbb\n" 169 " ^~~\n" 170 " zzz\n", 171 Output); 172 } 173 174 TEST_F(SourceMgrTest, FixitForTab) { 175 setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in"); 176 printMessage(getLoc(3), SourceMgr::DK_Error, "message", None, 177 makeArrayRef(SMFixIt(getRange(3, 1), "zzz"))); 178 179 EXPECT_EQ("file.in:1:4: error: message\n" 180 "aaa bbb\n" 181 " ^^^^^\n" 182 " zzz\n", 183 Output); 184 } 185 186