Refactor Tokenizer::simplifyUsing to use continue to reduce indentation (#1967)
* Refactor Tokenizer::simplifyUsing to use continue to reduce indentation added function findTemplateDeclarationEnd to skip template declarations to reduce duplicate code * fix travis build
This commit is contained in:
parent
db43dcd601
commit
e551057f59
|
@ -545,6 +545,43 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Token *TemplateSimplifier::findTemplateDeclarationEnd(const Token *tok)
|
||||||
|
{
|
||||||
|
return const_cast<const Token *>(findTemplateDeclarationEnd(const_cast<Token *>(tok)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Token *TemplateSimplifier::findTemplateDeclarationEnd(Token *tok)
|
||||||
|
{
|
||||||
|
if (Token::simpleMatch(tok, "template <")) {
|
||||||
|
tok = tok->next()->findClosingBracket();
|
||||||
|
if (tok)
|
||||||
|
tok = tok->next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tok)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Token * tok2 = tok;
|
||||||
|
while (tok2 && !Token::Match(tok2, ";|{")) {
|
||||||
|
if (tok2->str() == "<")
|
||||||
|
tok2 = tok2->findClosingBracket();
|
||||||
|
else if (Token::Match(tok2, "(|[") && tok2->link())
|
||||||
|
tok2 = tok2->link();
|
||||||
|
if (tok2)
|
||||||
|
tok2 = tok2->next();
|
||||||
|
}
|
||||||
|
if (tok2 && tok2->str() == "{") {
|
||||||
|
tok = tok2->link();
|
||||||
|
if (tok && tok->strAt(1) == ";")
|
||||||
|
tok = tok->next();
|
||||||
|
} else if (tok2 && tok2->str() == ";")
|
||||||
|
tok = tok2;
|
||||||
|
else
|
||||||
|
tok = nullptr;
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
void TemplateSimplifier::eraseTokens(Token *begin, const Token *end)
|
void TemplateSimplifier::eraseTokens(Token *begin, const Token *end)
|
||||||
{
|
{
|
||||||
if (!begin || begin == end)
|
if (!begin || begin == end)
|
||||||
|
@ -829,18 +866,9 @@ void TemplateSimplifier::getTemplateInstantiations()
|
||||||
// #7914
|
// #7914
|
||||||
// Ignore template instantiations within template definitions: they will only be
|
// Ignore template instantiations within template definitions: they will only be
|
||||||
// handled if the definition is actually instantiated
|
// handled if the definition is actually instantiated
|
||||||
Token * tok2 = tok->next();
|
|
||||||
while (tok2 && !Token::Match(tok2, ";|{")) {
|
Token * tok2 = findTemplateDeclarationEnd(tok->next());
|
||||||
if (tok2->str() == "<")
|
|
||||||
tok2 = tok2->findClosingBracket();
|
|
||||||
else if (Token::Match(tok2, "(|[") && tok2->link())
|
|
||||||
tok2 = tok2->link();
|
|
||||||
if (tok2)
|
if (tok2)
|
||||||
tok2 = tok2->next();
|
|
||||||
}
|
|
||||||
if (tok2 && tok2->str() == "{")
|
|
||||||
tok = tok2->link();
|
|
||||||
else if (tok2 && tok2->str() == ";")
|
|
||||||
tok = tok2;
|
tok = tok2;
|
||||||
}
|
}
|
||||||
} else if (Token::Match(tok, "template using %name% <")) {
|
} else if (Token::Match(tok, "template using %name% <")) {
|
||||||
|
|
|
@ -222,6 +222,14 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find last token of a template declaration.
|
||||||
|
* @param tok start token of declaration "template" or token after "template < ... >"
|
||||||
|
* @return last token of declaration or nullptr if syntax error
|
||||||
|
*/
|
||||||
|
static Token *findTemplateDeclarationEnd(Token *tok);
|
||||||
|
static const Token *findTemplateDeclarationEnd(const Token *tok);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Match template declaration/instantiation
|
* Match template declaration/instantiation
|
||||||
* @param instance template instantiation
|
* @param instance template instantiation
|
||||||
|
|
|
@ -1878,8 +1878,6 @@ bool Tokenizer::simplifyUsing()
|
||||||
{
|
{
|
||||||
bool substitute = false;
|
bool substitute = false;
|
||||||
std::list<ScopeInfo3> scopeList;
|
std::list<ScopeInfo3> scopeList;
|
||||||
bool inTemplateDefinition = false;
|
|
||||||
const Token *endOfTemplateDefinition = nullptr;
|
|
||||||
struct Using {
|
struct Using {
|
||||||
Using(Token *start, Token *end) : startTok(start), endTok(end) { }
|
Using(Token *start, Token *end) : startTok(start), endTok(end) { }
|
||||||
Token *startTok;
|
Token *startTok;
|
||||||
|
@ -1901,33 +1899,21 @@ bool Tokenizer::simplifyUsing()
|
||||||
setScopeInfo(tok, &scopeList);
|
setScopeInfo(tok, &scopeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inTemplateDefinition) {
|
// skip template declarations
|
||||||
if (!endOfTemplateDefinition) {
|
if (Token::Match(tok, "template < !!>")) {
|
||||||
if (tok->str() == "{")
|
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok);
|
||||||
endOfTemplateDefinition = tok->link();
|
if (endToken)
|
||||||
else if (tok->str() == ";")
|
tok = endToken;
|
||||||
endOfTemplateDefinition = tok;
|
|
||||||
}
|
|
||||||
if (tok == endOfTemplateDefinition) {
|
|
||||||
inTemplateDefinition = false;
|
|
||||||
endOfTemplateDefinition = nullptr;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (tok->str()=="template") {
|
|
||||||
if (Token::Match(tok->next(), "< !!>"))
|
|
||||||
inTemplateDefinition = true;
|
|
||||||
else
|
|
||||||
inTemplateDefinition = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inTemplateDefinition) {
|
|
||||||
// look for non-template type aliases
|
// look for non-template type aliases
|
||||||
if (tok->strAt(-1) != ">" &&
|
if (!(tok->strAt(-1) != ">" &&
|
||||||
(Token::Match(tok, "using %name% = ::| %name%") ||
|
(Token::Match(tok, "using %name% = ::| %name%") ||
|
||||||
(Token::Match(tok, "using %name% [ [") &&
|
(Token::Match(tok, "using %name% [ [") &&
|
||||||
Token::Match(tok->linkAt(2), "] ] = ::| %name%")))) {
|
Token::Match(tok->linkAt(2), "] ] = ::| %name%")))))
|
||||||
|
continue;
|
||||||
|
|
||||||
std::list<ScopeInfo3> scopeList1;
|
std::list<ScopeInfo3> scopeList1;
|
||||||
scopeList1.emplace_back("", nullptr);
|
scopeList1.emplace_back("", nullptr);
|
||||||
std::string name = tok->strAt(1);
|
std::string name = tok->strAt(1);
|
||||||
|
@ -2013,22 +1999,9 @@ bool Tokenizer::simplifyUsing()
|
||||||
|
|
||||||
// skip template definitions
|
// skip template definitions
|
||||||
if (Token::Match(tok1, "template < !!>")) {
|
if (Token::Match(tok1, "template < !!>")) {
|
||||||
tok1 = tok1->next()->findClosingBracket();
|
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok1);
|
||||||
if (tok1) {
|
if (endToken)
|
||||||
Token * tok2 = tok1->next();
|
tok1 = endToken;
|
||||||
while (tok2 && !Token::Match(tok2, ";|{")) {
|
|
||||||
if (tok2->str() == "<")
|
|
||||||
tok2 = tok2->findClosingBracket();
|
|
||||||
else if (Token::Match(tok2, "(|[") && tok2->link())
|
|
||||||
tok2 = tok2->link();
|
|
||||||
if (tok2)
|
|
||||||
tok2 = tok2->next();
|
|
||||||
}
|
|
||||||
if (tok2 && tok2->str() == "{")
|
|
||||||
tok1 = tok2->link();
|
|
||||||
else if (tok2 && tok2->str() == ";")
|
|
||||||
tok1 = tok2;
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2195,8 +2168,6 @@ bool Tokenizer::simplifyUsing()
|
||||||
if (!skip)
|
if (!skip)
|
||||||
usingList.emplace_back(usingStart, usingEnd);
|
usingList.emplace_back(usingStart, usingEnd);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete all used type alias definitions
|
// delete all used type alias definitions
|
||||||
for (std::list<Using>::reverse_iterator it = usingList.rbegin(); it != usingList.rend(); ++it) {
|
for (std::list<Using>::reverse_iterator it = usingList.rbegin(); it != usingList.rend(); ++it) {
|
||||||
|
|
|
@ -190,6 +190,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(templateNamePosition);
|
TEST_CASE(templateNamePosition);
|
||||||
|
|
||||||
|
TEST_CASE(findTemplateDeclarationEnd);
|
||||||
|
|
||||||
TEST_CASE(expandSpecialized1);
|
TEST_CASE(expandSpecialized1);
|
||||||
TEST_CASE(expandSpecialized2);
|
TEST_CASE(expandSpecialized2);
|
||||||
TEST_CASE(expandSpecialized3); // #8671
|
TEST_CASE(expandSpecialized3); // #8671
|
||||||
|
@ -3713,6 +3715,35 @@ private:
|
||||||
"template<> unsigned A<int, v<char> >::foo() { return 0; }", 2));
|
"template<> unsigned A<int, v<char> >::foo() { return 0; }", 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to unit test TemplateSimplifier::findTemplateDeclarationEnd
|
||||||
|
bool findTemplateDeclarationEndHelper(const char code[], const char pattern[], unsigned offset = 0) {
|
||||||
|
Tokenizer tokenizer(&settings, this);
|
||||||
|
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.createTokens(istr, "test.cpp");
|
||||||
|
tokenizer.createLinks();
|
||||||
|
tokenizer.mTemplateSimplifier->fixAngleBrackets();
|
||||||
|
|
||||||
|
const Token *_tok = tokenizer.tokens();
|
||||||
|
for (unsigned i = 0 ; i < offset ; ++i)
|
||||||
|
_tok = _tok->next();
|
||||||
|
|
||||||
|
const Token *tok1 = tokenizer.mTemplateSimplifier->findTemplateDeclarationEnd(_tok);
|
||||||
|
|
||||||
|
return (tok1 == Token::findsimplematch(tokenizer.list.front(), pattern));
|
||||||
|
}
|
||||||
|
|
||||||
|
void findTemplateDeclarationEnd() {
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename T> class Fred { }; int x;", "; int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename T> void Fred() { } int x;", "} int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename T> int Fred = 0; int x;", "; int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename T> constexpr auto func = [](auto x){ return T(x);}; int x;", "; int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>); int x;", "; int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <class, class a> auto b() -> decltype(a{}.template b<void(int, int)>){} int x;", "} int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(); int x;", "; int x ;"));
|
||||||
|
ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(){} int x;", "} int x ;"));
|
||||||
|
}
|
||||||
|
|
||||||
void expandSpecialized1() {
|
void expandSpecialized1() {
|
||||||
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
|
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
|
||||||
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};"));
|
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};"));
|
||||||
|
|
Loading…
Reference in New Issue