small template simplifier fixes (#3168)
* small template simplifier optimization * don't look for template parameter name in default values * fix cppcheck warning * add test for TemplateSimplifier::getTemplateParametersInDeclaration() Also removed TemplateSimplifier::getTemplateParametersInDeclaration() return value since it wasn't used. * added another test Co-authored-by: Robert Reif <reif@FX6840>
This commit is contained in:
parent
b1eaa3021f
commit
c9f09fc73f
|
@ -1650,7 +1650,7 @@ void TemplateSimplifier::expandTemplate(
|
||||||
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
||||||
bool pointerType = false;
|
bool pointerType = false;
|
||||||
Token * const dst1 = dst->previous();
|
Token * const dst1 = dst->previous();
|
||||||
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token();
|
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype];
|
||||||
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
|
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
|
||||||
typetok = typetok->next()) {
|
typetok = typetok->next()) {
|
||||||
if (typeindentlevel == 0 && typetok->str() == "*")
|
if (typeindentlevel == 0 && typetok->str() == "*")
|
||||||
|
@ -1896,7 +1896,7 @@ void TemplateSimplifier::expandTemplate(
|
||||||
if (itype < typeParametersInDeclaration.size()) {
|
if (itype < typeParametersInDeclaration.size()) {
|
||||||
unsigned int typeindentlevel = 0;
|
unsigned int typeindentlevel = 0;
|
||||||
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
||||||
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token();
|
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype];
|
||||||
typetok && (typeindentlevel>0 || !Token::Match(typetok, ",|>"));
|
typetok && (typeindentlevel>0 || !Token::Match(typetok, ",|>"));
|
||||||
typetok = typetok->next()) {
|
typetok = typetok->next()) {
|
||||||
if (!Token::simpleMatch(typetok, "...")) {
|
if (!Token::simpleMatch(typetok, "...")) {
|
||||||
|
@ -2003,7 +2003,7 @@ void TemplateSimplifier::expandTemplate(
|
||||||
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
std::stack<Token *> brackets1; // holds "(" and "{" tokens
|
||||||
Token * const beforeTypeToken = mTokenList.back();
|
Token * const beforeTypeToken = mTokenList.back();
|
||||||
bool pointerType = false;
|
bool pointerType = false;
|
||||||
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype].token();
|
for (const Token *typetok = mTypesUsedInTemplateInstantiation[itype];
|
||||||
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
|
typetok && (typeindentlevel > 0 || !Token::Match(typetok, ",|>"));
|
||||||
typetok = typetok->next()) {
|
typetok = typetok->next()) {
|
||||||
if (typeindentlevel == 0 && typetok->str() == "*")
|
if (typeindentlevel == 0 && typetok->str() == "*")
|
||||||
|
@ -2817,7 +2817,7 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, Token *backToke
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token * TemplateSimplifier::getTemplateParametersInDeclaration(
|
void TemplateSimplifier::getTemplateParametersInDeclaration(
|
||||||
const Token * tok,
|
const Token * tok,
|
||||||
std::vector<const Token *> & typeParametersInDeclaration)
|
std::vector<const Token *> & typeParametersInDeclaration)
|
||||||
{
|
{
|
||||||
|
@ -2825,6 +2825,7 @@ const Token * TemplateSimplifier::getTemplateParametersInDeclaration(
|
||||||
|
|
||||||
typeParametersInDeclaration.clear();
|
typeParametersInDeclaration.clear();
|
||||||
const Token *end = tok->previous()->findClosingBracket();
|
const Token *end = tok->previous()->findClosingBracket();
|
||||||
|
bool inDefaultValue = false;
|
||||||
for (; tok && tok!= end; tok = tok->next()) {
|
for (; tok && tok!= end; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "template <")) {
|
if (Token::simpleMatch(tok, "template <")) {
|
||||||
const Token *closing = tok->next()->findClosingBracket();
|
const Token *closing = tok->next()->findClosingBracket();
|
||||||
|
@ -2832,10 +2833,22 @@ const Token * TemplateSimplifier::getTemplateParametersInDeclaration(
|
||||||
tok = closing->next();
|
tok = closing->next();
|
||||||
} else if (tok->link() && Token::Match(tok, "{|(|["))
|
} else if (tok->link() && Token::Match(tok, "{|(|["))
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
else if (Token::Match(tok, "%name% ,|>|="))
|
else if (Token::Match(tok, "%name% ,|>|=")) {
|
||||||
typeParametersInDeclaration.push_back(tok);
|
if (!inDefaultValue) {
|
||||||
|
typeParametersInDeclaration.push_back(tok);
|
||||||
|
if (tok->strAt(1) == "=")
|
||||||
|
inDefaultValue = true;
|
||||||
|
}
|
||||||
|
} else if (inDefaultValue) {
|
||||||
|
if (tok->str() == ",")
|
||||||
|
inDefaultValue = false;
|
||||||
|
else if (tok->str() == "<") {
|
||||||
|
const Token *closing = tok->findClosingBracket();
|
||||||
|
if (closing)
|
||||||
|
tok = closing;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TemplateSimplifier::matchSpecialization(
|
bool TemplateSimplifier::matchSpecialization(
|
||||||
|
@ -2909,7 +2922,7 @@ std::string TemplateSimplifier::getNewName(
|
||||||
else if (indentlevel > 0 && Token::Match(tok3, "> [,>]"))
|
else if (indentlevel > 0 && Token::Match(tok3, "> [,>]"))
|
||||||
--indentlevel;
|
--indentlevel;
|
||||||
if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) {
|
if (indentlevel == 0 && Token::Match(tok3->previous(), "[<,]")) {
|
||||||
mTypesUsedInTemplateInstantiation.emplace_back(tok3, "");
|
mTypesUsedInTemplateInstantiation.push_back(tok3);
|
||||||
}
|
}
|
||||||
if (tok3->str() == "(")
|
if (tok3->str() == "(")
|
||||||
++indentlevel;
|
++indentlevel;
|
||||||
|
|
|
@ -43,6 +43,8 @@ class TokenList;
|
||||||
|
|
||||||
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
/** @brief Simplify templates from the preprocessed and partially simplified code. */
|
||||||
class CPPCHECKLIB TemplateSimplifier {
|
class CPPCHECKLIB TemplateSimplifier {
|
||||||
|
friend class TestSimplifyTemplate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TemplateSimplifier(Tokenizer *tokenizer);
|
explicit TemplateSimplifier(Tokenizer *tokenizer);
|
||||||
~TemplateSimplifier();
|
~TemplateSimplifier();
|
||||||
|
@ -437,10 +439,8 @@ private:
|
||||||
* ^ tok
|
* ^ tok
|
||||||
* @param typeParametersInDeclaration template < typename T, typename S >
|
* @param typeParametersInDeclaration template < typename T, typename S >
|
||||||
* ^ [0] ^ [1]
|
* ^ [0] ^ [1]
|
||||||
* @return template < typename T, typename S >
|
|
||||||
* ^ return
|
|
||||||
*/
|
*/
|
||||||
static const Token * getTemplateParametersInDeclaration(
|
static void getTemplateParametersInDeclaration(
|
||||||
const Token * tok,
|
const Token * tok,
|
||||||
std::vector<const Token *> & typeParametersInDeclaration);
|
std::vector<const Token *> & typeParametersInDeclaration);
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ private:
|
||||||
std::list<TokenAndName> mInstantiatedTemplates;
|
std::list<TokenAndName> mInstantiatedTemplates;
|
||||||
std::list<TokenAndName> mMemberFunctionsToDelete;
|
std::list<TokenAndName> mMemberFunctionsToDelete;
|
||||||
std::vector<TokenAndName> mExplicitInstantiationsToDelete;
|
std::vector<TokenAndName> mExplicitInstantiationsToDelete;
|
||||||
std::vector<TokenAndName> mTypesUsedInTemplateInstantiation;
|
std::vector<const Token *> mTypesUsedInTemplateInstantiation;
|
||||||
std::unordered_map<const Token*, int> mTemplateNamePos;
|
std::unordered_map<const Token*, int> mTemplateNamePos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -243,6 +243,8 @@ private:
|
||||||
|
|
||||||
TEST_CASE(findTemplateDeclarationEnd);
|
TEST_CASE(findTemplateDeclarationEnd);
|
||||||
|
|
||||||
|
TEST_CASE(getTemplateParametersInDeclaration);
|
||||||
|
|
||||||
TEST_CASE(expandSpecialized1);
|
TEST_CASE(expandSpecialized1);
|
||||||
TEST_CASE(expandSpecialized2);
|
TEST_CASE(expandSpecialized2);
|
||||||
TEST_CASE(expandSpecialized3); // #8671
|
TEST_CASE(expandSpecialized3); // #8671
|
||||||
|
@ -5206,6 +5208,36 @@ private:
|
||||||
ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(){} int x;", "} int x ;"));
|
ASSERT(findTemplateDeclarationEndHelper("template <typename... f, c<h<e<typename f::d...>>::g>> void i(){} int x;", "} int x ;"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to unit test TemplateSimplifier::getTemplateParametersInDeclaration
|
||||||
|
bool getTemplateParametersInDeclarationHelper(const char code[], const std::vector<std::string> & params) {
|
||||||
|
Tokenizer tokenizer(&settings, this);
|
||||||
|
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.createTokens(istr, "test.cpp");
|
||||||
|
tokenizer.createLinks();
|
||||||
|
tokenizer.splitTemplateRightAngleBrackets(false);
|
||||||
|
|
||||||
|
std::vector<const Token *> typeParametersInDeclaration;
|
||||||
|
TemplateSimplifier::getTemplateParametersInDeclaration(tokenizer.tokens()->tokAt(2), typeParametersInDeclaration);
|
||||||
|
|
||||||
|
if (params.size() != typeParametersInDeclaration.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < typeParametersInDeclaration.size(); ++i) {
|
||||||
|
if (typeParametersInDeclaration[i]->str() != params[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTemplateParametersInDeclaration() {
|
||||||
|
ASSERT(getTemplateParametersInDeclarationHelper("template<typename T> class Fred {};", std::vector<std::string>{"T"}));
|
||||||
|
ASSERT(getTemplateParametersInDeclarationHelper("template<typename T=int> class Fred {};", std::vector<std::string>{"T"}));
|
||||||
|
ASSERT(getTemplateParametersInDeclarationHelper("template<typename T,typename U> class Fred {};", std::vector<std::string>{"T","U"}));
|
||||||
|
ASSERT(getTemplateParametersInDeclarationHelper("template<typename T,typename U=int> class Fred {};", std::vector<std::string>{"T","U"}));
|
||||||
|
ASSERT(getTemplateParametersInDeclarationHelper("template<typename T=int,typename U=int> class Fred {};", std::vector<std::string>{"T","U"}));
|
||||||
|
}
|
||||||
|
|
||||||
void expandSpecialized1() {
|
void expandSpecialized1() {
|
||||||
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
|
ASSERT_EQUALS("class A<int> { } ;", tok("template<> class A<int> {};"));
|
||||||
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};"));
|
ASSERT_EQUALS("class A<int> : public B { } ;", tok("template<> class A<int> : public B {};"));
|
||||||
|
|
Loading…
Reference in New Issue