llvm-project
100 строк · 3.8 Кб
1//===- unittests/Frontend/TextDiagnosticTest.cpp - ------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
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"
15
16using namespace llvm;
17using namespace clang;
18
19namespace {
20
21/// Prints a diagnostic with the given DiagnosticOptions and the given
22/// SourceLocation and returns the printed diagnostic text.
23static std::string PrintDiag(const DiagnosticOptions &Opts, FullSourceLoc Loc) {
24std::string Out;
25llvm::raw_string_ostream OS(Out);
26clang::LangOptions LangOpts;
27// Owned by TextDiagnostic.
28DiagnosticOptions *DiagOpts = new DiagnosticOptions(Opts);
29TextDiagnostic Diag(OS, LangOpts, DiagOpts);
30// Emit a dummy diagnostic that is just 'message'.
31Diag.emitDiagnostic(Loc, DiagnosticsEngine::Level::Warning, "message",
32/*Ranges=*/{}, /*FixItHints=*/{});
33OS.flush();
34return Out;
35}
36
37TEST(TextDiagnostic, ShowLine) {
38// Create dummy FileManager and SourceManager.
39FileSystemOptions FSOpts;
40FileManager FileMgr(FSOpts);
41IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs);
42DiagnosticsEngine DiagEngine(DiagID, new DiagnosticOptions,
43new IgnoringDiagConsumer());
44SourceManager SrcMgr(DiagEngine, FileMgr);
45
46// Create a dummy file with some contents to produce a test SourceLocation.
47const llvm::StringRef file_path = "main.cpp";
48const llvm::StringRef main_file_contents = "some\nsource\ncode\n";
49const clang::FileEntryRef fe = FileMgr.getVirtualFileRef(
50file_path,
51/*Size=*/static_cast<off_t>(main_file_contents.size()),
52/*ModificationTime=*/0);
53
54llvm::SmallVector<char, 64> buffer;
55buffer.append(main_file_contents.begin(), main_file_contents.end());
56auto file_contents = std::make_unique<llvm::SmallVectorMemoryBuffer>(
57std::move(buffer), file_path, /*RequiresNullTerminator=*/false);
58SrcMgr.overrideFileContents(fe, std::move(file_contents));
59
60// Create the actual file id and use it as the main file.
61clang::FileID fid =
62SrcMgr.createFileID(fe, SourceLocation(), clang::SrcMgr::C_User);
63SrcMgr.setMainFileID(fid);
64
65// Create the source location for the test diagnostic.
66FullSourceLoc Loc(SrcMgr.translateLineCol(fid, /*Line=*/1, /*Col=*/2),
67SrcMgr);
68
69DiagnosticOptions DiagOpts;
70DiagOpts.ShowLine = true;
71DiagOpts.ShowColumn = true;
72// Hide printing the source line/caret to make the diagnostic shorter and it's
73// not relevant for this test.
74DiagOpts.ShowCarets = false;
75EXPECT_EQ("main.cpp:1:2: warning: message\n", PrintDiag(DiagOpts, Loc));
76
77// Check that ShowLine doesn't influence the Vi/MSVC diagnostic formats as its
78// a Clang-specific diagnostic option.
79DiagOpts.setFormat(TextDiagnosticFormat::Vi);
80DiagOpts.ShowLine = false;
81EXPECT_EQ("main.cpp +1:2: warning: message\n", PrintDiag(DiagOpts, Loc));
82
83DiagOpts.setFormat(TextDiagnosticFormat::MSVC);
84DiagOpts.ShowLine = false;
85EXPECT_EQ("main.cpp(1,2): warning: message\n", PrintDiag(DiagOpts, Loc));
86
87// Reset back to the Clang format.
88DiagOpts.setFormat(TextDiagnosticFormat::Clang);
89
90// Hide line number but show column.
91DiagOpts.ShowLine = false;
92EXPECT_EQ("main.cpp:2: warning: message\n", PrintDiag(DiagOpts, Loc));
93
94// Show line number but hide column.
95DiagOpts.ShowLine = true;
96DiagOpts.ShowColumn = false;
97EXPECT_EQ("main.cpp:1: warning: message\n", PrintDiag(DiagOpts, Loc));
98}
99
100} // anonymous namespace
101