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 
setMainBuffer(StringRef Text,StringRef BufferName)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 
getLoc(unsigned Offset)31   SMLoc getLoc(unsigned Offset) {
32     return SMLoc::getFromPointer(
33         SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset);
34   }
35 
getRange(unsigned Offset,unsigned Length)36   SMRange getRange(unsigned Offset, unsigned Length) {
37     return SMRange(getLoc(Offset), getLoc(Offset + Length));
38   }
39 
printMessage(SMLoc Loc,SourceMgr::DiagKind Kind,const Twine & Msg,ArrayRef<SMRange> Ranges,ArrayRef<SMFixIt> FixIts)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 
TEST_F(SourceMgrTest,BasicError)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 
TEST_F(SourceMgrTest,BasicWarning)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 
TEST_F(SourceMgrTest,BasicNote)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 
TEST_F(SourceMgrTest,LocationAtEndOfLine)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 
TEST_F(SourceMgrTest,LocationAtNewline)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 
TEST_F(SourceMgrTest,BasicRange)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 
TEST_F(SourceMgrTest,RangeWithTab)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 
TEST_F(SourceMgrTest,MultiLineRange)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 
TEST_F(SourceMgrTest,MultipleRanges)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 
TEST_F(SourceMgrTest,OverlappingRanges)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 
TEST_F(SourceMgrTest,BasicFixit)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 
TEST_F(SourceMgrTest,FixitForTab)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