]> granicus.if.org Git - clang/commitdiff
[Frontend] Honor UserFilesAreVolatile flag getting file buffer in ASTUnit
authorIvan Donchevskii <ivan.donchevskii@qt.io>
Wed, 6 Jun 2018 07:17:26 +0000 (07:17 +0000)
committerIvan Donchevskii <ivan.donchevskii@qt.io>
Wed, 6 Jun 2018 07:17:26 +0000 (07:17 +0000)
Do not memory map the main file if the flag UserFilesAreVolatile is set to true
in ASTUnit when calling FileSystem::getBufferForFile.

Differential Revision: https://reviews.llvm.org/D47460

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334070 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/FileManager.h
lib/Basic/FileManager.cpp
lib/Frontend/ASTUnit.cpp
unittests/Frontend/ASTUnitTest.cpp

index ea0ed39a8a01cd7b7853e3d00a660dd259fff9d9..ab5dfca71639737e02f843d00b17b3656d9370db 100644 (file)
@@ -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);
 
   /// Get the 'stat' information for the given \p Path.
   ///
index 5cbcdf4477e1bc777eaf86085213261fbbda03b4..7e2d01c4981d81ea12cc0410d712f07f8036eb6b 100644 (file)
@@ -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,
index e0e8e8b22aca5b9deaa4c4c9546af0804381ccb2..d7bbf6fe4aef06298333066f1bca78c9691a56b8 100644 (file)
@@ -156,7 +156,8 @@ static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
 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 @@ 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;
         }
@@ -201,7 +202,7 @@ 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;
   }
@@ -707,7 +708,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)
@@ -1278,7 +1279,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;
 
index 4f529cf55de980d5b0b7cabb81803c81943ba363..5296fc51f844adddb3b2aafc69a4026f596cf739 100644 (file)
@@ -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 = std::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