Fix issue 8897: Huge array initializations (#2135)

* Fix issue 8897: Huge array initializations

iscpp11init would take a lot of time when parsing huge arrays.
This patch add memoization to keeps track that we are parsing an array,
and allows to propagate the result without re-parsing the array for each
of its members.

* Use enum class instead of enum
This commit is contained in:
Ken-Patrick Lehrmann 2019-09-02 20:31:01 +02:00 committed by Daniel Marjamäki
parent bcc9f81a6e
commit 5c172bb55a
2 changed files with 17 additions and 0 deletions

View File

@ -117,6 +117,9 @@ struct TokenImpl {
};
struct CppcheckAttributes *mCppcheckAttributes;
// For memoization, to speed up parsing of huge arrays #8897
enum class Cpp11init {UNKNOWN, CPP11INIT, NOINIT} mCpp11init;
void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value);
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint *value) const;
@ -139,6 +142,7 @@ struct TokenImpl {
, mTemplateSimplifierPointers()
, mScopeInfo(nullptr)
, mCppcheckAttributes(nullptr)
, mCpp11init(Cpp11init::UNKNOWN)
{}
~TokenImpl();
@ -1220,6 +1224,9 @@ public:
void scopeInfo(std::shared_ptr<ScopeInfo2> newScopeInfo);
std::shared_ptr<ScopeInfo2> scopeInfo() const;
void setCpp11init(bool cpp11init) const { mImpl->mCpp11init=cpp11init ? TokenImpl::Cpp11init::CPP11INIT : TokenImpl::Cpp11init::NOINIT; }
TokenImpl::Cpp11init isCpp11init() const { return mImpl->mCpp11init; }
};
/// @}

View File

@ -540,10 +540,20 @@ static Token * findCppTypeInitPar(Token *tok)
}
// X{} X<Y>{} etc
static bool iscpp11init_impl(const Token * const tok);
static bool iscpp11init(const Token * const tok)
{
if (tok->isCpp11init() == TokenImpl::Cpp11init::UNKNOWN)
tok->setCpp11init(iscpp11init_impl(tok));
return tok->isCpp11init() == TokenImpl::Cpp11init::CPP11INIT;
}
static bool iscpp11init_impl(const Token * const tok)
{
const Token *nameToken = tok;
while (nameToken && nameToken->str() == "{") {
if(nameToken->isCpp11init() != TokenImpl::Cpp11init::UNKNOWN)
return nameToken->isCpp11init() == TokenImpl::Cpp11init::CPP11INIT;
nameToken = nameToken->previous();
if (nameToken && nameToken->str() == "," && Token::simpleMatch(nameToken->previous(), "} ,"))
nameToken = nameToken->linkAt(-1);