diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 95399bc06749a428599eeb248b0bccb8240679f0..b73c22b6571c6721feb46d459450d5ded03fc230 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -335,6 +335,10 @@ QList<LookupItem> LookupContext::lookup(const Name *name, Scope *scope) const if (ClassOrNamespace *binding = bindings()->lookupType(fun)) { candidates = binding->find(name); + // try find this name in parent class + while (candidates.isEmpty() && (binding = binding->parent())) + candidates = binding->find(name); + if (! candidates.isEmpty()) return candidates; } diff --git a/src/plugins/cpptools/cppchecksymbols.cpp b/src/plugins/cpptools/cppchecksymbols.cpp index 8d930457896acd126ca7b9f6fb8254c9287ad8a4..5f7b6f04d78339f1ec94ca4d559dd301a2039245 100644 --- a/src/plugins/cpptools/cppchecksymbols.cpp +++ b/src/plugins/cpptools/cppchecksymbols.cpp @@ -1164,6 +1164,7 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam else if (c->isUsingNamespaceDirective()) // ... and using namespace directives. continue; else if (c->isTypedef() || c->isNamespace() || + c->isStatic() || //consider also static variable c->isClass() || c->isEnum() || isTemplateClass(c) || c->isForwardClassDeclaration() || c->isTypenameArgument() || c->enclosingEnum() != 0) { @@ -1174,6 +1175,9 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam UseKind kind = SemanticInfo::TypeUse; if (c->enclosingEnum() != 0) kind = SemanticInfo::EnumerationUse; + else if (c->isStatic()) + // treat static variable as a field(highlighting) + kind = SemanticInfo::FieldUse; const Use use(line, column, length, kind); addUse(use); diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp index 34d4569a3157c81a0ead2d2621a2abc71cfb5a88..ac586b75d85fd197cb3fd5d29e531f8b60bc5959 100644 --- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp +++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp @@ -182,6 +182,7 @@ private slots: void test_checksymbols_MacroUse(); void test_checksymbols_FunctionUse(); void test_checksymbols_PseudoKeywordUse(); + void test_checksymbols_StaticUse(); }; void tst_CheckSymbols::test_checksymbols_TypeUse() @@ -331,5 +332,50 @@ void tst_CheckSymbols::test_checksymbols_PseudoKeywordUse() TestData::check(source, expectedUses); } +void tst_CheckSymbols::test_checksymbols_StaticUse() +{ + const QByteArray source = + "struct Outer\n" + "{\n" + " static int Foo;\n" + " struct Inner\n" + " {\n" + " Outer *outer;\n" + " void foo();\n" + " };\n" + "};\n" + "\n" + "int Outer::Foo = 42;\n" + "\n" + "void Outer::Inner::foo()\n" + "{\n" + " Foo = 7;\n" + " Outer::Foo = 7;\n" + " outer->Foo = 7;\n" + "}\n" + ; + + const QList<Use> expectedUses = QList<Use>() + << Use(1, 8, 5, SemanticInfo::TypeUse) + << Use(3, 16, 3, SemanticInfo::FieldUse) + << Use(4, 12, 5, SemanticInfo::TypeUse) + << Use(6, 16, 5, SemanticInfo::FieldUse) + << Use(6, 9, 5, SemanticInfo::TypeUse) + << Use(7, 14, 3, SemanticInfo::FunctionUse) + << Use(11, 12, 3, SemanticInfo::FieldUse) + << Use(11, 5, 5, SemanticInfo::TypeUse) + << Use(13, 20, 3, SemanticInfo::FunctionUse) + << Use(13, 6, 5, SemanticInfo::TypeUse) + << Use(13, 13, 5, SemanticInfo::TypeUse) + << Use(15, 5, 3, SemanticInfo::FieldUse) + << Use(16, 12, 3, SemanticInfo::FieldUse) + << Use(16, 5, 5, SemanticInfo::TypeUse) + << Use(17, 5, 5, SemanticInfo::FieldUse) + << Use(17, 12, 3, SemanticInfo::FieldUse) + ; + + TestData::check(source, expectedUses); +} + QTEST_APPLESS_MAIN(tst_CheckSymbols) #include "tst_checksymbols.moc" diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index 0d84cb515bc6d6e8456bad486eb641d976ce7e37..ed98cb803013b88ca8a2efa95f9ad24f53f83c47 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -81,6 +81,7 @@ private Q_SLOTS: void lambdaCaptureByReference(); void shadowedNames_1(); void shadowedNames_2(); + void staticVariables(); // Qt keywords void qproperty_1(); @@ -257,6 +258,52 @@ void tst_FindUsages::shadowedNames_2() QCOMPARE(findUsages.usages().size(), 3); } +void tst_FindUsages::staticVariables() +{ + const QByteArray src = "\n" + "struct Outer\n" + "{\n" + " static int Foo;\n" + " struct Inner\n" + " {\n" + " Outer *outer;\n" + " void foo();\n" + " };\n" + "};\n" + "\n" + "int Outer::Foo = 42;\n" + "\n" + "void Outer::Inner::foo()\n" + "{\n" + " Foo = 7;\n" + " Outer::Foo = 7;\n" + " outer->Foo = 7;\n" + "}\n" + ; + Document::Ptr doc = Document::create("staticVariables"); + doc->setUtf8Source(src); + doc->parse(); + doc->check(); + + QVERIFY(doc->diagnosticMessages().isEmpty()); + QCOMPARE(doc->globalSymbolCount(), 3U); + + Snapshot snapshot; + snapshot.insert(doc); + + Class *c = doc->globalSymbolAt(0)->asClass(); + QVERIFY(c); + QCOMPARE(c->name()->identifier()->chars(), "Outer"); + QCOMPARE(c->memberCount(), 2U); + Declaration *d = c->memberAt(0)->asDeclaration(); + QVERIFY(d); + QCOMPARE(d->name()->identifier()->chars(), "Foo"); + + FindUsages findUsages(src, doc, snapshot); + findUsages(d); + QCOMPARE(findUsages.usages().size(), 5); +} + #if 0 @interface Clazz {} +(void)method:(int)arg; @end @implementation Clazz +(void)method:(int)arg {