diff options
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r-- | src/libs/cplusplus/CppRewriter.cpp | 3 | ||||
-rw-r--r-- | src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp | 7 | ||||
-rw-r--r-- | src/libs/cplusplus/LookupContext.cpp | 41 | ||||
-rw-r--r-- | src/libs/cplusplus/LookupContext.h | 3 |
4 files changed, 45 insertions, 9 deletions
diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp index 2dee6ddc94..15d3b9d156 100644 --- a/src/libs/cplusplus/CppRewriter.cpp +++ b/src/libs/cplusplus/CppRewriter.cpp @@ -263,7 +263,8 @@ public: QVarLengthArray<FullySpecifiedType, 8> args(name->templateArgumentCount()); for (unsigned i = 0; i < name->templateArgumentCount(); ++i) args[i] = rewrite->rewriteType(name->templateArgumentAt(i)); - temps.append(control()->templateNameId(identifier(name->identifier()), args.data(), args.size())); + temps.append(control()->templateNameId(identifier(name->identifier()), name->isSpecialization(), + args.data(), args.size())); } virtual void visit(const DestructorNameId *name) diff --git a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp index eb27a6bf55..83a833cc38 100644 --- a/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp +++ b/src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp @@ -253,6 +253,7 @@ private: } const TemplateNameId *templId = control()->templateNameId(name->identifier(), + name->isSpecialization(), arguments.data(), arguments.size()); _type = control()->namedType(templId); @@ -269,13 +270,15 @@ private: } else if (const TemplateNameId *templId = name->asTemplateNameId()) { QVarLengthArray<FullySpecifiedType, 8> arguments(templId->templateArgumentCount()); - for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount(); ++templateArgIndex) { + for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount(); + ++templateArgIndex) { FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex); arguments[templateArgIndex] = q->apply(argTy); } const Identifier *id = control()->identifier(templId->identifier()->chars(), templId->identifier()->size()); - return control()->templateNameId(id, arguments.data(), arguments.size()); + return control()->templateNameId(id, templId->isSpecialization(), arguments.data(), + arguments.size()); } else if (const QualifiedNameId *qq = name->asQualifiedNameId()) { const Name *base = instantiate(qq->base()); diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index b73c22b657..32e2fef6dd 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -716,6 +716,42 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac ClassOrNamespace *reference = it->second; + const TemplateNameId *templId = name->asTemplateNameId(); + if (templId) { + // if it is a TemplateNameId it could be a specialization(full or partial) or + // instantiation of one of the specialization(reference->_specialization) or + // base class(reference) + if (templId->isSpecialization()) { + // if it is a specialization we try to find or create new one and + // add to base class(reference) + TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId); + if (cit != reference->_specializations.end()) { + return cit->second; + } else { + ClassOrNamespace *newSpecialization = _factory->allocClassOrNamespace(reference); +#ifdef DEBUG_LOOKUP + newSpecialization->_name = templId; +#endif // DEBUG_LOOKUP + reference->_specializations[templId] = newSpecialization; + return newSpecialization; + } + } else { + TemplateNameId *nonConstTemplId = const_cast<TemplateNameId *>(templId); + // make this instantiation looks like specialization which help to find + // full specialization for this instantiation + nonConstTemplId->setIsSpecialization(true); + TemplateNameIdTable::const_iterator cit = reference->_specializations.find(templId); + if (cit != reference->_specializations.end()) { + // we found full specialization + reference = cit->second; + } else { + // TODO: find the best specialization(probably partial) for this instantiation + } + // let's instantiation be instantiation + nonConstTemplId->setIsSpecialization(false); + } + } + // The reference binding might still be missing some of its base classes in the case they // are templates. We need to collect them now. First, we track the bases which are already // part of the binding so we can identify the missings ones later. @@ -737,7 +773,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac if (!referenceClass) return reference; - const TemplateNameId *templId = name->asTemplateNameId(); if ((! templId && _alreadyConsideredClasses.contains(referenceClass)) || (templId && _alreadyConsideredTemplates.contains(templId))) { @@ -752,9 +787,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac // If we are dealling with a template type, more work is required, since we need to // construct all instantiation data. if (templId) { - if (_instantiations.contains(templId)) - return _instantiations[templId]; - _alreadyConsideredTemplates.insert(templId); ClassOrNamespace *instantiation = _factory->allocClassOrNamespace(reference); #ifdef DEBUG_LOOKUP @@ -863,7 +895,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac } _alreadyConsideredTemplates.clear(templId); - _instantiations[templId] = instantiation; return instantiation; } diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 8144cbfa84..d5f6a9acc3 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -101,6 +101,7 @@ private: private: typedef std::map<const Name *, ClassOrNamespace *, Name::Compare> Table; + typedef std::map<const TemplateNameId *, ClassOrNamespace *, TemplateNameId::Compare> TemplateNameIdTable; CreateBindings *_factory; ClassOrNamespace *_parent; @@ -110,7 +111,7 @@ private: QList<Enum *> _enums; QList<Symbol *> _todo; QSharedPointer<Control> _control; - QMap<const Name *, ClassOrNamespace *> _instantiations; + TemplateNameIdTable _specializations; // it's an instantiation. const TemplateNameId *_templateId; |