llvm-capstone/clang/unittests/Frontend/TextDiagnosticTest.cpp
Jan Svoboda d0262c2394 [llvm] Add null-termination capability to SmallVectorMemoryBuffer
Most of `MemoryBuffer` interfaces expose a `RequiresNullTerminator` parameter that's being used to:
* determine how to open a file (`mmap` vs `open`),
* assert newly initialized buffer indeed has an implicit null terminator.

This patch adds the paramater to the `SmallVectorMemoryBuffer` constructors, meaning:
* null terminator can now be added to `SmallVector`s that didn't have one before,
* `SmallVectors` that had a null terminator before keep it even after the move.

In line with existing code, the new parameter is defaulted to `true`. This patch makes sure all calls to the `SmallVectorMemoryBuffer` constructor set it to `false` to preserve the current semantics.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D115331
2021-12-09 11:32:13 +01:00

101 lines
3.8 KiB
C++

//===- 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, /*RequiresNullTerminator=*/false);
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