summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/LangOptions.def1
-rw-r--r--clang/include/clang/Serialization/ASTWriter.h7
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp4
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp5
-rw-r--r--clang/lib/Serialization/GeneratePCH.cpp9
-rw-r--r--clang/unittests/Frontend/FrontendActionTest.cpp40
6 files changed, 57 insertions, 9 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 7b2ab7a66fa..8a35f4ed21d 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -154,6 +154,7 @@ BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None,
"compiling a module interface")
BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch")
BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file")
+BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory")
COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses")
BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references")
COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules")
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index b0f72224700..3e287d9657f 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -570,7 +570,8 @@ public:
/// the module but currently is merely a random 32-bit number.
ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
- bool hasErrors = false);
+ bool hasErrors = false,
+ bool ShouldCacheASTInMemory = false);
/// Emit a token.
void AddToken(const Token &Tok, RecordDataImpl &Record);
@@ -974,6 +975,7 @@ class PCHGenerator : public SemaConsumer {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
bool AllowASTWithErrors;
+ bool ShouldCacheASTInMemory;
protected:
ASTWriter &getWriter() { return Writer; }
@@ -985,7 +987,8 @@ public:
StringRef OutputFile, StringRef isysroot,
std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors = false, bool IncludeTimestamps = true);
+ bool AllowASTWithErrors = false, bool IncludeTimestamps = true,
+ bool ShouldCacheASTInMemory = false);
~PCHGenerator() override;
void InitializeSema(Sema &S) override { SemaPtr = &S; }
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 5ad9a1cc036..9cb2ab2d5ee 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -112,7 +112,7 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
FrontendOpts.ModuleFileExtensions,
CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
- FrontendOpts.IncludeTimestamps));
+ FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, std::move(OS), Buffer));
@@ -176,6 +176,8 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
CI.getFrontendOpts().ModuleFileExtensions,
/*AllowASTWithErrors=*/false,
/*IncludeTimestamps=*/
+ +CI.getFrontendOpts().BuildingImplicitModule,
+ /*ShouldCacheASTInMemory=*/
+CI.getFrontendOpts().BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, std::move(OS), Buffer));
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 85bc2818395..933cc6b12c6 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4596,7 +4596,8 @@ time_t ASTWriter::getTimestampForOutput(const FileEntry *E) const {
ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
const std::string &OutputFile,
Module *WritingModule, StringRef isysroot,
- bool hasErrors) {
+ bool hasErrors,
+ bool ShouldCacheASTInMemory) {
WritingAST = true;
ASTHasCompilerErrors = hasErrors;
@@ -4620,7 +4621,7 @@ ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
this->BaseDirectory.clear();
WritingAST = false;
- if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
+ if (ShouldCacheASTInMemory) {
// Construct MemoryBuffer and update buffer manager.
ModuleCache.addBuiltPCM(OutputFile,
llvm::MemoryBuffer::getMemBufferCopy(
diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp
index 7c2ef5a13a1..6d98524636f 100644
--- a/clang/lib/Serialization/GeneratePCH.cpp
+++ b/clang/lib/Serialization/GeneratePCH.cpp
@@ -24,12 +24,14 @@ PCHGenerator::PCHGenerator(
const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile, StringRef isysroot, std::shared_ptr<PCHBuffer> Buffer,
ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
- bool AllowASTWithErrors, bool IncludeTimestamps)
+ bool AllowASTWithErrors, bool IncludeTimestamps,
+ bool ShouldCacheASTInMemory)
: PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
SemaPtr(nullptr), Buffer(std::move(Buffer)), Stream(this->Buffer->Data),
Writer(Stream, this->Buffer->Data, ModuleCache, Extensions,
IncludeTimestamps),
- AllowASTWithErrors(AllowASTWithErrors) {
+ AllowASTWithErrors(AllowASTWithErrors),
+ ShouldCacheASTInMemory(ShouldCacheASTInMemory) {
this->Buffer->IsComplete = false;
}
@@ -61,7 +63,8 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) {
Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot,
// For serialization we are lenient if the errors were
// only warn-as-error kind.
- PP.getDiagnostics().hasUncompilableErrorOccurred());
+ PP.getDiagnostics().hasUncompilableErrorOccurred(),
+ ShouldCacheASTInMemory);
Buffer->IsComplete = true;
}
diff --git a/clang/unittests/Frontend/FrontendActionTest.cpp b/clang/unittests/Frontend/FrontendActionTest.cpp
index 0203fe4ce2b..20356c6d833 100644
--- a/clang/unittests/Frontend/FrontendActionTest.cpp
+++ b/clang/unittests/Frontend/FrontendActionTest.cpp
@@ -6,18 +6,20 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Frontend/FrontendAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Sema/Sema.h"
+#include "clang/Serialization/InMemoryModuleCache.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -253,4 +255,40 @@ TEST(ASTFrontendAction, ExternalSemaSource) {
EXPECT_EQ("This is a note", TDC->Note.str().str());
}
+TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
+ // Create a temporary file for writing out the PCH that will be cleaned up.
+ int PCHFD;
+ llvm::SmallString<128> PCHFilename;
+ ASSERT_FALSE(
+ llvm::sys::fs::createTemporaryFile("test.h", "pch", PCHFD, PCHFilename));
+ llvm::ToolOutputFile PCHFile(PCHFilename, PCHFD);
+
+ for (bool ShouldCache : {false, true}) {
+ auto Invocation = std::make_shared<CompilerInvocation>();
+ Invocation->getLangOpts()->CacheGeneratedPCH = ShouldCache;
+ Invocation->getPreprocessorOpts().addRemappedFile(
+ "test.h",
+ MemoryBuffer::getMemBuffer("int foo(void) { return 1; }\n").release());
+ Invocation->getFrontendOpts().Inputs.push_back(
+ FrontendInputFile("test.h", InputKind::C));
+ Invocation->getFrontendOpts().OutputFile = StringRef(PCHFilename);
+ Invocation->getFrontendOpts().ProgramAction = frontend::GeneratePCH;
+ Invocation->getTargetOpts().Triple = "x86_64-apple-darwin19.0.0";
+ CompilerInstance Compiler;
+ Compiler.setInvocation(std::move(Invocation));
+ Compiler.createDiagnostics();
+
+ GeneratePCHAction TestAction;
+ ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
+
+ // Check whether the PCH was cached.
+ if (ShouldCache)
+ EXPECT_EQ(InMemoryModuleCache::Final,
+ Compiler.getModuleCache().getPCMState(PCHFilename));
+ else
+ EXPECT_EQ(InMemoryModuleCache::Unknown,
+ Compiler.getModuleCache().getPCMState(PCHFilename));
+ }
+}
+
} // anonymous namespace
OpenPOWER on IntegriCloud