TemplateSimplifier: Improved handling of unknown inner template instantiation inside template instantiation (#3818)

This commit is contained in:
Daniel Marjamäki 2012-08-09 17:19:15 +02:00
parent 4ec12209dc
commit 6ff1760c72
2 changed files with 15 additions and 2 deletions

View File

@ -1014,7 +1014,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions(
std::string typeForNewNameStr;
std::string templateMatchPattern(name + " < ");
unsigned int indentlevel = 0;
for (const Token *tok3 = tok2->tokAt(2); tok3 && tok3->str() != ">"; tok3 = tok3->next()) {
for (const Token *tok3 = tok2->tokAt(2); tok3 && (indentlevel > 0 || tok3->str() != ">"); tok3 = tok3->next()) {
// #2648 - unhandled parenthesis => bail out
// #2721 - unhandled [ => bail out
if (tok3->str() == "(" || tok3->str() == "[") {
@ -1027,7 +1027,7 @@ bool TemplateSimplifier::simplifyTemplateInstantions(
}
if (tok3->str() == "<" && templateParameters(tok3) > 0)
++indentlevel;
else if (indentlevel > 0 && Token::simpleMatch(tok3, "> ,"))
else if (indentlevel > 0 && Token::simpleMatch(tok3, "> [,>]"))
--indentlevel;
templateMatchPattern += tok3->str();
templateMatchPattern += " ";

View File

@ -126,6 +126,7 @@ private:
TEST_CASE(template30); // #3529 - template < template < ..
TEST_CASE(template31); // #4010 - reference type
TEST_CASE(template32); // #3818 - mismatching template not handled well
TEST_CASE(template33); // #3818 - inner templates in template instantiation not handled well
TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type);
@ -2171,6 +2172,18 @@ private:
"struct B<int> { public: A < int , Pair < int , int > , int > a ; }", tok(code));
}
void template33() {
// #3818 - inner templates in template instantiation not handled well
const char code[] = "template<class T> struct A { };\n"
"template<class T> struct B { };\n"
"template<class T> struct C { A<B<X<T> > > ab; };\n"
"C<int> c;";
ASSERT_EQUALS("template < class T > struct A { } ; "
"template < class T > struct B { } ; "
"C<int> c ; "
"struct C<int> { A < B < X < int > > > ab ; }", tok(code));
}
void template_unhandled() {
// An unhandled template usage should be simplified..
ASSERT_EQUALS("x<int> ( ) ;", tok("x<int>();"));