diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 09ce5d0f40e..e5bb6158d9b 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -529,6 +529,7 @@ ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *pa , _scopeLookupCache(0) , _templateId(0) , _instantiationOrigin(0) + , _rootClass(0) #ifdef DEBUG_LOOKUP , _name(0) #endif // DEBUG_LOOKUP @@ -1067,6 +1068,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac instantiation->_enums.append(reference->unscopedEnums()); instantiation->_usings.append(reference->usings()); + instantiation->_rootClass = reference->rootClass(); + // It gets a bit complicated if the reference is actually a class template because we // now must worry about dependent names in base classes. if (Template *templateSpecialization = referenceClass->enclosingTemplate()) { @@ -1347,7 +1350,8 @@ void ClassOrNamespace::addNestedType(const Name *alias, ClassOrNamespace *e) _classOrNamespaces[alias] = e; } -ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNamespace *origin) +ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNamespace *origin, + Class *clazz) { if (! name) return this; @@ -1356,15 +1360,16 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa if (const QualifiedNameId *q = name->asQualifiedNameId()) { if (! q->base()) - return globalNamespace()->findOrCreateType(q->name(), origin); + return globalNamespace()->findOrCreateType(q->name(), origin, clazz); - return findOrCreateType(q->base(), origin)->findOrCreateType(q->name(), origin); + return findOrCreateType(q->base(), origin)->findOrCreateType(q->name(), origin, clazz); } else if (name->isNameId() || name->isTemplateNameId() || name->isAnonymousNameId()) { ClassOrNamespace *e = nestedType(name, origin); if (! e) { e = _factory->allocClassOrNamespace(this); + e->_rootClass = clazz; #ifdef DEBUG_LOOKUP e->_name = name; #endif // DEBUG_LOOKUP @@ -1470,7 +1475,8 @@ void CreateBindings::process(Document::Ptr doc) ClassOrNamespace *CreateBindings::enterClassOrNamespaceBinding(Symbol *symbol) { - ClassOrNamespace *entity = _currentClassOrNamespace->findOrCreateType(symbol->name()); + ClassOrNamespace *entity = _currentClassOrNamespace->findOrCreateType(symbol->name(), 0, + symbol->asClass()); entity->addSymbol(symbol); return switchCurrentClassOrNamespace(entity); @@ -1478,7 +1484,8 @@ ClassOrNamespace *CreateBindings::enterClassOrNamespaceBinding(Symbol *symbol) ClassOrNamespace *CreateBindings::enterGlobalClassOrNamespace(Symbol *symbol) { - ClassOrNamespace *entity = _globalNamespace->findOrCreateType(symbol->name()); + ClassOrNamespace *entity = _globalNamespace->findOrCreateType(symbol->name(), 0, + symbol->asClass()); entity->addSymbol(symbol); return switchCurrentClassOrNamespace(entity); @@ -1516,7 +1523,7 @@ bool CreateBindings::visit(Class *klass) binding = _currentClassOrNamespace->lookupType(klass->name()); if (! binding) - binding = _currentClassOrNamespace->findOrCreateType(klass->name()); + binding = _currentClassOrNamespace->findOrCreateType(klass->name(), 0, klass); _currentClassOrNamespace = binding; _currentClassOrNamespace->addSymbol(klass); @@ -1568,7 +1575,8 @@ bool CreateBindings::visit(Declaration *decl) } } else if (Class *klass = ty->asClassType()) { if (const Identifier *nameId = decl->name()->asNameId()) { - ClassOrNamespace *binding = _currentClassOrNamespace->findOrCreateType(nameId); + ClassOrNamespace *binding + = _currentClassOrNamespace->findOrCreateType(nameId, 0, klass); binding->addSymbol(klass); } } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index cc229cb730f..d61cb4af174 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -87,6 +87,9 @@ public: Symbol *lookupInScope(const QList &fullName); + /// The class this ClassOrNamespace is based on. + Class *rootClass() const { return _rootClass; } + private: typedef std::map Table; typedef std::map TemplateNameIdTable; @@ -95,7 +98,8 @@ private: void flush(); /// \internal - ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0); + ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0, + Class *clazz = 0); void addTodo(Symbol *symbol); void addSymbol(Symbol *symbol); @@ -145,6 +149,8 @@ private: AlreadyConsideredClassContainer _alreadyConsideredClasses; AlreadyConsideredClassContainer _alreadyConsideredTemplates; + Class *_rootClass; + class NestedClassInstantiator { public: