* Fixed #8959 ("(debug) Unknown type 'x'" with using/alias) * fix cppcheck warning
This commit is contained in:
parent
91de606243
commit
98fc6d1d32
|
@ -932,12 +932,16 @@ void TemplateSimplifier::simplifyTemplateAliases()
|
||||||
startToken = startToken->tokAt(-5);
|
startToken = startToken->tokAt(-5);
|
||||||
while (Token::Match(startToken, "%name%|<|>|>>|,"))
|
while (Token::Match(startToken, "%name%|<|>|>>|,"))
|
||||||
startToken = startToken->previous();
|
startToken = startToken->previous();
|
||||||
if (!Token::Match(startToken, "[;{}] template <"))
|
// handle case where 'template' is first token
|
||||||
|
if (!startToken) {
|
||||||
|
if (!Token::simpleMatch(mTokenList.front(), "template <"))
|
||||||
|
continue;
|
||||||
|
} else if (!Token::Match(startToken, "[;{}] template <"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// alias parameters..
|
// alias parameters..
|
||||||
std::vector<const Token *> aliasParameters;
|
std::vector<const Token *> aliasParameters;
|
||||||
getTemplateParametersInDeclaration(startToken->tokAt(3), aliasParameters);
|
getTemplateParametersInDeclaration(startToken ? startToken->tokAt(3) : mTokenList.front()->tokAt(2), aliasParameters);
|
||||||
std::map<std::string, unsigned int> aliasParameterNames;
|
std::map<std::string, unsigned int> aliasParameterNames;
|
||||||
for (unsigned int argnr = 0; argnr < aliasParameters.size(); ++argnr)
|
for (unsigned int argnr = 0; argnr < aliasParameters.size(); ++argnr)
|
||||||
aliasParameterNames[aliasParameters[argnr]->str()] = argnr;
|
aliasParameterNames[aliasParameters[argnr]->str()] = argnr;
|
||||||
|
@ -1016,7 +1020,7 @@ void TemplateSimplifier::simplifyTemplateAliases()
|
||||||
}
|
}
|
||||||
if (endToken) {
|
if (endToken) {
|
||||||
// Remove all template instantiations in template alias
|
// Remove all template instantiations in template alias
|
||||||
for (const Token *tok = startToken; tok != endToken; tok = tok->next()) {
|
for (const Token *tok = startToken ? startToken : mTokenList.front(); tok != endToken; tok = tok->next()) {
|
||||||
if (!Token::Match(tok, "%name% <"))
|
if (!Token::Match(tok, "%name% <"))
|
||||||
continue;
|
continue;
|
||||||
std::list<TokenAndName>::iterator it = std::find_if(mTemplateInstantiations.begin(),
|
std::list<TokenAndName>::iterator it = std::find_if(mTemplateInstantiations.begin(),
|
||||||
|
@ -1031,7 +1035,21 @@ void TemplateSimplifier::simplifyTemplateAliases()
|
||||||
mTemplateInstantiations.erase(it,next);
|
mTemplateInstantiations.erase(it,next);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token::eraseTokens(startToken, endToken);
|
// find declaration
|
||||||
|
const std::list<TokenAndName>::iterator it2 = std::find_if(mTemplateDeclarations.begin(),
|
||||||
|
mTemplateDeclarations.end(),
|
||||||
|
FindToken(startToken ? startToken : mTokenList.front()));
|
||||||
|
|
||||||
|
if (startToken)
|
||||||
|
eraseTokens(startToken, endToken);
|
||||||
|
else {
|
||||||
|
eraseTokens(mTokenList.front(), endToken);
|
||||||
|
deleteToken(mTokenList.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove declaration
|
||||||
|
if (it2 != mTemplateDeclarations.end())
|
||||||
|
mTemplateDeclarations.erase(it2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1125,6 +1143,8 @@ int TemplateSimplifier::getTemplateNamePosition(const Token *tok)
|
||||||
int namepos = 0;
|
int namepos = 0;
|
||||||
if (Token::Match(tok, "> class|struct|union %type% :|<|;|{"))
|
if (Token::Match(tok, "> class|struct|union %type% :|<|;|{"))
|
||||||
namepos = 2;
|
namepos = 2;
|
||||||
|
else if (Token::Match(tok, "> using %name% ="))
|
||||||
|
namepos = 2;
|
||||||
else if (getTemplateNamePositionTemplateVariable(tok, namepos))
|
else if (getTemplateNamePositionTemplateVariable(tok, namepos))
|
||||||
;
|
;
|
||||||
else if (!getTemplateNamePositionTemplateFunction(tok, namepos))
|
else if (!getTemplateNamePositionTemplateFunction(tok, namepos))
|
||||||
|
|
|
@ -135,6 +135,7 @@ private:
|
||||||
TEST_CASE(template95); // #7417
|
TEST_CASE(template95); // #7417
|
||||||
TEST_CASE(template96); // #7854
|
TEST_CASE(template96); // #7854
|
||||||
TEST_CASE(template97);
|
TEST_CASE(template97);
|
||||||
|
TEST_CASE(template98); // #8959
|
||||||
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||||
|
@ -2052,6 +2053,25 @@ private:
|
||||||
ASSERT_EQUALS(exp, tok(code));
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template98() { // #8959
|
||||||
|
const char code[] = "template <typename T>\n"
|
||||||
|
"using unique_ptr_with_deleter = std::unique_ptr<T, std::function<void(T*)>>;\n"
|
||||||
|
"class A {};\n"
|
||||||
|
"static void func() {\n"
|
||||||
|
" unique_ptr_with_deleter<A> tmp(new A(), [](A* a) {\n"
|
||||||
|
" delete a;\n"
|
||||||
|
" });\n"
|
||||||
|
"}";
|
||||||
|
const char exp[] = "; "
|
||||||
|
"class A { } ; "
|
||||||
|
"static void func ( ) { "
|
||||||
|
"std :: unique_ptr < A , std :: function < void ( A * ) > > tmp ( new A ( ) , [ ] ( A * a ) { "
|
||||||
|
"delete a ; "
|
||||||
|
"} ) ; "
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
|
}
|
||||||
|
|
||||||
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
const char code[] = "template <typename T> struct C {};\n"
|
const char code[] = "template <typename T> struct C {};\n"
|
||||||
"template <typename T> struct S {a};\n"
|
"template <typename T> struct S {a};\n"
|
||||||
|
|
|
@ -2144,10 +2144,9 @@ private:
|
||||||
void varid_templateUsing() { // #5781 #7273
|
void varid_templateUsing() { // #5781 #7273
|
||||||
const char code[] = "template<class T> using X = Y<T,4>;\n"
|
const char code[] = "template<class T> using X = Y<T,4>;\n"
|
||||||
"X<int> x;";
|
"X<int> x;";
|
||||||
TODO_ASSERT_EQUALS("\nY<int,4> x@1;\n",
|
ASSERT_EQUALS("1: ;\n"
|
||||||
"1: template < class T > using X = Y < T , 4 > ;\n"
|
"2: Y < int , 4 > x@1 ;\n",
|
||||||
"2: X < int > x@1 ;\n",
|
tokenize(code));
|
||||||
tokenize(code));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void varid_not_template_in_condition() {
|
void varid_not_template_in_condition() {
|
||||||
|
|
Loading…
Reference in New Issue