18a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//===- unittests/Support/SourceMgrTest.cpp - SourceMgr tests --------------===//
28a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//
38a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//                     The LLVM Compiler Infrastructure
48a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//
58a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko// This file is distributed under the University of Illinois Open Source
68a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko// License. See LICENSE.TXT for details.
78a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//
88a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko//===----------------------------------------------------------------------===//
98a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
108a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko#include "llvm/Support/SourceMgr.h"
118a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko#include "llvm/Support/MemoryBuffer.h"
128a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko#include "llvm/Support/raw_ostream.h"
138a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko#include "gtest/gtest.h"
148a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
158a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenkousing namespace llvm;
168a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
178a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenkonamespace {
188a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
198a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenkoclass SourceMgrTest : public testing::Test {
208a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenkopublic:
218a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  SourceMgr SM;
228a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  unsigned MainBufferID;
238a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  std::string Output;
248a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
258a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  void setMainBuffer(StringRef Text, StringRef BufferName) {
268a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    MemoryBuffer *MainBuffer = MemoryBuffer::getMemBuffer(Text, BufferName);
278a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    MainBufferID = SM.AddNewSourceBuffer(MainBuffer, llvm::SMLoc());
288a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  }
298a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
308a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  SMLoc getLoc(unsigned Offset) {
318a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    return SMLoc::getFromPointer(
328a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko        SM.getMemoryBuffer(MainBufferID)->getBufferStart() + Offset);
338a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  }
348a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
358a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  SMRange getRange(unsigned Offset, unsigned Length) {
368a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    return SMRange(getLoc(Offset), getLoc(Offset + Length));
378a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  }
388a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
398a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  void printMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
408a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko                    const Twine &Msg, ArrayRef<SMRange> Ranges,
418a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko                    ArrayRef<SMFixIt> FixIts) {
428a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    raw_string_ostream OS(Output);
438a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko    SM.PrintMessage(OS, Loc, Kind, Msg, Ranges, FixIts);
448a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  }
458a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko};
468a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
478a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko} // unnamed namespace
488a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
498a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, BasicError) {
508a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
518a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None, None);
528a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
538a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
548a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
558a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^\n",
568a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
578a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
588a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
598a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, BasicWarning) {
608a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
618a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Warning, "message", None, None);
628a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
638a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: warning: message\n"
648a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
658a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^\n",
668a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
678a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
688a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
698a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, BasicNote) {
708a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
718a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Note, "message", None, None);
728a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
738a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: note: message\n"
748a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
758a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^\n",
768a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
778a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
788a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
798a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, LocationAtEndOfLine) {
808a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
818a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(6), SourceMgr::DK_Error, "message", None, None);
828a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
838a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:7: error: message\n"
848a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
858a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "      ^\n",
868a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
878a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
888a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
898a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, LocationAtNewline) {
908a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
918a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(7), SourceMgr::DK_Error, "message", None, None);
928a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
938a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:8: error: message\n"
948a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
958a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "       ^\n",
968a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
978a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
988a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
998a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, BasicRange) {
1008a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
1018a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 3), None);
1028a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1038a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1048a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
1058a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^~~\n",
1068a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1078a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1088a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1098a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, RangeWithTab) {
1108a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
1118a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(3, 3), None);
1128a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1138a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1148a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa     bbb\n"
1158a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "   ~~~~~^~\n",
1168a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1178a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1188a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1198a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, MultiLineRange) {
1208a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
1218a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", getRange(4, 7), None);
1228a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1238a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1248a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
1258a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^~~\n",
1268a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1278a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1288a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1298a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, MultipleRanges) {
1308a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
1318a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  SMRange Ranges[] = { getRange(0, 3), getRange(4, 3) };
1328a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None);
1338a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1348a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1358a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
1368a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "~~~ ^~~\n",
1378a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1388a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1398a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1408a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, OverlappingRanges) {
1418a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
1428a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  SMRange Ranges[] = { getRange(0, 3), getRange(2, 4) };
1438a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", Ranges, None);
1448a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1458a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1468a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
1478a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "~~~~^~\n",
1488a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1498a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1508a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1518a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri GribenkoTEST_F(SourceMgrTest, BasicFixit) {
1528a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  setMainBuffer("aaa bbb\nccc ddd\n", "file.in");
1538a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  printMessage(getLoc(4), SourceMgr::DK_Error, "message", None,
1548a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko               makeArrayRef(SMFixIt(getRange(4, 3), "zzz")));
1558a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
1568a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko  EXPECT_EQ("file.in:1:5: error: message\n"
1578a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "aaa bbb\n"
1588a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    ^~~\n"
1598a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            "    zzz\n",
1608a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko            Output);
1618a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko}
1628a93c3ab2121f8c9f0739971070b042cd6aa8024Dmitri Gribenko
163867c189d891f175969164515c6cb91e4d3650ea6Dmitri GribenkoTEST_F(SourceMgrTest, FixitForTab) {
164867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko  setMainBuffer("aaa\tbbb\nccc ddd\n", "file.in");
165867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko  printMessage(getLoc(3), SourceMgr::DK_Error, "message", None,
166867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko               makeArrayRef(SMFixIt(getRange(3, 1), "zzz")));
167867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko
168867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko  EXPECT_EQ("file.in:1:4: error: message\n"
169867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko            "aaa     bbb\n"
170867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko            "   ^^^^^\n"
171867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko            "   zzz\n",
172867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko            Output);
173867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko}
174867c189d891f175969164515c6cb91e4d3650ea6Dmitri Gribenko
175