forked from qt-creator/qt-creator
C++: Fix variable template parsing in expression
Fix parser to not fail on TemplateId without parentheses, for example: int i = foo<int> + foo<char>; This fixes std::pair structure parsing in MSVC headers and find Usages to work with pair->first and pair->second. Change-Id: Ic300ea99d44a749705430d5eb47b2744715af995 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
6
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
6
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -5066,12 +5066,6 @@ bool Parser::parseNameId(NameAST *&name)
|
||||
case T_CONST_CAST:
|
||||
rewind(start);
|
||||
return parseName(name, false);
|
||||
|
||||
default:
|
||||
if (tok().isLiteral() || tok().isPunctuationOrOperator()) {
|
||||
rewind(start);
|
||||
return parseName(name, false);
|
||||
}
|
||||
} // switch
|
||||
|
||||
return true;
|
||||
|
||||
@@ -173,6 +173,7 @@ private slots:
|
||||
//! "template<class ...Args> class T : Args... {};"
|
||||
void cpp11_variadic_inheritance();
|
||||
void cpp11_attributes();
|
||||
void variableTemplatesInExpression();
|
||||
|
||||
// Q_PROPERTY
|
||||
void cpp_qproperty();
|
||||
@@ -1354,6 +1355,19 @@ void tst_AST::cpp11_attributes()
|
||||
QVERIFY(attr != nullptr);
|
||||
}
|
||||
|
||||
void tst_AST::variableTemplatesInExpression()
|
||||
{
|
||||
QSharedPointer<TranslationUnit> unit(parseDeclaration("int i = t<int> + t<char>;",
|
||||
false, false, true));
|
||||
AST *ast = unit->ast();
|
||||
QVERIFY(ast != nullptr);
|
||||
|
||||
QCOMPARE(diag.errorCount, 0);
|
||||
|
||||
DeclarationAST *d = ast->asDeclaration();
|
||||
QVERIFY(d != nullptr);
|
||||
}
|
||||
|
||||
void tst_AST::if_constexpr()
|
||||
{
|
||||
QSharedPointer<TranslationUnit> unit(parseStatement("if constexpr (a) b;",true));
|
||||
|
||||
@@ -125,6 +125,7 @@ private Q_SLOTS:
|
||||
void templatePartialSpecialization();
|
||||
void templatePartialSpecialization_2();
|
||||
void template_SFINAE_1();
|
||||
void variableTemplateInExpression();
|
||||
};
|
||||
|
||||
void tst_FindUsages::dump(const QList<Usage> &usages) const
|
||||
@@ -1580,5 +1581,48 @@ int main(){
|
||||
QCOMPARE(find.usages().size(), 2);
|
||||
}
|
||||
|
||||
void tst_FindUsages::variableTemplateInExpression()
|
||||
{
|
||||
const QByteArray src =
|
||||
R"(
|
||||
struct S{int value;};
|
||||
template<class T> constexpr int foo = sizeof(T);
|
||||
template<class T1, class T2>
|
||||
struct pair{
|
||||
pair() noexcept(foo<T1> + foo<T2>){}
|
||||
T1 first;
|
||||
T2 second;
|
||||
};
|
||||
int main(){
|
||||
pair<int, S> pair;
|
||||
pair.second.value;
|
||||
}
|
||||
)";
|
||||
|
||||
Document::Ptr doc = Document::create("variableTemplateInExpression");
|
||||
doc->setUtf8Source(src);
|
||||
doc->parse();
|
||||
doc->check();
|
||||
|
||||
QVERIFY(doc->diagnosticMessages().isEmpty());
|
||||
QVERIFY(doc->globalSymbolCount()>=1);
|
||||
|
||||
Snapshot snapshot;
|
||||
snapshot.insert(doc);
|
||||
|
||||
Class *s = doc->globalSymbolAt(0)->asClass();
|
||||
QVERIFY(s);
|
||||
QCOMPARE(s->name()->identifier()->chars(), "S");
|
||||
QCOMPARE(s->memberCount(), 1);
|
||||
|
||||
Declaration *sv = s->memberAt(0)->asDeclaration();
|
||||
QVERIFY(sv);
|
||||
QCOMPARE(sv->name()->identifier()->chars(), "value");
|
||||
|
||||
FindUsages find(src, doc, snapshot);
|
||||
find(sv);
|
||||
QCOMPARE(find.usages().size(), 2);
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_FindUsages)
|
||||
#include "tst_findusages.moc"
|
||||
|
||||
Reference in New Issue
Block a user