parent
510748134f
commit
7ebc9d1b5f
|
@ -1000,7 +1000,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
continue;
|
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;
|
++templateParmDepth;
|
||||||
|
|
||||||
// end of template parameters?
|
// end of template parameters?
|
||||||
|
@ -1012,7 +1014,7 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
// map type parameter name to index
|
// 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;
|
typeParameterNames[tok->strAt(1)] = templatepar - 1;
|
||||||
|
|
||||||
// next template parameter
|
// next template parameter
|
||||||
|
@ -1054,7 +1056,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
tok1 = tok1->next();
|
tok1 = tok1->next();
|
||||||
} while (tok1 && tok1 != endLink);
|
} while (tok1 && tok1 != endLink);
|
||||||
instantiationArgs[index].push_back(tok1);
|
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();
|
const Token *endLink = tok1->findClosingBracket();
|
||||||
do {
|
do {
|
||||||
instantiationArgs[index].push_back(tok1);
|
instantiationArgs[index].push_back(tok1);
|
||||||
|
@ -1071,7 +1075,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
// count the parameters..
|
// count the parameters..
|
||||||
Token *tok = instantiation.token->next();
|
Token *tok = instantiation.token->next();
|
||||||
unsigned int usedpar = templateParameters(tok);
|
unsigned int usedpar = templateParameters(tok);
|
||||||
tok = tok->findClosingBracket();
|
Token *instantiationEnd = tok->findClosingBracket();
|
||||||
|
tok = instantiationEnd;
|
||||||
|
|
||||||
if (tok && tok->str() == ">") {
|
if (tok && tok->str() == ">") {
|
||||||
tok = tok->previous();
|
tok = tok->previous();
|
||||||
|
@ -1088,7 +1093,9 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
const Token *from = (*it)->next();
|
const Token *from = (*it)->next();
|
||||||
std::stack<Token *> links;
|
std::stack<Token *> links;
|
||||||
while (from && (!links.empty() || indentlevel || !Token::Match(from, ",|>"))) {
|
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;
|
++indentlevel;
|
||||||
else if (from->str() == ">")
|
else if (from->str() == ">")
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
|
@ -1123,6 +1130,8 @@ void TemplateSimplifier::useDefaultArgumentValues(TokenAndName &declaration)
|
||||||
usedpar++;
|
usedpar++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simplifyTemplateArgs(instantiation.token->next(), instantiationEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Token * const eqtok : eq) {
|
for (Token * const eqtok : eq) {
|
||||||
|
@ -2276,6 +2285,35 @@ void TemplateSimplifier::simplifyTemplateArgs(Token *start, Token *end)
|
||||||
} else if (tok->strAt(1) == "(") {
|
} else if (tok->strAt(1) == "(") {
|
||||||
tok = tok->linkAt(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;
|
return nullptr;
|
||||||
|
|
||||||
const Token *closing = nullptr;
|
const Token *closing = nullptr;
|
||||||
|
const bool templateParameter(strAt(-1) == "template");
|
||||||
|
std::set<std::string> templateParameters;
|
||||||
|
|
||||||
unsigned int depth = 0;
|
unsigned int depth = 0;
|
||||||
for (closing = this; closing != nullptr; closing = closing->next()) {
|
for (closing = this; closing != nullptr; closing = closing->next()) {
|
||||||
|
@ -864,7 +866,10 @@ const Token * Token::findClosingBracket() const
|
||||||
return nullptr; // #6803
|
return nullptr; // #6803
|
||||||
} else if (Token::Match(closing, "}|]|)|;"))
|
} else if (Token::Match(closing, "}|]|)|;"))
|
||||||
return nullptr;
|
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;
|
++depth;
|
||||||
else if (closing->str() == ">") {
|
else if (closing->str() == ">") {
|
||||||
if (--depth == 0)
|
if (--depth == 0)
|
||||||
|
@ -874,6 +879,10 @@ const Token * Token::findClosingBracket() const
|
||||||
return closing;
|
return closing;
|
||||||
depth -= 2;
|
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;
|
return closing;
|
||||||
|
|
|
@ -168,6 +168,7 @@ private:
|
||||||
TEST_CASE(template128); // #9224
|
TEST_CASE(template128); // #9224
|
||||||
TEST_CASE(template129);
|
TEST_CASE(template129);
|
||||||
TEST_CASE(template130); // #9246
|
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_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_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)
|
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||||
|
@ -3101,6 +3102,33 @@ private:
|
||||||
ASSERT_EQUALS(exp, tok(code));
|
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>> {..};
|
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
const char code[] = "template <typename T> struct C {};\n"
|
const char code[] = "template <typename T> struct C {};\n"
|
||||||
"template <typename T> struct S {a};\n"
|
"template <typename T> struct S {a};\n"
|
||||||
|
|
Loading…
Reference in New Issue