Fix Ticket 180 (Templates: Expanding member functions that are not implemented inline)

This commit is contained in:
Daniel Marjamäki 2009-03-15 20:03:29 +01:00
parent 9b06b22053
commit a6ad972aad
2 changed files with 63 additions and 25 deletions

View File

@ -512,10 +512,10 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[])
s += ","; s += ",";
s += " %any% "; s += " %any% ";
} }
const std::string pattern(s + "> " + (isfunc ? "(" : "%var%")); const std::string pattern(s + "> ");
for (Token *tok2 = _tokens; tok2; tok2 = tok2->next()) for (Token *tok2 = _tokens; tok2; tok2 = tok2->next())
{ {
if (!Token::Match(tok2, pattern.c_str())) if (!Token::Match(tok2, (pattern + (isfunc ? "(" : "%var%")).c_str()))
continue; continue;
// New type.. // New type..
@ -532,9 +532,29 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[])
// New classname/funcname.. // New classname/funcname..
const std::string name2(name + "<" + type2 + ">"); const std::string name2(name + "<" + type2 + ">");
// Create copy of template.. // Copy template..
for (const Token *tok3 = _tokens; tok3; tok3 = tok3->next())
{
// Start of template..
if (tok3 == tok)
{
tok3 = tok3->next();
}
// member function implemented outside class definition
else if (Token::Match(tok3, (pattern + " :: %var% (").c_str()))
{
addtoken(name2.c_str(), tok3->linenr(), tok3->fileIndex());
while (tok3->str() != "::")
tok3 = tok3->next();
}
// not part of template.. go on to next token
else
continue;
int indentlevel = 0; int indentlevel = 0;
for (const Token *tok3 = tok->next(); tok3; tok3 = tok3->next()) for (; tok3; tok3 = tok3->next())
{ {
for (unsigned int i = 0; i <= type.size(); ++i) for (unsigned int i = 0; i <= type.size(); ++i)
{ {
@ -562,6 +582,7 @@ void Tokenizer::tokenize(std::istream &code, const char FileName[])
--indentlevel; --indentlevel;
} }
} }
}
// Replace all these template usages.. // Replace all these template usages..
s = name + " < " + type2 + " >"; s = name + " < " + type2 + " >";

View File

@ -81,6 +81,7 @@ private:
TEST_CASE(template2); TEST_CASE(template2);
TEST_CASE(template3); TEST_CASE(template3);
TEST_CASE(template4); TEST_CASE(template4);
TEST_CASE(template5);
TEST_CASE(namespaces); TEST_CASE(namespaces);
} }
@ -508,6 +509,22 @@ private:
ASSERT_EQUALS(expected, sizeof_(code)); ASSERT_EQUALS(expected, sizeof_(code));
} }
void template5()
{
const char code[] = "template <classname T> class Fred { };\n"
"template <classname T> Fred<T>::Fred() { }\n"
"Fred<float> fred;";
const std::string expected(" "
"template < classname T > class Fred { } ; "
"template < classname T > Fred < T > :: Fred ( ) { } "
"Fred<float> fred ; "
"class Fred<float> { } "
"Fred<float> :: Fred<float> ( ) { }");
ASSERT_EQUALS(expected, sizeof_(code));
}
void namespaces() void namespaces()
{ {