Ticket #6567: Handle member functions in TemplateSimplifier::getTemplateNamePosition.

This commit is contained in:
Simon Martin 2015-03-07 21:52:12 +01:00
parent 0131bda065
commit 1d973b882d
2 changed files with 48 additions and 3 deletions

View File

@ -699,18 +699,24 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri
int TemplateSimplifier::getTemplateNamePosition(const Token *tok) int TemplateSimplifier::getTemplateNamePosition(const Token *tok)
{ {
// get the position of the template name // get the position of the template name
int namepos = 0; int namepos = 0, starAmpPossiblePosition = 0;
if (Token::Match(tok, "> class|struct %type% {|:")) if (Token::Match(tok, "> class|struct %type% {|:"))
namepos = 2; namepos = 2;
else if (Token::Match(tok, "> %type% *|&| %type% (")) else if (Token::Match(tok, "> %type% *|&| %type% ("))
namepos = 2; namepos = 2;
else if (Token::Match(tok, "> %type% %type% *|&| %type% (")) else if (Token::Match(tok, "> %type% %type% *|&| %type% ("))
namepos = 3; namepos = 3;
else { else if (Token::Match(tok, "> %type% *|&| %type% :: %type% (")) {
namepos = 4;
starAmpPossiblePosition = 2;
} else if (Token::Match(tok, "> %type% %type% *|&| %type% :: %type% (")) {
namepos = 5;
starAmpPossiblePosition = 3;
} else {
// Name not found // Name not found
return -1; return -1;
} }
if ((tok->strAt(namepos) == "*" || tok->strAt(namepos) == "&")) if (Token::Match(tok->tokAt(starAmpPossiblePosition ? starAmpPossiblePosition : namepos), "*|&"))
++namepos; ++namepos;
return namepos; return namepos;

View File

@ -95,6 +95,8 @@ private:
// Test TemplateSimplifier::templateParameters // Test TemplateSimplifier::templateParameters
TEST_CASE(templateParameters); TEST_CASE(templateParameters);
TEST_CASE(templateParameters1); // #4169 - segmentation fault TEST_CASE(templateParameters1); // #4169 - segmentation fault
TEST_CASE(templateNamePosition);
} }
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Unspecified) { std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Unspecified) {
@ -1110,6 +1112,43 @@ private:
// do not crash on invalid code // do not crash on invalid code
ASSERT_EQUALS(0, templateParameters(code)); ASSERT_EQUALS(0, templateParameters(code));
} }
// Helper function to unit test TemplateSimplifier::getTemplateNamePosition
int templateNamePositionHelper(const char code[], unsigned offset = 0) {
Settings settings;
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp", "", true);
const Token *tok = tokenizer.tokens();
for (unsigned i = 0 ; i < offset ; ++i)
tok = tok->next();
return TemplateSimplifier::getTemplateNamePosition(tok);
}
void templateNamePosition() {
// Template class
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A {};", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A {};", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A : B {};", 4));
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A : B {};", 4));
// Template function definitions
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> unsigned foo() { return 0; }", 4));
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> unsigned* foo() { return 0; }", 4));
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> const unsigned foo() { return 0; }", 4));
ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> const unsigned& foo() { return 0; }", 4));
// Class template members
ASSERT_EQUALS(4, templateNamePositionHelper("class A { template<class T> unsigned foo(); }; "
"template<class T> unsigned A::foo() { return 0; }", 19));
ASSERT_EQUALS(5, templateNamePositionHelper("class A { template<class T> const unsigned foo(); }; "
"template<class T> const unsigned A::foo() { return 0; }", 20));
TODO_ASSERT_EQUALS(7, -1, templateNamePositionHelper("class A { class B { template<class T> const unsigned foo(); }; } ; "
"template<class T> const unsigned A::B::foo() { return 0; }", 25));
// Template class member
TODO_ASSERT_EQUALS(7, -1, templateNamePositionHelper("template<class T> class A { unsigned foo(); }; "
"template<class T> unsigned A<T>::foo() { return 0; }", 19));
}
}; };
REGISTER_TEST(TestSimplifyTemplate) REGISTER_TEST(TestSimplifyTemplate)