template simplifier: add minimal template template support (#1779)
This commit is contained in:
parent
d8d4ca51d7
commit
5cdde701ba
|
@ -327,6 +327,15 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok)
|
||||||
unsigned int level = 0;
|
unsigned int level = 0;
|
||||||
|
|
||||||
while (tok) {
|
while (tok) {
|
||||||
|
// skip template template
|
||||||
|
if (level == 0 && Token::simpleMatch(tok, "template <")) {
|
||||||
|
const Token *closing = tok->next()->findClosingBracket();
|
||||||
|
if (closing)
|
||||||
|
tok = closing->next();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// skip const/volatile
|
// skip const/volatile
|
||||||
if (Token::Match(tok, "const|volatile"))
|
if (Token::Match(tok, "const|volatile"))
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
@ -2324,7 +2333,14 @@ const Token * TemplateSimplifier::getTemplateParametersInDeclaration(
|
||||||
std::vector<const Token *> & typeParametersInDeclaration)
|
std::vector<const Token *> & typeParametersInDeclaration)
|
||||||
{
|
{
|
||||||
typeParametersInDeclaration.clear();
|
typeParametersInDeclaration.clear();
|
||||||
for (; tok && tok->str() != ">"; tok = tok->next()) {
|
const Token *closing = tok->previous()->findClosingBracket();
|
||||||
|
for (; tok && tok!= closing; tok = tok->next()) {
|
||||||
|
if (Token::simpleMatch(tok, "template <")) {
|
||||||
|
const Token *closing = tok->next()->findClosingBracket();
|
||||||
|
if (closing)
|
||||||
|
tok = closing->next();
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::Match(tok, "%name% ,|>|="))
|
if (Token::Match(tok, "%name% ,|>|="))
|
||||||
typeParametersInDeclaration.push_back(tok);
|
typeParametersInDeclaration.push_back(tok);
|
||||||
}
|
}
|
||||||
|
@ -3009,8 +3025,7 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
tok->deleteThis();
|
tok->deleteThis();
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "template <")) {
|
if (Token::simpleMatch(tok, "template <")) {
|
||||||
while (tok && tok->str() != ">")
|
tok = tok->next()->findClosingBracket();
|
||||||
tok = tok->next();
|
|
||||||
if (!tok)
|
if (!tok)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ private:
|
||||||
TEST_CASE(template103);
|
TEST_CASE(template103);
|
||||||
TEST_CASE(template104); // #9021
|
TEST_CASE(template104); // #9021
|
||||||
TEST_CASE(template105); // #9076
|
TEST_CASE(template105); // #9076
|
||||||
|
TEST_CASE(template106);
|
||||||
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)
|
||||||
|
@ -2398,6 +2399,27 @@ private:
|
||||||
ASSERT_EQUALS(exp, tok(code));
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template106() {
|
||||||
|
const char code[] = "template<class T, class U> class A {\n"
|
||||||
|
"public:\n"
|
||||||
|
" int x;\n"
|
||||||
|
"};\n"
|
||||||
|
"template<template<class T, class U> class V> class B {\n"
|
||||||
|
" V<char, char> i;\n"
|
||||||
|
"};\n"
|
||||||
|
"B<A> c;";
|
||||||
|
const char exp[] = "class A<char,char> ; "
|
||||||
|
"class B<A> ; "
|
||||||
|
"B<A> c ; "
|
||||||
|
"class B<A> { "
|
||||||
|
"A<char,char> i ; "
|
||||||
|
"} ; class A<char,char> { "
|
||||||
|
"public: "
|
||||||
|
"int x ; "
|
||||||
|
"} ;";
|
||||||
|
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"
|
||||||
|
@ -3386,7 +3408,7 @@ private:
|
||||||
void templateParameterWithoutName() {
|
void templateParameterWithoutName() {
|
||||||
ASSERT_EQUALS(1U, templateParameters("template<typename = void> struct s;"));
|
ASSERT_EQUALS(1U, templateParameters("template<typename = void> struct s;"));
|
||||||
ASSERT_EQUALS(1U, templateParameters("template<template<typename = float> typename T> struct A {\n"
|
ASSERT_EQUALS(1U, templateParameters("template<template<typename = float> typename T> struct A {\n"
|
||||||
" void f();n"
|
" void f();\n"
|
||||||
" void g();\n"
|
" void g();\n"
|
||||||
"};n"));
|
"};n"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2435,7 +2435,7 @@ private:
|
||||||
"public:\n"
|
"public:\n"
|
||||||
" int f() { return C< ::D,int>::f(); }\n"
|
" int f() { return C< ::D,int>::f(); }\n"
|
||||||
"};");
|
"};");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (debug) Failed to instantiate template \"C\". The checking continues anyway.\n", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void symboldatabase8() {
|
void symboldatabase8() {
|
||||||
|
|
Loading…
Reference in New Issue