1 //===- unittests/Frontend/TextDiagnosticTest.cpp - ------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/Frontend/TextDiagnostic.h"
10 #include "clang/Basic/FileManager.h"
11 #include "clang/Basic/LangOptions.h"
12 #include "clang/Basic/SourceManager.h"
13 #include "llvm/Support/SmallVectorMemoryBuffer.h"
14 #include "gtest/gtest.h"
17 using namespace clang
;
21 /// Prints a diagnostic with the given DiagnosticOptions and the given
22 /// SourceLocation and returns the printed diagnostic text.
23 static std::string
PrintDiag(const DiagnosticOptions
&Opts
, FullSourceLoc Loc
) {
25 llvm::raw_string_ostream
OS(Out
);
26 clang::LangOptions LangOpts
;
27 // Owned by TextDiagnostic.
28 DiagnosticOptions
*DiagOpts
= new DiagnosticOptions(Opts
);
29 TextDiagnostic
Diag(OS
, LangOpts
, DiagOpts
);
30 // Emit a dummy diagnostic that is just 'message'.
31 Diag
.emitDiagnostic(Loc
, DiagnosticsEngine::Level::Warning
, "message",
32 /*Ranges=*/{}, /*FixItHints=*/{});
37 TEST(TextDiagnostic
, ShowLine
) {
38 // Create dummy FileManager and SourceManager.
39 FileSystemOptions FSOpts
;
40 FileManager
FileMgr(FSOpts
);
41 IntrusiveRefCntPtr
<DiagnosticIDs
> DiagID(new DiagnosticIDs
);
42 DiagnosticsEngine
DiagEngine(DiagID
, new DiagnosticOptions
,
43 new IgnoringDiagConsumer());
44 SourceManager
SrcMgr(DiagEngine
, FileMgr
);
46 // Create a dummy file with some contents to produce a test SourceLocation.
47 const llvm::StringRef file_path
= "main.cpp";
48 const llvm::StringRef main_file_contents
= "some\nsource\ncode\n";
49 const clang::FileEntryRef fe
= FileMgr
.getVirtualFileRef(
51 /*Size=*/static_cast<off_t
>(main_file_contents
.size()),
52 /*ModificationTime=*/0);
54 llvm::SmallVector
<char, 64> buffer
;
55 buffer
.append(main_file_contents
.begin(), main_file_contents
.end());
56 auto file_contents
= std::make_unique
<llvm::SmallVectorMemoryBuffer
>(
57 std::move(buffer
), file_path
);
58 SrcMgr
.overrideFileContents(fe
, std::move(file_contents
));
60 // Create the actual file id and use it as the main file.
62 SrcMgr
.createFileID(fe
, SourceLocation(), clang::SrcMgr::C_User
);
63 SrcMgr
.setMainFileID(fid
);
65 // Create the source location for the test diagnostic.
66 FullSourceLoc
Loc(SrcMgr
.translateLineCol(fid
, /*Line=*/1, /*Col=*/2),
69 DiagnosticOptions DiagOpts
;
70 DiagOpts
.ShowLine
= true;
71 DiagOpts
.ShowColumn
= true;
72 // Hide printing the source line/caret to make the diagnostic shorter and it's
73 // not relevant for this test.
74 DiagOpts
.ShowCarets
= false;
75 EXPECT_EQ("main.cpp:1:2: warning: message\n", PrintDiag(DiagOpts
, Loc
));
77 // Check that ShowLine doesn't influence the Vi/MSVC diagnostic formats as its
78 // a Clang-specific diagnostic option.
79 DiagOpts
.setFormat(TextDiagnosticFormat::Vi
);
80 DiagOpts
.ShowLine
= false;
81 EXPECT_EQ("main.cpp +1:2: warning: message\n", PrintDiag(DiagOpts
, Loc
));
83 DiagOpts
.setFormat(TextDiagnosticFormat::MSVC
);
84 DiagOpts
.ShowLine
= false;
85 EXPECT_EQ("main.cpp(1,2): warning: message\n", PrintDiag(DiagOpts
, Loc
));
87 // Reset back to the Clang format.
88 DiagOpts
.setFormat(TextDiagnosticFormat::Clang
);
90 // Hide line number but show column.
91 DiagOpts
.ShowLine
= false;
92 EXPECT_EQ("main.cpp:2: warning: message\n", PrintDiag(DiagOpts
, Loc
));
94 // Show line number but hide column.
95 DiagOpts
.ShowLine
= true;
96 DiagOpts
.ShowColumn
= false;
97 EXPECT_EQ("main.cpp:1: warning: message\n", PrintDiag(DiagOpts
, Loc
));
100 } // anonymous namespace