parent
510748134f
commit
7ebc9d1b5f
|
@ -1000,7 +1000,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tok->str() == "<" && (tok->strAt(1) == ">" || templateParameters(tok)))
|
||||
if (tok->str() == "<" &&
|
||||
(tok->strAt(1) == ">" || (tok->previous()->isName() &&
|
||||
typeParameterNames.find(tok->strAt(-1)) == typeParameterNames.end())))
|
||||
++templateParmDepth;
|
||||
|
||||
// end of template parameters?
|
||||
|
@ -1012,7 +1014,7 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
}
|
||||
|
||||
// map type parameter name to index
|
||||
if (Token::Match(tok, "typename|class %name% ,|>"))
|
||||
if (Token::Match(tok, "typename|class|%type% %name% ,|>"))
|
||||
typeParameterNames[tok->strAt(1)] = templatepar - 1;
|
||||
|
||||
// next template parameter
|
||||
|
@ -1054,7 +1056,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
tok1 = tok1->next();
|
||||
} while (tok1 && tok1 != endLink);
|
||||
instantiationArgs[index].push_back(tok1);
|
||||
} else if (tok1->str() == "<" && (tok1->strAt(1) == ">" || templateParameters(tok1))) {
|
||||
} else if (tok1->str() == "<" &&
|
||||
(tok1->strAt(1) == ">" || (tok1->previous()->isName() &&
|
||||
typeParameterNames.find(tok1->strAt(-1)) == typeParameterNames.end()))) {
|
||||
const Token *endLink = tok1->findClosingBracket();
|
||||
do {
|
||||
instantiationArgs[index].push_back(tok1);
|
||||
|
@ -1071,7 +1075,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
// count the parameters..
|
||||
Token *tok = instantiation.token->next();
|
||||
unsigned int usedpar = templateParameters(tok);
|
||||
tok = tok->findClosingBracket();
|
||||
Token *instantiationEnd = tok->findClosingBracket();
|
||||
tok = instantiationEnd;
|
||||
|
||||
if (tok && tok->str() == ">") {
|
||||
tok = tok->previous();
|
||||
|
@ -1088,7 +1093,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
const Token *from = (*it)->next();
|
||||
std::stack<Token *> links;
|
||||
while (from && (!links.empty() || indentlevel || !Token::Match(from, ",|>"))) {
|
||||
if (from->str() == "<" && (from->strAt(1) == ">" || templateParameters(from)))
|
||||
if (from->str() == "<" &&
|
||||
(from->strAt(1) == ">" || (from->previous()->isName() &&
|
||||
typeParameterNames.find(from->strAt(-1)) == typeParameterNames.end())))
|
||||
++indentlevel;
|
||||
else if (from->str() == ">")
|
||||
--indentlevel;
|
||||
|
@ -1123,6 +1130,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
|||
usedpar++;
|
||||
}
|
||||
}
|
||||
|
||||
simplifyTemplateArgs(instantiation.token->next(), instantiationEnd);
|
||||
}
|
||||
|
||||
for (Token * const eqtok : eq) {
|
||||
|
@ -2276,6 +2285,35 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
|||
} else if (tok->strAt(1) == "(") {
|
||||
tok = tok->linkAt(1);
|
||||
}
|
||||
} else if (Token::Match(tok, "%num% %comp% %num%") &&
|
||||
MathLib::isInt(tok->str()) &&
|
||||
MathLib::isInt(tok->strAt(2))) {
|
||||
if ((Token::Match(tok->previous(), "(|&&|%oror%|,") || tok->previous() == start) &&
|
||||
(Token::Match(tok->tokAt(3), ")|&&|%oror%|?") || tok->tokAt(3) == end)) {
|
||||
const MathLib::bigint op1(MathLib::toLongNumber(tok->str()));
|
||||
const std::string &cmp(tok->next()->str());
|
||||
const MathLib::bigint op2(MathLib::toLongNumber(tok->strAt(2)));
|
||||
|
||||
std::string result;
|
||||
|
||||
if (cmp == "==")
|
||||
result = (op1 == op2) ? "true" : "false";
|
||||
else if (cmp == "!=")
|
||||
result = (op1 != op2) ? "true" : "false";
|
||||
else if (cmp == "<=")
|
||||
result = (op1 <= op2) ? "true" : "false";
|
||||
else if (cmp == ">=")
|
||||
result = (op1 >= op2) ? "true" : "false";
|
||||
else if (cmp == "<")
|
||||
result = (op1 < op2) ? "true" : "false";
|
||||
else
|
||||
result = (op1 > op2) ? "true" : "false";
|
||||
|
||||
tok->str(result);
|
||||
tok->deleteNext(2);
|
||||
again = true;
|
||||
tok = tok->previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -855,6 +855,8 @@ const Token * Token::findClosingBracket() const
|
|||
return nullptr;
|
||||
|
||||
const Token *closing = nullptr;
|
||||
const bool templateParameter(strAt(-1) == "template");
|
||||
std::set<std::string> templateParameters;
|
||||
|
||||
unsigned int depth = 0;
|
||||
for (closing = this; closing != nullptr; closing = closing->next()) {
|
||||
|
@ -864,7 +866,10 @@ const Token * Token::findClosingBracket() const
|
|||
return nullptr; // #6803
|
||||
} else if (Token::Match(closing, "}|]|)|;"))
|
||||
return nullptr;
|
||||
else if (closing->str() == "<")
|
||||
// we can make some guesses for template parameters
|
||||
else if (closing->str() == "<" &&
|
||||
(!templateParameter || (closing->previous() && closing->previous()->isName() &&
|
||||
templateParameters.find(closing->strAt(-1)) == templateParameters.end())))
|
||||
++depth;
|
||||
else if (closing->str() == ">") {
|
||||
if (--depth == 0)
|
||||
|
@ -874,6 +879,10 @@ const Token * Token::findClosingBracket() const
|
|||
return closing;
|
||||
depth -= 2;
|
||||
}
|
||||
// save named template parameter
|
||||
else if (templateParameter && depth == 1 && closing->str() == "," &&
|
||||
closing->previous()->isName() && !Match(closing->previous(), "class|typename|."))
|
||||
templateParameters.insert(closing->strAt(-1));
|
||||
}
|
||||
|
||||
return closing;
|
||||
|
|
|
@ -168,6 +168,7 @@ private:
|
|||
TEST_CASE(template128); // #9224
|
||||
TEST_CASE(template129);
|
||||
TEST_CASE(template130); // #9246
|
||||
TEST_CASE(template131); // #9249
|
||||
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)
|
||||
|
@ -3101,6 +3102,33 @@ private:
|
|||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
||||
void template131() { // #9249
|
||||
{
|
||||
const char code[] = "template <long a, bool = 0 == a> struct b {};\n"
|
||||
"b<1> b1;";
|
||||
const char exp[] = "struct b<1,false> ; "
|
||||
"b<1,false> b1 ; "
|
||||
"struct b<1,false> { } ;";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template <long a, bool = a < 0> struct b {};\n"
|
||||
"b<1> b1;";
|
||||
const char exp[] = "struct b<1,false> ; "
|
||||
"b<1,false> b1 ; "
|
||||
"struct b<1,false> { } ;";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
{
|
||||
const char code[] = "template <long a, bool = 0 < a> struct b {};\n"
|
||||
"b<1> b1;";
|
||||
const char exp[] = "struct b<1,true> ; "
|
||||
"b<1,true> b1 ; "
|
||||
"struct b<1,true> { } ;";
|
||||
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"
|
||||
|
|
Loading…
Reference in New Issue