diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index f4b39763ce5b62358961e5f632f1ecaec3e9522c..74612de3ba054d441899d974c37b6a67a438f404 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -64,6 +64,15 @@ static void fullyQualifiedName(Symbol *symbol, QList<const Name *> *names) } } +bool ClassOrNamespace::CompareName::operator()(const Name *name, const Name *other) const +{ + Q_ASSERT(name != 0); + Q_ASSERT(other != 0); + const Identifier *id = name->identifier(); + const Identifier *otherId = other->identifier(); + return std::lexicographical_compare(id->begin(), id->end(), otherId->begin(), otherId->end()); +} + ///////////////////////////////////////////////////////////////////// // LookupContext ///////////////////////////////////////////////////////////////////// @@ -218,19 +227,15 @@ QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const if (fun->name() && fun->name()->isQualifiedNameId()) { const QualifiedNameId *q = fun->name()->asQualifiedNameId(); - QList<QByteArray> path; - QList<const Name *> enclosingNames; - fullyQualifiedName(scope->owner(), &enclosingNames); - foreach (const Name *p, enclosingNames) { - if (const Identifier *id = p->identifier()) { - path.append(QByteArray::fromRawData(id->chars(), id->size())); - } - } + QList<const Name *> path; + fullyQualifiedName(scope->owner(), &path); + + for (unsigned index = 0; index < q->nameCount() - 1; ++index) { // ### TODO remove me. + const Name *name = q->nameAt(index); - for (unsigned index = 0; index < q->nameCount() - 1; ++index) { - if (const Identifier *id = q->nameAt(index)->identifier()) - path.append(QByteArray::fromRawData(id->chars(), id->size())); + if (name->isNameId() || name->isTemplateNameId()) + path.append(name); } if (ClassOrNamespace *binding = bindings()->findClassOrNamespace(path)) @@ -398,7 +403,7 @@ ClassOrNamespace *ClassOrNamespace::findClassOrNamespace(const Name *name) return findClassOrNamespace_helper(name, &processed); } -ClassOrNamespace *ClassOrNamespace::findClassOrNamespace(const QList<QByteArray> &path) +ClassOrNamespace *ClassOrNamespace::findClassOrNamespace(const QList<const Name *> &path) { if (path.isEmpty()) return globalNamespace(); @@ -436,10 +441,8 @@ ClassOrNamespace *ClassOrNamespace::lookupClassOrNamespace_helper(const Name *na return e; - } else if (const Identifier *id = name->identifier()) { - const QByteArray classOrNamespaceName = QByteArray::fromRawData(id->chars(), id->size()); - - if (ClassOrNamespace *e = nestedClassOrNamespace(classOrNamespaceName)) + } else if (name->isNameId() || name->isTemplateNameId()) { + if (ClassOrNamespace *e = nestedClassOrNamespace(name)) return e; foreach (ClassOrNamespace *u, usings()) { @@ -474,37 +477,37 @@ ClassOrNamespace *ClassOrNamespace::findClassOrNamespace_helper(const Name *name return e; - } else if (const Identifier *id = name->identifier()) { - const QByteArray classOrNamespaceName = QByteArray::fromRawData(id->chars(), id->size()); - return findClassOrNamespace_helper(classOrNamespaceName, processed); + } else if (name->isNameId() || name->isTemplateNameId()) { + if (ClassOrNamespace *e = nestedClassOrNamespace(name)) + return e; + + else if (! processed->contains(this)) { + processed->insert(this); + + foreach (ClassOrNamespace *u, usings()) { + if (ClassOrNamespace *e = u->findClassOrNamespace_helper(name, processed)) + return e; + } + } } return 0; } -ClassOrNamespace *ClassOrNamespace::findClassOrNamespace_helper(const QByteArray &name, - QSet<ClassOrNamespace *> *processed) +ClassOrNamespace *ClassOrNamespace::nestedClassOrNamespace(const Name *name) const { - if (ClassOrNamespace *e = nestedClassOrNamespace(name)) - return e; + Q_ASSERT(name != 0); + Q_ASSERT(name->isNameId() || name->isTemplateNameId()); - else if (! processed->contains(this)) { - processed->insert(this); + const_cast<ClassOrNamespace *>(this)->flush(); - foreach (ClassOrNamespace *u, usings()) { - if (ClassOrNamespace *e = u->findClassOrNamespace_helper(name, processed)) - return e; - } - } + Table::const_iterator it = _classOrNamespaces.find(name); - return 0; -} + if (it == _classOrNamespaces.end()) + return 0; -ClassOrNamespace *ClassOrNamespace::nestedClassOrNamespace(const QByteArray &name) const -{ - const_cast<ClassOrNamespace *>(this)->flush(); - return _classOrNamespaces.value(name); + return it->second; } void ClassOrNamespace::flush() @@ -540,9 +543,9 @@ void ClassOrNamespace::addUsing(ClassOrNamespace *u) _usings.append(u); } -void ClassOrNamespace::addNestedClassOrNamespace(const QByteArray &alias, ClassOrNamespace *e) +void ClassOrNamespace::addNestedClassOrNamespace(const Name *alias, ClassOrNamespace *e) { - _classOrNamespaces.insert(alias, e); + _classOrNamespaces[alias] = e; } ClassOrNamespace *ClassOrNamespace::findOrCreate(const Name *name) @@ -558,13 +561,12 @@ ClassOrNamespace *ClassOrNamespace::findOrCreate(const Name *name) return e; - } else if (const Identifier *id = name->identifier()) { - const QByteArray name = QByteArray::fromRawData(id->chars(), id->size()); + } else if (name->isNameId() || name->isTemplateNameId()) { ClassOrNamespace *e = nestedClassOrNamespace(name); if (! e) { e = _factory->allocClassOrNamespace(this); - _classOrNamespaces.insert(name, e); + _classOrNamespaces[name] = e; } return e; @@ -615,7 +617,7 @@ ClassOrNamespace *CreateBindings::findClassOrNamespace(Symbol *symbol) return b; } -ClassOrNamespace *CreateBindings::findClassOrNamespace(const QList<QByteArray> &path) +ClassOrNamespace *CreateBindings::findClassOrNamespace(const QList<const Name *> &path) { ClassOrNamespace *e = _globalNamespace->findClassOrNamespace(path); return e; @@ -726,8 +728,7 @@ bool CreateBindings::visit(Declaration *decl) if (typedefId && ! (ty.isConst() || ty.isVolatile())) { if (const NamedType *namedTy = ty->asNamedType()) { if (ClassOrNamespace *e = _currentClassOrNamespace->lookupClassOrNamespace(namedTy->name())) { - const QByteArray alias = QByteArray::fromRawData(typedefId->chars(), typedefId->size()); - _currentClassOrNamespace->addNestedClassOrNamespace(alias, e); + _currentClassOrNamespace->addNestedClassOrNamespace(decl->name(), e); } else if (false) { Overview oo; qDebug() << "found entity not found for" << oo(namedTy->name()); @@ -772,8 +773,8 @@ bool CreateBindings::visit(NamespaceAlias *a) return false; } else if (ClassOrNamespace *e = _currentClassOrNamespace->lookupClassOrNamespace(a->namespaceName())) { - const QByteArray name = QByteArray::fromRawData(a->identifier()->chars(), a->identifier()->size()); - _currentClassOrNamespace->addNestedClassOrNamespace(name, e); + if (a->name()->isNameId() || a->name()->isTemplateNameId()) + _currentClassOrNamespace->addNestedClassOrNamespace(a->name(), e); } else if (false) { Overview oo; diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 242b353cb7dcf261624d8e7841d5a986bed47194..3d073aa6bbd1ebc13f601e87b0afa1f71ffa836c 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -36,6 +36,8 @@ #include <Type.h> #include <SymbolVisitor.h> #include <QtCore/QSet> +#include <map> +#include <functional> namespace CPlusPlus { @@ -56,7 +58,7 @@ public: ClassOrNamespace *lookupClassOrNamespace(const Name *name); ClassOrNamespace *findClassOrNamespace(const Name *name); - ClassOrNamespace *findClassOrNamespace(const QList<QByteArray> &path); + ClassOrNamespace *findClassOrNamespace(const QList<const Name *> &path); /// \internal static void lookup_helper(const Name *name, Scope *scope, QList<Symbol *> *result); @@ -72,7 +74,7 @@ private: void addSymbol(Symbol *symbol); void addEnum(Enum *e); void addUsing(ClassOrNamespace *u); - void addNestedClassOrNamespace(const QByteArray &alias, ClassOrNamespace *e); + void addNestedClassOrNamespace(const Name *alias, ClassOrNamespace *e); void lookup_helper(const Name *name, ClassOrNamespace *binding, QList<Symbol *> *result, @@ -80,16 +82,20 @@ private: ClassOrNamespace *lookupClassOrNamespace_helper(const Name *name, QSet<ClassOrNamespace *> *processed); ClassOrNamespace *findClassOrNamespace_helper(const Name *name, QSet<ClassOrNamespace *> *processed); - ClassOrNamespace *findClassOrNamespace_helper(const QByteArray &name, QSet<ClassOrNamespace *> *processed); + ClassOrNamespace *nestedClassOrNamespace(const Name *name) const; - ClassOrNamespace *nestedClassOrNamespace(const QByteArray &name) const; +private: + struct CompareName: std::binary_function<const Name *, const Name *, bool> { + bool operator()(const Name *name, const Name *other) const; + }; private: + typedef std::map<const Name *, ClassOrNamespace *, CompareName> Table; CreateBindings *_factory; ClassOrNamespace *_parent; QList<Symbol *> _symbols; QList<ClassOrNamespace *> _usings; - QHash<QByteArray, ClassOrNamespace *> _classOrNamespaces; + Table _classOrNamespaces; QList<Enum *> _enums; QList<Symbol *> _todo; @@ -107,7 +113,7 @@ public: ClassOrNamespace *globalNamespace() const; ClassOrNamespace *findClassOrNamespace(Symbol *s); // ### rename - ClassOrNamespace *findClassOrNamespace(const QList<QByteArray> &path); + ClassOrNamespace *findClassOrNamespace(const QList<const Name *> &path); /// \internal void process(Symbol *s, ClassOrNamespace *classOrNamespace);