TemplateSimplifier: Fix in expandTemplate
This commit is contained in:
parent
1eb2df34ad
commit
a80760cb6f
|
@ -774,8 +774,16 @@ void TemplateSimplifier::expandTemplate(
|
|||
std::list<Token *> &templateInstantiations)
|
||||
{
|
||||
bool inTemplateDefinition=false;
|
||||
const Token *endOfTemplateDefinition = nullptr;
|
||||
std::vector<const Token *> localTypeParametersInDeclaration;
|
||||
for (const Token *tok3 = tokenlist.front(); tok3; tok3 = tok3 ? tok3->next() : nullptr) {
|
||||
if (inTemplateDefinition) {
|
||||
if (!endOfTemplateDefinition && tok3->str() == "{")
|
||||
endOfTemplateDefinition = tok3->link();
|
||||
if (tok3 == endOfTemplateDefinition)
|
||||
inTemplateDefinition = false;
|
||||
}
|
||||
|
||||
if (tok3->str()=="template") {
|
||||
if (tok3->next() && tok3->next()->str()=="<") {
|
||||
TemplateParametersInDeclaration(tok3->tokAt(2), localTypeParametersInDeclaration);
|
||||
|
@ -799,6 +807,11 @@ void TemplateSimplifier::expandTemplate(
|
|||
// member function implemented outside class definition
|
||||
else if (inTemplateDefinition &&
|
||||
TemplateSimplifier::instantiateMatch(tok3, name, typeParametersInDeclaration.size(), ":: ~| %name% (")) {
|
||||
const Token *tok4 = tok3->next()->findClosingBracket();
|
||||
while (tok4 && tok4->str() != "(")
|
||||
tok4 = tok4->next();
|
||||
if (!Tokenizer::isFunctionHead(tok4, "{:", true))
|
||||
continue;
|
||||
tokenlist.addtoken(newName, tok3->linenr(), tok3->fileIndex());
|
||||
while (tok3 && tok3->str() != "::")
|
||||
tok3 = tok3->next();
|
||||
|
|
|
@ -504,8 +504,6 @@ public:
|
|||
*/
|
||||
const Token * isFunctionHead(const Token *tok, const std::string &endsWith) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* is token pointing at function head?
|
||||
* @param tok A '(' or ')' token in a possible function head
|
||||
|
@ -515,6 +513,8 @@ private:
|
|||
*/
|
||||
static const Token * isFunctionHead(const Token *tok, const std::string &endsWith, bool cpp);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* simplify "while (0)"
|
||||
*/
|
||||
|
|
|
@ -97,6 +97,7 @@ private:
|
|||
TEST_CASE(template57); // #7891
|
||||
TEST_CASE(template58); // #6021 - use after free (deleted tokens in simplifyCalculations)
|
||||
TEST_CASE(template59); // #8051 - TemplateSimplifier::simplifyTemplateInstantiation failure
|
||||
TEST_CASE(template60); // handling of methods outside template definition
|
||||
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||
TEST_CASE(template_unhandled);
|
||||
TEST_CASE(template_default_parameter);
|
||||
|
@ -1096,6 +1097,19 @@ private:
|
|||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
||||
void template60() { // Extracted from Clang testfile
|
||||
const char code[] = "template <typename T> struct S { typedef int type; };\n"
|
||||
"template <typename T> void f() {}\n"
|
||||
"template <typename T> void h() { f<typename S<T>::type(0)>(); }\n"
|
||||
"\n"
|
||||
"void j() { h<int>(); }";
|
||||
const char exp[] = "template < typename T > void f ( ) { } " // <- TODO: This template is not expanded
|
||||
"void j ( ) { h < int > ( ) ; } "
|
||||
"void h < int > ( ) { f < S < int > :: type ( 0 ) > ( ) ; } "
|
||||
"struct S < int > { } ;";
|
||||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
||||
void template_enum() {
|
||||
const char code1[] = "template <class T>\n"
|
||||
"struct Unconst {\n"
|
||||
|
|
Loading…
Reference in New Issue