summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor/cpphoverhandler.cpp
diff options
context:
space:
mode:
authorLeandro Melo <leandro.melo@nokia.com>2010-08-05 11:41:21 +0200
committerLeandro Melo <leandro.melo@nokia.com>2010-08-05 11:46:44 +0200
commitb61dbac6ff78b08318049e77f57965c9005bdde3 (patch)
tree2fb48515c683f97422dcc7821a1f33052bf4f177 /src/plugins/cppeditor/cpphoverhandler.cpp
parent6c009f19cd71286767eb344bc30b60e485144bc9 (diff)
downloadqt-creator-b61dbac6ff78b08318049e77f57965c9005bdde3.tar.gz
Fix potential endless recursion in C++ hover handler.
To catch cases of invalid code like this: struct A : B {}; struct B : A {}; Reviewed-by: Roberto Raggi
Diffstat (limited to 'src/plugins/cppeditor/cpphoverhandler.cpp')
-rw-r--r--src/plugins/cppeditor/cpphoverhandler.cpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp
index 6efc3ae1b1..d90162e608 100644
--- a/src/plugins/cppeditor/cpphoverhandler.cpp
+++ b/src/plugins/cppeditor/cpphoverhandler.cpp
@@ -49,6 +49,7 @@
#include <cplusplus/LookupContext.h>
#include <cplusplus/LookupItem.h>
+#include <QtCore/QSet>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QtAlgorithms>
@@ -82,24 +83,30 @@ namespace {
}
}
- void buildClassHierarchyHelper(Symbol *symbol,
+ void buildClassHierarchyHelper(ClassOrNamespace *classSymbol,
const LookupContext &context,
const Overview &overview,
- QList<QStringList> *hierarchy) {
- if (ClassOrNamespace *classSymbol = context.lookupType(symbol)) {
- const QList<ClassOrNamespace *> &bases = classSymbol->usings();
- foreach (ClassOrNamespace *baseClass, bases) {
- const QList<Symbol *> &symbols = baseClass->symbols();
- foreach (Symbol *baseSymbol, symbols) {
- if (baseSymbol->isClass()) {
- const QString &qualifiedName = overview.prettyName(
- LookupContext::fullyQualifiedName(baseSymbol));
- if (!qualifiedName.isEmpty()) {
- hierarchy->back().append(qualifiedName);
- buildClassHierarchyHelper(baseSymbol, context, overview, hierarchy);
- hierarchy->append(hierarchy->back());
- hierarchy->back().removeLast();
- }
+ QList<QStringList> *hierarchy,
+ QSet<ClassOrNamespace *> *visited) {
+ visited->insert(classSymbol);
+ const QList<ClassOrNamespace *> &bases = classSymbol->usings();
+ foreach (ClassOrNamespace *baseClass, bases) {
+ const QList<Symbol *> &symbols = baseClass->symbols();
+ foreach (Symbol *baseSymbol, symbols) {
+ if (baseSymbol->isClass() && (
+ classSymbol = context.lookupType(baseSymbol)) &&
+ !visited->contains(classSymbol)) {
+ const QString &qualifiedName = overview.prettyName(
+ LookupContext::fullyQualifiedName(baseSymbol));
+ if (!qualifiedName.isEmpty()) {
+ hierarchy->back().append(qualifiedName);
+ buildClassHierarchyHelper(classSymbol,
+ context,
+ overview,
+ hierarchy,
+ visited);
+ hierarchy->append(hierarchy->back());
+ hierarchy->back().removeLast();
}
}
}
@@ -110,10 +117,12 @@ namespace {
const LookupContext &context,
const Overview &overview,
QList<QStringList> *hierarchy) {
- if (hierarchy->isEmpty())
+ if (ClassOrNamespace *classSymbol = context.lookupType(symbol)) {
hierarchy->append(QStringList());
- buildClassHierarchyHelper(symbol, context, overview, hierarchy);
- hierarchy->removeLast();
+ QSet<ClassOrNamespace *> visited;
+ buildClassHierarchyHelper(classSymbol, context, overview, hierarchy, &visited);
+ hierarchy->removeLast();
+ }
}
struct ClassHierarchyComp