Fixed #6883 (Template parsing error)
This commit is contained in:
parent
ad01a89e05
commit
8568a80208
|
@ -3059,8 +3059,16 @@ void Tokenizer::createLinks2()
|
||||||
if (isC())
|
if (isC())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const Token * templateToken = nullptr;
|
||||||
|
bool isStruct = false;
|
||||||
|
|
||||||
std::stack<Token*> type;
|
std::stack<Token*> type;
|
||||||
for (Token *token = list.front(); token; token = token->next()) {
|
for (Token *token = list.front(); token; token = token->next()) {
|
||||||
|
if (Token::Match(token, "struct|class %name% :"))
|
||||||
|
isStruct = true;
|
||||||
|
else if (Token::Match(token, "[;{}]"))
|
||||||
|
isStruct = false;
|
||||||
|
|
||||||
if (token->link()) {
|
if (token->link()) {
|
||||||
if (Token::Match(token, "{|[|("))
|
if (Token::Match(token, "{|[|("))
|
||||||
type.push(token);
|
type.push(token);
|
||||||
|
@ -3068,16 +3076,17 @@ void Tokenizer::createLinks2()
|
||||||
while (type.top()->str() == "<")
|
while (type.top()->str() == "<")
|
||||||
type.pop();
|
type.pop();
|
||||||
type.pop();
|
type.pop();
|
||||||
|
templateToken = nullptr;
|
||||||
} else
|
} else
|
||||||
token->link(0);
|
token->link(0);
|
||||||
}
|
} else if (!templateToken && !isStruct && Token::Match(token, "%oror%|&&|;")) {
|
||||||
|
|
||||||
else if (Token::Match(token, "%oror%|&&|;"))
|
|
||||||
while (!type.empty() && type.top()->str() == "<")
|
while (!type.empty() && type.top()->str() == "<")
|
||||||
type.pop();
|
type.pop();
|
||||||
else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId())
|
} else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId()) {
|
||||||
type.push(token);
|
type.push(token);
|
||||||
else if (token->str() == ">") {
|
if (!templateToken && (token->previous()->str() == "template"))
|
||||||
|
templateToken = token;
|
||||||
|
} else if (token->str() == ">") {
|
||||||
if (type.empty() || type.top()->str() != "<") // < and > don't match.
|
if (type.empty() || type.top()->str() != "<") // < and > don't match.
|
||||||
continue;
|
continue;
|
||||||
if (token->next() && !Token::Match(token->next(), "%name%|>|&|*|::|,|(|)|{|;|[|:"))
|
if (token->next() && !Token::Match(token->next(), "%name%|>|&|*|::|,|(|)|{|;|[|:"))
|
||||||
|
@ -3097,6 +3106,9 @@ void Tokenizer::createLinks2()
|
||||||
Token* top = type.top();
|
Token* top = type.top();
|
||||||
type.pop();
|
type.pop();
|
||||||
|
|
||||||
|
if (top == templateToken)
|
||||||
|
templateToken = nullptr;
|
||||||
|
|
||||||
Token::createMutualLinks(top, token);
|
Token::createMutualLinks(top, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4514,6 +4514,28 @@ private:
|
||||||
ASSERT_EQUALS(true, tok->linkAt(3) == nullptr);
|
ASSERT_EQUALS(true, tok->linkAt(3) == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "template < f = b || c > struct S;";
|
||||||
|
errout.str("");
|
||||||
|
Tokenizer tokenizer(&settings0, this);
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
const Token *tok = tokenizer.tokens();
|
||||||
|
ASSERT_EQUALS(true, tok->linkAt(1) == tok->tokAt(7));
|
||||||
|
ASSERT_EQUALS(true, tok->tokAt(1) == tok->linkAt(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char code[] = "struct A : B<c&&d> {};";
|
||||||
|
errout.str("");
|
||||||
|
Tokenizer tokenizer(&settings0, this);
|
||||||
|
std::istringstream istr(code);
|
||||||
|
tokenizer.tokenize(istr, "test.cpp");
|
||||||
|
const Token *tok = tokenizer.tokens();
|
||||||
|
ASSERT_EQUALS(true, tok->linkAt(4) == tok->tokAt(8));
|
||||||
|
ASSERT_EQUALS(true, tok->tokAt(4) == tok->linkAt(8));
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// #6601
|
// #6601
|
||||||
const char code[] = "template<class R> struct FuncType<R(&)()> : FuncType<R()> { };";
|
const char code[] = "template<class R> struct FuncType<R(&)()> : FuncType<R()> { };";
|
||||||
|
|
Loading…
Reference in New Issue