Commit 8edea338 authored by Milian Wolff's avatar Milian Wolff
Browse files

kdev-clang: selectively apply ForceUpdate to the requested document

When we get a parse job with the ForceUpdate flag set, we used to
apply this flag to all imports. So basically ForceUpdateRecursive
and ForceUpdate where handled in the same way, which is obviously
not a good idea.

Instead, track the document for which the parse job got created and
only apply ForceUpdate to that one.

This greatly improves the performance of reparsing after switching
git branches or using git stash: These actions would always trigger
a document reload and a parse job is created with ForceUpdate set.
Previously, this then meant that we reparsed all imports too. For
files with many imports, this was extremely slow and totally unneeded.

As an example: Editing heaptrack's accumulatedtracedata.cpp and then
applying `git stash` tackes ~34s on my machine before this patch. With
this patch, it only takes ~200ms instead.
parent ef28c644
......@@ -333,9 +333,9 @@ void ClangParseJob::run(ThreadWeaver::JobPointer /*self*/, ThreadWeaver::Thread*
return;
}
auto context
= ClangHelpers::buildDUChain(session.mainFile(), imports, session, minimumFeatures(), includedFiles,
m_unsavedRevisions, clang()->index(), [this] { return abortRequested(); });
auto context = ClangHelpers::buildDUChain(session.mainFile(), imports, session, minimumFeatures(), includedFiles,
m_unsavedRevisions, document(), clang()->index(),
[this] { return abortRequested(); });
setDuChain(context);
if (abortRequested()) {
......
......@@ -112,7 +112,8 @@ bool importLocationLessThan(const Import& lhs, const Import& rhs)
ReferencedTopDUContext ClangHelpers::buildDUChain(CXFile file, const Imports& imports, const ParseSession& session,
TopDUContext::Features features, IncludeFileContexts& includedFiles,
const UnsavedRevisions& unsavedRevisions, ClangIndex* index,
const UnsavedRevisions& unsavedRevisions,
const KDevelop::IndexedString& parseDocument, ClangIndex* index,
const std::function<bool()>& abortFunction)
{
if (includedFiles.contains(file)) {
......@@ -131,7 +132,8 @@ ReferencedTopDUContext ClangHelpers::buildDUChain(CXFile file, const Imports& im
std::sort(sortedImports.begin(), sortedImports.end(), importLocationLessThan);
for (const auto& import : qAsConst(sortedImports)) {
buildDUChain(import.file, imports, session, features, includedFiles, unsavedRevisions, index, abortFunction);
buildDUChain(import.file, imports, session, features, includedFiles, unsavedRevisions, parseDocument, index,
abortFunction);
}
const QFileInfo pathInfo(ClangString(clang_getFileName(file)).toString());
......@@ -163,14 +165,19 @@ ReferencedTopDUContext ClangHelpers::buildDUChain(CXFile file, const Imports& im
return context;
if (update) {
/* NOTE: When we are here, then either the translation unit or one of its headers was changed.
* Thus we must always update the translation unit to propagate the change(s).
* See also: https://bugs.kde.org/show_bug.cgi?id=356327
* This assumes that headers are independent, we may need to improve that in the future
* and also update header files more often when other files included therein got updated.
/*
* The features of the parse request are meant for the parseDocument.
* We don't want to apply ForceUpdate to all imports,
* except when ForceUpdateRecursive is set!
*/
if (path != environment.translationUnitUrl() && !envFile->needsUpdate(&environment)
&& envFile->featuresSatisfied(features)) {
const auto pathFeatures = [features, path, parseDocument]() {
if (path == parseDocument || features.testFlag(TopDUContext::ForceUpdateRecursive)) {
return features;
}
auto ret = features;
return ret.setFlag(TopDUContext::ForceUpdate, false);
};
if (!envFile->needsUpdate(&environment) && envFile->featuresSatisfied(pathFeatures())) {
return context;
}
......
......@@ -84,8 +84,8 @@ KDEVCLANGPRIVATE_EXPORT Imports tuImports(CXTranslationUnit tu);
KDEVCLANGPRIVATE_EXPORT KDevelop::ReferencedTopDUContext
buildDUChain(CXFile file, const Imports& imports, const ParseSession& session,
KDevelop::TopDUContext::Features features, IncludeFileContexts& includedFiles,
const UnsavedRevisions& unsavedRevisions, ClangIndex* index = nullptr,
const std::function<bool()>& abortFunction = {});
const UnsavedRevisions& unsavedRevisions, const KDevelop::IndexedString& parseDocument,
ClangIndex* index = nullptr, const std::function<bool()>& abortFunction = {});
/**
* @return List of possible header extensions used for definition/declaration fallback switching
......
......@@ -57,7 +57,7 @@ ClangPCH::ClangPCH(const ClangParsingEnvironment& environment, ClangIndex* index
}
auto imports = ClangHelpers::tuImports(m_session.unit());
m_context = ClangHelpers::buildDUChain(m_session.mainFile(), imports, m_session, pchFeatures, m_includes, {});
m_context = ClangHelpers::buildDUChain(m_session.mainFile(), imports, m_session, pchFeatures, m_includes, {}, {});
}
IncludeFileContexts ClangPCH::mapIncludes(CXTranslationUnit tu) const
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment