summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-30 14:00:57 +0200
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-06-08 06:02:55 +0000
commit74dff2b4165421e67427db09f02d6a52ae1fa96d (patch)
tree2e8fd73c7b94e1859da9f8abb4c72273113bed2c
parent12ff64e073489179762152cef695b795eb2fcb16 (diff)
[backported/clang-7][Frontend] Honor UserFilesAreVolatile flag getting file buffer in ASTUnit
-------------------------------------------------------------------------- * https://reviews.llvm.org/D47460 -------------------------------------------------------------------------- Do not memory map the main file if the flag UserFilesAreVolatile is set to true in ASTUnit when calling FileSystem::getBufferForFile. Task-number: QTCREATORBUG-15449 Change-Id: I283d684f4c1ca38a4689ce09bd594700678679c1 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
-rw-r--r--include/clang/Basic/FileManager.h2
-rw-r--r--lib/Basic/FileManager.cpp6
-rw-r--r--lib/Frontend/ASTUnit.cpp13
-rw-r--r--unittests/Frontend/ASTUnitTest.cpp81
4 files changed, 66 insertions, 36 deletions
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index b817dd20c3..4e939f3eed 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -239,7 +239,7 @@ public:
getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
bool ShouldCloseOpenFile = true);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- getBufferForFile(StringRef Filename);
+ getBufferForFile(StringRef Filename, bool isVolatile = false);
/// \brief Get the 'stat' information for the given \p Path.
///
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index a3e226d6cc..c1b9693ee8 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -450,13 +450,13 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(StringRef Filename) {
+FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
if (FileSystemOpts.WorkingDir.empty())
- return FS->getBufferForFile(Filename);
+ return FS->getBufferForFile(Filename, -1, true, isVolatile);
SmallString<128> FilePath(Filename);
FixupRelativePath(FilePath);
- return FS->getBufferForFile(FilePath.c_str());
+ return FS->getBufferForFile(FilePath.c_str(), -1, true, isVolatile);
}
/// getStatValue - Get the 'stat' information for the specified path,
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index c334e3e6db..1ec4502ba5 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -100,7 +100,8 @@ namespace {
static std::unique_ptr<llvm::MemoryBuffer>
getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
vfs::FileSystem *VFS,
- StringRef FilePath) {
+ StringRef FilePath,
+ bool isVolatile) {
const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
// Try to determine if the main file has been remapped, either from the
@@ -120,7 +121,8 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
if (MainFileID == MID) {
// We found a remapping. Try to load the resulting, remapped source.
- BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second));
+ BufferOwner = valueOrNull(
+ VFS->getBufferForFile(RF.second, -1, true, isVolatile));
if (!BufferOwner)
return nullptr;
}
@@ -145,7 +147,8 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
// If the main source file was not remapped, load it now.
if (!Buffer && !BufferOwner) {
- BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath));
+ BufferOwner =
+ valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));
if (!BufferOwner)
return nullptr;
}
@@ -664,7 +667,7 @@ ASTDeserializationListener *ASTUnit::getDeserializationListener() {
std::unique_ptr<llvm::MemoryBuffer>
ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
assert(FileMgr);
- auto Buffer = FileMgr->getBufferForFile(Filename);
+ auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
if (Buffer)
return std::move(*Buffer);
if (ErrorStr)
@@ -1231,7 +1234,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
- MainFilePath);
+ MainFilePath, UserFilesAreVolatile);
if (!MainFileBuffer)
return nullptr;
diff --git a/unittests/Frontend/ASTUnitTest.cpp b/unittests/Frontend/ASTUnitTest.cpp
index 4f529cf55d..c60004e40b 100644
--- a/unittests/Frontend/ASTUnitTest.cpp
+++ b/unittests/Frontend/ASTUnitTest.cpp
@@ -23,7 +23,41 @@ using namespace clang;
namespace {
-TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
+class ASTUnitTest : public ::testing::Test {
+protected:
+ int FD;
+ llvm::SmallString<256> InputFileName;
+ std::unique_ptr<ToolOutputFile> input_file;
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+ std::shared_ptr<CompilerInvocation> CInvok;
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps;
+
+ std::unique_ptr<ASTUnit> createASTUnit(bool isVolatile) {
+ EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD,
+ InputFileName));
+ input_file = llvm::make_unique<ToolOutputFile>(InputFileName, FD);
+ input_file->os() << "";
+
+ const char *Args[] = {"clang", "-xc++", InputFileName.c_str()};
+
+ Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
+
+ CInvok = createInvocationFromCommandLine(Args, Diags);
+
+ if (!CInvok)
+ return nullptr;
+
+ FileManager *FileMgr =
+ new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
+ PCHContainerOps = std::make_shared<PCHContainerOperations>();
+
+ return ASTUnit::LoadFromCompilerInvocation(
+ CInvok, PCHContainerOps, Diags, FileMgr, false, false, 0, TU_Complete,
+ false, false, isVolatile);
+ }
+};
+
+TEST_F(ASTUnitTest, SaveLoadPreservesLangOptionsInPrintingPolicy) {
// Check that the printing policy is restored with the correct language
// options when loading an ASTUnit from a file. To this end, an ASTUnit
// for a C++ translation unit is set up and written to a temporary file.
@@ -38,29 +72,7 @@ TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
}
- int FD;
- llvm::SmallString<256> InputFileName;
- ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, InputFileName));
- ToolOutputFile input_file(InputFileName, FD);
- input_file.os() << "";
-
- const char* Args[] = {"clang", "-xc++", InputFileName.c_str()};
-
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
- CompilerInstance::createDiagnostics(new DiagnosticOptions());
-
- std::shared_ptr<CompilerInvocation> CInvok =
- createInvocationFromCommandLine(Args, Diags);
-
- if (!CInvok)
- FAIL() << "could not create compiler invocation";
-
- FileManager *FileMgr =
- new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
- auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
-
- std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
- CInvok, PCHContainerOps, Diags, FileMgr);
+ std::unique_ptr<ASTUnit> AST = createASTUnit(false);
if (!AST)
FAIL() << "failed to create ASTUnit";
@@ -68,15 +80,17 @@ TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
llvm::SmallString<256> ASTFileName;
- ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName));
+ ASSERT_FALSE(
+ llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName));
ToolOutputFile ast_file(ASTFileName, FD);
AST->Save(ASTFileName.str());
EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
- ASTFileName.str(), PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags,
- FileSystemOptions(), /*UseDebugInfo=*/false);
+ ASTFileName.str(), PCHContainerOps->getRawReader(),
+ ASTUnit::LoadEverything, Diags, FileSystemOptions(),
+ /*UseDebugInfo=*/false);
if (!AU)
FAIL() << "failed to load ASTUnit";
@@ -84,4 +98,17 @@ TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
}
+TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) {
+ std::unique_ptr<ASTUnit> AST = createASTUnit(true);
+
+ if (!AST)
+ FAIL() << "failed to create ASTUnit";
+
+ std::unique_ptr<llvm::MemoryBuffer> memoryBuffer =
+ AST->getBufferForFile(InputFileName);
+
+ EXPECT_NE(memoryBuffer->getBufferKind(),
+ llvm::MemoryBuffer::MemoryBuffer_MMap);
+}
+
} // anonymous namespace