forked from OSchip/llvm-project
[Frontend] Honor UserFilesAreVolatile flag getting file buffer in ASTUnit
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 llvm-svn: 334070
This commit is contained in:
parent
cb5b004a9b
commit
2ebe3a0240
|
@ -239,7 +239,7 @@ public:
|
||||||
getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
|
getBufferForFile(const FileEntry *Entry, bool isVolatile = false,
|
||||||
bool ShouldCloseOpenFile = true);
|
bool ShouldCloseOpenFile = true);
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
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.
|
/// Get the 'stat' information for the given \p Path.
|
||||||
///
|
///
|
||||||
|
|
|
@ -450,13 +450,13 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
|
||||||
FileManager::getBufferForFile(StringRef Filename) {
|
FileManager::getBufferForFile(StringRef Filename, bool isVolatile) {
|
||||||
if (FileSystemOpts.WorkingDir.empty())
|
if (FileSystemOpts.WorkingDir.empty())
|
||||||
return FS->getBufferForFile(Filename);
|
return FS->getBufferForFile(Filename, -1, true, isVolatile);
|
||||||
|
|
||||||
SmallString<128> FilePath(Filename);
|
SmallString<128> FilePath(Filename);
|
||||||
FixupRelativePath(FilePath);
|
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,
|
/// getStatValue - Get the 'stat' information for the specified path,
|
||||||
|
|
|
@ -156,7 +156,8 @@ static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
|
||||||
static std::unique_ptr<llvm::MemoryBuffer>
|
static std::unique_ptr<llvm::MemoryBuffer>
|
||||||
getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
|
getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
|
||||||
vfs::FileSystem *VFS,
|
vfs::FileSystem *VFS,
|
||||||
StringRef FilePath) {
|
StringRef FilePath,
|
||||||
|
bool isVolatile) {
|
||||||
const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
|
const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
|
||||||
|
|
||||||
// Try to determine if the main file has been remapped, either from the
|
// 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();
|
llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
|
||||||
if (MainFileID == MID) {
|
if (MainFileID == MID) {
|
||||||
// We found a remapping. Try to load the resulting, remapped source.
|
// 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)
|
if (!BufferOwner)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +202,7 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
|
||||||
|
|
||||||
// If the main source file was not remapped, load it now.
|
// If the main source file was not remapped, load it now.
|
||||||
if (!Buffer && !BufferOwner) {
|
if (!Buffer && !BufferOwner) {
|
||||||
BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath));
|
BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));
|
||||||
if (!BufferOwner)
|
if (!BufferOwner)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -707,7 +708,7 @@ ASTDeserializationListener *ASTUnit::getDeserializationListener() {
|
||||||
std::unique_ptr<llvm::MemoryBuffer>
|
std::unique_ptr<llvm::MemoryBuffer>
|
||||||
ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
|
ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
|
||||||
assert(FileMgr);
|
assert(FileMgr);
|
||||||
auto Buffer = FileMgr->getBufferForFile(Filename);
|
auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
|
||||||
if (Buffer)
|
if (Buffer)
|
||||||
return std::move(*Buffer);
|
return std::move(*Buffer);
|
||||||
if (ErrorStr)
|
if (ErrorStr)
|
||||||
|
@ -1278,7 +1279,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
|
||||||
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
|
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
|
||||||
std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
|
std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
|
||||||
getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
|
getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
|
||||||
MainFilePath);
|
MainFilePath, UserFilesAreVolatile);
|
||||||
if (!MainFileBuffer)
|
if (!MainFileBuffer)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,41 @@ using namespace clang;
|
||||||
|
|
||||||
namespace {
|
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
|
// Check that the printing policy is restored with the correct language
|
||||||
// options when loading an ASTUnit from a file. To this end, an ASTUnit
|
// 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.
|
// 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);
|
EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FD;
|
std::unique_ptr<ASTUnit> AST = createASTUnit(false);
|
||||||
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);
|
|
||||||
|
|
||||||
if (!AST)
|
if (!AST)
|
||||||
FAIL() << "failed to create ASTUnit";
|
FAIL() << "failed to create ASTUnit";
|
||||||
|
@ -68,15 +80,17 @@ TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
|
||||||
EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
|
EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
|
||||||
|
|
||||||
llvm::SmallString<256> ASTFileName;
|
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);
|
ToolOutputFile ast_file(ASTFileName, FD);
|
||||||
AST->Save(ASTFileName.str());
|
AST->Save(ASTFileName.str());
|
||||||
|
|
||||||
EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
|
EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
|
||||||
|
|
||||||
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
|
std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
|
||||||
ASTFileName.str(), PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags,
|
ASTFileName.str(), PCHContainerOps->getRawReader(),
|
||||||
FileSystemOptions(), /*UseDebugInfo=*/false);
|
ASTUnit::LoadEverything, Diags, FileSystemOptions(),
|
||||||
|
/*UseDebugInfo=*/false);
|
||||||
|
|
||||||
if (!AU)
|
if (!AU)
|
||||||
FAIL() << "failed to load ASTUnit";
|
FAIL() << "failed to load ASTUnit";
|
||||||
|
@ -84,4 +98,17 @@ TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
|
||||||
EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
|
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
|
} // anonymous namespace
|
||||||
|
|
Loading…
Reference in New Issue