template simplifier: add minimal template template support (#1779)

This commit is contained in:
IOBYTE 2019-04-04 00:07:49 -04:00 committed by Daniel Marjamäki
parent d8d4ca51d7
commit 5cdde701ba
3 changed files with 42 additions and 5 deletions

View File

@ -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;
} }

View File

@ -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"));
} }

View File

@ -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() {