Skip to content

Commit 7abfca5

Browse files
committed
introduced a cache for followAllReferences() calls with default parameters
1 parent f78e5a7 commit 7abfca5

File tree

8 files changed

+81
-65
lines changed

8 files changed

+81
-65
lines changed

Makefile

Lines changed: 32 additions & 32 deletions
Large diffs are not rendered by default.

lib/astutils.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ bool isAliasOf(const Token* tok, const Token* expr, int* indirect)
10641064
const Token* r = nullptr;
10651065
if (indirect)
10661066
*indirect = 1;
1067-
for (const ReferenceToken& ref : followAllReferences(tok)) {
1067+
for (const ReferenceToken& ref : tok->refs()) {
10681068
const bool pointer = astIsPointer(ref.token);
10691069
r = findAstNode(expr, [&](const Token* childTok) {
10701070
if (childTok->exprId() == 0)
@@ -1242,11 +1242,11 @@ static void followVariableExpressionError(const Token *tok1, const Token *tok2,
12421242
errors->push_back(std::move(item));
12431243
}
12441244

1245-
SmallVector<ReferenceToken> followAllReferences(const Token* tok,
1246-
bool temporary,
1247-
bool inconclusive,
1248-
ErrorPath errors,
1249-
int depth)
1245+
static SmallVector<ReferenceToken> followAllReferencesInternal(const Token* tok,
1246+
bool temporary = true,
1247+
bool inconclusive = true,
1248+
ErrorPath errors = ErrorPath{},
1249+
int depth = 20)
12501250
{
12511251
struct ReferenceTokenLess {
12521252
bool operator()(const ReferenceToken& x, const ReferenceToken& y) const {
@@ -1292,16 +1292,16 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
12921292
return refs_result;
12931293
}
12941294
if (vartok)
1295-
return followAllReferences(vartok, temporary, inconclusive, std::move(errors), depth - 1);
1295+
return followAllReferencesInternal(vartok, temporary, inconclusive, std::move(errors), depth - 1);
12961296
}
12971297
}
12981298
} else if (Token::simpleMatch(tok, "?") && Token::simpleMatch(tok->astOperand2(), ":")) {
12991299
std::set<ReferenceToken, ReferenceTokenLess> result;
13001300
const Token* tok2 = tok->astOperand2();
13011301

1302-
auto refs = followAllReferences(tok2->astOperand1(), temporary, inconclusive, errors, depth - 1);
1302+
auto refs = followAllReferencesInternal(tok2->astOperand1(), temporary, inconclusive, errors, depth - 1);
13031303
result.insert(refs.cbegin(), refs.cend());
1304-
refs = followAllReferences(tok2->astOperand2(), temporary, inconclusive, errors, depth - 1);
1304+
refs = followAllReferencesInternal(tok2->astOperand2(), temporary, inconclusive, errors, depth - 1);
13051305
result.insert(refs.cbegin(), refs.cend());
13061306

13071307
if (!inconclusive && result.size() != 1) {
@@ -1329,7 +1329,7 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
13291329
if (returnTok == tok)
13301330
continue;
13311331
for (const ReferenceToken& rt :
1332-
followAllReferences(returnTok, temporary, inconclusive, errors, depth - returns.size())) {
1332+
followAllReferencesInternal(returnTok, temporary, inconclusive, errors, depth - returns.size())) {
13331333
const Variable* argvar = rt.token->variable();
13341334
if (!argvar) {
13351335
SmallVector<ReferenceToken> refs_result;
@@ -1354,7 +1354,7 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
13541354
er.emplace_back(returnTok, "Return reference.");
13551355
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
13561356
auto refs =
1357-
followAllReferences(argTok, temporary, inconclusive, std::move(er), depth - returns.size());
1357+
followAllReferencesInternal(argTok, temporary, inconclusive, std::move(er), depth - returns.size());
13581358
result.insert(refs.cbegin(), refs.cend());
13591359
if (!inconclusive && result.size() > 1) {
13601360
SmallVector<ReferenceToken> refs_result;
@@ -1375,11 +1375,16 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
13751375
return refs_result;
13761376
}
13771377

1378+
SmallVector<ReferenceToken> followAllReferences(const Token* tok, bool temporary)
1379+
{
1380+
return followAllReferencesInternal(tok, temporary);
1381+
}
1382+
13781383
const Token* followReferences(const Token* tok, ErrorPath* errors)
13791384
{
13801385
if (!tok)
13811386
return nullptr;
1382-
auto refs = followAllReferences(tok, true, false);
1387+
auto refs = followAllReferencesInternal(tok, true, false);
13831388
if (refs.size() == 1) {
13841389
if (errors)
13851390
*errors = std::move(refs.front().errors);

lib/astutils.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,7 @@ struct ReferenceToken {
253253
ErrorPath errors;
254254
};
255255

256-
SmallVector<ReferenceToken> followAllReferences(const Token* tok,
257-
bool temporary = true,
258-
bool inconclusive = true,
259-
ErrorPath errors = ErrorPath{},
260-
int depth = 20);
256+
SmallVector<ReferenceToken> followAllReferences(const Token* tok, bool temporary = true);
261257
const Token* followReferences(const Token* tok, ErrorPath* errors = nullptr);
262258

263259
CPPCHECKLIB bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Settings& settings, bool pure, bool followVar, ErrorPath* errors=nullptr);

lib/token.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,7 @@ TokenImpl::~TokenImpl()
26292629
delete mOriginalName;
26302630
delete mValueType;
26312631
delete mValues;
2632+
delete mRefs;
26322633

26332634
if (mTemplateSimplifierPointers) {
26342635
for (auto *templateSimplifierPointer : *mTemplateSimplifierPointers) {
@@ -2717,3 +2718,10 @@ const Token* findLambdaEndScope(const Token* tok) {
27172718
const std::string& Token::fileName() const {
27182719
return mTokensFrontBack.list.getFiles()[mImpl->mFileIndex];
27192720
}
2721+
2722+
const SmallVector<ReferenceToken>& Token::refs() const
2723+
{
2724+
if (!mImpl->mRefs)
2725+
mImpl->mRefs = new SmallVector<ReferenceToken>(followAllReferences(this));
2726+
return *mImpl->mRefs;
2727+
}

lib/token.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "config.h"
2525
#include "errortypes.h"
2626
#include "mathlib.h"
27+
#include "smallvector.h"
2728
#include "templatesimplifier.h"
2829
#include "utils.h"
2930
#include "vfvalue.h"
@@ -52,6 +53,7 @@ class Variable;
5253
class ConstTokenRange;
5354
class Token;
5455
struct TokensFrontBack;
56+
struct ReferenceToken;
5557

5658
struct ScopeInfo2 {
5759
ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set<std::string> usingNamespaces_ = std::set<std::string>()) : name(std::move(name_)), bodyEnd(bodyEnd_), usingNamespaces(std::move(usingNamespaces_)) {}
@@ -143,6 +145,8 @@ struct TokenImpl {
143145
void setCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint value);
144146
bool getCppcheckAttribute(CppcheckAttributes::Type type, MathLib::bigint &value) const;
145147

148+
SmallVector<ReferenceToken>* mRefs{};
149+
146150
TokenImpl() : mFunction(nullptr) {}
147151

148152
~TokenImpl();
@@ -1286,6 +1290,9 @@ class CPPCHECKLIB Token {
12861290
return mImpl->mValues ? *mImpl->mValues : TokenImpl::mEmptyValueList;
12871291
}
12881292

1293+
// provides and caches result of a followAllReferences() call with default parameters
1294+
const SmallVector<ReferenceToken>& refs() const;
1295+
12891296
/**
12901297
* Sets the original name.
12911298
*/

lib/valueflow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3918,7 +3918,7 @@ static void valueFlowForwardConst(Token* start,
39183918
} else {
39193919
[&] {
39203920
// Follow references
3921-
auto refs = followAllReferences(tok);
3921+
const auto& refs = tok->refs();
39223922
auto it = std::find_if(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) {
39233923
return ref.token->varId() == var->declarationId();
39243924
});

lib/vf_analyzers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ struct ValueFlowAnalyzer : Analyzer {
630630
if (invalid())
631631
return Action::Invalid;
632632
// Follow references
633-
auto refs = followAllReferences(tok);
633+
auto refs = tok->refs();
634634
const bool inconclusiveRefs = refs.size() != 1;
635635
if (std::none_of(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) {
636636
return tok == ref.token;

0 commit comments

Comments
 (0)