| //===- unittests/Frontend/TextDiagnosticTest.cpp - ------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Frontend/TextDiagnostic.h" |
| #include "clang/Basic/FileManager.h" |
| #include "clang/Basic/LangOptions.h" |
| #include "clang/Basic/SourceManager.h" |
| #include "llvm/Support/SmallVectorMemoryBuffer.h" |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| using namespace clang; |
| |
| namespace { |
| |
| /// Prints a diagnostic with the given DiagnosticOptions and the given |
| /// SourceLocation and returns the printed diagnostic text. |
| static std::string PrintDiag(const DiagnosticOptions &Opts, FullSourceLoc Loc) { |
| std::string Out; |
| llvm::raw_string_ostream OS(Out); |
| clang::LangOptions LangOpts; |
| // Owned by TextDiagnostic. |
| DiagnosticOptions *DiagOpts = new DiagnosticOptions(Opts); |
| TextDiagnostic Diag(OS, LangOpts, DiagOpts); |
| // Emit a dummy diagnostic that is just 'message'. |
| Diag.emitDiagnostic(Loc, DiagnosticsEngine::Level::Warning, "message", |
| /*Ranges=*/{}, /*FixItHints=*/{}); |
| OS.flush(); |
| return Out; |
| } |
| |
| TEST(TextDiagnostic, ShowLine) { |
| // Create dummy FileManager and SourceManager. |
| FileSystemOptions FSOpts; |
| FileManager FileMgr(FSOpts); |
| IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs); |
| DiagnosticsEngine DiagEngine(DiagID, new DiagnosticOptions, |
| new IgnoringDiagConsumer()); |
| SourceManager SrcMgr(DiagEngine, FileMgr); |
| |
| // Create a dummy file with some contents to produce a test SourceLocation. |
| const llvm::StringRef file_path = "main.cpp"; |
| const llvm::StringRef main_file_contents = "some\nsource\ncode\n"; |
| const clang::FileEntryRef fe = FileMgr.getVirtualFileRef( |
| file_path, |
| /*Size=*/static_cast<off_t>(main_file_contents.size()), |
| /*ModificationTime=*/0); |
| |
| llvm::SmallVector<char, 64> buffer; |
| buffer.append(main_file_contents.begin(), main_file_contents.end()); |
| auto file_contents = std::make_unique<llvm::SmallVectorMemoryBuffer>( |
| std::move(buffer), file_path); |
| SrcMgr.overrideFileContents(fe, std::move(file_contents)); |
| |
| // Create the actual file id and use it as the main file. |
| clang::FileID fid = |
| SrcMgr.createFileID(fe, SourceLocation(), clang::SrcMgr::C_User); |
| SrcMgr.setMainFileID(fid); |
| |
| // Create the source location for the test diagnostic. |
| FullSourceLoc Loc(SrcMgr.translateLineCol(fid, /*Line=*/1, /*Col=*/2), |
| SrcMgr); |
| |
| DiagnosticOptions DiagOpts; |
| DiagOpts.ShowLine = true; |
| DiagOpts.ShowColumn = true; |
| // Hide printing the source line/caret to make the diagnostic shorter and it's |
| // not relevant for this test. |
| DiagOpts.ShowCarets = false; |
| EXPECT_EQ("main.cpp:1:2: warning: message\n", PrintDiag(DiagOpts, Loc)); |
| |
| // Check that ShowLine doesn't influence the Vi/MSVC diagnostic formats as its |
| // a Clang-specific diagnostic option. |
| DiagOpts.setFormat(TextDiagnosticFormat::Vi); |
| DiagOpts.ShowLine = false; |
| EXPECT_EQ("main.cpp +1:2: warning: message\n", PrintDiag(DiagOpts, Loc)); |
| |
| DiagOpts.setFormat(TextDiagnosticFormat::MSVC); |
| DiagOpts.ShowLine = false; |
| EXPECT_EQ("main.cpp(1,2): warning: message\n", PrintDiag(DiagOpts, Loc)); |
| |
| // Reset back to the Clang format. |
| DiagOpts.setFormat(TextDiagnosticFormat::Clang); |
| |
| // Hide line number but show column. |
| DiagOpts.ShowLine = false; |
| EXPECT_EQ("main.cpp:2: warning: message\n", PrintDiag(DiagOpts, Loc)); |
| |
| // Show line number but hide column. |
| DiagOpts.ShowLine = true; |
| DiagOpts.ShowColumn = false; |
| EXPECT_EQ("main.cpp:1: warning: message\n", PrintDiag(DiagOpts, Loc)); |
| } |
| |
| } // anonymous namespace |