diff options
| author | Roberto Raggi <[email protected]> | 2010-05-11 12:47:20 +0200 |
|---|---|---|
| committer | Roberto Raggi <[email protected]> | 2010-05-11 14:15:07 +0200 |
| commit | c282da7d1e2e44a342a353e9681c862b768549f7 (patch) | |
| tree | 90db6e3dcca6a448ac18acbdd6e1c3b12fceff06 /src/libs/cplusplus/CppDocument.cpp | |
| parent | 7eae51507cac3edd4c15519afcbf81bc36e03818 (diff) | |
Introduced Snapshot::findMatchingDefinition().
Diffstat (limited to 'src/libs/cplusplus/CppDocument.cpp')
| -rw-r--r-- | src/libs/cplusplus/CppDocument.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 1f2ee33368a..cf4dd079401 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -29,6 +29,8 @@ #include "CppDocument.h" #include "FastPreprocessor.h" +#include "LookupContext.h" +#include "Overview.h" #include <Control.h> #include <TranslationUnit.h> @@ -36,8 +38,10 @@ #include <Semantic.h> #include <Literals.h> #include <Symbols.h> +#include <Names.h> #include <AST.h> #include <Scope.h> +#include <SymbolVisitor.h> #include <QtCore/QByteArray> #include <QtCore/QBitArray> @@ -570,3 +574,120 @@ void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const } } } + +namespace { +class FindMatchingDefinition: public SymbolVisitor +{ + Symbol *_declaration; + QList<Function *> _result; + +public: + FindMatchingDefinition(Symbol *declaration) + : _declaration(declaration) {} + + QList<Function *> result() const { return _result; } + + using SymbolVisitor::visit; + + virtual bool visit(Function *fun) + { + if (_declaration->identifier()->isEqualTo(fun->identifier())) + _result.append(fun); + + return false; + } + + virtual bool visit(Block *) + { + return false; + } +}; +} // end of anonymous namespace + +Symbol *Snapshot::findMatchingDefinition(Symbol *symbol) const +{ + if (! symbol->identifier()) + return 0; + + Document::Ptr thisDocument = document(QString::fromUtf8(symbol->fileName(), symbol->fileNameLength())); + if (! thisDocument) { + qWarning() << "undefined document:" << symbol->fileName(); + return 0; + } + + LookupContext thisContext(thisDocument, *this); + const QList<Symbol *> declarationCandidates = thisContext.lookup(symbol->name(), symbol); + if (declarationCandidates.isEmpty()) { + qWarning() << "unresolved declaration:" << symbol->fileName() << symbol->line() << symbol->column(); + return 0; + } + + Symbol *declaration = declarationCandidates.first(); + Function *declarationTy = declaration->type()->asFunctionType(); + if (! declarationTy) { + qWarning() << "not a function:" << declaration->fileName() << declaration->line() << declaration->column(); + return 0; + } + + foreach (Document::Ptr doc, *this) { + if (! doc->control()->findIdentifier(declaration->identifier()->chars(), + declaration->identifier()->size())) + continue; + + FindMatchingDefinition candidates(declaration); + candidates.accept(doc->globalNamespace()); + + const QList<Function *> result = candidates.result(); + if (! result.isEmpty()) { + LookupContext context(doc, *this); + + QList<Function *> viableFunctions; + + foreach (Function *fun, result) { + const QList<Symbol *> declarations = context.lookup(fun->name(), fun); + + if (declarations.contains(declaration)) + viableFunctions.append(fun); + + else if (false) + qDebug() << "does not contain" << declaration->fileName() << declaration->line() << declaration->column(); + } + + if (viableFunctions.isEmpty()) + continue; + + else if (viableFunctions.length() == 1) + return viableFunctions.first(); + + Function *best = 0; + + foreach (Function *fun, viableFunctions) { + if (fun->identity()->isEqualTo(declaration->identity())) + continue; + + else if (fun->argumentCount() == declarationTy->argumentCount()) { + if (! best) + best = fun; + + unsigned argc = 0; + for (; argc < declarationTy->argumentCount(); ++argc) { + Symbol *arg = fun->argumentAt(argc); + Symbol *otherArg = declarationTy->argumentAt(argc); + if (! arg->type().isEqualTo(otherArg->type())) + break; + } + + if (argc == declarationTy->argumentCount()) + best = fun; + } + } + + if (! best) + best = viableFunctions.first(); + + return best; + } + } + + return 0; +} |
