forked from qt-creator/qt-creator
Fixed possible crashes when resolving namespace and class bindings.
This commit is contained in:
@@ -113,8 +113,13 @@ NamespaceBinding *NamespaceBinding::globalNamespaceBinding()
|
||||
return it;
|
||||
}
|
||||
|
||||
Binding *NamespaceBinding::findClassOrNamespaceBinding(Identifier *id)
|
||||
Binding *NamespaceBinding::findClassOrNamespaceBinding(Identifier *id, QSet<Binding *> *processed)
|
||||
{
|
||||
if (processed->contains(this))
|
||||
return 0;
|
||||
|
||||
processed->insert(this);
|
||||
|
||||
if (id->isEqualTo(identifier()))
|
||||
return const_cast<NamespaceBinding *>(this);
|
||||
|
||||
@@ -129,21 +134,26 @@ Binding *NamespaceBinding::findClassOrNamespaceBinding(Identifier *id)
|
||||
}
|
||||
|
||||
foreach (NamespaceBinding *u, usings) {
|
||||
if (Binding *b = u->findClassOrNamespaceBinding(id))
|
||||
if (Binding *b = u->findClassOrNamespaceBinding(id, processed))
|
||||
return b;
|
||||
}
|
||||
|
||||
if (parent)
|
||||
return parent->findClassOrNamespaceBinding(id);
|
||||
return parent->findClassOrNamespaceBinding(id, processed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassBinding *NamespaceBinding::findClassBinding(Name *name)
|
||||
ClassBinding *NamespaceBinding::findClassBinding(Name *name, QSet<Binding *> *processed)
|
||||
{
|
||||
if (! name)
|
||||
return 0;
|
||||
|
||||
if (processed->contains(this))
|
||||
return 0;
|
||||
|
||||
processed->insert(this);
|
||||
|
||||
Identifier *id = name->identifier();
|
||||
|
||||
foreach (ClassBinding *classBinding, classBindings) {
|
||||
@@ -152,7 +162,12 @@ ClassBinding *NamespaceBinding::findClassBinding(Name *name)
|
||||
}
|
||||
|
||||
if (parent)
|
||||
return parent->findClassBinding(name);
|
||||
return parent->findClassBinding(name, processed);
|
||||
|
||||
foreach (NamespaceBinding *u, usings) {
|
||||
if (ClassBinding *classBinding = u->findClassBinding(name, processed))
|
||||
return classBinding;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -384,7 +399,7 @@ QByteArray ClassBinding::qualifiedId() const
|
||||
return s;
|
||||
}
|
||||
|
||||
Binding *ClassBinding::findClassOrNamespaceBinding(Identifier *id)
|
||||
Binding *ClassBinding::findClassOrNamespaceBinding(Identifier *id, QSet<Binding *> *processed)
|
||||
{
|
||||
if (id->isEqualTo(identifier()))
|
||||
return this;
|
||||
@@ -397,21 +412,26 @@ Binding *ClassBinding::findClassOrNamespaceBinding(Identifier *id)
|
||||
foreach (ClassBinding *baseClassBinding, baseClassBindings) {
|
||||
if (! baseClassBinding)
|
||||
continue;
|
||||
else if (Binding *b = baseClassBinding->findClassOrNamespaceBinding(id))
|
||||
else if (Binding *b = baseClassBinding->findClassOrNamespaceBinding(id, processed))
|
||||
return b;
|
||||
}
|
||||
|
||||
if (parent)
|
||||
return parent->findClassOrNamespaceBinding(id);
|
||||
return parent->findClassOrNamespaceBinding(id, processed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassBinding *ClassBinding::findClassBinding(Name *name)
|
||||
ClassBinding *ClassBinding::findClassBinding(Name *name, QSet<Binding *> *processed)
|
||||
{
|
||||
if (! name)
|
||||
return 0;
|
||||
|
||||
if (processed->contains(this))
|
||||
return 0;
|
||||
|
||||
processed->insert(this);
|
||||
|
||||
if (const QualifiedNameId *q = name->asQualifiedNameId()) {
|
||||
Binding *currentBinding = this;
|
||||
|
||||
@@ -420,7 +440,7 @@ ClassBinding *ClassBinding::findClassBinding(Name *name)
|
||||
if (! id)
|
||||
return 0;
|
||||
|
||||
Binding *classOrNamespaceBinding = currentBinding->findClassOrNamespaceBinding(id);
|
||||
Binding *classOrNamespaceBinding = currentBinding->findClassOrNamespaceBinding(id, processed);
|
||||
|
||||
if (! classOrNamespaceBinding)
|
||||
return 0;
|
||||
@@ -429,7 +449,7 @@ ClassBinding *ClassBinding::findClassBinding(Name *name)
|
||||
}
|
||||
|
||||
if (currentBinding)
|
||||
return currentBinding->findClassBinding(q->unqualifiedNameId());
|
||||
return currentBinding->findClassBinding(q->unqualifiedNameId(), processed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -446,7 +466,7 @@ ClassBinding *ClassBinding::findClassBinding(Name *name)
|
||||
}
|
||||
|
||||
if (parent)
|
||||
return parent->findClassBinding(name);
|
||||
return parent->findClassBinding(name, processed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -637,6 +657,7 @@ NamespaceBinding *Binder::switchNamespaceBinding(NamespaceBinding *binding)
|
||||
|
||||
ClassBinding *Binder::findOrCreateClassBinding(Class *classSymbol)
|
||||
{
|
||||
// ### FINISH ME
|
||||
ClassBinding *binding = 0;
|
||||
|
||||
if (classBinding)
|
||||
@@ -650,13 +671,15 @@ ClassBinding *Binder::findOrCreateClassBinding(Class *classSymbol)
|
||||
|
||||
ClassBinding *Binder::findClassBinding(Name *name)
|
||||
{
|
||||
QSet<Binding *> processed;
|
||||
|
||||
if (classBinding) {
|
||||
if (ClassBinding *k = classBinding->findClassBinding(name))
|
||||
if (ClassBinding *k = classBinding->findClassBinding(name, &processed))
|
||||
return k;
|
||||
}
|
||||
|
||||
if (namespaceBinding)
|
||||
return namespaceBinding->findClassBinding(name);
|
||||
return namespaceBinding->findClassBinding(name, &processed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ public:
|
||||
virtual NamespaceBinding *asNamespaceBinding() { return 0; }
|
||||
virtual ClassBinding *asClassBinding() { return 0; }
|
||||
|
||||
virtual ClassBinding *findClassBinding(Name *name) = 0;
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id) = 0;
|
||||
virtual ClassBinding *findClassBinding(Name *name, QSet<Binding *> *processed) = 0;
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id, QSet<Binding *> *processed) = 0;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT NamespaceBinding: public Binding
|
||||
@@ -116,8 +116,8 @@ public:
|
||||
Name *name,
|
||||
bool lookAtParent = true);
|
||||
|
||||
virtual ClassBinding *findClassBinding(Name *name);
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id);
|
||||
virtual ClassBinding *findClassBinding(Name *name, QSet<Binding *> *processed);
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id, QSet<Binding *> *processed);
|
||||
|
||||
/// Helpers.
|
||||
virtual QByteArray qualifiedId() const;
|
||||
@@ -171,8 +171,8 @@ public:
|
||||
Identifier *identifier() const;
|
||||
virtual QByteArray qualifiedId() const;
|
||||
|
||||
virtual ClassBinding *findClassBinding(Name *name);
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id);
|
||||
virtual ClassBinding *findClassBinding(Name *name, QSet<Binding *> *processed);
|
||||
virtual Binding *findClassOrNamespaceBinding(Identifier *id, QSet<Binding *> *processed);
|
||||
|
||||
void dump();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user