Commit b61dbac6 authored by Leandro Melo's avatar Leandro Melo
Browse files

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
parent 6c009f19
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment