
Starting with 41e3919ded78d8870f7c95e9181c7f7e29aa3cc4 DiagnosticsEngine creation might perform IO. It was implicitly defaulting to getRealFileSystem. This patch makes it explicit by pushing the decision making to callers. It uses ambient VFS if one is available, and keeps using `getRealFileSystem` if there aren't any VFS.
119 lines
4.0 KiB
C++
119 lines
4.0 KiB
C++
//====-- unittests/Frontend/ReparseWorkingDirTest.cpp - FrontendAction tests =//
|
|
//
|
|
// 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/Basic/Diagnostic.h"
|
|
#include "clang/Basic/FileManager.h"
|
|
#include "clang/Frontend/ASTUnit.h"
|
|
#include "clang/Frontend/CompilerInstance.h"
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
|
#include "clang/Frontend/FrontendActions.h"
|
|
#include "clang/Frontend/FrontendOptions.h"
|
|
#include "clang/Lex/PreprocessorOptions.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
using namespace clang;
|
|
|
|
namespace {
|
|
class ReparseWorkingDirTest : public ::testing::Test {
|
|
IntrusiveRefCntPtr<vfs::InMemoryFileSystem> VFS;
|
|
std::shared_ptr<PCHContainerOperations> PCHContainerOpts;
|
|
|
|
public:
|
|
void SetUp() override { VFS = new vfs::InMemoryFileSystem(); }
|
|
void TearDown() override {}
|
|
|
|
void setWorkingDirectory(StringRef Path) {
|
|
VFS->setCurrentWorkingDirectory(Path);
|
|
}
|
|
|
|
void AddFile(const std::string &Filename, const std::string &Contents) {
|
|
::time_t now;
|
|
::time(&now);
|
|
VFS->addFile(Filename, now,
|
|
MemoryBuffer::getMemBufferCopy(Contents, Filename));
|
|
}
|
|
|
|
std::unique_ptr<ASTUnit> ParseAST(StringRef EntryFile) {
|
|
PCHContainerOpts = std::make_shared<PCHContainerOperations>();
|
|
auto CI = std::make_shared<CompilerInvocation>();
|
|
CI->getFrontendOpts().Inputs.push_back(FrontendInputFile(
|
|
EntryFile, FrontendOptions::getInputKindForExtension(
|
|
llvm::sys::path::extension(EntryFile).substr(1))));
|
|
|
|
CI->getHeaderSearchOpts().AddPath("headers",
|
|
frontend::IncludeDirGroup::Quoted,
|
|
/*isFramework*/ false,
|
|
/*IgnoreSysRoot*/ false);
|
|
|
|
CI->getFileSystemOpts().WorkingDir = *VFS->getCurrentWorkingDirectory();
|
|
CI->getTargetOpts().Triple = "i386-unknown-linux-gnu";
|
|
|
|
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
|
|
CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions,
|
|
new DiagnosticConsumer));
|
|
|
|
FileManager *FileMgr = new FileManager(CI->getFileSystemOpts(), VFS);
|
|
|
|
std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
|
|
CI, PCHContainerOpts, Diags, FileMgr, false, CaptureDiagsKind::None,
|
|
/*PrecompilePreambleAfterNParses=*/1);
|
|
return AST;
|
|
}
|
|
|
|
bool ReparseAST(const std::unique_ptr<ASTUnit> &AST) {
|
|
bool reparseFailed =
|
|
AST->Reparse(PCHContainerOpts, /*RemappedFiles*/ {}, VFS);
|
|
return !reparseFailed;
|
|
}
|
|
};
|
|
|
|
TEST_F(ReparseWorkingDirTest, ReparseWorkingDir) {
|
|
// Setup the working directory path.
|
|
SmallString<16> WorkingDir;
|
|
#ifdef _WIN32
|
|
WorkingDir = "C:\\";
|
|
#else
|
|
WorkingDir = "/";
|
|
#endif
|
|
llvm::sys::path::append(WorkingDir, "root");
|
|
setWorkingDirectory(WorkingDir);
|
|
|
|
SmallString<32> Header;
|
|
llvm::sys::path::append(Header, WorkingDir, "headers", "header.h");
|
|
|
|
SmallString<32> MainName;
|
|
llvm::sys::path::append(MainName, WorkingDir, "main.cpp");
|
|
|
|
AddFile(MainName.str().str(), R"cpp(
|
|
#include "header.h"
|
|
int main() { return foo(); }
|
|
)cpp");
|
|
AddFile(Header.str().str(), R"h(
|
|
static int foo() { return 0; }
|
|
)h");
|
|
|
|
// Parse the main file, ensuring we can include the header.
|
|
std::unique_ptr<ASTUnit> AST(ParseAST(MainName.str()));
|
|
ASSERT_TRUE(AST.get());
|
|
ASSERT_FALSE(AST->getDiagnostics().hasErrorOccurred());
|
|
|
|
// Reparse and check that the working directory was preserved.
|
|
ASSERT_TRUE(ReparseAST(AST));
|
|
|
|
const auto &FM = AST->getFileManager();
|
|
const auto &FS = FM.getVirtualFileSystem();
|
|
ASSERT_EQ(FM.getFileSystemOpts().WorkingDir, WorkingDir);
|
|
ASSERT_EQ(*FS.getCurrentWorkingDirectory(), WorkingDir);
|
|
}
|
|
|
|
} // end anonymous namespace
|