This commit is contained in:
parent
8d88f75f03
commit
7224ee27d9
|
@ -942,11 +942,11 @@ static bool getTemplateNamePositionTemplateMember(const Token *tok, int &namepos
|
|||
if (!templateParmEnd)
|
||||
return false;
|
||||
|
||||
if (Token::Match(templateParmEnd->next(), ":: %type% (")) {
|
||||
if (Token::Match(templateParmEnd->next(), ":: ~| %type% (")) {
|
||||
// We have a match, and currPos points at the template list opening '<'. Move it to the closing '>'
|
||||
for (const Token *tok2 = tok->tokAt(currPos) ; tok2 != templateParmEnd ; tok2 = tok2->next())
|
||||
++currPos;
|
||||
namepos = currPos + 2;
|
||||
namepos = currPos + (templateParmEnd->strAt(2) == "~" ? 3 : 2);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1053,7 +1053,12 @@ void TemplateSimplifier::expandTemplate(
|
|||
tok5 = tok5->next();
|
||||
// copy return type
|
||||
while (tok5 && tok5 != tok3) {
|
||||
mTokenList.addtoken(tok5, tok5->linenr(), tok5->fileIndex());
|
||||
// replace name if found
|
||||
if (Token::Match(tok5, "%name% <") && tok5->str() == fullName) {
|
||||
mTokenList.addtoken(newName, tok5->linenr(), tok5->fileIndex());
|
||||
tok5 = tok5->next()->findClosingBracket();
|
||||
} else
|
||||
mTokenList.addtoken(tok5, tok5->linenr(), tok5->fileIndex());
|
||||
tok5 = tok5->next();
|
||||
}
|
||||
mTokenList.addtoken(newName, tok3->linenr(), tok3->fileIndex());
|
||||
|
@ -1100,9 +1105,7 @@ void TemplateSimplifier::expandTemplate(
|
|||
|
||||
// replace name..
|
||||
if (tok3->str() == lastName) {
|
||||
if (Token::Match(tok3->tokAt(-2), "> :: %name% ( )")) {
|
||||
; // Ticket #7942: Replacing for out-of-line constructors generates invalid syntax
|
||||
} else if (!Token::simpleMatch(tok3->next(), "<")) {
|
||||
if (!Token::simpleMatch(tok3->next(), "<")) {
|
||||
mTokenList.addtoken(newName, tok3->linenr(), tok3->fileIndex());
|
||||
continue;
|
||||
} else if (tok3 == templateDeclarationNameToken) {
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
TEST_CASE(template64); // #8683
|
||||
TEST_CASE(template65); // #8321
|
||||
TEST_CASE(template66); // #8725
|
||||
TEST_CASE(template67); // #8122
|
||||
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)
|
||||
|
@ -210,12 +211,16 @@ private:
|
|||
"template <class T> Fred<T>::Fred() { }\n"
|
||||
"Fred<float> fred;";
|
||||
|
||||
const char expected[] = "template < class T > Fred < T > :: Fred ( ) { } " // <- TODO: this should be removed
|
||||
"Fred<float> fred ; "
|
||||
const char expected[] = "Fred<float> fred ; "
|
||||
"class Fred<float> { } ; "
|
||||
"Fred<float> :: Fred ( ) { }";
|
||||
"Fred<float> :: Fred<float> ( ) { }";
|
||||
|
||||
ASSERT_EQUALS(expected, tok(code));
|
||||
const char actual[] = "template < class T > Fred < T > :: Fred ( ) { } " // <- TODO: this should be removed
|
||||
"Fred<float> fred ; "
|
||||
"class Fred<float> { } ; "
|
||||
"Fred<float> :: Fred<float> ( ) { }";
|
||||
|
||||
TODO_ASSERT_EQUALS(expected, actual, tok(code));
|
||||
}
|
||||
|
||||
void template6() {
|
||||
|
@ -1211,6 +1216,56 @@ private:
|
|||
TODO_ASSERT_EQUALS(exp, curr, tok(code));
|
||||
}
|
||||
|
||||
void template67() { // ticket #8122
|
||||
const char code[] = "template <class T> struct Containter {\n"
|
||||
" Containter();\n"
|
||||
" Containter(const Containter &);\n"
|
||||
" Containter & operator = (const Containter &);\n"
|
||||
" ~Containter();\n"
|
||||
" T* mElements;\n"
|
||||
" const Containter * c;\n"
|
||||
"};\n"
|
||||
"template <class T> Containter<T>::Containter() : mElements(nullptr), c(nullptr) {}\n"
|
||||
"template <class T> Containter<T>::Containter(const Containter & x) { nElements = x.nElements; c = x.c; }\n"
|
||||
"template <class T> Containter<T> & Containter<T>::operator = (const Containter & x) { mElements = x.mElements; c = x.c; return *this; }\n"
|
||||
"template <class T> Containter<T>::~Containter() {}\n"
|
||||
"Containter<int> intContainer;";
|
||||
|
||||
const char expected[] = "Containter<int> intContainer ; "
|
||||
"struct Containter<int> { "
|
||||
"Containter<int> ( ) ; "
|
||||
"Containter<int> ( const Containter<int> & ) ; "
|
||||
"Containter<int> & operator= ( const Containter<int> & ) ; "
|
||||
"~ Containter<int> ( ) ; "
|
||||
"int * mElements ; "
|
||||
"const Containter<int> * c ; "
|
||||
"} ; "
|
||||
"Containter<int> :: Containter<int> ( ) : mElements ( nullptr ) , c ( nullptr ) { } "
|
||||
"Containter<int> :: Containter<int> ( const Containter<int> & ) { nElements = x . nElements ; c = x . c ; } "
|
||||
"Containter<int> & Containter<int> :: operator= ( const Containter<int> & x) { mElements = x . mElements ; c = x . c ; return * this ; }\n"
|
||||
"Containter<int> :: ~ Containter<int> ( ) { }";
|
||||
|
||||
const char actual[] = "template < class T > Containter < T > :: Containter ( ) : mElements ( nullptr ) , c ( nullptr ) { } "
|
||||
"template < class T > Containter < T > :: Containter ( const Containter & x ) { nElements = x . nElements ; c = x . c ; } "
|
||||
"template < class T > Containter < T > & Containter < T > :: operator= ( const Containter & x ) { mElements = x . mElements ; c = x . c ; return * this ; } "
|
||||
"template < class T > Containter < T > :: ~ Containter ( ) { } "
|
||||
"Containter<int> intContainer ; "
|
||||
"struct Containter<int> { "
|
||||
"Containter<int> ( ) ; "
|
||||
"Containter<int> ( const Containter<int> & ) ; "
|
||||
"Containter<int> & operator= ( const Containter<int> & ) ; "
|
||||
"~ Containter<int> ( ) ; "
|
||||
"int * mElements ; "
|
||||
"const Containter<int> * c ; "
|
||||
"} ; "
|
||||
"Containter<int> :: Containter<int> ( ) : mElements ( nullptr ) , c ( nullptr ) { } "
|
||||
"Containter<int> :: Containter<int> ( const Containter<int> & x ) { nElements = x . nElements ; c = x . c ; } "
|
||||
"Containter<int> & Containter<int> :: operator= ( const Containter<int> & x ) { mElements = x . mElements ; c = x . c ; return * this ; } "
|
||||
"Containter<int> :: ~ Containter<int> ( ) { }";
|
||||
|
||||
TODO_ASSERT_EQUALS(expected, actual, 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"
|
||||
|
|
|
@ -843,7 +843,7 @@ private:
|
|||
"2: Containter<int> ( ) ;\n"
|
||||
"3: int * mElements@2 ;\n"
|
||||
"4: } ;\n"
|
||||
"5: Containter<int> :: Containter ( ) : mElements@2 ( nullptr ) { }\n";
|
||||
"5: Containter<int> :: Containter<int> ( ) : mElements@2 ( nullptr ) { }\n";
|
||||
ASSERT_EQUALS(exp, tokenizeDebugListing(code, /*simplify=*/true));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue