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;
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
if (Token::Match(tok, "const|volatile"))
tok = tok->next();
@ -2324,7 +2333,14 @@ const Token * TemplateSimplifier::getTemplateParametersInDeclaration(
std::vector<const Token *> & typeParametersInDeclaration)
{
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% ,|>|="))
typeParametersInDeclaration.push_back(tok);
}
@ -3009,8 +3025,7 @@ void TemplateSimplifier::simplifyTemplates(
tok->deleteThis();
if (Token::simpleMatch(tok, "template <")) {
while (tok && tok->str() != ">")
tok = tok->next();
tok = tok->next()->findClosingBracket();
if (!tok)
break;
}

View File

@ -143,6 +143,7 @@ private:
TEST_CASE(template103);
TEST_CASE(template104); // #9021
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_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@ -2398,6 +2399,27 @@ private:
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>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"
@ -3386,7 +3408,7 @@ private:
void templateParameterWithoutName() {
ASSERT_EQUALS(1U, templateParameters("template<typename = void> struct s;"));
ASSERT_EQUALS(1U, templateParameters("template<template<typename = float> typename T> struct A {\n"
" void f();n"
" void f();\n"
" void g();\n"
"};n"));
}

View File

@ -2435,7 +2435,7 @@ private:
"public:\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() {