summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang-c/Index.h10
-rw-r--r--clang/include/clang/Frontend/ASTUnit.h16
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp35
-rw-r--r--clang/test/Index/complete-preamble.cpp13
-rw-r--r--clang/tools/c-index-test/c-index-test.c4
-rw-r--r--clang/tools/libclang/CIndex.cpp11
-rw-r--r--clang/tools/libclang/Indexing.cpp10
7 files changed, 70 insertions, 29 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index e7ba2b26a4b..09e21608263 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -1200,7 +1200,15 @@ enum CXTranslationUnit_Flags {
* included into the set of code completions returned from this translation
* unit.
*/
- CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
+ CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80,
+
+ /**
+ * \brief Used to indicate that the precompiled preamble should be created on
+ * the first parse. Otherwise it will be created on the first reparse. This
+ * trades runtime on the first parse (serializing the preamble takes time) for
+ * reduced runtime on the second parse (can now reuse the preamble).
+ */
+ CXTranslationUnit_CreatePreambleOnFirstParse = 0x100
};
/**
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index d326a53dc2a..a5f7af57143 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -737,14 +737,15 @@ private:
/// \brief Helper function for \c LoadFromCompilerInvocation() and
/// \c LoadFromCommandLine(), which loads an AST from a compiler invocation.
///
- /// \param PrecompilePreamble Whether to precompile the preamble of this
- /// translation unit, to improve the performance of reparsing.
+ /// \param PrecompilePreambleAfterNParses After how many parses the preamble
+ /// of this translation unit should be precompiled, to improve the performance
+ /// of reparsing. Set to zero to disable preambles.
///
/// \returns \c true if a catastrophic failure occurred (which means that the
/// \c ASTUnit itself is invalid), or \c false otherwise.
bool LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- bool PrecompilePreamble);
+ unsigned PrecompilePreambleAfterNParses);
public:
@@ -783,7 +784,8 @@ public:
ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
- bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false,
+ unsigned PrecompilePreambleAfterNParses = 0,
+ bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
bool UserFilesAreVolatile = false,
std::unique_ptr<ASTUnit> *ErrAST = nullptr);
@@ -807,7 +809,8 @@ public:
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
- bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+ unsigned PrecompilePreambleAfterNParses = 0,
+ TranslationUnitKind TUKind = TU_Complete,
bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
bool UserFilesAreVolatile = false);
@@ -842,7 +845,8 @@ public:
bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
ArrayRef<RemappedFile> RemappedFiles = None,
bool RemappedFilesKeepOriginalName = true,
- bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+ unsigned PrecompilePreambleAfterNParses = 0,
+ TranslationUnitKind TUKind = TU_Complete,
bool CacheCodeCompletionResults = false,
bool IncludeBriefCommentsInCodeCompletion = false,
bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 0d5dd536589..e6ba29201f8 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -1725,9 +1725,10 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTFrontendAction *Action,
ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
- bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
- bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
- bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
+ bool OnlyLocalDecls, bool CaptureDiagnostics,
+ unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
+ bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
+ std::unique_ptr<ASTUnit> *ErrAST) {
assert(CI && "A CompilerInvocation is required");
std::unique_ptr<ASTUnit> OwnAST;
@@ -1746,8 +1747,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
}
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
- if (PrecompilePreamble)
- AST->PreambleRebuildCounter = 2;
+ if (PrecompilePreambleAfterNParses > 0)
+ AST->PreambleRebuildCounter = PrecompilePreambleAfterNParses;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
AST->IncludeBriefCommentsInCodeCompletion
@@ -1864,7 +1865,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
bool ASTUnit::LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- bool PrecompilePreamble) {
+ unsigned PrecompilePreambleAfterNParses) {
if (!Invocation)
return true;
@@ -1874,8 +1875,8 @@ bool ASTUnit::LoadFromCompilerInvocation(
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
- if (PrecompilePreamble) {
- PreambleRebuildCounter = 2;
+ if (PrecompilePreambleAfterNParses > 0) {
+ PreambleRebuildCounter = PrecompilePreambleAfterNParses;
OverrideMainBuffer =
getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
}
@@ -1894,9 +1895,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
CompilerInvocation *CI,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
- bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
- TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
- bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {
+ bool OnlyLocalDecls, bool CaptureDiagnostics,
+ unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
+ bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
+ bool UserFilesAreVolatile) {
// Create the AST unit.
std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
@@ -1919,7 +1921,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.get());
- if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble))
+ if (AST->LoadFromCompilerInvocation(PCHContainerOps,
+ PrecompilePreambleAfterNParses))
return nullptr;
return AST;
}
@@ -1930,12 +1933,11 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
bool OnlyLocalDecls, bool CaptureDiagnostics,
ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
- bool PrecompilePreamble, TranslationUnitKind TUKind,
+ unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
bool UserFilesAreVolatile, bool ForSerialization,
- llvm::Optional<StringRef> ModuleFormat,
- std::unique_ptr<ASTUnit> *ErrAST) {
+ llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST) {
assert(Diags.get() && "no DiagnosticsEngine was provided");
SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
@@ -2002,7 +2004,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
ASTUnitCleanup(AST.get());
- if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble)) {
+ if (AST->LoadFromCompilerInvocation(PCHContainerOps,
+ PrecompilePreambleAfterNParses)) {
// Some error occurred, if caller wants to examine diagnostics, pass it the
// ASTUnit.
if (ErrAST) {
diff --git a/clang/test/Index/complete-preamble.cpp b/clang/test/Index/complete-preamble.cpp
index c57c88ab330..15720f9a297 100644
--- a/clang/test/Index/complete-preamble.cpp
+++ b/clang/test/Index/complete-preamble.cpp
@@ -3,6 +3,15 @@ void f() {
std::
}
-// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:3:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
-// CHECK-CC1: {ResultType void}{TypedText wibble}{LeftParen (}{RightParen )} (50)
+// RUN: env CINDEXTEST_EDITING=1 LIBCLANG_TIMING=1 c-index-test -code-completion-at=%s:3:8 %s -o - 2>&1 | FileCheck -check-prefix=CHECK-CC1 -check-prefix=SECOND %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_CREATE_PREAMBLE_ON_FIRST_PARSE=1 LIBCLANG_TIMING=1 c-index-test -code-completion-at=%s:3:8 %s -o - 2>&1 | FileCheck -check-prefix=CHECK-CC1 -check-prefix=FIRST %s
+
+// FIRST: Precompiling preamble
+// FIRST: Parsing
+// FIRST: Reparsing
+// SECOND: Parsing
+// SECOND: Precompiling preamble
+// SECOND: Reparsing
+
+// CHECK-CC1: {ResultType void}{TypedText wibble}{LeftParen (}{RightParen )} (50)
diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c
index 948195debae..48f22eb4bbf 100644
--- a/clang/tools/c-index-test/c-index-test.c
+++ b/clang/tools/c-index-test/c-index-test.c
@@ -76,7 +76,9 @@ static unsigned getDefaultParsingOptions() {
options |= CXTranslationUnit_SkipFunctionBodies;
if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS"))
options |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
-
+ if (getenv("CINDEXTEST_CREATE_PREAMBLE_ON_FIRST_PARSE"))
+ options |= CXTranslationUnit_CreatePreambleOnFirstParse;
+
return options;
}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 768cd6a5b23..5022417d9af 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -3083,6 +3083,8 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
setThreadBackgroundPriority();
bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
+ bool CreatePreambleOnFirstParse =
+ options & CXTranslationUnit_CreatePreambleOnFirstParse;
// FIXME: Add a flag for modules.
TranslationUnitKind TUKind
= (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
@@ -3157,13 +3159,18 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
unsigned NumErrors = Diags->getClient()->getNumErrors();
std::unique_ptr<ASTUnit> ErrUnit;
+ // Unless the user specified that they want the preamble on the first parse
+ // set it up to be created on the first reparse. This makes the first parse
+ // faster, trading for a slower (first) reparse.
+ unsigned PrecompilePreambleAfterNParses =
+ !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Args->data(), Args->data() + Args->size(),
CXXIdx->getPCHContainerOperations(), Diags,
CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
/*CaptureDiagnostics=*/true, *RemappedFiles.get(),
- /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
- CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
+ /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
+ TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
/*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
/*UserFilesAreVolatile=*/true, ForSerialization,
CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index d198f404a08..5bfc4245eac 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -601,6 +601,7 @@ static CXErrorCode clang_indexSourceFile_Impl(
bool Persistent = requestedToGetTU;
bool OnlyLocalDecls = false;
bool PrecompilePreamble = false;
+ bool CreatePreambleOnFirstParse = false;
bool CacheCodeCompletionResults = false;
PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
PPOpts.AllowPCHWithCompilerErrors = true;
@@ -608,6 +609,8 @@ static CXErrorCode clang_indexSourceFile_Impl(
if (requestedToGetTU) {
OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
+ CreatePreambleOnFirstParse =
+ TU_options & CXTranslationUnit_CreatePreambleOnFirstParse;
// FIXME: Add a flag for modules.
CacheCodeCompletionResults
= TU_options & CXTranslationUnit_CacheCompletionResults;
@@ -620,11 +623,16 @@ static CXErrorCode clang_indexSourceFile_Impl(
if (!requestedToGetTU && !CInvok->getLangOpts()->Modules)
PPOpts.DetailedRecord = false;
+ // Unless the user specified that they want the preamble on the first parse
+ // set it up to be created on the first reparse. This makes the first parse
+ // faster, trading for a slower (first) reparse.
+ unsigned PrecompilePreambleAfterNParses =
+ !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
DiagnosticErrorTrap DiagTrap(*Diags);
bool Success = ASTUnit::LoadFromCompilerInvocationAction(
CInvok.get(), CXXIdx->getPCHContainerOperations(), Diags,
IndexAction.get(), Unit, Persistent, CXXIdx->getClangResourcesPath(),
- OnlyLocalDecls, CaptureDiagnostics, PrecompilePreamble,
+ OnlyLocalDecls, CaptureDiagnostics, PrecompilePreambleAfterNParses,
CacheCodeCompletionResults,
/*IncludeBriefCommentsInCodeCompletion=*/false,
/*UserFilesAreVolatile=*/true);
OpenPOWER on IntegriCloud