Recursive definition of CPlusPlus::QualifiedNameId.

Done-with: Erik Verbruggen
This commit is contained in:
Roberto Raggi
2010-07-12 13:41:54 +02:00
parent 94264617bf
commit adfdb51660
17 changed files with 166 additions and 237 deletions

View File

@@ -870,35 +870,31 @@ bool CheckDeclaration::visit(QtPropertyDeclarationAST *ast)
return false;
}
void CheckDeclaration::checkQEnumsQFlagsNames(NameListAST *nameListAst,
const char *declName)
static bool checkEnumName(const Name *name)
{
if (! name)
return false;
else if (name->asNameId() != 0)
return true;
else if (const QualifiedNameId *q = name->asQualifiedNameId()) {
if (! q->base())
return false; // global qualified name
if (checkEnumName(q->base()) && checkEnumName(q->name()))
return true;
}
return false;
}
void CheckDeclaration::checkQEnumsQFlagsNames(NameListAST *nameListAst, const char *declName)
{
for (NameListAST *iter = nameListAst; iter; iter = iter->next) {
const Name *name = semantic()->check(iter->value, _scope);
if (!name)
continue;
if (name->isNameId())
continue;
const QualifiedNameId *qName = name->asQualifiedNameId();
if (!qName)
translationUnit()->error(iter->firstToken(), "invalid name in %s",
declName);
else if (qName->isGlobal())
translationUnit()->error(iter->firstToken(),
"invalid name '%s' in %s",
qName->identifier()->chars(), declName);
else {
for (unsigned i = 0; i < qName->nameCount(); ++i) {
const Name *namePart = qName->nameAt(i);
if (!namePart || !namePart->isNameId()) {
translationUnit()->error(iter->firstToken(),
"invalid name '%s' in %s",
qName->identifier()->chars(), declName);
}
}
if (const Name *name = semantic()->check(iter->value, _scope)) {
if (! checkEnumName(name))
translationUnit()->error(iter->firstToken(), "invalid name in %s", declName);
}
}
}

View File

@@ -87,15 +87,15 @@ const Name *CheckName::check(NestedNameSpecifierListAST *nested_name_specifier_l
const Name *previousName = switchName(0);
Scope *previousScope = switchScope(scope);
std::vector<const Name *> names;
for (NestedNameSpecifierListAST *it = nested_name_specifier_list; it; it = it->next) {
NestedNameSpecifierAST *nested_name_specifier = it->value;
names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
const Name *n = semantic()->check(nested_name_specifier->class_or_namespace_name, _scope);
if (! _name)
_name = n;
else
_name = control()->qualifiedNameId(_name, n);
}
if (! names.empty())
_name = control()->qualifiedNameId(&names[0], names.size());
(void) switchScope(previousScope);
return switchName(previousName);
}
@@ -127,13 +127,20 @@ Scope *CheckName::switchScope(Scope *scope)
bool CheckName::visit(QualifiedNameAST *ast)
{
std::vector<const Name *> names;
for (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list; it; it = it->next) {
NestedNameSpecifierAST *nested_name_specifier = it->value;
names.push_back(semantic()->check(nested_name_specifier->class_or_namespace_name, _scope));
const Name *n = semantic()->check(nested_name_specifier->class_or_namespace_name, _scope);
if (_name || ast->global_scope_token)
_name = control()->qualifiedNameId(_name, n);
else
_name = n;
}
names.push_back(semantic()->check(ast->unqualified_name, _scope));
_name = control()->qualifiedNameId(&names[0], names.size(), ast->global_scope_token != 0);
const Name *n = semantic()->check(ast->unqualified_name, _scope);
if (_name || ast->global_scope_token)
_name = control()->qualifiedNameId(_name, n);
else
_name = n;
ast->name = _name;
return false;

View File

@@ -177,11 +177,10 @@ template <> struct Compare<QualifiedNameId>
{
bool operator()(const QualifiedNameId &name, const QualifiedNameId &otherName) const
{
if (name.isGlobal() == otherName.isGlobal())
return std::lexicographical_compare(name.firstName(), name.lastName(),
otherName.firstName(), otherName.lastName());
if (name.base() == otherName.base())
return name.name() < otherName.name();
return name.isGlobal() < otherName.isGlobal();
return name.base() < otherName.base();
}
};
@@ -285,10 +284,9 @@ public:
return conversionNameIds.intern(ConversionNameId(type));
}
template <typename _Iterator>
const QualifiedNameId *findOrInsertQualifiedNameId(_Iterator first, _Iterator last, bool isGlobal)
const QualifiedNameId *findOrInsertQualifiedNameId(const Name *base, const Name *name)
{
return qualifiedNameIds.intern(QualifiedNameId(first, last, isGlobal));
return qualifiedNameIds.intern(QualifiedNameId(base, name));
}
template <typename _Iterator>
@@ -641,11 +639,9 @@ const OperatorNameId *Control::operatorNameId(int kind)
const ConversionNameId *Control::conversionNameId(const FullySpecifiedType &type)
{ return d->findOrInsertConversionNameId(type); }
const QualifiedNameId *Control::qualifiedNameId(const Name *const *names,
unsigned nameCount,
bool isGlobal)
const QualifiedNameId *Control::qualifiedNameId(const Name *base, const Name *name)
{
return d->findOrInsertQualifiedNameId(names, names + nameCount, isGlobal);
return d->findOrInsertQualifiedNameId(base, name);
}
const SelectorNameId *Control::selectorNameId(const Name *const *names,

View File

@@ -83,9 +83,7 @@ public:
const ConversionNameId *conversionNameId(const FullySpecifiedType &type);
/// Returns the canonical qualified name id.
const QualifiedNameId *qualifiedNameId(const Name *const *names,
unsigned nameCount,
bool isGlobal = false);
const QualifiedNameId *qualifiedNameId(const Name *base, const Name *name);
const SelectorNameId *selectorNameId(const Name *const *names,
unsigned nameCount,

View File

@@ -298,11 +298,11 @@ bool NamedType::isEqualTo(const Type *other) const
const Name *name = _name;
if (const QualifiedNameId *q = name->asQualifiedNameId())
name = q->unqualifiedNameId();
name = q->name();
const Name *otherName = o->name();
if (const QualifiedNameId *q = otherName->asQualifiedNameId())
otherName = q->unqualifiedNameId();
otherName = q->name();
return name->isEqualTo(otherName);
}

View File

@@ -63,48 +63,29 @@ void QualifiedNameId::accept0(NameVisitor *visitor) const
const Identifier *QualifiedNameId::identifier() const
{
if (const Name *u = unqualifiedNameId())
if (const Name *u = name())
return u->identifier();
return 0;
}
unsigned QualifiedNameId::nameCount() const
{ return _names.size(); }
const Name *QualifiedNameId::base() const
{ return _base; }
const Name *QualifiedNameId::nameAt(unsigned index) const
{ return _names[index]; }
bool QualifiedNameId::isGlobal() const
{ return _isGlobal; }
const Name *QualifiedNameId::unqualifiedNameId() const
{
if (_names.empty())
return 0;
return _names.back();
}
const Name *QualifiedNameId::name() const
{ return _name; }
bool QualifiedNameId::isEqualTo(const Name *other) const
{
const QualifiedNameId *q = other->asQualifiedNameId();
if (! q)
return false;
else if (isGlobal() != q->isGlobal())
return false;
else {
const unsigned count = nameCount();
if (count != q->nameCount())
return false;
for (unsigned i = 0; i < count; ++i) {
const Name *l = nameAt(i);
const Name *r = q->nameAt(i);
if (! l->isEqualTo(r))
return false;
if (const QualifiedNameId *q = other->asQualifiedNameId()) {
if (_base == q->_base || (_base && _base->isEqualTo(q->_base))) {
if (_name == q->_name || (_name && _name->isEqualTo(q->_name))) {
return true;
}
}
}
return true;
return false;
}
NameId::NameId(const Identifier *identifier)

View File

@@ -59,36 +59,27 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT QualifiedNameId: public Name
{
public:
template <typename _Iterator>
QualifiedNameId(_Iterator first, _Iterator last, bool isGlobal = false)
: _names(first, last), _isGlobal(isGlobal) {}
QualifiedNameId(const Name *base, const Name *name)
: _base(base), _name(name) {}
virtual ~QualifiedNameId();
virtual const Identifier *identifier() const;
unsigned nameCount() const;
const Name *nameAt(unsigned index) const;
const Name *unqualifiedNameId() const;
const Name *const *names() const { return &_names[0]; } // ### remove me
bool isGlobal() const;
const Name *base() const;
const Name *name() const;
virtual bool isEqualTo(const Name *other) const;
virtual const QualifiedNameId *asQualifiedNameId() const
{ return this; }
typedef std::vector<const Name *>::const_iterator NameIterator;
NameIterator firstName() const { return _names.begin(); }
NameIterator lastName() const { return _names.end(); }
protected:
virtual void accept0(NameVisitor *visitor) const;
private:
std::vector<const Name *> _names;
bool _isGlobal;
const Name *_base;
const Name *_name;
};
class CPLUSPLUS_EXPORT NameId: public Name

View File

@@ -101,7 +101,7 @@ protected:
{ _value = 0; } // ### TODO: implement me
virtual void visit(const QualifiedNameId *name)
{ _value = operator()(name->unqualifiedNameId()); }
{ _value = operator()(name->name()); }
virtual void visit(const SelectorNameId *name)
{ _value = name->identifier()->hashCode(); }
@@ -110,56 +110,6 @@ private:
unsigned _value;
};
class Symbol::IdentityForName: protected NameVisitor
{
public:
IdentityForName()
: _identity(0)
{ }
virtual ~IdentityForName()
{ }
const Name *operator()(const Name *name)
{
const Name *previousIdentity = switchIdentity(0);
accept(name);
return switchIdentity(previousIdentity);
}
protected:
const Name *switchIdentity(const Name *identity)
{
const Name *previousIdentity = _identity;
_identity = identity;
return previousIdentity;
}
virtual void visit(const NameId *name)
{ _identity = name; }
virtual void visit(const TemplateNameId *name)
{ _identity = name; }
virtual void visit(const DestructorNameId *name)
{ _identity = name; }
virtual void visit(const OperatorNameId *name)
{ _identity = name; }
virtual void visit(const ConversionNameId *name)
{ _identity = name; }
virtual void visit(const QualifiedNameId *name)
{ _identity = name->unqualifiedNameId(); }
virtual void visit(const SelectorNameId *name)
{ _identity = name; }
private:
const Name *_identity;
};
Symbol::Symbol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
: _startOffset(0),
_endOffset(0),
@@ -265,8 +215,13 @@ void Symbol::setEndOffset(unsigned offset)
const Name *Symbol::identity() const
{
IdentityForName id;
return id(_name);
if (! _name)
return 0;
else if (const QualifiedNameId *q = _name->asQualifiedNameId())
return q->name();
return _name;
}
const Name *Symbol::name() const
@@ -279,9 +234,8 @@ void Symbol::setName(const Name *name)
if (! _name)
_hashCode = 0;
else {
IdentityForName identityForName;
HashCode hh;
_hashCode = hh(identityForName(_name));
_hashCode = hh(identity());
}
}

View File

@@ -337,7 +337,6 @@ private:
bool _isDeprecated: 1;
bool _isUnavailable: 1;
class IdentityForName;
class HashCode;
friend class Scope;