diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 192d389fe23e3dccb8ca70dba132d6089f21b298..0b2fd4bba26a2ba6056a83a631873a2b0b118bab 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -30,6 +30,7 @@ #include "LookupContext.h" #include "ResolveExpression.h" #include "Overview.h" +#include "CppBindings.h" #include <CoreTypes.h> #include <Symbols.h> @@ -501,6 +502,97 @@ void LookupContext::expand(Scope *scope, } } +static void visibleClassBindings_helper(ClassBinding *classBinding, + QList<ClassBinding *> *allClassBindings, + QSet<ClassBinding *> *processed) +{ + if (! classBinding) + return; + + else if (processed->contains(classBinding)) + return; + + processed->insert(classBinding); + + foreach (ClassBinding *baseClassBinding, classBinding->baseClassBindings) + visibleClassBindings_helper(baseClassBinding, allClassBindings, processed); + + allClassBindings->append(classBinding); +} + +static QList<ClassBinding *> visibleClassBindings(Symbol *symbol, NamespaceBinding *globalNamespace) +{ + QList<ClassBinding *> classBindings; + + if (! symbol) + return classBindings; + + else if (Class *klass = symbol->asClass()) { + QSet<ClassBinding *> processed; + + visibleClassBindings_helper(NamespaceBinding::find(klass, globalNamespace), + &classBindings, &processed); + } + + return classBindings; +} + +Symbol *LookupContext::canonicalSymbol(Symbol *symbol, + NamespaceBinding *globalNamespace) +{ + Symbol *canonicalSymbol = LookupContext::canonicalSymbol(symbol); + + if (Identifier *symbolId = canonicalSymbol->identifier()) { + if (symbolId && canonicalSymbol->type()->isFunctionType()) { + Class *enclosingClass = canonicalSymbol->scope()->owner()->asClass(); + const QList<ClassBinding *> classBindings = visibleClassBindings(enclosingClass, globalNamespace); + + foreach (ClassBinding *baseClassBinding, classBindings) { + if (! baseClassBinding) + continue; + + foreach (Class *baseClass, baseClassBinding->symbols) { + if (! baseClass) + continue; + + for (Symbol *c = baseClass->members()->lookat(symbolId); c; c = c->next()) { + if (! symbolId->isEqualTo(c->identifier())) + continue; + else if (Function *f = c->type()->asFunctionType()) { + if (f->isVirtual()) + return LookupContext::canonicalSymbol(f); + } + } + } + } + } + } + + return canonicalSymbol; +} + +Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates, + NamespaceBinding *globalNamespaceBinding) +{ + if (candidates.isEmpty()) + return 0; + + return canonicalSymbol(candidates.first(), globalNamespaceBinding); +} + +Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results, + NamespaceBinding *globalNamespaceBinding) +{ + QList<Symbol *> candidates; + QPair<FullySpecifiedType, Symbol *> result; + + foreach (result, results) + candidates.append(result.second); // ### not exacly. + + return canonicalSymbol(candidates, globalNamespaceBinding); +} + + Symbol *LookupContext::canonicalSymbol(Symbol *symbol) { Symbol *canonical = symbol; @@ -531,22 +623,3 @@ Symbol *LookupContext::canonicalSymbol(Symbol *symbol) return canonical; } - -Symbol *LookupContext::canonicalSymbol(const QList<Symbol *> &candidates) -{ - if (candidates.isEmpty()) - return 0; - - return canonicalSymbol(candidates.first()); -} - -Symbol *LookupContext::canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &results) -{ - QList<Symbol *> candidates; - QPair<FullySpecifiedType, Symbol *> result; - - foreach (result, results) - candidates.append(result.second); // ### not exacly. - - return canonicalSymbol(candidates); -} diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index bb5b053926898de5e618b3d46c89eec60e6cff13..5424da869ca4efda055195d5762a6dd68beced9f 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -54,9 +54,14 @@ public: Document::Ptr document(const QString &fileName) const; Snapshot snapshot() const; - static Symbol *canonicalSymbol(Symbol *symbol); - static Symbol *canonicalSymbol(const QList<Symbol *> &candidates); - static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates); // ### FIXME + static Symbol *canonicalSymbol(const QList<Symbol *> &candidates, + NamespaceBinding *globalNamespaceBinding); + + static Symbol *canonicalSymbol(Symbol *symbol, + NamespaceBinding *globalNamespaceBinding); + + static Symbol *canonicalSymbol(const QList<QPair<FullySpecifiedType, Symbol *> > &candidates, + NamespaceBinding *globalNamespaceBinding); QList<Symbol *> resolve(Name *name) const { return resolve(name, visibleScopes()); } @@ -126,6 +131,8 @@ public: QList<Scope *> *expandedScopes) const; private: + static Symbol *canonicalSymbol(Symbol *symbol); + QList<Symbol *> resolveQualifiedNameId(QualifiedNameId *q, const QList<Scope *> &visibleScopes, ResolveMode mode) const; diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 13228855f904e5cc3d5539b8c34e15078b15d865..eeda79c9e1a24e31d6ba8a40b5916c34971e612f 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -58,6 +58,7 @@ #include <cplusplus/MatchingText.h> #include <cplusplus/BackwardsScanner.h> #include <cplusplus/FastPreprocessor.h> +#include <cplusplus/CppBindings.h> #include <cpptools/cppmodelmanagerinterface.h> @@ -838,8 +839,6 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor, const QString code = expressionUnderCursor(tc); // qDebug() << "code:" << code; - const QString fileName = const_cast<CPPEditor *>(this)->file()->fileName(); - TypeOfExpression typeOfExpression; typeOfExpression.setSnapshot(snapshot); @@ -849,7 +848,8 @@ CPlusPlus::Symbol *CPPEditor::findCanonicalSymbol(const QTextCursor &cursor, lastVisibleSymbol, TypeOfExpression::Preprocess); - Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results); + NamespaceBindingPtr glo = bind(doc, snapshot); + Symbol *canonicalSymbol = LookupContext::canonicalSymbol(results, glo.data()); return canonicalSymbol; } diff --git a/src/plugins/cpptools/cppfindreferences.cpp b/src/plugins/cpptools/cppfindreferences.cpp index 40259589a27f4fdea02c2d073ac770e7d7dd4fe1..9fab3493683ec0b0b2dccee646bc3a44ff4e01f5 100644 --- a/src/plugins/cpptools/cppfindreferences.cpp +++ b/src/plugins/cpptools/cppfindreferences.cpp @@ -152,7 +152,8 @@ protected: bool checkCandidates(const QList<Symbol *> &candidates) const { - if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates)) { + if (Symbol *canonicalSymbol = LookupContext::canonicalSymbol(candidates, _globalNamespaceBinding.data())) { + #if 0 qDebug() << "*** canonical symbol:" << canonicalSymbol->fileName() << canonicalSymbol->line() << canonicalSymbol->column() @@ -498,7 +499,7 @@ static void find_helper(QFutureInterface<Utils::FileSearchResult> &future, files += snapshot.dependsOn(sourceFile); } - qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size(); + //qDebug() << "done in:" << tm.elapsed() << "number of files to parse:" << files.size(); future.setProgressRange(0, files.size()); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 56e7b1d48f5d23fb09a69c64731bdb0c505d4f8d..89df8fdda5c3845344297283bc3579447d2663c2 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -752,7 +752,8 @@ QList<int> CppModelManager::references(CPlusPlus::Symbol *symbol, CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot) { - return m_findReferences->references(LookupContext::canonicalSymbol(symbol), doc, snapshot); + NamespaceBindingPtr glo = bind(doc, snapshot); + return m_findReferences->references(LookupContext::canonicalSymbol(symbol, glo.data()), doc, snapshot); } void CppModelManager::findUsages(CPlusPlus::Symbol *symbol)