C++: Do type and name equality checking in a safe manner.

Change the TypeMatcher to also match names, and use two "block" lists
in SafeMatcher to prevent infinite recursion.

Task-number: QTCREATORBUG-11240
Change-Id: I0367ae795ee6be579b83aeb8d46723c877e4aa75
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
Erik Verbruggen
2014-03-24 16:06:39 +01:00
committed by Erik Verbruggen
parent 186570a259
commit b0618281ec
27 changed files with 768 additions and 328 deletions

View File

@@ -19,6 +19,7 @@
// THE SOFTWARE.
#include "Names.h"
#include "Matcher.h"
#include "NameVisitor.h"
#include "Literals.h"
#include <algorithm>
@@ -32,6 +33,13 @@ QualifiedNameId::~QualifiedNameId()
void QualifiedNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool QualifiedNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const QualifiedNameId *name = otherName->asQualifiedNameId())
return matcher->match(this, name);
return false;
}
const Identifier *QualifiedNameId::identifier() const
{
if (const Name *u = name())
@@ -71,6 +79,13 @@ DestructorNameId::~DestructorNameId()
void DestructorNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool DestructorNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const DestructorNameId *name = otherName->asDestructorNameId())
return matcher->match(this, name);
return false;
}
const Name *DestructorNameId::name() const
{ return _name; }
@@ -96,6 +111,13 @@ TemplateNameId::~TemplateNameId()
void TemplateNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool TemplateNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const TemplateNameId *other = otherName->asTemplateNameId())
return matcher->match(this, other);
return false;
}
const Identifier *TemplateNameId::identifier() const
{ return _identifier; }
@@ -117,7 +139,7 @@ bool TemplateNameId::isEqualTo(const Name *other) const
return false;
if (templateArgumentCount() != t->templateArgumentCount())
return false;
for (unsigned i = 0; i < templateArgumentCount(); ++i) {
for (unsigned i = 0, ei = templateArgumentCount(); i != ei; ++i) {
const FullySpecifiedType &l = _templateArguments[i];
const FullySpecifiedType &r = t->_templateArguments[i];
if (! l.isEqualTo(r))
@@ -171,6 +193,13 @@ OperatorNameId::~OperatorNameId()
void OperatorNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool OperatorNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const OperatorNameId *name = otherName->asOperatorNameId())
return matcher->match(this, name);
return false;
}
OperatorNameId::Kind OperatorNameId::kind() const
{ return _kind; }
@@ -198,6 +227,13 @@ ConversionNameId::~ConversionNameId()
void ConversionNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool ConversionNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const ConversionNameId *name = otherName->asConversionNameId())
return matcher->match(this, name);
return false;
}
FullySpecifiedType ConversionNameId::type() const
{ return _type; }
@@ -221,6 +257,13 @@ SelectorNameId::~SelectorNameId()
void SelectorNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool SelectorNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const SelectorNameId *name = otherName->asSelectorNameId())
return matcher->match(this, name);
return false;
}
const Identifier *SelectorNameId::identifier() const
{
if (_names.empty())
@@ -276,6 +319,13 @@ unsigned AnonymousNameId::classTokenIndex() const
void AnonymousNameId::accept0(NameVisitor *visitor) const
{ visitor->visit(this); }
bool AnonymousNameId::match0(const Name *otherName, Matcher *matcher) const
{
if (const AnonymousNameId *id = otherName->asAnonymousNameId())
return matcher->match(this, id);
return false;
}
const Identifier *AnonymousNameId::identifier() const
{ return 0; }