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)
{
// get the position of the template name
int namepos = 0;
int namepos = 0, starAmpPossiblePosition = 0;
if (Token::Match(tok, "> class|struct %type% {|:"))
namepos = 2;
else if (Token::Match(tok, "> %type% *|&| %type% ("))
namepos = 2;
else if (Token::Match(tok, "> %type% %type% *|&| %type% ("))
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
return -1;
}
if ((tok->strAt(namepos) == "*" || tok->strAt(namepos) == "&"))
if (Token::Match(tok->tokAt(starAmpPossiblePosition ? starAmpPossiblePosition : namepos), "*|&"))
++namepos;
return namepos;

View File

@ -95,6 +95,8 @@ private:
// Test TemplateSimplifier::templateParameters
TEST_CASE(templateParameters);
TEST_CASE(templateParameters1); // #4169 - segmentation fault
TEST_CASE(templateNamePosition);
}
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
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)