Index: cfe/trunk/include/clang/Basic/FileManager.h =================================================================== --- cfe/trunk/include/clang/Basic/FileManager.h +++ cfe/trunk/include/clang/Basic/FileManager.h @@ -239,7 +239,7 @@ getBufferForFile(const FileEntry *Entry, bool isVolatile = false, bool ShouldCloseOpenFile = true); llvm::ErrorOr> - getBufferForFile(StringRef Filename); + getBufferForFile(StringRef Filename, bool isVolatile = false); /// Get the 'stat' information for the given \p Path. /// Index: cfe/trunk/lib/Basic/FileManager.cpp =================================================================== --- cfe/trunk/lib/Basic/FileManager.cpp +++ cfe/trunk/lib/Basic/FileManager.cpp @@ -450,13 +450,13 @@ } llvm::ErrorOr> -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: cfe/trunk/lib/Frontend/ASTUnit.cpp =================================================================== --- cfe/trunk/lib/Frontend/ASTUnit.cpp +++ cfe/trunk/lib/Frontend/ASTUnit.cpp @@ -156,7 +156,8 @@ static std::unique_ptr 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 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 MainFileBuffer = getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(), - MainFilePath); + MainFilePath, UserFilesAreVolatile); if (!MainFileBuffer) return nullptr; Index: cfe/trunk/unittests/Frontend/ASTUnitTest.cpp =================================================================== --- cfe/trunk/unittests/Frontend/ASTUnitTest.cpp +++ cfe/trunk/unittests/Frontend/ASTUnitTest.cpp @@ -23,7 +23,41 @@ namespace { -TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) { +class ASTUnitTest : public ::testing::Test { +protected: + int FD; + llvm::SmallString<256> InputFileName; + std::unique_ptr input_file; + IntrusiveRefCntPtr Diags; + std::shared_ptr CInvok; + std::shared_ptr PCHContainerOps; + + std::unique_ptr createASTUnit(bool isVolatile) { + EXPECT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, + InputFileName)); + input_file = std::make_unique(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(); + + 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 @@ 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 Diags = - CompilerInstance::createDiagnostics(new DiagnosticOptions()); - - std::shared_ptr CInvok = - createInvocationFromCommandLine(Args, Diags); - - if (!CInvok) - FAIL() << "could not create compiler invocation"; - - FileManager *FileMgr = - new FileManager(FileSystemOptions(), vfs::getRealFileSystem()); - auto PCHContainerOps = std::make_shared(); - - std::unique_ptr AST = ASTUnit::LoadFromCompilerInvocation( - CInvok, PCHContainerOps, Diags, FileMgr); + std::unique_ptr AST = createASTUnit(false); if (!AST) FAIL() << "failed to create ASTUnit"; @@ -68,15 +80,17 @@ 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 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 @@ EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams); } +TEST_F(ASTUnitTest, GetBufferForFileMemoryMapping) { + std::unique_ptr AST = createASTUnit(true); + + if (!AST) + FAIL() << "failed to create ASTUnit"; + + std::unique_ptr memoryBuffer = + AST->getBufferForFile(InputFileName); + + EXPECT_NE(memoryBuffer->getBufferKind(), + llvm::MemoryBuffer::MemoryBuffer_MMap); +} + } // anonymous namespace