summaryrefslogtreecommitdiff
path: root/unittests/Frontend
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2019-05-21 07:26:59 +0000
committerNikolai Kosjar <nikolai.kosjar@qt.io>2019-05-21 07:26:59 +0000
commit29994b0c63a40f9c97c664170244a7bba5ecc15e (patch)
tree6154685cce6c7714d89cf77e889d58539fdf8348 /unittests/Frontend
parentcc6493e85b03bc13560dfa6de1cd609b9ba7b4ec (diff)
downloadclang-29994b0c63a40f9c97c664170244a7bba5ecc15e.tar.gz
[Preamble] Reuse preamble even if an unsaved file does not exist
When a preamble is created an unsaved file not existing on disk is already part of PrecompiledPreamble::FilesInPreamble. However, when checking whether the preamble can be re-used, a failed stat of such an unsaved file invalidated the preamble, which led to pointless and time consuming preamble regenerations on subsequent reparses. Do not require anymore that unsaved files should exist on disk. This avoids costly preamble invalidations depending on timing issues for the cases where the file on disk might be removed just to be regenerated a bit later. It also allows an IDE to provide in-memory files that might not exist on disk, e.g. because the build system hasn't generated those yet. Differential Revision: https://reviews.llvm.org/D41005 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361226 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Frontend')
-rw-r--r--unittests/Frontend/PCHPreambleTest.cpp74
1 files changed, 70 insertions, 4 deletions
diff --git a/unittests/Frontend/PCHPreambleTest.cpp b/unittests/Frontend/PCHPreambleTest.cpp
index 70567405f1..0dc567efaa 100644
--- a/unittests/Frontend/PCHPreambleTest.cpp
+++ b/unittests/Frontend/PCHPreambleTest.cpp
@@ -52,7 +52,10 @@ class PCHPreambleTest : public ::testing::Test {
FileSystemOptions FSOpts;
public:
- void SetUp() override {
+ void SetUp() override { ResetVFS(); }
+ void TearDown() override {}
+
+ void ResetVFS() {
VFS = new ReadCountingInMemoryFileSystem();
// We need the working directory to be set to something absolute,
// otherwise it ends up being inadvertently set to the current
@@ -63,9 +66,6 @@ public:
VFS->setCurrentWorkingDirectory("//./");
}
- void TearDown() override {
- }
-
void AddFile(const std::string &Filename, const std::string &Contents) {
::time_t now;
::time(&now);
@@ -123,6 +123,72 @@ private:
}
};
+TEST_F(PCHPreambleTest, ReparseReusesPreambleWithUnsavedFileNotExistingOnDisk) {
+ std::string Header1 = "//./header1.h";
+ std::string MainName = "//./main.cpp";
+ AddFile(MainName, R"cpp(
+#include "//./header1.h"
+int main() { return ZERO; }
+)cpp");
+ RemapFile(Header1, "#define ZERO 0\n");
+
+ // Parse with header file provided as unsaved file, which does not exist on
+ // disk.
+ std::unique_ptr<ASTUnit> AST(ParseAST(MainName));
+ ASSERT_TRUE(AST.get());
+ ASSERT_FALSE(AST->getDiagnostics().hasErrorOccurred());
+
+ // Reparse and check that the preamble was reused.
+ ASSERT_TRUE(ReparseAST(AST));
+ ASSERT_EQ(AST->getPreambleCounterForTests(), 1U);
+}
+
+TEST_F(PCHPreambleTest, ReparseReusesPreambleAfterUnsavedFileWasCreatedOnDisk) {
+ std::string Header1 = "//./header1.h";
+ std::string MainName = "//./main.cpp";
+ AddFile(MainName, R"cpp(
+#include "//./header1.h"
+int main() { return ZERO; }
+)cpp");
+ RemapFile(Header1, "#define ZERO 0\n");
+
+ // Parse with header file provided as unsaved file, which does not exist on
+ // disk.
+ std::unique_ptr<ASTUnit> AST(ParseAST(MainName));
+ ASSERT_TRUE(AST.get());
+ ASSERT_FALSE(AST->getDiagnostics().hasErrorOccurred());
+
+ // Create the unsaved file also on disk and check that preamble was reused.
+ AddFile(Header1, "#define ZERO 0\n");
+ ASSERT_TRUE(ReparseAST(AST));
+ ASSERT_EQ(AST->getPreambleCounterForTests(), 1U);
+}
+
+TEST_F(PCHPreambleTest,
+ ReparseReusesPreambleAfterUnsavedFileWasRemovedFromDisk) {
+ std::string Header1 = "//./foo/header1.h";
+ std::string MainName = "//./main.cpp";
+ std::string MainFileContent = R"cpp(
+#include "//./foo/header1.h"
+int main() { return ZERO; }
+)cpp";
+ AddFile(MainName, MainFileContent);
+ AddFile(Header1, "#define ZERO 0\n");
+ RemapFile(Header1, "#define ZERO 0\n");
+
+ // Parse with header file provided as unsaved file, which exists on disk.
+ std::unique_ptr<ASTUnit> AST(ParseAST(MainName));
+ ASSERT_TRUE(AST.get());
+ ASSERT_FALSE(AST->getDiagnostics().hasErrorOccurred());
+ ASSERT_EQ(AST->getPreambleCounterForTests(), 1U);
+
+ // Remove the unsaved file from disk and check that the preamble was reused.
+ ResetVFS();
+ AddFile(MainName, MainFileContent);
+ ASSERT_TRUE(ReparseAST(AST));
+ ASSERT_EQ(AST->getPreambleCounterForTests(), 1U);
+}
+
TEST_F(PCHPreambleTest, ReparseWithOverriddenFileDoesNotInvalidatePreamble) {
std::string Header1 = "//./header1.h";
std::string Header2 = "//./header2.h";