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
15using namespace llvm;
16
17namespace {
18
19class SourceMgrTest : public testing::Test {
20public:
21  SourceMgr SM;
22  unsigned MainBufferID;
23  std::string Output;
24
25  void setMainBuffer(StringRef Text, StringRef BufferName) {
26    MemoryBuffer *MainBuffer = MemoryBuffer::getMemBuffer(Text, BufferName);
27    MainBufferID = SM.AddNewSourceBuffer(MainBuffer, llvm::SMLoc());
28  }
29
30  SMLoc getLoc(unsigned Offset) {
31    return SMLoc::getFromPointer(
32        SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset);
33  }
34
35  SMRange getRange(unsigned Offset, unsigned Length) {
36    return SMRange(getLoc(Offset), getLoc(Offset + Length));
37  }
38
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);
44  }
45};
46
47} // unnamed namespace
48
49TEST_F(SourceMgrTest, BasicError) {
50  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
51  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None);
52
53  EXPECT_EQ("file.in:1:5: error: message\n"
54            "aaa bbb\n"
55            "    ^\n",
56            Output);
57}
58
59TEST_F(SourceMgrTest, BasicWarning) {
60  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
61  printMessage(getLoc(4), SourceMgr::DK_Warning, "message", None, None);
62
63  EXPECT_EQ("file.in:1:5: warning: message\n"
64            "aaa bbb\n"
65            "    ^\n",
66            Output);
67}
68
69TEST_F(SourceMgrTest, BasicNote) {
70  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
71  printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None);
72
73  EXPECT_EQ("file.in:1:5: note: message\n"
74            "aaa bbb\n"
75            "    ^\n",
76            Output);
77}
78
79TEST_F(SourceMgrTest, LocationAtEndOfLine) {
80  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
81  printMessage(getLoc(6), SourceMgr::DK_Error, "message", None, None);
82
83  EXPECT_EQ("file.in:1:7: error: message\n"
84            "aaa bbb\n"
85            "      ^\n",
86            Output);
87}
88
89TEST_F(SourceMgrTest, LocationAtNewline) {
90  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
91  printMessage(getLoc(7), SourceMgr::DK_Error, "message", None, None);
92
93  EXPECT_EQ("file.in:1:8: error: message\n"
94            "aaa bbb\n"
95            "       ^\n",
96            Output);
97}
98
99TEST_F(SourceMgrTest, BasicRange) {
100  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
101  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3), None);
102
103  EXPECT_EQ("file.in:1:5: error: message\n"
104            "aaa bbb\n"
105            "    ^~~\n",
106            Output);
107}
108
109TEST_F(SourceMgrTest, RangeWithTab) {
110  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
111  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), None);
112
113  EXPECT_EQ("file.in:1:5: error: message\n"
114            "aaa     bbb\n"
115            "   ~~~~~^~\n",
116            Output);
117}
118
119TEST_F(SourceMgrTest, MultiLineRange) {
120  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
121  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None);
122
123  EXPECT_EQ("file.in:1:5: error: message\n"
124            "aaa bbb\n"
125            "    ^~~\n",
126            Output);
127}
128
129TEST_F(SourceMgrTest, MultipleRanges) {
130  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
131  SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) };
132  printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None);
133
134  EXPECT_EQ("file.in:1:5: error: message\n"
135            "aaa bbb\n"
136            "~~~ ^~~\n",
137            Output);
138}
139
140TEST_F(SourceMgrTest, OverlappingRanges) {
141  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
142  SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) };
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
151TEST_F(SourceMgrTest, BasicFixit) {
152  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
153  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None,
154               makeArrayRef(SMFixIt(getRange(4, 3), "zzz")));
155
156  EXPECT_EQ("file.in:1:5: error: message\n"
157            "aaa bbb\n"
158            "    ^~~\n"
159            "    zzz\n",
160            Output);
161}
162
163TEST_F(SourceMgrTest, FixitForTab) {
164  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
165  printMessage(getLoc(3), SourceMgr::DK_Error, "message", None,
166               makeArrayRef(SMFixIt(getRange(3, 1), "zzz")));
167
168  EXPECT_EQ("file.in:1:4: error: message\n"
169            "aaa     bbb\n"
170            "   ^^^^^\n"
171            "   zzz\n",
172            Output);
173}
174
175