diff options
author | Volodymyr Zibarov <gogan419@gmail.com> | 2020-06-18 15:22:13 +0300 |
---|---|---|
committer | Volodymyr Zibarov <gogan419@gmail.com> | 2020-06-22 14:27:49 +0000 |
commit | 40173ad4ab86f0a49d0bb091f654bdf7220931f5 (patch) | |
tree | a994dfc4b7cbce205106988b72adab6bc672a587 /tests | |
parent | a927c320f728b0902ea5a4ccf120ce35f6972c64 (diff) |
C++: Fix auto variable resolving for template class constructor call
Code snippet:
template<class T> struct MyStruct { int value; };
int main() {
auto s = MyStruct<int>();
s.value; // "value" is not found
}
This fixes find usages for unique_ptr declared as auto like this:
auto ptr = std::unique_ptr<MyStruct>(new MyStruct());
ptr->value;
Also fixes in-place constructors:
std::unique_ptr<MyStruct>(new MyStruct())->value;
Fixes: QTCREATORBUG-15364
Change-Id: I8d452a77fe85e63665ec8d4c4afbcf8aad063121
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/cplusplus/findusages/tst_findusages.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index b09e2cc47f..2dd9566021 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -86,6 +86,8 @@ private Q_SLOTS: void functionNameFoundInArguments(); void memberFunctionFalsePositives_QTCREATORBUG2176(); + void resolveTemplateConstructor(); + void templateConstructorVsCallOperator(); // Qt keywords void qproperty_1(); @@ -465,6 +467,112 @@ struct Struct{ QCOMPARE(find.usages()[1].col, 22); } +void tst_FindUsages::resolveTemplateConstructor() +{ + const QByteArray src = + R"( +struct MyStruct { int value; }; +template <class T> struct Tmp { + T str; +}; +template <class T> struct Tmp2 { + Tmp2(){} + T str; +}; +template <class T> struct Tmp3 { + Tmp3(int i){} + T str; +}; +int main() { + auto tmp = Tmp<MyStruct>(); + auto tmp2 = Tmp2<MyStruct>(); + auto tmp3 = Tmp3<MyStruct>(1); + tmp.str.value; + tmp2.str.value; + tmp3.str.value; + Tmp<MyStruct>().str.value; + Tmp2<MyStruct>().str.value; + Tmp3<MyStruct>(1).str.value; +} +)"; + + Document::Ptr doc = Document::create("resolveTemplateConstructor"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QVERIFY(doc->globalSymbolCount() == 5); + + Class *s = doc->globalSymbolAt(0)->asClass(); + QVERIFY(s); + QCOMPARE(s->name()->identifier()->chars(), "MyStruct"); + QCOMPARE(s->memberCount(), 1); + + Declaration *sv = s->memberAt(0)->asDeclaration(); + QVERIFY(sv); + QCOMPARE(sv->name()->identifier()->chars(), "value"); + + Snapshot snapshot; + snapshot.insert(doc); + + FindUsages find(src, doc, snapshot); + find(sv); + QCOMPARE(find.usages().size(), 7); +} + +void tst_FindUsages::templateConstructorVsCallOperator() +{ + const QByteArray src = + R"( +struct MyStruct { int value; }; +template<class T> struct Tmp { + T str; + MyStruct operator()() { return MyStruct(); } +}; +struct Simple { + MyStruct str; + MyStruct operator()() { return MyStruct(); } +}; +int main() +{ + Tmp<MyStruct>().str.value; + Tmp<MyStruct>()().value; + Tmp<MyStruct> t; + t().value; + + Simple().str.value; + Simple()().value; + Simple s; + s().value; +} +)"; + + Document::Ptr doc = Document::create("resolveTemplateConstructor"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QVERIFY(doc->globalSymbolCount() == 4); + + Class *s = doc->globalSymbolAt(0)->asClass(); + QVERIFY(s); + QCOMPARE(s->name()->identifier()->chars(), "MyStruct"); + QCOMPARE(s->memberCount(), 1); + + Declaration *sv = s->memberAt(0)->asDeclaration(); + QVERIFY(sv); + QCOMPARE(sv->name()->identifier()->chars(), "value"); + + Snapshot snapshot; + snapshot.insert(doc); + + FindUsages find(src, doc, snapshot); + find(sv); + QCOMPARE(find.usages().size(), 7); +} + #if 0 @interface Clazz {} +(void)method:(int)arg; @end @implementation Clazz +(void)method:(int)arg { |