fix location of forward declaration of specialized template (#3031)

This commit is contained in:
IOBYTE 2021-01-09 14:00:35 -05:00 committed by GitHub
parent f6c98a0999
commit 2482873029
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 1 deletions

View File

@ -1575,7 +1575,7 @@ void TemplateSimplifier::expandTemplate(
Token * start;
Token * end;
auto it = mTemplateForwardDeclarationsMap.find(dst);
if (it != mTemplateForwardDeclarationsMap.end()) {
if (!isSpecialization && it != mTemplateForwardDeclarationsMap.end()) {
dst = it->second;
dstStart = dst->previous();
const Token * temp1 = dst->tokAt(1)->findClosingBracket();
@ -1583,6 +1583,14 @@ void TemplateSimplifier::expandTemplate(
start = temp1->next();
end = temp2->linkAt(1)->next();
} else {
if (it != mTemplateForwardDeclarationsMap.end()) {
std::list<TokenAndName>::iterator it1 = std::find_if(mTemplateForwardDeclarations.begin(),
mTemplateForwardDeclarations.end(),
FindToken(it->second));
if (it1 != mTemplateForwardDeclarations.end())
mMemberFunctionsToDelete.push_back(*it1);
}
auto it2 = mTemplateSpecializationMap.find(dst);
if (it2 != mTemplateSpecializationMap.end()) {
dst = it2->second;
@ -3734,6 +3742,15 @@ void TemplateSimplifier::simplifyTemplates(
if (it != mTemplateDeclarations.end()) {
removeTemplate(it->token());
mTemplateDeclarations.erase(it);
} else {
const std::list<TokenAndName>::iterator it1 = std::find_if(mTemplateForwardDeclarations.begin(),
mTemplateForwardDeclarations.end(),
FindToken(mMemberFunctionsToDelete.begin()->token()));
// multiple functions can share the same declaration so make sure it hasn't already been deleted
if (it1 != mTemplateForwardDeclarations.end()) {
removeTemplate(it1->token());
mTemplateForwardDeclarations.erase(it1);
}
}
mMemberFunctionsToDelete.erase(mMemberFunctionsToDelete.begin());
}

View File

@ -209,6 +209,7 @@ private:
TEST_CASE(template164); // #9394
TEST_CASE(template165); // #10032 syntax error
TEST_CASE(template166); // #10081 hang
TEST_CASE(template167);
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)
@ -4189,6 +4190,34 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template167() {
const char code[] = "struct MathLib {\n"
" template<class T> static std::string toString(T value) {\n"
" return std::string{};\n"
" }\n"
"};\n"
"template<> std::string MathLib::toString(double value);\n"
"template<> std::string MathLib::toString(double value) {\n"
" return std::string{std::to_string(value)};\n"
"}\n"
"void foo() {\n"
" std::string str = MathLib::toString(1.0);\n"
"}";
const char exp[] = "struct MathLib { "
"static std :: string toString<double> ( double value ) ; "
"template < class T > static std :: string toString ( T value ) { "
"return std :: string { } ; "
"} "
"} ; "
"std :: string MathLib :: toString<double> ( double value ) { "
"return std :: string { std :: to_string ( value ) } ; "
"} "
"void foo ( ) { "
"std :: string str ; str = MathLib :: toString<double> ( 1.0 ) ; "
"}";
ASSERT_EQUALS(exp, 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"