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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!begin || begin == end)
|
||||
|
@ -829,18 +866,9 @@ void TemplateSimplifier::getTemplateInstantiations()
|
|||
// #7914
|
||||
// Ignore template instantiations within template definitions: they will only be
|
||||
// handled if the definition is actually instantiated
|
||||
Token * tok2 = tok->next();
|
||||
while (tok2 && !Token::Match(tok2, ";|{")) {
|
||||
if (tok2->str() == "<")
|
||||
tok2 = tok2->findClosingBracket();
|
||||
else if (Token::Match(tok2, "(|[") && tok2->link())
|
||||
tok2 = tok2->link();
|
||||
|
||||
Token * tok2 = findTemplateDeclarationEnd(tok->next());
|
||||
if (tok2)
|
||||
tok2 = tok2->next();
|
||||
}
|
||||
if (tok2 && tok2->str() == "{")
|
||||
tok = tok2->link();
|
||||
else if (tok2 && tok2->str() == ";")
|
||||
tok = tok2;
|
||||
}
|
||||
} 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
|
||||
* @param instance template instantiation
|
||||
|
|
|
@ -1878,8 +1878,6 @@ bool Tokenizer::simplifyUsing()
|
|||
{
|
||||
bool substitute = false;
|
||||
std::list<ScopeInfo3> scopeList;
|
||||
bool inTemplateDefinition = false;
|
||||
const Token *endOfTemplateDefinition = nullptr;
|
||||
struct Using {
|
||||
Using(Token *start, Token *end) : startTok(start), endTok(end) { }
|
||||
Token *startTok;
|
||||
|
@ -1901,33 +1899,21 @@ bool Tokenizer::simplifyUsing()
|
|||
setScopeInfo(tok, &scopeList);
|
||||
}
|
||||
|
||||
if (inTemplateDefinition) {
|
||||
if (!endOfTemplateDefinition) {
|
||||
if (tok->str() == "{")
|
||||
endOfTemplateDefinition = tok->link();
|
||||
else if (tok->str() == ";")
|
||||
endOfTemplateDefinition = tok;
|
||||
}
|
||||
if (tok == endOfTemplateDefinition) {
|
||||
inTemplateDefinition = false;
|
||||
endOfTemplateDefinition = nullptr;
|
||||
// skip template declarations
|
||||
if (Token::Match(tok, "template < !!>")) {
|
||||
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok);
|
||||
if (endToken)
|
||||
tok = endToken;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (tok->str()=="template") {
|
||||
if (Token::Match(tok->next(), "< !!>"))
|
||||
inTemplateDefinition = true;
|
||||
else
|
||||
inTemplateDefinition = false;
|
||||
}
|
||||
|
||||
if (!inTemplateDefinition) {
|
||||
// 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% [ [") &&
|
||||
Token::Match(tok->linkAt(2), "] ] = ::| %name%")))) {
|
||||
Token::Match(tok->linkAt(2), "] ] = ::| %name%")))))
|
||||
continue;
|
||||
|
||||
std::list<ScopeInfo3> scopeList1;
|
||||
scopeList1.emplace_back("", nullptr);
|
||||
std::string name = tok->strAt(1);
|
||||
|
@ -2013,22 +1999,9 @@ bool Tokenizer::simplifyUsing()
|
|||
|
||||
// skip template definitions
|
||||
if (Token::Match(tok1, "template < !!>")) {
|
||||
tok1 = tok1->next()->findClosingBracket();
|
||||
if (tok1) {
|
||||
Token * tok2 = tok1->next();
|
||||
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;
|
||||
}
|
||||
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok1);
|
||||
if (endToken)
|
||||
tok1 = endToken;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2195,8 +2168,6 @@ bool Tokenizer::simplifyUsing()
|
|||
if (!skip)
|
||||
usingList.emplace_back(usingStart, usingEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete all used type alias definitions
|
||||
for (std::list<Using>::reverse_iterator it = usingList.rbegin(); it != usingList.rend(); ++it) {
|
||||
|
|
|
@ -190,6 +190,8 @@ private:
|
|||
|
||||
TEST_CASE(templateNamePosition);
|
||||
|
||||
TEST_CASE(findTemplateDeclarationEnd);
|
||||
|
||||
TEST_CASE(expandSpecialized1);
|
||||
TEST_CASE(expandSpecialized2);
|
||||
TEST_CASE(expandSpecialized3); // #8671
|
||||
|
@ -3713,6 +3715,35 @@ private:
|
|||
"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() {
|
||||
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
|
||||
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};"));
|
||||
|
|
Loading…
Reference in New Issue