Clang: Optimize clang overview model

Build the tree in only one loop.

clangbackend generates tokens almost as fast as it
did before (about 10% slower in general).
Broken documents are more affected and take much more
time (about 300%) but it's better to have this time spent
on backend side then in QtC itself.

Task-number: QTCREATORBUG-20205
Change-Id: I34c58bca30c4494005a029abd82c7e612ecd6fb9
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Ivan Donchevskii
2018-04-06 14:24:28 +02:00
parent 5de5794c49
commit f9d95c9205
6 changed files with 114 additions and 81 deletions

View File

@@ -29,6 +29,8 @@
#include "tokenprocessoriterator.h"
#include "tokeninfocontainer.h"
#include <utils/algorithm.h>
#include <clang-c/Index.h>
#include <QVector>
@@ -102,21 +104,7 @@ public:
QVector<TokenInfoContainer> toTokenInfoContainers() const
{
QVector<TokenInfoContainer> containers;
containers.reserve(size());
const auto isValidTokenInfo = [] (const T &tokenInfo) {
return !tokenInfo.hasInvalidMainType()
&& !tokenInfo.hasMainType(HighlightingType::NumberLiteral)
&& !tokenInfo.hasMainType(HighlightingType::Comment);
};
for (size_t index = 0; index < cxCursors.size(); ++index) {
T tokenInfo = (*this)[index];
if (isValidTokenInfo(tokenInfo))
containers.push_back(tokenInfo);
}
return containers;
return toTokens<TokenInfoContainer>();
}
bool currentOutputArgumentRangesAreEmpty() const
@@ -125,6 +113,27 @@ public:
}
private:
template<class TC>
QVector<TC> toTokens() const
{
QVector<TC> tokens;
tokens.reserve(size());
const auto isValidTokenInfo = [](const T &tokenInfo) {
return !tokenInfo.hasInvalidMainType()
&& !tokenInfo.hasMainType(HighlightingType::NumberLiteral)
&& !tokenInfo.hasMainType(HighlightingType::Comment);
};
for (size_t index = 0; index < cxCursors.size(); ++index) {
T tokenInfo = (*this)[index];
if (isValidTokenInfo(tokenInfo))
tokens.push_back(tokenInfo);
}
return tokens;
}
mutable std::vector<CXSourceRange> currentOutputArgumentRanges;
CXTranslationUnit cxTranslationUnit = nullptr;
CXToken *cxTokens = nullptr;
@@ -132,4 +141,29 @@ private:
std::vector<CXCursor> cxCursors;
};
template <>
inline
QVector<TokenInfoContainer> TokenProcessor<FullTokenInfo>::toTokenInfoContainers() const
{
QVector<FullTokenInfo> tokens = toTokens<FullTokenInfo>();
return Utils::transform(tokens,
[&tokens](FullTokenInfo &token) -> TokenInfoContainer {
if (!token.m_extraInfo.declaration || token.hasMainType(HighlightingType::LocalVariable))
return token;
const int index = tokens.indexOf(token);
const SourceLocationContainer &tokenStart = token.m_extraInfo.cursorRange.start;
for (auto it = tokens.rend() - index; it != tokens.rend(); ++it) {
if (it->m_extraInfo.declaration && !it->hasMainType(HighlightingType::LocalVariable)
&& it->m_originalCursor != token.m_originalCursor
&& it->m_extraInfo.cursorRange.contains(tokenStart)) {
token.m_extraInfo.lexicalParentIndex = std::distance(it, tokens.rend()) - 1;
break;
}
}
return token;
});
}
} // namespace ClangBackEnd