Templates: Scaled up the handling of default values for template parameters (#638)
This commit is contained in:
parent
75a65a02a8
commit
535fe17ffd
|
@ -512,8 +512,10 @@ void Tokenizer::simplifyTemplates()
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "template <"))
|
if (Token::simpleMatch(tok, "template <"))
|
||||||
{
|
{
|
||||||
while (tok->str() != ">")
|
while (tok && tok->str() != ">")
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
if (!tok)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -582,47 +584,69 @@ void Tokenizer::simplifyTemplates()
|
||||||
// Template arguments with default values
|
// Template arguments with default values
|
||||||
for (std::list<Token *>::iterator iter1 = templates.begin(); iter1 != templates.end(); ++iter1)
|
for (std::list<Token *>::iterator iter1 = templates.begin(); iter1 != templates.end(); ++iter1)
|
||||||
{
|
{
|
||||||
Token *eq = 0;
|
std::list<Token *> eq;
|
||||||
std::string pattern;
|
unsigned int templatepar = 1;
|
||||||
|
std::string classname;
|
||||||
for (Token *tok = *iter1; tok; tok = tok->next())
|
for (Token *tok = *iter1; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (tok->str() == ">")
|
||||||
|
{
|
||||||
|
if (Token::Match(tok, "> class %var%"))
|
||||||
|
classname = tok->strAt(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok->str() == ",")
|
||||||
|
++templatepar;
|
||||||
|
|
||||||
|
else if (tok->str() == "=")
|
||||||
|
eq.push_back(tok);
|
||||||
|
}
|
||||||
|
if (eq.empty() || classname.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (std::list<Token *>::iterator iter2 = used.begin(); iter2 != used.end(); ++iter2)
|
||||||
|
{
|
||||||
|
Token *tok = *iter2;
|
||||||
|
|
||||||
|
if (!Token::Match(tok, (classname + " < %any%").c_str()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// count the parameters..
|
||||||
|
unsigned int usedpar = 1;
|
||||||
|
for (tok = tok->tokAt(3); tok; tok = tok->tokAt(2))
|
||||||
{
|
{
|
||||||
if (tok->str() == ">")
|
if (tok->str() == ">")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (tok->str() == ",")
|
if (tok->str() == ",")
|
||||||
{
|
++usedpar;
|
||||||
if (pattern.empty())
|
|
||||||
pattern = " < ";
|
|
||||||
else
|
else
|
||||||
pattern += "%any% , ";
|
|
||||||
}
|
|
||||||
if (tok->str() == "=")
|
|
||||||
{
|
|
||||||
if (Token::Match(tok, "= %any% > class %var% {"))
|
|
||||||
{
|
|
||||||
pattern = tok->strAt(4) + pattern + "%any% >";
|
|
||||||
eq = tok;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
if (tok && tok->str() == ">")
|
||||||
if (!eq || pattern.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (std::list<Token *>::iterator iter2 = used.begin(); iter2 != used.end(); ++iter2)
|
|
||||||
{
|
{
|
||||||
if (Token::Match(*iter2, pattern.c_str()))
|
tok = tok->previous();
|
||||||
|
std::list<Token *>::const_iterator it = eq.begin();
|
||||||
|
for (unsigned int i = (templatepar - eq.size()); it != eq.end() && i < usedpar; ++i)
|
||||||
|
++it;
|
||||||
|
while (it != eq.end())
|
||||||
{
|
{
|
||||||
Token *tok = *iter2;
|
|
||||||
while (tok->next()->str() != ">")
|
|
||||||
tok = tok->next();
|
|
||||||
tok->insertToken(eq->strAt(1));
|
|
||||||
tok->insertToken(",");
|
tok->insertToken(",");
|
||||||
|
tok = tok->next();
|
||||||
|
tok->insertToken((*it)->strAt(1));
|
||||||
|
tok = tok->next();
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eq->deleteThis();
|
for (std::list<Token *>::iterator it = eq.begin(); it != eq.end(); ++it)
|
||||||
eq->deleteThis();
|
{
|
||||||
|
(*it)->deleteThis();
|
||||||
|
(*it)->deleteThis();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -924,6 +924,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void template_default_parameter()
|
void template_default_parameter()
|
||||||
|
{
|
||||||
{
|
{
|
||||||
const char code[] = "template <class T, int n=3>\n"
|
const char code[] = "template <class T, int n=3>\n"
|
||||||
"class A\n"
|
"class A\n"
|
||||||
|
@ -950,6 +951,31 @@ private:
|
||||||
" { int ar [ 3 ] ; }");
|
" { int ar [ 3 ] ; }");
|
||||||
ASSERT_EQUALS(expected, sizeof_(code));
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const char code[] = "template <class T, int n1=3, int n2=2>\n"
|
||||||
|
"class A\n"
|
||||||
|
"{ T ar[n1+n2]; };\n"
|
||||||
|
"\n"
|
||||||
|
"void f()\n"
|
||||||
|
"{\n"
|
||||||
|
" A<int> a1;\n"
|
||||||
|
" A<int,3> a2;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
// The expected result..
|
||||||
|
const std::string expected(" template < class T , int n1 , int n2 >"
|
||||||
|
" class A"
|
||||||
|
" { T ar [ n1 + n2 ] ; } ;"
|
||||||
|
" void f ( )"
|
||||||
|
" {"
|
||||||
|
" A<int,3,2> a1 ;"
|
||||||
|
" A<int,3,2> a2 ;"
|
||||||
|
" }"
|
||||||
|
" class A<int,3,2>"
|
||||||
|
" { int ar [ 5 ] ; }");
|
||||||
|
ASSERT_EQUALS(expected, sizeof_(code));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void template_typename()
|
void template_typename()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue