Skip to content

Commit d9a9743

Browse files
committed
Revert "Calculate token scopes in advance rather than as the tokenlist is iterated (#1882)"
This reverts commit 0d7836f.
1 parent 236c195 commit d9a9743

5 files changed

Lines changed: 126 additions & 220 deletions

File tree

lib/templatesimplifier.cpp

Lines changed: 120 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -632,10 +632,106 @@ bool TemplateSimplifier::removeTemplate(Token *tok)
632632
return false;
633633
}
634634

635+
/// TODO: This is copy pasted from Tokenizer. We should reuse this code.
636+
namespace {
637+
struct ScopeInfo2 {
638+
ScopeInfo2(const std::string &name_, const Token *bodyEnd_) : name(name_), bodyEnd(bodyEnd_) {}
639+
const std::string name;
640+
const Token * const bodyEnd;
641+
std::set<std::string> usingNamespaces;
642+
};
643+
}
644+
static std::string getScopeName(const std::list<ScopeInfo2> &scopeInfo)
645+
{
646+
std::string ret;
647+
for (const ScopeInfo2 &i : scopeInfo) {
648+
if (!i.name.empty())
649+
ret += (ret.empty() ? "" : " :: ") + i.name;
650+
}
651+
return ret;
652+
}
653+
654+
static void setScopeInfo(Token *tok, std::list<ScopeInfo2> *scopeInfo, bool all = false)
655+
{
656+
while (tok->str() == "}" && !scopeInfo->empty() && tok == scopeInfo->back().bodyEnd)
657+
scopeInfo->pop_back();
658+
if (!Token::Match(tok, "namespace|class|struct|union %name% {|:|::")) {
659+
// check for using namespace
660+
if (Token::Match(tok, "using namespace %name% ;|::")) {
661+
const Token * tok1 = tok->tokAt(2);
662+
std::string nameSpace;
663+
while (tok1 && tok1->str() != ";") {
664+
if (!nameSpace.empty())
665+
nameSpace += " ";
666+
nameSpace += tok1->str();
667+
tok1 = tok1->next();
668+
}
669+
scopeInfo->back().usingNamespaces.insert(nameSpace);
670+
}
671+
// check for member function
672+
else if (tok->str() == "{") {
673+
bool added = false;
674+
Token *tok1 = tok;
675+
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
676+
tok1 = tok1->previous();
677+
if (tok1 && tok1->previous() && tok1->strAt(-1) == ")") {
678+
tok1 = tok1->linkAt(-1);
679+
if (Token::Match(tok1->previous(), "throw|noexcept")) {
680+
tok1 = tok1->previous();
681+
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
682+
tok1 = tok1->previous();
683+
if (tok1->strAt(-1) != ")")
684+
return;
685+
} else if (Token::Match(tok->tokAt(-2), ":|, %name%")) {
686+
tok1 = tok1->tokAt(-2);
687+
if (tok1->strAt(-1) != ")")
688+
return;
689+
}
690+
if (tok1->strAt(-1) == ">")
691+
tok1 = tok1->previous()->findOpeningBracket();
692+
if (tok1 && Token::Match(tok1->tokAt(-3), "%name% :: %name%")) {
693+
tok1 = tok1->tokAt(-2);
694+
std::string scope = tok1->strAt(-1);
695+
while (Token::Match(tok1->tokAt(-2), ":: %name%")) {
696+
scope = tok1->strAt(-3) + " :: " + scope;
697+
tok1 = tok1->tokAt(-2);
698+
}
699+
scopeInfo->emplace_back(scope, tok->link());
700+
added = true;
701+
}
702+
}
703+
704+
if (all && !added)
705+
scopeInfo->emplace_back("", tok->link());
706+
}
707+
return;
708+
}
709+
710+
tok = tok->next();
711+
std::string classname = tok->str();
712+
while (Token::Match(tok, "%name% :: %name%")) {
713+
tok = tok->tokAt(2);
714+
classname += " :: " + tok->str();
715+
}
716+
tok = tok->next();
717+
if (tok && tok->str() == ":") {
718+
while (tok && !Token::Match(tok, ";|{"))
719+
tok = tok->next();
720+
}
721+
if (tok && tok->str() == "{") {
722+
scopeInfo->emplace_back(classname,tok->link());
723+
}
724+
}
725+
635726
bool TemplateSimplifier::getTemplateDeclarations()
636727
{
637728
bool codeWithTemplates = false;
729+
std::list<ScopeInfo2> scopeInfo;
638730
for (Token *tok = mTokenList.front(); tok; tok = tok->next()) {
731+
if (Token::Match(tok, "{|}|namespace|class|struct|union")) {
732+
setScopeInfo(tok, &scopeInfo);
733+
continue;
734+
}
639735
if (!Token::simpleMatch(tok, "template <"))
640736
continue;
641737
// ignore template template parameter
@@ -660,7 +756,7 @@ bool TemplateSimplifier::getTemplateDeclarations()
660756
else if (Token::Match(tok2, "{|=|;")) {
661757
const int namepos = getTemplateNamePosition(parmEnd);
662758
if (namepos > 0) {
663-
TokenAndName decl(tok, tok->scopeInfo()->name, parmEnd->tokAt(namepos), parmEnd);
759+
TokenAndName decl(tok, getScopeName(scopeInfo), parmEnd->tokAt(namepos), parmEnd);
664760
if (decl.isForwardDeclaration()) {
665761
// Declaration => add to mTemplateForwardDeclarations
666762
mTemplateForwardDeclarations.emplace_back(decl);
@@ -697,9 +793,18 @@ void TemplateSimplifier::getTemplateInstantiations()
697793
functionNameMap.insert(std::make_pair(decl.name, &decl));
698794
}
699795

796+
std::list<ScopeInfo2> scopeList;
700797
const Token *skip = nullptr;
701798

799+
scopeList.emplace_back("", nullptr);
800+
702801
for (Token *tok = mTokenList.front(); tok; tok = tok->next()) {
802+
if (Token::Match(tok, "{|}|namespace|class|struct|union") ||
803+
Token::Match(tok, "using namespace %name% ;|::")) {
804+
setScopeInfo(tok, &scopeList);
805+
continue;
806+
}
807+
703808
// template definition.. skip it
704809
if (Token::simpleMatch(tok, "template <")) {
705810
tok = tok->next()->findClosingBracket();
@@ -750,7 +855,7 @@ void TemplateSimplifier::getTemplateInstantiations()
750855
} else if (Token::Match(tok->previous(), "(|{|}|;|=|>|<<|:|.|*|&|return|<|, %name% ::|<|(") ||
751856
Token::Match(tok->previous(), "%type% %name% ::|<") ||
752857
Token::Match(tok->tokAt(-2), "[,:] private|protected|public %name% ::|<")) {
753-
std::string scopeName = tok->scopeInfo()->name;
858+
std::string scopeName = getScopeName(scopeList);
754859
std::string qualification;
755860
Token * qualificationTok = tok;
756861
while (Token::Match(tok, "%name% :: %name%")) {
@@ -846,7 +951,7 @@ void TemplateSimplifier::getTemplateInstantiations()
846951
for (; tok2 && tok2 != tok; tok2 = tok2->previous()) {
847952
if (Token::Match(tok2, ",|< %name% <") &&
848953
(tok2->strAt(3) == ">" || templateParameters(tok2->tokAt(2)))) {
849-
addInstantiation(tok2->next(), tok->scopeInfo()->name);
954+
addInstantiation(tok2->next(), getScopeName(scopeList));
850955
} else if (Token::Match(tok2->next(), "class|struct"))
851956
tok2->deleteNext();
852957
}
@@ -865,7 +970,7 @@ void TemplateSimplifier::getTemplateInstantiations()
865970
} else {
866971
// full name doesn't match so try with using namespaces if available
867972
bool found = false;
868-
for (const auto & nameSpace : tok->scopeInfo()->usingNamespaces) {
973+
for (const auto & nameSpace : scopeList.back().usingNamespaces) {
869974
std::string fullNameSpace = scopeName + (scopeName.empty()?"":" :: ") +
870975
nameSpace + (qualification.empty()?"":" :: ") + qualification;
871976
std::string newFullName = fullNameSpace + " :: " + tok->str();
@@ -892,7 +997,7 @@ void TemplateSimplifier::getTemplateInstantiations()
892997
if (!qualification.empty())
893998
addInstantiation(tok, qualification);
894999
else
895-
addInstantiation(tok, tok->scopeInfo()->name);
1000+
addInstantiation(tok, getScopeName(scopeList));
8961001
break;
8971002
}
8981003
const std::string::size_type pos = scopeName.rfind(" :: ");
@@ -1433,6 +1538,7 @@ void TemplateSimplifier::expandTemplate(
14331538
const std::string &newName,
14341539
bool copy)
14351540
{
1541+
std::list<ScopeInfo2> scopeInfo;
14361542
bool inTemplateDefinition = false;
14371543
const Token *startOfTemplateDeclaration = nullptr;
14381544
const Token *endOfTemplateDefinition = nullptr;
@@ -1647,6 +1753,10 @@ void TemplateSimplifier::expandTemplate(
16471753
}
16481754

16491755
for (Token *tok3 = mTokenList.front(); tok3; tok3 = tok3 ? tok3->next() : nullptr) {
1756+
if (Token::Match(tok3, "{|}|namespace|class|struct|union")) {
1757+
setScopeInfo(tok3, &scopeInfo);
1758+
continue;
1759+
}
16501760
if (inTemplateDefinition) {
16511761
if (!endOfTemplateDefinition) {
16521762
if (isVariable) {
@@ -2826,8 +2936,13 @@ void TemplateSimplifier::replaceTemplateUsage(
28262936
const std::list<std::string> &typeStringsUsedInTemplateInstantiation,
28272937
const std::string &newName)
28282938
{
2939+
std::list<ScopeInfo2> scopeInfo;
28292940
std::list< std::pair<Token *, Token *> > removeTokens;
28302941
for (Token *nameTok = mTokenList.front(); nameTok; nameTok = nameTok->next()) {
2942+
if (Token::Match(nameTok, "{|}|namespace|class|struct|union")) {
2943+
setScopeInfo(nameTok, &scopeInfo);
2944+
continue;
2945+
}
28312946
if (!Token::Match(nameTok, "%name% <") ||
28322947
Token::Match(nameTok, "template|const_cast|dynamic_cast|reinterpret_cast|static_cast"))
28332948
continue;
@@ -3255,10 +3370,6 @@ void TemplateSimplifier::simplifyTemplates(
32553370
unsigned int passCount = 0;
32563371
const unsigned int passCountMax = 10;
32573372
for (; passCount < passCountMax; ++passCount) {
3258-
// Recalculate scopes from scratch every pass, in case a scope is missing or incorrect
3259-
for (auto tok = mTokenizer->list.front(); tok; tok = tok->next()) tok->scopeInfo(nullptr);
3260-
mTokenizer->calculateScopes();
3261-
32623373
if (passCount) {
32633374
// it may take more than one pass to simplify type aliases
32643375
bool usingChanged = false;

lib/token.cpp

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -990,84 +990,6 @@ void Token::insertToken(const std::string &tokenStr, const std::string &original
990990
this->next(newToken);
991991
newToken->previous(this);
992992
}
993-
994-
// If the token we're inserting from has a scope, the new token needs one too
995-
if (mImpl->mScopeInfo) {
996-
// If it's a brace, we need to open a new scope
997-
if (tokenStr == "{") {
998-
std::string nextScopeNameAddition = "";
999-
// This might be the opening of a member function
1000-
Token *tok1 = newToken;
1001-
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
1002-
tok1 = tok1->previous();
1003-
if (tok1 && tok1->previous() && tok1->strAt(-1) == ")") {
1004-
tok1 = tok1->linkAt(-1);
1005-
if (Token::Match(tok1->previous(), "throw|noexcept")) {
1006-
tok1 = tok1->previous();
1007-
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
1008-
tok1 = tok1->previous();
1009-
if (tok1->strAt(-1) != ")")
1010-
return;
1011-
} else if (Token::Match(newToken->tokAt(-2), ":|, %name%")) {
1012-
tok1 = tok1->tokAt(-2);
1013-
if (tok1->strAt(-1) != ")")
1014-
return;
1015-
}
1016-
if (tok1->strAt(-1) == ">")
1017-
tok1 = tok1->previous()->findOpeningBracket();
1018-
if (tok1 && Token::Match(tok1->tokAt(-3), "%name% :: %name%")) {
1019-
tok1 = tok1->tokAt(-2);
1020-
std::string scope = tok1->strAt(-1);
1021-
while (Token::Match(tok1->tokAt(-2), ":: %name%")) {
1022-
scope = tok1->strAt(-3) + " :: " + scope;
1023-
tok1 = tok1->tokAt(-2);
1024-
}
1025-
1026-
if (nextScopeNameAddition.length() > 0) nextScopeNameAddition += " :: ";
1027-
nextScopeNameAddition += scope;
1028-
}
1029-
}
1030-
1031-
// Or it might be a namespace/class/struct
1032-
if (Token::Match(newToken->previous(), "%name%|>")) {
1033-
Token* nameTok = newToken->previous();
1034-
while (nameTok && !Token::Match(nameTok, "namespace|class|struct|union %name% {|::|:|<")) {
1035-
nameTok = nameTok->previous();
1036-
}
1037-
if (nameTok) {
1038-
for (nameTok = nameTok->next(); nameTok && !Token::Match(nameTok, "{|:|<"); nameTok = nameTok->next()) {
1039-
nextScopeNameAddition.append(nameTok->str());
1040-
nextScopeNameAddition.append(" ");
1041-
}
1042-
if (nextScopeNameAddition.length() > 0) nextScopeNameAddition = nextScopeNameAddition.substr(0, nextScopeNameAddition.length() - 1);
1043-
}
1044-
}
1045-
1046-
// New scope is opening, record it here
1047-
std::shared_ptr<ScopeInfo2> newScopeInfo = std::make_shared<ScopeInfo2>(mImpl->mScopeInfo->name, nullptr, mImpl->mScopeInfo->usingNamespaces);
1048-
1049-
if (newScopeInfo->name != "") newScopeInfo->name.append(" :: ");
1050-
newScopeInfo->name.append(nextScopeNameAddition);
1051-
1052-
newToken->scopeInfo(newScopeInfo);
1053-
1054-
// If it's a closing brace, we need to find where the scope opened and take the scope before
1055-
} else if (tokenStr == "}") {
1056-
Token* matchingTok = newToken->previous();
1057-
int depth = 0;
1058-
while (matchingTok && (depth != 0 || !Token::simpleMatch(matchingTok, "{"))) {
1059-
if (Token::simpleMatch(matchingTok, "}")) depth++;
1060-
if (Token::simpleMatch(matchingTok, "{")) depth--;
1061-
matchingTok = matchingTok->previous();
1062-
}
1063-
if (matchingTok && matchingTok->previous()) {
1064-
newToken->mImpl->mScopeInfo = matchingTok->previous()->scopeInfo();
1065-
}
1066-
// Otherwise we can just take the previous scope
1067-
} else {
1068-
newToken->mImpl->mScopeInfo = mImpl->mScopeInfo;
1069-
}
1070-
}
1071993
}
1072994
}
1073995

@@ -1924,13 +1846,6 @@ std::string Token::typeStr(const Token* tok)
19241846
return r.first->stringifyList(r.second, false);
19251847
}
19261848

1927-
void Token::scopeInfo(std::shared_ptr<ScopeInfo2> newScopeInfo) {
1928-
mImpl->mScopeInfo = newScopeInfo;
1929-
}
1930-
std::shared_ptr<ScopeInfo2> Token::scopeInfo() const {
1931-
return mImpl->mScopeInfo;
1932-
}
1933-
19341849
TokenImpl::~TokenImpl()
19351850
{
19361851
delete mOriginalName;

lib/token.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include <cstddef>
3131
#include <functional>
3232
#include <list>
33-
#include <memory>
3433
#include <ostream>
3534
#include <string>
3635
#include <vector>
@@ -51,17 +50,6 @@ struct TokensFrontBack {
5150
Token *back;
5251
};
5352

54-
struct ScopeInfo2 {
55-
ScopeInfo2(const std::string &name_, const Token *bodyEnd_, const std::set<std::string> &usingNamespaces_ = std::set<std::string>())
56-
: name(name_),
57-
bodyEnd(bodyEnd_),
58-
usingNamespaces(usingNamespaces_)
59-
{}
60-
std::string name;
61-
const Token * const bodyEnd;
62-
std::set<std::string> usingNamespaces;
63-
};
64-
6553
struct TokenImpl {
6654
unsigned int mVarId;
6755
unsigned int mFileIndex;
@@ -109,8 +97,6 @@ struct TokenImpl {
10997
// Pointer to a template in the template simplifier
11098
std::set<TemplateSimplifier::TokenAndName*> mTemplateSimplifierPointers;
11199

112-
std::shared_ptr<ScopeInfo2> mScopeInfo;
113-
114100
TokenImpl()
115101
: mVarId(0)
116102
, mFileIndex(0)
@@ -128,7 +114,6 @@ struct TokenImpl {
128114
, mValues(nullptr)
129115
, mBits(0)
130116
, mTemplateSimplifierPointers()
131-
, mScopeInfo(nullptr)
132117
{}
133118

134119
~TokenImpl();
@@ -1183,10 +1168,6 @@ class CPPCHECKLIB Token {
11831168
void printAst(bool verbose, bool xml, std::ostream &out) const;
11841169

11851170
void printValueFlow(bool xml, std::ostream &out) const;
1186-
1187-
void scopeInfo(std::shared_ptr<ScopeInfo2> newScopeInfo);
1188-
1189-
std::shared_ptr<ScopeInfo2> scopeInfo() const;
11901171
};
11911172

11921173
/// @}

0 commit comments

Comments
 (0)