Merge pull request #310 from simartin/ticket_5816

Ticket #5816: Skip typename in template arguments for enum initializers.
This commit is contained in:
Daniel Marjamäki 2014-05-17 16:32:05 +02:00
commit 9ef7bb4525
2 changed files with 22 additions and 15 deletions

View File

@ -7558,23 +7558,17 @@ void Tokenizer::simplifyEnum()
enumValueStart = tok1; enumValueStart = tok1;
enumValueEnd = tok1; enumValueEnd = tok1;
int level = 0; while (enumValueEnd->next() && (!Token::Match(enumValueEnd->next(), "[},]"))) {
while (enumValueEnd->next() && (!Token::Match(enumValueEnd->next(), "[},]") || level)) { if (Token::Match(enumValueEnd, "(|[")) {
if (Token::Match(enumValueEnd, "(|[")) enumValueEnd = enumValueEnd->link();
++level; continue;
else if (Token::Match(enumValueEnd->next(), "]|)")) } else if (Token::Match(enumValueEnd, "%type% <") && isCPP() && TemplateSimplifier::templateParameters(enumValueEnd->next()) > 1U) {
--level; Token *endtoken = enumValueEnd->next();
else if (Token::Match(enumValueEnd, "%type% <") && isCPP() && TemplateSimplifier::templateParameters(enumValueEnd->next()) > 1U) { do {
Token *endtoken = enumValueEnd->tokAt(2);
while ((Token::Match(endtoken,"%any% *| [,>]") || Token::Match(endtoken,"%any% :: %any%")) && (endtoken->isName() || endtoken->isNumber())) {
endtoken = endtoken->next(); endtoken = endtoken->next();
if (endtoken->str() == "*") if (Token::Match(endtoken, "*|,|::|typename"))
endtoken = endtoken->next(); endtoken = endtoken->next();
if (endtoken->str() == ",") } while (Token::Match(endtoken, "%var%|%num% *| [,>]") || Token::Match(endtoken, "%var%|%num% :: %any%"));
endtoken = endtoken->next();
if (endtoken->str() == "::")
endtoken = endtoken->next();
}
if (endtoken->str() == ">") { if (endtoken->str() == ">") {
enumValueEnd = endtoken; enumValueEnd = endtoken;
if (Token::simpleMatch(endtoken, "> ( )")) if (Token::simpleMatch(endtoken, "> ( )"))

View File

@ -138,6 +138,7 @@ private:
TEST_CASE(template43); // #5097 - assert due to '>>' not treated as end of template instantiation TEST_CASE(template43); // #5097 - assert due to '>>' not treated as end of template instantiation
TEST_CASE(template44); // #5297 - TemplateSimplifier::simplifyCalculations not eager enough TEST_CASE(template44); // #5297 - TemplateSimplifier::simplifyCalculations not eager enough
TEST_CASE(template45); // #5814 - syntax error reported for valid code TEST_CASE(template45); // #5814 - syntax error reported for valid code
TEST_CASE(template46); // #5816 - syntax error reported for valid code
TEST_CASE(template_unhandled); TEST_CASE(template_unhandled);
TEST_CASE(template_default_parameter); TEST_CASE(template_default_parameter);
TEST_CASE(template_default_type); TEST_CASE(template_default_type);
@ -2403,6 +2404,18 @@ private:
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
} }
void template46() { // #5816
tok("template<class T, class U> struct A { static const int value = 0; }; "
"template <class T> struct B { "
" enum { value = A<typename T::type, int>::value }; "
"};");
ASSERT_EQUALS("", errout.str());
tok("template <class T, class U> struct A {}; "
"enum { e = sizeof(A<int, int>) }; "
"template <class T, class U> struct B {};");
ASSERT_EQUALS("", errout.str());
}
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"