diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-05-30 14:00:57 +0200 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-06-08 06:02:55 +0000 |
commit | 74dff2b4165421e67427db09f02d6a52ae1fa96d (patch) | |
tree | 2e8fd73c7b94e1859da9f8abb4c72273113bed2c | |
parent | 12ff64e073489179762152cef695b795eb2fcb16 (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.h | 2 | ||||
-rw-r--r-- | lib/Basic/FileManager.cpp | 6 | ||||
-rw-r--r-- | lib/Frontend/ASTUnit.cpp | 13 | ||||
-rw-r--r-- | unittests/Frontend/ASTUnitTest.cpp | 81 |
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 |