yvvan updated this revision to Diff 149683. yvvan added a comment. I could not properly test getMainBufferWithPrecompiledPreamble because it's private and requires some extra context to be called.
But there's another getBufferForFile call in ASTUnit which has similar symptoms and might cause wrong mmap behavior. I've also appended it with the same parameter 'UserFilesAreVolatile' and added unit-test for it. https://reviews.llvm.org/D47460 Files: include/clang/Basic/FileManager.h lib/Basic/FileManager.cpp lib/Frontend/ASTUnit.cpp unittests/Frontend/ASTUnitTest.cpp
Index: unittests/Frontend/ASTUnitTest.cpp =================================================================== --- unittests/Frontend/ASTUnitTest.cpp +++ unittests/Frontend/ASTUnitTest.cpp @@ -18,6 +18,33 @@ #include "llvm/Support/ToolOutputFile.h" #include "gtest/gtest.h" +#define CREATE_AST_UNIT(isVolatile) \ + 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, false, false, 0, TU_Complete, \ + false, false, isVolatile); + using namespace llvm; using namespace clang; @@ -38,29 +65,7 @@ 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); + CREATE_AST_UNIT(false); if (!AST) FAIL() << "failed to create ASTUnit"; @@ -84,4 +89,17 @@ EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams); } +TEST(ASTUnit, GetBufferForFileMemoryMapping) { + CREATE_AST_UNIT(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 Index: lib/Frontend/ASTUnit.cpp =================================================================== --- lib/Frontend/ASTUnit.cpp +++ lib/Frontend/ASTUnit.cpp @@ -156,7 +156,8 @@ 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 @@ -176,7 +177,7 @@ 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; } @@ -201,7 +202,7 @@ // 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; } @@ -707,7 +708,7 @@ 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) @@ -1278,7 +1279,7 @@ PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile(); std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer = getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(), - MainFilePath); + MainFilePath, UserFilesAreVolatile); if (!MainFileBuffer) return nullptr; Index: lib/Basic/FileManager.cpp =================================================================== --- lib/Basic/FileManager.cpp +++ lib/Basic/FileManager.cpp @@ -450,13 +450,13 @@ } 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, Index: include/clang/Basic/FileManager.h =================================================================== --- include/clang/Basic/FileManager.h +++ include/clang/Basic/FileManager.h @@ -239,7 +239,7 @@ 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); /// Get the 'stat' information for the given \p Path. ///
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits