Remove out of line member functions of instantiated template classes. (#1377)

* Remove out of line member functions of instantiated template classes.
This commit is contained in:
IOBYTE 2018-09-14 08:16:34 -04:00 committed by amai2012
parent 4e7ed9ea6e
commit e9a44f70b2
4 changed files with 48 additions and 61 deletions

View File

@ -929,25 +929,24 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::size
// hence this pattern: "> %type% [%type%] < ... > :: %type% ("
static bool getTemplateNamePositionTemplateMember(const Token *tok, int &namepos)
{
if (!Token::Match(tok, "> %type% <") && !Token::Match(tok, "> %type% %type% <"))
return false;
int currPos = 0;
currPos = 2 + (Token::Match(tok, "> %type% %type%"));
// Find the end of the template argument list
const Token *templateParmEnd = tok->linkAt(currPos);
if (!templateParmEnd)
templateParmEnd = tok->tokAt(currPos)->findClosingBracket();
if (!templateParmEnd)
return false;
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 + (templateParmEnd->strAt(2) == "~" ? 3 : 2);
return true;
namepos = 2;
while (tok && tok->next()) {
if (Token::Match(tok->next(), ";|{"))
return false;
else if (Token::Match(tok->next(), "%type% <")) {
const Token *closing = tok->tokAt(2)->findClosingBracket();
if (closing && Token::Match(closing->next(), ":: ~| %name% (")) {
if (closing->strAt(1) == "~")
closing = closing->next();
while (tok && tok->next() != closing->next()) {
tok = tok->next();
namepos++;
}
return true;
}
}
tok = tok->next();
namepos++;
}
return false;
}
@ -990,6 +989,7 @@ void TemplateSimplifier::expandTemplate(
{
std::list<ScopeInfo2> scopeInfo;
bool inTemplateDefinition = false;
const Token *startOfTemplateDeclaration = nullptr;
const Token *endOfTemplateDefinition = nullptr;
const Token * const templateDeclarationNameToken = templateDeclarationToken->tokAt(getTemplateNamePosition(templateDeclarationToken));
for (const Token *tok3 = mTokenList.front(); tok3; tok3 = tok3 ? tok3->next() : nullptr) {
@ -1000,8 +1000,10 @@ void TemplateSimplifier::expandTemplate(
if (inTemplateDefinition) {
if (!endOfTemplateDefinition && tok3->str() == "{")
endOfTemplateDefinition = tok3->link();
if (tok3 == endOfTemplateDefinition)
if (tok3 == endOfTemplateDefinition) {
inTemplateDefinition = false;
startOfTemplateDeclaration = nullptr;
}
}
if (tok3->str()=="template") {
@ -1015,6 +1017,7 @@ void TemplateSimplifier::expandTemplate(
} else {
inTemplateDefinition = false; // Only template instantiation
}
startOfTemplateDeclaration = tok3;
}
if (Token::Match(tok3, "(|["))
tok3 = tok3->link();
@ -1064,6 +1067,12 @@ void TemplateSimplifier::expandTemplate(
mTokenList.addtoken(newName, tok3->linenr(), tok3->fileIndex());
while (tok3 && tok3->str() != "::")
tok3 = tok3->next();
std::list<TokenAndName>::iterator it = std::find_if(mTemplateDeclarations.begin(),
mTemplateDeclarations.end(),
FindToken(startOfTemplateDeclaration));
if (it != mTemplateDeclarations.end())
mMemberFunctionsToDelete.push_back(*it);
}
// not part of template.. go on to next token
@ -1855,6 +1864,13 @@ void TemplateSimplifier::simplifyTemplates(
removeTemplate(it->token);
}
}
// remove out of line member functions
while (!mMemberFunctionsToDelete.empty()) {
removeTemplate(mMemberFunctionsToDelete.begin()->token);
mTemplateDeclarations.remove(mMemberFunctionsToDelete.front());
mMemberFunctionsToDelete.erase(mMemberFunctionsToDelete.begin());
}
}
}

View File

@ -69,6 +69,9 @@ public:
*/
struct TokenAndName {
TokenAndName(Token *tok, const std::string &s, const std::string &n);
bool operator == (const TokenAndName & rhs) const {
return token == rhs.token && scope == rhs.scope && name == rhs.name;
}
Token *token;
std::string scope;
std::string name;
@ -234,6 +237,7 @@ private:
std::list<TokenAndName> mTemplateDeclarations;
std::list<TokenAndName> mTemplateInstantiations;
std::list<TokenAndName> mInstantiatedTemplates;
std::list<TokenAndName> mMemberFunctionsToDelete;
};
/// @}

View File

@ -215,12 +215,7 @@ private:
"class Fred<float> { } ; "
"Fred<float> :: Fred<float> ( ) { }";
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));
ASSERT_EQUALS(expected, tok(code));
}
void template6() {
@ -563,8 +558,7 @@ private:
"A<int> a;\n";
// The expected result..
const char expected[] = "template < class T > A < T > :: ~ A ( ) { } " // <- TODO: this should be removed
"A<int> a ; "
const char expected[] = "A<int> a ; "
"class A<int> { public: ~ A<int> ( ) ; } ; "
"A<int> :: ~ A<int> ( ) { }";
ASSERT_EQUALS(expected, tok(code));
@ -950,9 +944,7 @@ private:
"template void Fred<float>::f();\n"
"template void Fred<int>::g();\n";
const char expected[] = "template < class T > void Fred < T > :: f ( ) { } "
"template < class T > void Fred < T > :: g ( ) { } "
"template void Fred<float> :: f ( ) ; "
const char expected[] = "template void Fred<float> :: f ( ) ; "
"template void Fred<int> :: g ( ) ; "
"class Fred<float> { void f ( ) ; void g ( ) ; } ; "
"void Fred<float> :: f ( ) { } "
@ -1147,7 +1139,6 @@ private:
"template <class T, unsigned S> C3<T, S>::C3(const C3<T, S> &v) { C1<T *> c1; }\n"
"C3<int,6> c3;";
const char exp[] = "template < class T > void f ( ) { x = y ? C1 < int > :: allocate ( 1 ) : 0 ; } "
"template < class T , int S > C3 < T , S > :: C3 ( const C3 < T , S > & v ) { C1 < T * > c1 ; } "
"C3<int,6> c3 ; "
"class C3<int,6> { } ; "
"C3<int,6> :: C3<int,6> ( const C3<int,6> & v ) { C1<int*> c1 ; } "
@ -1208,12 +1199,7 @@ private:
"const int * * foo ( ) ; "
"} ; "
"const int * * Fred<int> :: foo ( ) { return nullptr ; }";
const char curr[] = "template < class T > const int * * Fred < T > :: foo ( ) { return nullptr ; } "
"Fred<int> fred ; struct Fred<int> { "
"const int * * foo ( ) ; "
"} ; "
"const int * * Fred<int> :: foo ( ) { return nullptr ; }";
TODO_ASSERT_EQUALS(exp, curr, tok(code));
ASSERT_EQUALS(exp, tok(code));
}
void template67() { // ticket #8122
@ -1241,29 +1227,11 @@ private:
"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 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> ( ) { }";
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));
ASSERT_EQUALS(expected, tok(code));
}
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};

View File

@ -839,8 +839,7 @@ private:
"};\n"
"template <class T> Containter<T>::Containter() : mElements(nullptr) {}\n"
"Containter<int> intContainer;";
const char exp [] = "5: template < class T > Containter < T > :: Containter ( ) : mElements ( nullptr ) { }\n"
"6: Containter<int> intContainer@1 ; struct Containter<int> {\n"
const char exp [] = "6: Containter<int> intContainer@1 ; struct Containter<int> {\n"
"2: Containter<int> ( ) ;\n"
"3: int * mElements@2 ;\n"
"4: } ;\n"