Commit 28749545 authored by Milian Wolff's avatar Milian Wolff
Browse files

Handle operator--> properly in ParamIterator

This is actually `operator--` followed by an `>`, not a single
`operator->`. The problem only shows up when we nest this inside
a template template argument.
parent 2d72dfe4
......@@ -112,6 +112,13 @@ bool isOperator(const QString& str, int pos)
return endsWithWordBoundary(prefix);
}
// check for operator-> but don't get confused by operator-->
bool isArrowOperator(const QString& str, int pos)
{
Q_ASSERT(str[pos] == QLatin1Char('>'));
return pos > 0 && str[pos - 1] == QLatin1Char('-') && (pos == 1 || str[pos - 2] != QLatin1Char('-'));
}
int skipStringOrCharLiteral(const QString& str, int pos)
{
const auto quote = str[pos];
......@@ -163,8 +170,6 @@ int findClose(const QString& str, int pos)
QVarLengthArray<QChar, 16> st;
st.append(str[pos]);
QChar last = QLatin1Char(' ');
for (int a = pos + 1; a < str.length(); a++) {
switch (str[a].unicode()) {
case '<':
......@@ -178,10 +183,9 @@ int findClose(const QString& str, int pos)
depth++;
break;
case '>':
if (isOperator(str, a))
break;
if (last == QLatin1Char('-'))
if (isOperator(str, a) || isArrowOperator(str, a))
break;
[[fallthrough]];
case ')':
case ']':
......@@ -194,12 +198,9 @@ int findClose(const QString& str, int pos)
case '"':
case '\'':
a = skipStringOrCharLiteral(str, a);
last = str[a - 1];
break;
}
last = str[a];
if (depth == 0) {
return a;
}
......@@ -228,8 +229,9 @@ int findCommaOrEnd(const QString& str, int pos, QChar validEnd)
return str.length();
break;
case '>':
if (isOperator(str, a))
if (isOperator(str, a) || isArrowOperator(str, a))
break;
[[fallthrough]];
case ')':
case ']':
......
......@@ -159,7 +159,10 @@ void TestStringHelpers::testParamIterator_data()
addTest("A<'>'>", {"'>'"});
addTest("myoperator<anoperator<anotheroperator>, my_operator>", {"anoperator<anotheroperator>", "my_operator"});
addTest("Y<decltype(&X::operator<=), &X::operator<=>", {"decltype(&X::operator<=)", "&X::operator<="});
addTest("Y<decltype(&X::operator->), &X::operator->>", {"decltype(&X::operator->)", "&X::operator->"});
addTest("Y<decltype(&X::operator->), Z<&X::operator->>>", {"decltype(&X::operator->)", "Z<&X::operator->>"});
addTest("Y<decltype(&X::operator--), &X::operator-->", {"decltype(&X::operator--)", "&X::operator--"});
addTest("Y<decltype(&X::operator--), Z<&X::operator-->>", {"decltype(&X::operator--)", "Z<&X::operator-->"});
}
void TestStringHelpers::testParamIterator()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment