forked from qt-creator/qt-creator
Recursive definition of CPlusPlus::QualifiedNameId.
Done-with: Erik Verbruggen
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -337,7 +337,6 @@ private:
|
||||
bool _isDeprecated: 1;
|
||||
bool _isUnavailable: 1;
|
||||
|
||||
class IdentityForName;
|
||||
class HashCode;
|
||||
|
||||
friend class Scope;
|
||||
|
||||
Reference in New Issue
Block a user