From a945d52a62b73b23674f6dc0948e22011e278cf9 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sat, 26 Dec 2020 15:42:03 +0100 Subject: When instantiating templates also instantiate nested classes --- src/classdef.cpp | 60 +++++++++++++++++++++++++++++++++++++++++--------------- src/classdef.h | 2 +- src/doxygen.cpp | 11 ++--------- 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/classdef.cpp b/src/classdef.cpp index 53d758e..b3eb353 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -269,7 +269,7 @@ class ClassDefImpl : public DefinitionMixin virtual void setTemplateBaseClassNames(QDict *templateNames); virtual void setTemplateMaster(const ClassDef *tm); virtual void setTypeConstraints(const ArgumentList &al); - virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec); + virtual void addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const char *templSpec); virtual void makeTemplateArgument(bool b=TRUE); virtual void setCategoryOf(ClassDef *cd); virtual void setUsedOnly(bool b); @@ -4034,16 +4034,35 @@ ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName, { QCString tcname = removeRedundantWhiteSpace(localName()+templSpec); Debug::print(Debug::Classes,0," New template instance class '%s''%s' inside '%s' hidden=%d\n",qPrint(name()),qPrint(templSpec),qPrint(name()),isHidden()); - templateClass = - toClassDefMutable( - Doxygen::classLinkedMap->add(tcname, - std::unique_ptr( - new ClassDefImpl(fileName,startLine,startColumn,tcname,ClassDef::Class)))); - templateClass->setTemplateMaster(this); - templateClass->setOuterScope(getOuterScope()); - templateClass->setHidden(isHidden()); - m_impl->templateInstances->insert(templSpec,templateClass); - freshInstance=TRUE; + + templateClass = toClassDefMutable(Doxygen::classLinkedMap->find(tcname)); + if (templateClass==0) + { + templateClass = + toClassDefMutable( + Doxygen::classLinkedMap->add(tcname, + std::unique_ptr( + new ClassDefImpl(fileName,startLine,startColumn,tcname,ClassDef::Class)))); + templateClass->setTemplateMaster(this); + templateClass->setOuterScope(getOuterScope()); + templateClass->setHidden(isHidden()); + m_impl->templateInstances->insert(templSpec,templateClass); + + // also add nested classes + for (const auto &innerCd : m_impl->innerClasses) + { + QCString innerName = tcname+"::"+innerCd->localName(); + ClassDefMutable *innerClass = + toClassDefMutable( + Doxygen::classLinkedMap->add(innerName, + std::unique_ptr( + new ClassDefImpl(fileName,startLine,startColumn,innerName,ClassDef::Class)))); + templateClass->addInnerCompound(innerClass); + innerClass->setOuterScope(templateClass); + innerClass->setHidden(isHidden()); + } + freshInstance=TRUE; + } } return templateClass; } @@ -4062,7 +4081,7 @@ ClassDef *ClassDefImpl::getVariableInstance(const char *templSpec) const QCString tcname = removeRedundantWhiteSpace(name()+templSpec); templateClass = new ClassDefImpl("",1,1,tcname, ClassDef::Class,0,0,FALSE); - templateClass->addMembersToTemplateInstance( this, templSpec ); + templateClass->addMembersToTemplateInstance( this, templateArguments(), templSpec ); templateClass->setTemplateMaster(this); m_impl->variableInstances->insert(templSpec,templateClass); } @@ -4093,17 +4112,17 @@ QDict *ClassDefImpl::getTemplateBaseClassNames() const return m_impl->templBaseClassNames; } -void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) +void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const char *templSpec) { //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec); - for (auto &mni : cd->memberNameInfoLinkedMap()) + for (const auto &mni : cd->memberNameInfoLinkedMap()) { - for (auto &mi : *mni) + for (const auto &mi : *mni) { auto actualArguments_p = stringToArgumentList(getLanguage(),templSpec); MemberDef *md = mi->memberDef(); std::unique_ptr imd { md->createTemplateInstanceMember( - cd->templateArguments(),actualArguments_p) }; + templateArguments,actualArguments_p) }; //printf("%s->setMemberClass(%p)\n",imd->name().data(),this); imd->setMemberClass(this); imd->setTemplateMaster(md); @@ -4122,6 +4141,15 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t mn->push_back(std::move(imd)); } } + // also instantatie members for nested classes + for (const auto &innerCd : cd->getClasses()) + { + ClassDefMutable *ncd = toClassDefMutable(m_impl->innerClasses.find(innerCd->localName())); + if (ncd) + { + ncd->addMembersToTemplateInstance(innerCd,cd->templateArguments(),templSpec); + } + } } QCString ClassDefImpl::getReference() const diff --git a/src/classdef.h b/src/classdef.h index 62db01e..217002d 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -410,7 +410,7 @@ class ClassDefMutable : public DefinitionMutable, public ClassDef virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0) = 0; virtual void insertMember(MemberDef *) = 0; virtual void insertUsedFile(FileDef *) = 0; - virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec) = 0; + virtual void addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const char *templSpec) = 0; virtual void addInnerCompound(const Definition *d) = 0; virtual bool addExample(const char *anchor,const char *name, const char *file) = 0; virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot) = 0; diff --git a/src/doxygen.cpp b/src/doxygen.cpp index b5e79dc..709b6f1 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -4372,7 +4372,7 @@ static bool findClassRelation( int i=findTemplateSpecializationPosition(baseClassName); int si=baseClassName.findRev("::",i); if (si==-1) si=0; - if (baseClass==0 && i!=-1) + if (baseClass==0 && static_cast(i)!=baseClassName.length()) // base class has template specifiers { // TODO: here we should try to find the correct template specialization @@ -4428,13 +4428,6 @@ static bool findClassRelation( } //printf("2. found=%d\n",found); - //printf("root->name=%s biName=%s baseClassName=%s\n", - // root->name.data(),biName.data(),baseClassName.data()); - //if (cd->isCSharp() && i!=-1) // C# generic -> add internal -g postfix - //{ - // baseClassName+="-g"; - //} - if (!found) { baseClass=toClassDefMutable(findClassWithinClassContext(context,cd,baseClassName)); @@ -7574,7 +7567,7 @@ static void createTemplateInstanceMembers() ClassDefMutable *tcdm = toClassDefMutable(tcd); if (tcdm) { - tcdm->addMembersToTemplateInstance(cd.get(),qdi.currentKey()); + tcdm->addMembersToTemplateInstance(cd.get(),cd->templateArguments(),qdi.currentKey()); } } } -- cgit v0.12