diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-11-05 17:53:20 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-11-09 18:47:45 (GMT) |
commit | 075229e586b391c3ec7ad79597aaeae392ca64e5 (patch) | |
tree | 2ad99929371727ad0811a55e597fa81a70ba43a7 /src | |
parent | 6922d5d63d77c8f640c58e9c68a9955f9f0aa9a7 (diff) | |
download | Doxygen-075229e586b391c3ec7ad79597aaeae392ca64e5.zip Doxygen-075229e586b391c3ec7ad79597aaeae392ca64e5.tar.gz Doxygen-075229e586b391c3ec7ad79597aaeae392ca64e5.tar.bz2 |
Refactoring: Introduce immutable and mutable interfaces
Split Definition/ClassDef/NamespaceDef/MemberDef into a immutable and mutable part
Aliases are immutable, other symbols are stored using an immutable
interface but can be made mutable explicitly by dynamic casting.
Diffstat (limited to 'src')
36 files changed, 1514 insertions, 1367 deletions
diff --git a/src/clangparser.cpp b/src/clangparser.cpp index d17ed91..1f52fb4 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -696,7 +696,7 @@ void ClangTUParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd, p->currentMemberDef && d->definitionType()==Definition::TypeMember && (p->currentMemberDef!=d || p->currentLine<line)) // avoid self-reference { - addDocCrossReference(p->currentMemberDef,dynamic_cast<MemberDef *>(d)); + addDocCrossReference(MemberDef::make_mutable(p->currentMemberDef),MemberDef::make_mutable(dynamic_cast<MemberDef *>(d))); } writeMultiLineCodeLink(ol,fd,line,column,d,text); } diff --git a/src/classdef.cpp b/src/classdef.cpp index ffbbbb4..cb98622 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -56,7 +56,7 @@ /** Implementation of the ClassDef interface */ -class ClassDefImpl : public DefinitionImpl, public ClassDef +class ClassDefImpl : public DefinitionImpl, public ClassDefMutable { public: ClassDefImpl(const char *fileName,int startLine,int startColumn, @@ -108,7 +108,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual UsesClassDict *usedInterfaceClasses() const; virtual ConstraintClassDict *templateTypeConstraints() const; virtual bool isTemplateArgument() const; - virtual Definition *findInnerCompound(const char *name) const; + virtual const Definition *findInnerCompound(const char *name) const; virtual ArgumentLists getTemplateParameterLists() const; virtual QCString qualifiedNameWithTemplateParameters( const ArgumentLists *actualParams=0,uint *actualParamIndex=0) const; @@ -199,7 +199,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef const ClassDef *inheritedFrom,const char *inheritId) const; virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const; virtual void writeSummaryLinks(OutputList &ol) const; - virtual void reclassifyMember(MemberDef *md,MemberType t); + virtual void reclassifyMember(MemberDefMutable *md,MemberType t); virtual void writeInlineDocumentation(OutputList &ol) const; virtual void writeDeclarationLink(OutputList &ol,bool &found, const char *header,bool localNames) const; @@ -273,7 +273,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef IMPL *m_impl = 0; }; -ClassDef *createClassDef( +ClassDefMutable *createClassDef( const char *fileName,int startLine,int startColumn, const char *name,ClassDef::CompoundType ct, const char *ref,const char *fName, @@ -369,7 +369,7 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef { return getCdAlias()->templateTypeConstraints(); } virtual bool isTemplateArgument() const { return getCdAlias()->isTemplateArgument(); } - virtual Definition *findInnerCompound(const char *name) const + virtual const Definition *findInnerCompound(const char *name) const { return getCdAlias()->findInnerCompound(name); } virtual ArgumentLists getTemplateParameterLists() const { return getCdAlias()->getTemplateParameterLists(); } @@ -450,89 +450,34 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef { return getCdAlias()->isSliceLocal(); } virtual bool hasNonReferenceSuperClass() const { return getCdAlias()->hasNonReferenceSuperClass(); } - virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, - const QCString &templSpec,bool &freshInstance) const - { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); } - virtual void insertBaseClass(ClassDef *,const char *,Protection,Specifier,const char *) { } - virtual void insertSubClass(ClassDef *,Protection,Specifier,const char *) { } - virtual void setIncludeFile(FileDef *,const char *,bool,bool) {} - virtual void insertMember(MemberDef *) {} - virtual void insertUsedFile(FileDef *) {} - virtual bool addExample(const char *,const char *, const char *) { return FALSE; } - virtual void mergeCategory(ClassDef *) {} - virtual void setNamespace(NamespaceDef *) {} - virtual void setFileDef(FileDef *) {} - virtual void setSubGrouping(bool) {} - virtual void setProtection(Protection) {} - virtual void setGroupDefForAllMembers(GroupDef *,Grouping::GroupPri_t,const QCString &,int,bool) {} - virtual void addInnerCompound(const Definition *) {} - virtual void addUsedClass(ClassDef *,const char *,Protection) {} - virtual void addUsedByClass(ClassDef *,const char *,Protection) {} - virtual void setIsStatic(bool) {} - virtual void setCompoundType(CompoundType) {} - virtual void setClassName(const char *) {} - virtual void setClassSpecifier(uint64) {} - virtual void setTemplateArguments(const ArgumentList &) {} - virtual void setTemplateBaseClassNames(QDict<int> *) {} - virtual void setTemplateMaster(const ClassDef *) {} - virtual void setTypeConstraints(const ArgumentList &) {} - virtual void addMembersToTemplateInstance(const ClassDef *,const char *) {} - virtual void makeTemplateArgument(bool=TRUE) {} - virtual void setCategoryOf(ClassDef *) {} - virtual void setUsedOnly(bool) {} - virtual void addTaggedInnerClass(ClassDef *) {} - virtual void setTagLessReference(ClassDef *) {} - virtual void setName(const char *) {} - virtual void setMetaData(const char *) {} - virtual void findSectionsInDocumentation() {} - virtual void addMembersToMemberGroup() {} - virtual void addListReferences() {} - virtual void addTypeConstraints() {} - virtual void computeAnchors() {} - virtual void mergeMembers() {} - virtual void sortMemberLists() {} - virtual void distributeMemberGroupDocumentation() {} - virtual void writeDocumentation(OutputList &) const {} - virtual void writeDocumentationForInnerClasses(OutputList &) const {} - virtual void writeMemberPages(OutputList &) const {} - virtual void writeMemberList(OutputList &) const {} - virtual void writeDeclaration(OutputList &,const MemberDef *,bool, - const ClassDef *,const char *) const {} - virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {} - virtual void writeSummaryLinks(OutputList &) const {} - virtual void reclassifyMember(MemberDef *,MemberType) {} - virtual void writeInlineDocumentation(OutputList &) const {} + virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const + { return getCdAlias()->countMembersIncludingGrouped(lt,inheritedFrom,additional); } + virtual int countInheritanceNodes() const + { return getCdAlias()->countInheritanceNodes(); } + virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const + { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); } + virtual void writeDeclarationLink(OutputList &ol,bool &found, const char *header,bool localNames) const { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); } - virtual void removeMemberFromLists(MemberDef *) {} - virtual void setAnonymousEnumType() {} - virtual void countMembers() {} - virtual void sortAllMembersList() {} - virtual void addGroupedInheritedMembers(OutputList &,MemberListType, - const ClassDef *,const QCString &) const {} - virtual void writeTagFile(FTextStream &) {} + virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, + const QCString &templSpec,bool &freshInstance) const + { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); } + virtual void updateBaseClasses(const BaseClassList &) {} virtual void updateSubClasses(const BaseClassList &) {} virtual void setVisited(bool visited) const { m_visited = visited; } virtual bool isVisited() const { return m_visited; } - virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const - { return getCdAlias()->countMembersIncludingGrouped(lt,inheritedFrom,additional); } - virtual int countInheritanceNodes() const - { return getCdAlias()->countInheritanceNodes(); } - virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, - int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const - { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); } - virtual void writeMemberDeclarations(OutputList &,MemberListType,const QCString &, - const char *,bool,const ClassDef *, int,bool,bool, QPtrDict<void> *) const {} private: mutable bool m_visited = false; }; + ClassDef *createClassDefAlias(const Definition *newScope,const ClassDef *cd) { return new ClassDefAliasImpl(newScope,cd); @@ -1272,7 +1217,11 @@ void ClassDefImpl::insertUsedFile(FileDef *fd) ClassDef *cd; for (qdi.toFirst();(cd=qdi.current());++qdi) { - cd->insertUsedFile(fd); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->insertUsedFile(fd); + } } } } @@ -2902,16 +2851,21 @@ void ClassDefImpl::writeDocumentationForInnerClasses(OutputList &ol) const ClassDef *innerCd; for (cli.toFirst();(innerCd=cli.current());++cli) { - if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 && - protectionLevelVisible(innerCd->protection()) && - !innerCd->isEmbeddedInOuterScope() - ) + ClassDefMutable *innerCdm = ClassDef::make_mutable(innerCd); + if (innerCdm) { - msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name())); - innerCd->writeDocumentation(ol); - innerCd->writeMemberList(ol); + if ( + innerCd->isLinkableInProject() && innerCd->templateMaster()==0 && + protectionLevelVisible(innerCd->protection()) && + !innerCd->isEmbeddedInOuterScope() + ) + { + msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name())); + innerCdm->writeDocumentation(ol); + innerCdm->writeMemberList(ol); + } + innerCdm->writeDocumentationForInnerClasses(ol); } - innerCd->writeDocumentationForInnerClasses(ol); } } } @@ -3233,7 +3187,7 @@ void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCStri static bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS); if (typeConstraint.isEmpty() || type.isEmpty()) return; SymbolResolver resolver(getFileDef()); - ClassDef *cd = const_cast<ClassDef*>(resolver.resolveClass(this,typeConstraint)); + ClassDefMutable *cd = resolver.resolveClassMutable(this,typeConstraint); if (cd==0 && !hideUndocRelation) { cd = new ClassDefImpl(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class); @@ -3520,204 +3474,206 @@ void ClassDefImpl::mergeMembers() static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); for (const auto &bcd : baseClasses()) { - ClassDef *bClass=bcd.classDef; - - // merge the members in the base class of this inheritance branch first - bClass->mergeMembers(); + ClassDefMutable *bClass=ClassDef::make_mutable(bcd.classDef); + if (bClass) + { + // merge the members in the base class of this inheritance branch first + bClass->mergeMembers(); - const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap(); - MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; + const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap(); + MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; - for (auto &srcMni : srcMnd) - { - //printf(" Base member name %s\n",srcMni->memberName()); - MemberNameInfo *dstMni; - if ((dstMni=dstMnd.find(srcMni->memberName()))) - // a member with that name is already in the class. - // the member may hide or reimplement the one in the sub class - // or there may be another path to the base class that is already - // visited via another branch in the class hierarchy. + for (auto &srcMni : srcMnd) { - for (auto &srcMi : *srcMni) + //printf(" Base member name %s\n",srcMni->memberName()); + MemberNameInfo *dstMni; + if ((dstMni=dstMnd.find(srcMni->memberName()))) + // a member with that name is already in the class. + // the member may hide or reimplement the one in the sub class + // or there may be another path to the base class that is already + // visited via another branch in the class hierarchy. { - MemberDef *srcMd = srcMi->memberDef(); - bool found=FALSE; - bool ambiguous=FALSE; - bool hidden=FALSE; - const ClassDef *srcCd = srcMd->getClassDef(); - for (auto &dstMi : *dstMni) + for (auto &srcMi : *srcMni) { - MemberDef *dstMd = dstMi->memberDef(); - if (srcMd!=dstMd) // different members + MemberDef *srcMd = srcMi->memberDef(); + bool found=FALSE; + bool ambiguous=FALSE; + bool hidden=FALSE; + const ClassDef *srcCd = srcMd->getClassDef(); + for (auto &dstMi : *dstMni) { - const ClassDef *dstCd = dstMd->getClassDef(); - //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data()); - if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) - // member is in the same or a base class - { - ArgumentList &srcAl = srcMd->argumentList(); - ArgumentList &dstAl = dstMd->argumentList(); - found=matchArguments2( - srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl, - dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl, - TRUE - ); - //printf(" Yes, matching (%s<->%s): %d\n", - // argListToString(srcMd->argumentList()).data(), - // argListToString(dstMd->argumentList()).data(), - // found); - hidden = hidden || !found; - } - else // member is in a non base class => multiple inheritance - // using the same base class. + MemberDef *dstMd = dstMi->memberDef(); + if (srcMd!=dstMd) // different members { - //printf("$$ Existing member %s %s add scope %s\n", - // dstMi->ambiguityResolutionScope.data(), - // dstMd->name().data(), - // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); - if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) + const ClassDef *dstCd = dstMd->getClassDef(); + //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data()); + if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) + // member is in the same or a base class { - dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope()); + ArgumentList &srcAl = const_cast<ArgumentList&>(srcMd->argumentList()); + ArgumentList &dstAl = const_cast<ArgumentList&>(dstMd->argumentList()); + found=matchArguments2( + srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl, + dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl, + TRUE + ); + //printf(" Yes, matching (%s<->%s): %d\n", + // argListToString(srcMd->argumentList()).data(), + // argListToString(dstMd->argumentList()).data(), + // found); + hidden = hidden || !found; + } + else // member is in a non base class => multiple inheritance + // using the same base class. + { + //printf("$$ Existing member %s %s add scope %s\n", + // dstMi->ambiguityResolutionScope.data(), + // dstMd->name().data(), + // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); + + QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) + { + dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope()); + } + ambiguous=TRUE; } - ambiguous=TRUE; - } - } - else // same members - { - // do not add if base class is virtual or - // if scope paths are equal or - // if base class is an interface (and thus implicitly virtual). - //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt); - if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) || - bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() || - dstMd->getClassDef()->compoundType()==Interface - ) - { - found=TRUE; } - else // member can be reached via multiple paths in the - // inheritance tree + else // same members { - //printf("$$ Existing member %s %s add scope %s\n", - // dstMi->ambiguityResolutionScope.data(), - // dstMd->name().data(), - // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); - - QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); - if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) + // do not add if base class is virtual or + // if scope paths are equal or + // if base class is an interface (and thus implicitly virtual). + //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt); + if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) || + bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() || + dstMd->getClassDef()->compoundType()==Interface + ) + { + found=TRUE; + } + else // member can be reached via multiple paths in the + // inheritance tree { - dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope); + //printf("$$ Existing member %s %s add scope %s\n", + // dstMi->ambiguityResolutionScope.data(), + // dstMd->name().data(), + // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data()); + + QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen); + if (scope!=dstMi->ambiguityResolutionScope().left(scope.length())) + { + dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope); + } + ambiguous=TRUE; } - ambiguous=TRUE; } + if (found) break; } - if (found) break; - } - //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n", - // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass); - - // TODO: fix the case where a member is hidden by inheritance - // of a member with the same name but with another prototype, - // while there is more than one path to the member in the - // base class due to multiple inheritance. In this case - // it seems that the member is not reachable by prefixing a - // scope name either (according to my compiler). Currently, - // this case is shown anyway. - if (!found && srcMd->protection()!=Private && !srcMd->isFriend()) - { - Protection prot=srcMd->protection(); - if (bcd.prot==Protected && prot==Public) prot=bcd.prot; - else if (bcd.prot==Private) prot=bcd.prot; - - if (inlineInheritedMembers) + //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n", + // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass); + + // TODO: fix the case where a member is hidden by inheritance + // of a member with the same name but with another prototype, + // while there is more than one path to the member in the + // base class due to multiple inheritance. In this case + // it seems that the member is not reachable by prefixing a + // scope name either (according to my compiler). Currently, + // this case is shown anyway. + if (!found && srcMd->protection()!=Private && !srcMd->isFriend()) { - if (!isStandardFunc(srcMd)) + Protection prot=srcMd->protection(); + if (bcd.prot==Protected && prot==Public) prot=bcd.prot; + else if (bcd.prot==Private) prot=bcd.prot; + + if (inlineInheritedMembers) { - //printf(" insertMember '%s'\n",srcMd->name().data()); - internalInsertMember(srcMd,prot,FALSE); + if (!isStandardFunc(srcMd)) + { + //printf(" insertMember '%s'\n",srcMd->name().data()); + internalInsertMember(srcMd,prot,FALSE); + } } - } - Specifier virt=srcMi->virt(); - if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; - - std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE); - newMi->setScopePath(bClass->name()+sep+srcMi->scopePath()); - if (ambiguous) - { - //printf("$$ New member %s %s add scope %s::\n", - // srcMi->ambiguityResolutionScope.data(), - // srcMd->name().data(), - // bClass->name().data()); + Specifier virt=srcMi->virt(); + if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; - QCString scope=bClass->name()+sep; - if (scope!=srcMi->ambiguityResolutionScope().left(scope.length())) - { - newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope()); - } - } - if (hidden) - { - if (srcMi->ambigClass()==0) + std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE); + newMi->setScopePath(bClass->name()+sep+srcMi->scopePath()); + if (ambiguous) { - newMi->setAmbigClass(bClass); - newMi->setAmbiguityResolutionScope(bClass->name()+sep); + //printf("$$ New member %s %s add scope %s::\n", + // srcMi->ambiguityResolutionScope.data(), + // srcMd->name().data(), + // bClass->name().data()); + + QCString scope=bClass->name()+sep; + if (scope!=srcMi->ambiguityResolutionScope().left(scope.length())) + { + newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope()); + } } - else + if (hidden) { - newMi->setAmbigClass(srcMi->ambigClass()); - newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep); + if (srcMi->ambigClass()==0) + { + newMi->setAmbigClass(bClass); + newMi->setAmbiguityResolutionScope(bClass->name()+sep); + } + else + { + newMi->setAmbigClass(srcMi->ambigClass()); + newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep); + } } + dstMni->push_back(std::move(newMi)); } - dstMni->push_back(std::move(newMi)); } } - } - else // base class has a member that is not in the sub class => copy - { - // create a deep copy of the list (only the MemberInfo's will be - // copied, not the actual MemberDef's) - MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); - - // copy the member(s) from the base to the sub class - for (auto &mi : *srcMni) + else // base class has a member that is not in the sub class => copy { - if (!mi->memberDef()->isFriend()) // don't inherit friends - { - Protection prot = mi->prot(); - if (bcd.prot==Protected) - { - if (prot==Public) prot=Protected; - } - else if (bcd.prot==Private) - { - prot=Private; - } - //printf("%s::%s: prot=%d bcd.prot=%d result=%d\n", - // name().data(),mi->memberDef->name().data(),mi->prot, - // bcd.prot,prot); + // create a deep copy of the list (only the MemberInfo's will be + // copied, not the actual MemberDef's) + MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); - if (prot!=Private || extractPrivate) + // copy the member(s) from the base to the sub class + for (auto &mi : *srcMni) + { + if (!mi->memberDef()->isFriend()) // don't inherit friends { - Specifier virt=mi->virt(); - if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; + Protection prot = mi->prot(); + if (bcd.prot==Protected) + { + if (prot==Public) prot=Protected; + } + else if (bcd.prot==Private) + { + prot=Private; + } + //printf("%s::%s: prot=%d bcd.prot=%d result=%d\n", + // name().data(),mi->memberDef->name().data(),mi->prot, + // bcd.prot,prot); - if (inlineInheritedMembers) + if (prot!=Private || extractPrivate) { - if (!isStandardFunc(mi->memberDef())) + Specifier virt=mi->virt(); + if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt; + + if (inlineInheritedMembers) { - //printf(" insertMember '%s'\n",mi->memberDef->name().data()); - internalInsertMember(mi->memberDef(),prot,FALSE); + if (!isStandardFunc(mi->memberDef())) + { + //printf(" insertMember '%s'\n",mi->memberDef->name().data()); + internalInsertMember(mi->memberDef(),prot,FALSE); + } } + //printf("Adding!\n"); + std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE); + newMi->setScopePath(bClass->name()+sep+mi->scopePath()); + newMi->setAmbigClass(mi->ambigClass()); + newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); + newMni->push_back(std::move(newMi)); } - //printf("Adding!\n"); - std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE); - newMi->setScopePath(bClass->name()+sep+mi->scopePath()); - newMi->setAmbigClass(mi->ambigClass()); - newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); - newMni->push_back(std::move(newMi)); } } } @@ -3731,97 +3687,113 @@ void ClassDefImpl::mergeMembers() /*! Merges the members of a Objective-C category into this class. */ -void ClassDefImpl::mergeCategory(ClassDef *category) +void ClassDefImpl::mergeCategory(ClassDef *cat) { - static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS); - bool makePrivate = category->isLocal(); - // in case extract local methods is not enabled we don't add the methods - // of the category in case it is defined in the .m file. - if (makePrivate && !extractLocalMethods) return; - bool isExtension = category->isExtension(); - - category->setCategoryOf(this); - if (isExtension) + ClassDefMutable *category = ClassDef::make_mutable(cat); + if (category) { - category->setArtificial(TRUE); + static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS); + bool makePrivate = category->isLocal(); + // in case extract local methods is not enabled we don't add the methods + // of the category in case it is defined in the .m file. + if (makePrivate && !extractLocalMethods) return; + bool isExtension = category->isExtension(); - // copy base classes/protocols from extension - for (const auto &bcd : category->baseClasses()) + category->setCategoryOf(this); + if (isExtension) { - insertBaseClass(bcd.classDef,bcd.usedName,bcd.prot,bcd.virt,bcd.templSpecifiers); - // correct bcd.classDef so that they do no longer derive from - // category, but from this class! - BaseClassList scl = bcd.classDef->subClasses(); - for (auto &scd : scl) + category->setArtificial(TRUE); + + // copy base classes/protocols from extension + for (const auto &bcd : category->baseClasses()) { - if (scd.classDef==category) + insertBaseClass(bcd.classDef,bcd.usedName,bcd.prot,bcd.virt,bcd.templSpecifiers); + // correct bcd.classDef so that they do no longer derive from + // category, but from this class! + BaseClassList scl = bcd.classDef->subClasses(); + for (auto &scd : scl) { - scd.classDef=this; + if (scd.classDef==category) + { + scd.classDef=this; + } } + bcd.classDef->updateSubClasses(scl); } - bcd.classDef->updateSubClasses(scl); } - } - // make methods private for categories defined in the .m file - //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate); + // make methods private for categories defined in the .m file + //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate); - const MemberNameInfoLinkedMap &srcMnd = category->memberNameInfoLinkedMap(); - MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; + const MemberNameInfoLinkedMap &srcMnd = category->memberNameInfoLinkedMap(); + MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap; - for (auto &srcMni : srcMnd) - { - MemberNameInfo *dstMni=dstMnd.find(srcMni->memberName()); - if (dstMni) // method is already defined in the class + for (auto &srcMni : srcMnd) { - //printf("Existing member %s\n",srcMni->memberName()); - auto &dstMi = dstMni->front(); - auto &srcMi = srcMni->front(); - if (srcMi && dstMi) + MemberNameInfo *dstMni=dstMnd.find(srcMni->memberName()); + if (dstMni) // method is already defined in the class { - combineDeclarationAndDefinition(srcMi->memberDef(),dstMi->memberDef()); - dstMi->memberDef()->setCategory(category); - dstMi->memberDef()->setCategoryRelation(srcMi->memberDef()); - srcMi->memberDef()->setCategoryRelation(dstMi->memberDef()); + //printf("Existing member %s\n",srcMni->memberName()); + auto &dstMi = dstMni->front(); + auto &srcMi = srcMni->front(); + if (srcMi && dstMi) + { + MemberDefMutable *smdm = MemberDef::make_mutable(srcMi->memberDef()); + MemberDefMutable *dmdm = MemberDef::make_mutable(dstMi->memberDef()); + if (smdm && dmdm) + { + combineDeclarationAndDefinition(smdm,dmdm); + dmdm->setCategory(category); + dmdm->setCategoryRelation(smdm); + smdm->setCategoryRelation(dmdm); + } + } } - } - else // new method name - { - //printf("New member %s\n",srcMni->memberName()); - // create a deep copy of the list - MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); - - // copy the member(s) from the category to this class - for (auto &mi : *srcMni) + else // new method name { - //printf("Adding '%s'\n",mi->memberDef->name().data()); - Protection prot = mi->prot(); - //if (makePrivate) prot = Private; - std::unique_ptr<MemberDef> newMd { mi->memberDef()->deepCopy() }; - if (newMd) + //printf("New member %s\n",srcMni->memberName()); + // create a deep copy of the list + MemberNameInfo *newMni = dstMnd.add(srcMni->memberName()); + + // copy the member(s) from the category to this class + for (auto &mi : *srcMni) { - //printf("Copying member %s\n",mi->memberDef->name().data()); - newMd->moveTo(this); + //printf("Adding '%s'\n",mi->memberDef->name().data()); + Protection prot = mi->prot(); + //if (makePrivate) prot = Private; + std::unique_ptr<MemberDefMutable> newMd { MemberDef::make_mutable(mi->memberDef()->deepCopy()) }; + if (newMd) + { + //printf("Copying member %s\n",mi->memberDef->name().data()); + newMd->moveTo(this); - std::unique_ptr<MemberInfo> newMi=std::make_unique<MemberInfo>(newMd.get(),prot,mi->virt(),mi->inherited()); - newMi->setScopePath(mi->scopePath()); - newMi->setAmbigClass(mi->ambigClass()); - newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); - newMni->push_back(std::move(newMi)); + std::unique_ptr<MemberInfo> newMi=std::make_unique<MemberInfo>(newMd.get(),prot,mi->virt(),mi->inherited()); + newMi->setScopePath(mi->scopePath()); + newMi->setAmbigClass(mi->ambigClass()); + newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope()); + newMni->push_back(std::move(newMi)); - // also add the newly created member to the global members list + // also add the newly created member to the global members list - QCString name = newMd->name(); - MemberName *mn = Doxygen::memberNameLinkedMap->add(name); + QCString name = newMd->name(); + MemberName *mn = Doxygen::memberNameLinkedMap->add(name); - newMd->setCategory(category); - newMd->setCategoryRelation(mi->memberDef()); - mi->memberDef()->setCategoryRelation(newMd.get()); - if (makePrivate || isExtension) - { - newMd->makeImplementationDetail(); + if (newMd) + { + newMd->setCategory(category); + newMd->setCategoryRelation(mi->memberDef()); + } + MemberDefMutable *mdm = MemberDef::make_mutable(mi->memberDef()); + if (mdm) + { + mdm->setCategoryRelation(newMd.get()); + } + if (newMd && (makePrivate || isExtension)) + { + newMd->makeImplementationDetail(); + } + internalInsertMember(newMd.get(),prot,FALSE); + mn->push_back(std::move(newMd)); } - internalInsertMember(newMd.get(),prot,FALSE); - mn->push_back(std::move(newMd)); } } } @@ -3995,11 +3967,14 @@ void ClassDefImpl::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pr { for (auto &mi : *mni) { - MemberDef *md=mi->memberDef(); - md->setGroupDef(gd,pri,fileName,startLine,hasDocs); - gd->insertMember(md,TRUE); - ClassDef *innerClass = md->getClassDefOfAnonymousType(); - if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs); + MemberDefMutable *md = MemberDef::make_mutable(mi->memberDef()); + if (md) + { + md->setGroupDef(gd,pri,fileName,startLine,hasDocs); + gd->insertMember(md,TRUE); + ClassDefMutable *innerClass = ClassDef::make_mutable(md->getClassDefOfAnonymousType()); + if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs); + } } } } @@ -4018,9 +3993,9 @@ void ClassDefImpl::addInnerCompound(const Definition *d) } } -Definition *ClassDefImpl::findInnerCompound(const char *name) const +const Definition *ClassDefImpl::findInnerCompound(const char *name) const { - Definition *result=0; + const Definition *result=0; if (name==0) return 0; if (m_impl->innerClasses) { @@ -4037,7 +4012,7 @@ ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName, { m_impl->templateInstances = new QDict<ClassDef>(17); } - ClassDef *templateClass=m_impl->templateInstances->find(templSpec); + ClassDefMutable *templateClass=ClassDef::make_mutable(m_impl->templateInstances->find(templSpec)); if (templateClass==0) { Debug::print(Debug::Classes,0," New template instance class '%s''%s'\n",qPrint(name()),qPrint(templSpec)); @@ -4060,7 +4035,7 @@ ClassDef *ClassDefImpl::getVariableInstance(const char *templSpec) const m_impl->variableInstances = new QDict<ClassDef>(17); m_impl->variableInstances->setAutoDelete(TRUE); } - ClassDef *templateClass=m_impl->variableInstances->find(templSpec); + ClassDefMutable *templateClass=ClassDef::make_mutable(m_impl->variableInstances->find(templSpec)); if (templateClass==0) { Debug::print(Debug::Classes,0," New template variable instance class '%s' '%s'\n",qPrint(name()),qPrint(templSpec)); @@ -4107,7 +4082,7 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t { auto actualArguments_p = stringToArgumentList(getLanguage(),templSpec); MemberDef *md = mi->memberDef(); - std::unique_ptr<MemberDef> imd { md->createTemplateInstanceMember( + std::unique_ptr<MemberDefMutable> imd { md->createTemplateInstanceMember( cd->templateArguments(),actualArguments_p) }; //printf("%s->setMemberClass(%p)\n",imd->name().data(),this); imd->setMemberClass(this); @@ -4352,7 +4327,14 @@ void ClassDefImpl::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief) ml->append(md); // for members in the declaration lists we set the section, needed for member grouping - if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(this,ml); + if ((ml->listType()&MemberListType_detailedLists)==0) + { + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->setSectionList(this,ml); + } + } } void ClassDefImpl::sortMemberLists() @@ -4474,9 +4456,9 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt, { for (const auto &ibcd : m_impl->inherits) { - ClassDef *icd=ibcd.classDef; + ClassDefMutable *icd=ClassDef::make_mutable(ibcd.classDef); int lt1,lt2; - if (icd->isLinkable()) + if (icd && icd->isLinkable()) { convertProtectionLevel(lt,ibcd.prot,<1,<2); //printf("%s: convert %d->(%d,%d) prot=%d\n", @@ -4610,8 +4592,8 @@ void ClassDefImpl::writeInheritedMemberDeclarations(OutputList &ol, { for (const auto &ibcd : m_impl->inherits) { - ClassDef *icd=ibcd.classDef; - if (icd->isLinkable()) + ClassDefMutable *icd=ClassDef::make_mutable(ibcd.classDef); + if (icd && icd->isLinkable()) { int lt1,lt3; convertProtectionLevel(lt,ibcd.prot,<1,<3); @@ -4972,7 +4954,7 @@ MemberDef *ClassDefImpl::isSmartPointer() const return m_impl->arrowOperator; } -void ClassDefImpl::reclassifyMember(MemberDef *md,MemberType t) +void ClassDefImpl::reclassifyMember(MemberDefMutable *md,MemberType t) { md->setMemberType(t); QListIterator<MemberList> mli(m_impl->memberLists); diff --git a/src/classdef.h b/src/classdef.h index faaf0f6..5dd35d3 100644 --- a/src/classdef.h +++ b/src/classdef.h @@ -30,6 +30,7 @@ struct Argument; class MemberDef; +class MemberDefMutable; class MemberList; class MemberDict; class ClassList; @@ -52,6 +53,7 @@ struct IncludeInfo; class ClassDefImpl; class FTextStream; class ClassDef; +class ClassDefMutable; /** Class that contains information about an inheritance relation. */ @@ -106,6 +108,7 @@ class ClassDef : virtual public Definition virtual ~ClassDef() {} + static ClassDefMutable *make_mutable(const ClassDef *); //----------------------------------------------------------------------------------- // --- getters @@ -258,7 +261,7 @@ class ClassDef : virtual public Definition * available, or 0 otherwise. * @param name The name of the nested compound */ - virtual Definition *findInnerCompound(const char *name) const = 0; + virtual const Definition *findInnerCompound(const char *name) const = 0; /** Returns the template parameter lists that form the template * declaration of this class. @@ -356,6 +359,37 @@ class ClassDef : virtual public Definition virtual bool hasNonReferenceSuperClass() const = 0; //----------------------------------------------------------------------------------- + // --- count members ---- + //----------------------------------------------------------------------------------- + + virtual int countMembersIncludingGrouped(MemberListType lt, + const ClassDef *inheritedFrom,bool additional) const = 0; + virtual int countInheritanceNodes() const = 0; + virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, + int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const = 0; + + //----------------------------------------------------------------------------------- + // --- helpers ---- + //----------------------------------------------------------------------------------- + + virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, + const QCString &templSpec,bool &freshInstance) const = 0; + virtual void writeDeclarationLink(OutputList &ol,bool &found, + const char *header,bool localNames) const = 0; + + //----------------------------------------------------------------------------------- + // --- visiting administration ---- + //----------------------------------------------------------------------------------- + + virtual void setVisited(bool visited) const = 0; + virtual bool isVisited() const = 0; + +}; + +class ClassDefMutable : virtual public DefinitionMutable, virtual public ClassDef +{ + public: + //----------------------------------------------------------------------------------- // --- setters ---- //----------------------------------------------------------------------------------- @@ -391,8 +425,6 @@ class ClassDef : virtual public Definition virtual void addTaggedInnerClass(ClassDef *cd) = 0; virtual void addInnerCompound(const Definition *d) = 0; virtual bool addExample(const char *anchor,const char *name, const char *file) = 0; - virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn, - const QCString &templSpec,bool &freshInstance) const = 0; virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot) = 0; virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot) = 0; virtual void makeTemplateArgument(bool b=TRUE) = 0; @@ -405,7 +437,7 @@ class ClassDef : virtual public Definition virtual void mergeMembers() = 0; virtual void sortMemberLists() = 0; virtual void distributeMemberGroupDocumentation() = 0; - virtual void reclassifyMember(MemberDef *md,MemberType t) = 0; + virtual void reclassifyMember(MemberDefMutable *md,MemberType t) = 0; virtual void removeMemberFromLists(MemberDef *md) = 0; virtual void setAnonymousEnumType() = 0; virtual void countMembers() = 0; @@ -424,8 +456,6 @@ class ClassDef : virtual public Definition virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const = 0; virtual void writeSummaryLinks(OutputList &ol) const = 0; virtual void writeInlineDocumentation(OutputList &ol) const = 0; - virtual void writeDeclarationLink(OutputList &ol,bool &found, - const char *header,bool localNames) const = 0; virtual void writeTagFile(FTextStream &) = 0; virtual void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title, const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0, @@ -434,27 +464,14 @@ class ClassDef : virtual public Definition virtual void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, const ClassDef *inheritedFrom,const QCString &inheritId) const = 0; - //----------------------------------------------------------------------------------- - // --- count members ---- - //----------------------------------------------------------------------------------- - virtual int countMembersIncludingGrouped(MemberListType lt, - const ClassDef *inheritedFrom,bool additional) const = 0; - virtual int countInheritanceNodes() const = 0; - virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom, - int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const = 0; - - - //----------------------------------------------------------------------------------- - // --- visiting administration ---- - //----------------------------------------------------------------------------------- - - virtual void setVisited(bool visited) const = 0; - virtual bool isVisited() const = 0; }; +inline ClassDefMutable *ClassDef::make_mutable(const ClassDef *cd) +{ return dynamic_cast<ClassDefMutable*>(const_cast<ClassDef*>(cd)); } + /** Factory method to create a new ClassDef object */ -ClassDef *createClassDef( +ClassDefMutable *createClassDef( const char *fileName,int startLine,int startColumn, const char *name,ClassDef::CompoundType ct, const char *ref=0,const char *fName=0, diff --git a/src/classlist.cpp b/src/classlist.cpp index ee4ffa4..a50f9d5 100644 --- a/src/classlist.cpp +++ b/src/classlist.cpp @@ -102,15 +102,17 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f bool found=FALSE; for (sdi.toFirst();(cd=sdi.current());++sdi) { + ClassDefMutable *cdm = ClassDef::make_mutable(cd); //printf(" ClassSDict::writeDeclaration for %s\n",cd->name().data()); - if (!cd->isAnonymous() && + if (cdm && + !cd->isAnonymous() && !cd->isExtension() && (cd->protection()!=Private || extractPrivate) && (filter==0 || *filter==cd->compoundType()) ) { //printf("writeDeclarationLink()\n"); - cd->writeDeclarationLink(ol,found,header,localNames); + cdm->writeDeclarationLink(ol,found,header,localNames); } } if (found) ol.endMemberList(); @@ -137,7 +139,9 @@ void ClassSDict::writeDocumentation(OutputList &ol,const Definition * container) // cd->name().data(),cd->getOuterScope(),cd->isLinkableInProject(),cd->isEmbeddedInOuterScope(), // container,cd->partOfGroups() ? cd->partOfGroups()->count() : 0); - if (!cd->isAnonymous() && + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm && + !cd->isAnonymous() && cd->isLinkableInProject() && cd->isEmbeddedInOuterScope() && !cd->isAlias() && @@ -154,7 +158,7 @@ void ClassSDict::writeDocumentation(OutputList &ol,const Definition * container) ol.endGroupHeader(); found=TRUE; } - cd->writeInlineDocumentation(ol); + cdm->writeInlineDocumentation(ol); } } } @@ -173,7 +173,6 @@ struct codeYY_state std::unordered_map< int, QCString> commentMap; int braceCount=0; - QCString forceTagReference; VariableContext theVarContext; CallContext theCallContext; TooltipManager tooltipManager; @@ -201,6 +200,7 @@ static void nextCodeLine(yyscan_t yyscanner); static void startFontClass(yyscan_t yyscanner,const char *s); static void endFontClass(yyscan_t yyscanner); static void codifyLines(yyscan_t yyscanner,const char *text); +static void incrementFlowKeyWordCount(yyscan_t yyscanner); static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol, const Definition *d, const char *text); @@ -953,10 +953,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} BEGIN(FuncCall); } <Body>{FLOWCONDITION}/{BN}*"(" { - if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) - { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); - } + incrementFlowKeyWordCount(yyscanner); startFontClass(yyscanner,"keywordflow"); codifyLines(yyscanner,yytext); endFontClass(yyscanner); @@ -974,10 +971,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} } } <Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) { - if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) - { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); - } + incrementFlowKeyWordCount(yyscanner); startFontClass(yyscanner,"keywordflow"); codifyLines(yyscanner,yytext); endFontClass(yyscanner); @@ -992,10 +986,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } <Body>{FLOWCONDITION}/{B}* { - if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) - { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); - } + incrementFlowKeyWordCount(yyscanner); startFontClass(yyscanner,"keywordflow"); codifyLines(yyscanner,yytext); endFontClass(yyscanner); @@ -1540,10 +1531,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } <MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) { - if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) - { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); - } + incrementFlowKeyWordCount(yyscanner); addParmType(yyscanner); yyextra->parmName=yytext; startFontClass(yyscanner,"keywordflow"); @@ -2050,12 +2038,6 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER} endFontClass(yyscanner); } } -<*>"/*[tag:"[^\]\n]*"]*/"{B}* { // special pattern /*[tag:filename]*/ to force linking to a tag file - yyextra->forceTagReference=yytext; - uint s=(uint)yyextra->forceTagReference.find(':'); - uint e=(uint)yyextra->forceTagReference.findRev(']'); - yyextra->forceTagReference = yyextra->forceTagReference.mid(s+1,e-s-1); - } <*>\n{B}*"/*"[!*]/[^/*] { if (Config_getBool(STRIP_CODE_COMMENTS)) { @@ -2464,6 +2446,19 @@ static void codifyLines(yyscan_t yyscanner,const char *text) } } +static void incrementFlowKeyWordCount(yyscan_t yyscanner) +{ + struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; + if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) + { + MemberDefMutable *md = MemberDef::make_mutable(yyextra->currentMemberDef); + if (md) + { + md->incrementFlowKeyWordCount(); + } + } +} + /*! writes a link to a fragment \a text that may span multiple lines, inserting * line numbers for each line. If \a text contains newlines, the link will be * split into multiple links with the same destination, one for each line. @@ -2685,9 +2680,7 @@ static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString & // in case there are multiple members we could link to, we // only link to members if defined in the same file or // defined as external. - if ((!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) && - (yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference()) - ) + if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) { yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope()))); //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); @@ -2733,7 +2726,7 @@ static bool getLinkInScope(yyscan_t yyscanner, const NamespaceDef *nd = 0; const GroupDef *gd = 0; DBG_CTX((stderr,"getLinkInScope: trying '%s'::'%s' varOnly=%d\n",c.data(),m.data(),varOnly)); - if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE,yyextra->forceTagReference) && + if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,yyextra->sourceFileDef,FALSE) && (!varOnly || md->isVariable())) { if (md->isLinkable()) @@ -2745,7 +2738,8 @@ static bool getLinkInScope(yyscan_t yyscanner, anchor.sprintf("a%d",yyextra->anchorCount); //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),yyextra->exampleName.data(), // yyextra->exampleFile.data()); - if (const_cast<MemberDef*>(md)->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) { ol.writeCodeAnchor(anchor); yyextra->anchorCount++; @@ -2765,7 +2759,7 @@ static bool getLinkInScope(yyscan_t yyscanner, md!=yyextra->currentMemberDef && yyextra->insideBody && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } //printf("d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data()); @@ -2910,7 +2904,8 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, anchor.sprintf("_a%d",yyextra->anchorCount); //printf("addExampleClass(%s,%s,%s)\n",anchor.data(),yyextra->exampleName.data(), // yyextra->exampleFile.data()); - if (const_cast<ClassDef*>(cd)->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) + ClassDefMutable *cdm = ClassDef::make_mutable(const_cast<ClassDef*>(cd)); + if (cdm && cdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) { ol.writeCodeAnchor(anchor); yyextra->anchorCount++; @@ -2928,7 +2923,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, yyextra->currentMemberDef && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } } } @@ -2960,29 +2955,13 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, DBG_CTX((stderr,"is a global md=%p yyextra->currentDefinition=%s linkable=%d\n",md,yyextra->currentDefinition?yyextra->currentDefinition->name().data():"<none>",md->isLinkable())); if (md->isLinkable()) { - QCString text; - if (!yyextra->forceTagReference.isEmpty()) // explicit reference to symbol in tag file - { - text=yyextra->forceTagReference; - if (text.right(4)==".tag") // strip .tag if present - { - text=text.left(text.length()-4); - } - text+=getLanguageSpecificSeparator(md->getLanguage()); - text+=clName; - const_cast<MemberDef*>(md)->setName(text); - const_cast<MemberDef*>(md)->setLocalName(text); - } - else // normal reference - { - text=clName; - } + QCString text=clName; writeMultiLineCodeLink(yyscanner,ol,md,text); addToSearchIndex(yyscanner,clName); if (yyextra->currentMemberDef && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } return; } @@ -3015,7 +2994,8 @@ static bool generateClassMemberLink(yyscan_t yyscanner, anchor.sprintf("a%d",yyextra->anchorCount); //printf("addExampleFile(%s,%s,%s)\n",anchor.data(),yyextra->exampleName.data(), // yyextra->exampleFile.data()); - if (xmd->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) + MemberDefMutable *mdm = MemberDef::make_mutable(xmd); + if (mdm && mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile)) { ol.writeCodeAnchor(anchor); yyextra->anchorCount++; @@ -3043,7 +3023,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner, /*xmd!=yyextra->currentMemberDef &&*/ yyextra->insideBody && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,xmd); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(xmd)); } // write the actual link @@ -3311,7 +3291,6 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons generateClassOrGlobalLink(yyscanner,ol,funcName); } exit: - yyextra->forceTagReference.resize(0); return; } @@ -3460,7 +3439,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (yyextra->currentMemberDef && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->method)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(ctx->method)); } } else @@ -3535,7 +3514,7 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (yyextra->currentMemberDef && yyextra->collectXRefs) { std::lock_guard<std::mutex> lock(g_docCrossReferenceMutex); - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(ctx->objectVar)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(ctx->objectVar)); } } else if (ctx->objectType && @@ -3803,7 +3782,6 @@ void CCodeParser::resetCodeParserState() { struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; //printf("***CodeParser::reset()\n"); - yyextra->forceTagReference.resize(0); yyextra->theVarContext.clear(); while (!yyextra->classScopeLengthStack.empty()) yyextra->classScopeLengthStack.pop(); yyextra->codeClassMap.clear(); diff --git a/src/context.cpp b/src/context.cpp index 59889ce..2f281b8 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -1670,7 +1670,6 @@ class DefinitionContext SharedPtr<TemplateStruct> lineLink; }; - private: Cachable &getCache() const { @@ -1678,7 +1677,7 @@ class DefinitionContext assert(c!=0); return *c; } - const Definition *m_def; + const Definition *m_def; }; //%% } diff --git a/src/definition.h b/src/definition.h index ee5c428..94c95b8 100644 --- a/src/definition.h +++ b/src/definition.h @@ -40,6 +40,7 @@ class GroupDef; class GroupList; class SectionInfo; class Definition; +class DefinitionMutable; class FTextStream; /** Data associated with a detailed description. */ @@ -94,6 +95,8 @@ class Definition TypeDir = 7 }; + static DefinitionMutable *make_mutable(const Definition *); + //----------------------------------------------------------------------------------- // ---- getters ----- //----------------------------------------------------------------------------------- @@ -284,6 +287,25 @@ class Definition virtual QCString pathFragment() const = 0; //----------------------------------------------------------------------------------- + // --- cookie storage ---- + //----------------------------------------------------------------------------------- + virtual void setCookie(Cookie *cookie) const = 0; + virtual Cookie *cookie() const = 0; + + //----------------------------------------------------------------------------------- + // --- symbol name ---- + //----------------------------------------------------------------------------------- + virtual void _setSymbolName(const QCString &name) = 0; + virtual QCString _symbolName() const = 0; + + // --------------------------------- + virtual ~Definition() = default; +}; + +class DefinitionMutable : virtual public Definition +{ + public: + //----------------------------------------------------------------------------------- // ---- setters ----- //----------------------------------------------------------------------------------- @@ -358,22 +380,12 @@ class Definition virtual void writeDocAnchorsToTagFile(FTextStream &) const = 0; virtual void writeToc(OutputList &ol, const LocalToc <) const = 0; - //----------------------------------------------------------------------------------- - // --- cookie storage ---- - //----------------------------------------------------------------------------------- - virtual void setCookie(Cookie *cookie) const = 0; - virtual Cookie *cookie() const = 0; - - //----------------------------------------------------------------------------------- - // --- symbol name ---- - //----------------------------------------------------------------------------------- - virtual void _setSymbolName(const QCString &name) = 0; - virtual QCString _symbolName() const = 0; - // --------------------------------- - virtual ~Definition() = default; }; +inline DefinitionMutable *Definition::make_mutable(const Definition *def) +{ return dynamic_cast<DefinitionMutable*>(const_cast<Definition*>(def)); } + /** Reads a fragment from file \a fileName starting with line \a startLine * and ending with line \a endLine. The result is returned as a string * via \a result. The function returns TRUE if successful and FALSE diff --git a/src/definitionimpl.h b/src/definitionimpl.h index 65027b4..2cf1bf6 100644 --- a/src/definitionimpl.h +++ b/src/definitionimpl.h @@ -23,7 +23,7 @@ #include "definition.h" -class DefinitionImpl : virtual public Definition +class DefinitionImpl : virtual public DefinitionMutable { public: /*! Create a new definition */ @@ -246,47 +246,14 @@ class DefinitionAliasImpl : virtual public Definition { return m_def->navigationPathAsString(); } virtual QCString pathFragment() const { return m_def->pathFragment(); } - virtual void setName(const char *) { } - virtual void setId(const char *) { } - virtual void setDefFile(const QCString&,int,int) {} - virtual void setDocumentation(const char *,const char *,int,bool=TRUE) {} - virtual void setBriefDescription(const char *,const char *,int) {} - virtual void setInbodyDocumentation(const char *,const char *,int) {} - virtual void setReference(const char *) {} - virtual void addSectionsToDefinition(const std::vector<const SectionInfo*> &) {} - virtual void setBodySegment(int,int,int) {} - virtual void setBodyDef(FileDef *) {} - virtual void addSourceReferencedBy(const MemberDef *) {} - virtual void addSourceReferences(const MemberDef *) {} - virtual void setRefItems(const RefItemVector &) {} - virtual void mergeRefItems(Definition *) {} - virtual void mergeReferences(const Definition *) {} - virtual void mergeReferencedBy(const Definition *) {} - virtual void addInnerCompound(const Definition *) {} - virtual void setOuterScope(Definition *) {} - virtual void setHidden(bool) {} - virtual void setArtificial(bool) {} - virtual void setLanguage(SrcLangExt) {} - virtual void writeSourceDef(OutputList &,const char *) const {} - virtual void writeInlineCode(OutputList &,const char *) const {} - virtual void writeSourceRefs(OutputList &,const char *) const {} - virtual void writeSourceReffedBy(OutputList &,const char *) const {} - virtual void makePartOfGroup(GroupDef *) {} - virtual void writeNavigationPath(OutputList &) const {} - virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {} - virtual void writeSummaryLinks(OutputList &) const {} - virtual void writeDocAnchorsToTagFile(FTextStream &) const {} - virtual void setLocalName(const QCString) {} - virtual void addSectionsToIndex() {} - virtual void writeToc(OutputList &, const LocalToc &) const {} - virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } - virtual Cookie *cookie() const { return m_cookie; } - virtual void computeTooltip() {} + protected: const Definition *getAlias() const { return m_def; } const Definition *getScope() const { return m_scope; } private: + virtual void setCookie(Cookie *cookie) const { delete m_cookie; m_cookie = cookie; } + virtual Cookie *cookie() const { return m_cookie; } virtual void _setSymbolName(const QCString &name) { m_symbolName = name; } virtual QCString _symbolName() const { return m_symbolName; } const Definition *m_scope; @@ -295,5 +262,4 @@ class DefinitionAliasImpl : virtual public Definition QCString m_symbolName; }; - #endif diff --git a/src/dirdef.h b/src/dirdef.h index 468901d..9097c09 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -39,7 +39,7 @@ typedef std::vector<DirDef*> DirList; bool compareDirDefs(const DirDef *item1, const DirDef *item2); /** A model of a directory symbol. */ -class DirDef : virtual public Definition +class DirDef : virtual public DefinitionMutable { public: virtual ~DirDef() {} diff --git a/src/dotgfxhierarchytable.cpp b/src/dotgfxhierarchytable.cpp index ddd9410..f9078cf 100644 --- a/src/dotgfxhierarchytable.cpp +++ b/src/dotgfxhierarchytable.cpp @@ -109,9 +109,9 @@ void DotGfxHierarchyTable::addHierarchy(DotNode *n,const ClassDef *cd,bool hideS //printf("addHierarchy '%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count()); for (const auto &bcd : cd->subClasses()) { - ClassDef *bClass=bcd.classDef; + ClassDefMutable *bClass=ClassDef::make_mutable(bcd.classDef); //printf(" Trying sub class='%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count()); - if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses())) + if (bClass && bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses())) { DotNode *bn; //printf(" Node '%s' Found visible class='%s'\n",n->label().data(), diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 0a86123..8d34955 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -140,7 +140,7 @@ StringUnorderedSet Doxygen::expandAsDefinedSet; // all macros that should be exp QIntDict<MemberGroupInfo> Doxygen::memGrpInfoDict(1009); // dictionary of the member groups heading PageDef *Doxygen::mainPage = 0; bool Doxygen::insideMainPage = FALSE; // are we generating docs for the main page? -NamespaceDef *Doxygen::globalScope = 0; +NamespaceDefMutable *Doxygen::globalScope = 0; bool Doxygen::parseSourcesNeeded = FALSE; SearchIndexIntf *Doxygen::searchIndex=0; SymbolMap<Definition> Doxygen::symbolMap; @@ -276,7 +276,7 @@ void statistics() -static void addMemberDocs(const Entry *root,MemberDef *md, const char *funcDecl, +static void addMemberDocs(const Entry *root,MemberDefMutable *md, const char *funcDecl, const ArgumentList *al,bool over_load,uint64 spec); static void findMember(const Entry *root, const QCString &relates, @@ -297,7 +297,7 @@ enum FindBaseClassRelation_Mode static bool findClassRelation( const Entry *root, Definition *context, - ClassDef *cd, + ClassDefMutable *cd, const BaseInfo *bi, QDict<int> *templateNames, /*bool insertUndocumented*/ @@ -307,7 +307,7 @@ static bool findClassRelation( //---------------------------------------------------------------------------- -static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n, +static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n, FileDef *fileScope,const TagInfo *tagInfo); static void addPageToContext(PageDef *pd,Entry *root) @@ -321,7 +321,7 @@ static void addPageToContext(PageDef *pd,Entry *root) } scope = stripAnonymousNamespaceScope(scope); scope+="::"+pd->name(); - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo()); + DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo()); if (d) { pd->setPageScope(d); @@ -558,7 +558,7 @@ static void buildFileList(const Entry *root) for (const auto &e : root->children()) buildFileList(e.get()); } -static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root) +static void addIncludeFile(ClassDefMutable *cd,FileDef *ifd,const Entry *root) { if ( (!root->doc.stripWhiteSpace().isEmpty() || @@ -716,13 +716,13 @@ static Definition *findScope(Entry *root,int level=0) * full qualified name \a name. Creates an artificial scope if the scope is * not found and set the parent/child scope relation if the scope is found. */ -static Definition *buildScopeFromQualifiedName(const QCString name, +static DefinitionMutable *buildScopeFromQualifiedName(const QCString name, int level,SrcLangExt lang,const TagInfo *tagInfo) { //printf("buildScopeFromQualifiedName(%s) level=%d\n",name.data(),level); int i=0; int p=0,l; - Definition *prevScope=Doxygen::globalScope; + DefinitionMutable *prevScope=Doxygen::globalScope; QCString fullScope; while (i<level) { @@ -732,10 +732,10 @@ static Definition *buildScopeFromQualifiedName(const QCString name, if (nsName.isEmpty()) return prevScope; if (!fullScope.isEmpty()) fullScope+="::"; fullScope+=nsName; - NamespaceDef *nd=Doxygen::namespaceSDict->find(fullScope); - Definition *innerScope = nd; - ClassDef *cd=0; - if (nd==0) cd = getClass(fullScope); + NamespaceDefMutable *nd=NamespaceDef::make_mutable(Doxygen::namespaceSDict->find(fullScope)); + DefinitionMutable *innerScope = nd; + ClassDefMutable *cd=0; + if (nd==0) cd = getClassMutable(fullScope); if (nd==0 && cd) // scope is a class { innerScope = cd; @@ -775,11 +775,11 @@ static Definition *buildScopeFromQualifiedName(const QCString name, return prevScope; } -static Definition *findScopeFromQualifiedName(Definition *startScope,const QCString &n, +static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n, FileDef *fileScope,const TagInfo *tagInfo) { //printf("<findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data()); - Definition *resultScope=startScope; + DefinitionMutable *resultScope=startScope; if (resultScope==0) resultScope=Doxygen::globalScope; QCString scope=stripTemplateSpecifiersFromScope(n,FALSE); int l1=0,i1; @@ -795,7 +795,7 @@ static Definition *findScopeFromQualifiedName(Definition *startScope,const QCStr QCString nestedNameSpecifier = scope.mid(i1,l1); Definition *orgScope = resultScope; //printf(" nestedNameSpecifier=%s\n",nestedNameSpecifier.data()); - resultScope = const_cast<Definition *>(resultScope->findInnerCompound(nestedNameSpecifier)); + resultScope = Definition::make_mutable(resultScope->findInnerCompound(nestedNameSpecifier)); //printf(" resultScope=%p\n",resultScope); if (resultScope==0) { @@ -804,7 +804,7 @@ static Definition *findScopeFromQualifiedName(Definition *startScope,const QCStr { for (const auto &nd : fileScope->getUsedNamespaces()) { - resultScope = findScopeFromQualifiedName(const_cast<NamespaceDef*>(nd),n,fileScope,tagInfo); + resultScope = findScopeFromQualifiedName(NamespaceDef::make_mutable(nd),n,fileScope,tagInfo); if (resultScope!=0) break; } if (resultScope) @@ -970,7 +970,7 @@ static void addClassToContext(const Entry *root) } // see if we already found the class before - ClassDef *cd = getClass(qualifiedName); + ClassDefMutable *cd = getClassMutable(qualifiedName); Debug::print(Debug::Classes,0, " Found class with name %s (qualifiedName=%s -> cd=%p)\n", cd ? qPrint(cd->name()) : qPrint(root->name), qPrint(qualifiedName),cd); @@ -1149,7 +1149,14 @@ static void buildClassDocList(const Entry *root) static void resolveClassNestingRelations() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + for (cli.toFirst();cli.current();++cli) + { + ClassDefMutable *cdm = ClassDef::make_mutable(cli.current()); + if (cdm) + { + cdm->setVisited(FALSE); + } + } bool done=FALSE; int iteration=0; @@ -1157,15 +1164,16 @@ static void resolveClassNestingRelations() { done=TRUE; ++iteration; - ClassDef *cd=0; - for (cli.toFirst();(cd=cli.current());++cli) + ClassDef *icd=0; + for (cli.toFirst();(icd=cli.current());++cli) { - if (!cd->isVisited()) + ClassDefMutable *cd = ClassDef::make_mutable(icd); + if (cd && !cd->isVisited()) { QCString name = stripAnonymousNamespaceScope(cd->name()); //printf("processing=%s, iteration=%d\n",cd->name().data(),iteration); // also add class to the correct structural context - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope, + DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope, name,cd->getFileDef(),0); if (d) { @@ -1178,9 +1186,9 @@ static void resolveClassNestingRelations() { NamespaceDef *nd = dynamic_cast<NamespaceDef*>(d); //printf("d->isInline()=%d\n",nd->isInline()); - if (nd->isInline()) + if (nd && nd->isInline()) { - d = d->getOuterScope(); + d = Definition::make_mutable(d->getOuterScope()); if (d) { ClassDef *aliasCd = createClassDefAlias(d,cd); @@ -1188,7 +1196,7 @@ static void resolveClassNestingRelations() QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName(); Doxygen::classSDict->append(aliasFullName,aliasCd); //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName)); - aliasCd->setVisited(TRUE); + //aliasCd->setVisited(TRUE); // not needed anymore, as aliasCd is not mutable } } else @@ -1209,16 +1217,17 @@ static void resolveClassNestingRelations() } //give warnings for unresolved compounds - ClassDef *cd=0; - for (cli.toFirst();(cd=cli.current());++cli) + ClassDef *icd=0; + for (cli.toFirst();(icd=cli.current());++cli) { - if (!cd->isVisited()) + ClassDefMutable *cd = ClassDef::make_mutable(icd); + if (cd && !cd->isVisited()) { QCString name = stripAnonymousNamespaceScope(cd->name()); //printf("processing unresolved=%s, iteration=%d\n",cd->name().data(),iteration); /// create the scope artificially // anyway, so we can at least relate scopes properly. - Definition *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0); + DefinitionMutable *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0); if (d!=cd && !cd->getDefFileName().isEmpty()) // avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; } // for this case doxygen assumes the existence of a namespace N::N in which C is to be found! @@ -1242,14 +1251,22 @@ void distributeClassGroupRelations() //printf("** distributeClassGroupRelations()\n"); ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + for (cli.toFirst();cli.current();++cli) + { + ClassDefMutable *cdm = ClassDef::make_mutable(cli.current()); + if (cdm) + { + cdm->setVisited(FALSE); + } + } - ClassDef *cd; - for (cli.toFirst();(cd=cli.current());++cli) + ClassDef *icd; + for (cli.toFirst();(icd=cli.current());++cli) { + ClassDefMutable *cd = ClassDef::make_mutable(icd); //printf("Checking %s\n",cd->name().data()); // distribute the group to nested classes as well - if (!cd->isVisited() && cd->partOfGroups()!=0 && cd->getClassSDict()) + if (cd && !cd->isVisited() && cd->partOfGroups()!=0 && cd->getClassSDict()) { //printf(" Candidate for merging\n"); ClassSDict::Iterator ncli(*cd->getClassSDict()); @@ -1257,12 +1274,13 @@ void distributeClassGroupRelations() GroupDef *gd = cd->partOfGroups()->at(0); for (ncli.toFirst();(ncd=ncli.current());++ncli) { - if (ncd->partOfGroups()==0) + ClassDefMutable *ncdm = ClassDef::make_mutable(ncd); + if (ncdm && ncdm->partOfGroups()==0) { //printf(" Adding %s to group '%s'\n",ncd->name().data(), // gd->groupTitle()); - ncd->makePartOfGroup(gd); - gd->addClass(ncd); + ncdm->makePartOfGroup(gd); + gd->addClass(ncdm); } } cd->setVisited(TRUE); // only visit every class once @@ -1272,12 +1290,12 @@ void distributeClassGroupRelations() //---------------------------- -static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QCString &fieldName) +static ClassDefMutable *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QCString &fieldName) { QCString fullName = removeAnonymousScopes(templ->name()); if (fullName.right(2)=="::") fullName=fullName.left(fullName.length()-2); fullName+="."+fieldName; - ClassDef *cd = createClassDef(templ->getDefFileName(), + ClassDefMutable *cd = createClassDef(templ->getDefFileName(), templ->getDefLine(), templ->getDefColumn(), fullName, @@ -1291,7 +1309,11 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC cd->setOuterScope(rootCd->getOuterScope()); if (rootCd->getOuterScope()!=Doxygen::globalScope) { - rootCd->getOuterScope()->addInnerCompound(cd); + DefinitionMutable *outerScope = Definition::make_mutable(rootCd->getOuterScope()); + if (outerScope) + { + outerScope->addInnerCompound(cd); + } } FileDef *fd = templ->getFileDef(); @@ -1322,7 +1344,7 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC for (li.toFirst();(md=li.current());++li) { //printf(" Member %s type=%s\n",md->name().data(),md->typeString()); - MemberDef *imd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(), + MemberDefMutable *imd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(), md->typeString(),md->name(),md->argsString(),md->excpString(), md->protection(),md->virtualness(),md->isStatic(),Member, md->memberType(), @@ -1354,12 +1376,12 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC */ static void processTagLessClasses(ClassDef *rootCd, ClassDef *cd, - ClassDef *tagParentCd, + ClassDefMutable *tagParentCd, const QCString &prefix,int count) { //printf("%d: processTagLessClasses %s\n",count,cd->name().data()); //printf("checking members for %s\n",cd->name().data()); - if (cd->getClassSDict()) + if (tagParentCd && cd->getClassSDict()) { MemberList *ml = cd->getMemberList(MemberListType_pubAttribs); if (ml) @@ -1383,7 +1405,7 @@ static void processTagLessClasses(ClassDef *rootCd, if (md->isAnonymous()) name = "__unnamed" + name.right(name.length()-1)+"__"; if (!prefix.isEmpty()) name.prepend(prefix+"."); //printf(" found %s for class %s\n",name.data(),cd->name().data()); - ClassDef *ncd = createTagLessInstance(rootCd,icd,name); + ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name); processTagLessClasses(rootCd,icd,ncd,name,count+1); //printf(" addTagged %s to %s\n",ncd->name().data(),tagParentCd->name().data()); tagParentCd->addTaggedInnerClass(ncd); @@ -1403,9 +1425,10 @@ static void processTagLessClasses(ClassDef *rootCd, MemberDef *pmd; for (pli.toFirst();(pmd=pli.current());++pli) { - if (pmd->name()==md->name()) + MemberDefMutable *pmdm = MemberDef::make_mutable(pmd); + if (pmdm && pmd->name()==md->name()) { - pmd->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name())); + pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name())); //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name())); } } @@ -1433,7 +1456,7 @@ static void findTagLessClasses(ClassDef *cd) } } - processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes (if any) + processTagLessClasses(cd,cd,ClassDef::make_mutable(cd),"",0); // process tag less inner struct/classes (if any) } static void findTagLessClasses() @@ -1477,8 +1500,8 @@ static void buildNamespaceList(const Entry *root) { //printf("Found namespace %s in %s at line %d\n",root->name.data(), // root->fileName.data(), root->startLine); - NamespaceDef *nd; - if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace + NamespaceDefMutable *nd; + if ((nd=NamespaceDef::make_mutable(Doxygen::namespaceSDict->find(fullName)))) // existing namespace { nd->setDocumentation(root->doc,root->docFile,root->docLine); nd->setName(fullName); // change name to match docs @@ -1546,7 +1569,7 @@ static void buildNamespaceList(const Entry *root) Doxygen::namespaceSDict->inSort(fullName,nd); // also add namespace to the correct structural context - Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo); + DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo); //printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"<none>"); if (d==0) // we didn't find anything, create the scope artificially // anyway, so we can at least relate scopes properly. @@ -1565,9 +1588,9 @@ static void buildNamespaceList(const Entry *root) while (d->definitionType()==Definition::TypeNamespace) { NamespaceDef *pnd = dynamic_cast<NamespaceDef*>(d); - if (pnd->isInline()) + if (pnd && pnd->isInline()) { - d = d->getOuterScope(); + d = Definition::make_mutable(d->getOuterScope()); if (d) { NamespaceDef *aliasNd = createNamespaceDefAlias(d,nd); @@ -1616,7 +1639,7 @@ static void findUsingDirectives(const Entry *root) if (!name.isEmpty()) { const NamespaceDef *usingNd = 0; - NamespaceDef *nd = 0; + NamespaceDefMutable *nd = 0; FileDef *fd = root->fileDef(); QCString nsName; @@ -1629,7 +1652,7 @@ static void findUsingDirectives(const Entry *root) nsName=stripAnonymousNamespaceScope(root->parent()->name); if (!nsName.isEmpty()) { - nd = getResolvedNamespace(nsName); + nd = getResolvedNamespaceMutable(nsName); } } @@ -1657,17 +1680,17 @@ static void findUsingDirectives(const Entry *root) if (usingNd==0 && nd) // not found, try used namespaces in this scope // or in one of the parent namespace scopes { - const NamespaceDef *pnd = nd; + const NamespaceDefMutable *pnd = nd; while (pnd && usingNd==0) { // also try with one of the used namespaces found earlier - usingNd = findUsedNamespace(pnd->getUsedNamespaces(),name); + usingNd = NamespaceDef::make_mutable(findUsedNamespace(pnd->getUsedNamespaces(),name)); // goto the parent const Definition *s = pnd->getOuterScope(); if (s && s->definitionType()==Definition::TypeNamespace) { - pnd = dynamic_cast<const NamespaceDef*>(s); + pnd = NamespaceDef::make_mutable(dynamic_cast<const NamespaceDef*>(s)); } else { @@ -1776,8 +1799,8 @@ static void findUsingDeclarations(const Entry *root) // rootNav->parent()->section()); if (!root->name.isEmpty()) { - ClassDef *usingCd = 0; - NamespaceDef *nd = 0; + ClassDefMutable *usingCd = 0; + NamespaceDefMutable *nd = 0; FileDef *fd = root->fileDef(); QCString scName; @@ -1788,7 +1811,7 @@ static void findUsingDeclarations(const Entry *root) scName=root->parent()->name; if (!scName.isEmpty()) { - nd = getResolvedNamespace(scName); + nd = getResolvedNamespaceMutable(scName); } } @@ -1799,17 +1822,17 @@ static void findUsingDeclarations(const Entry *root) // file scope). QCString name = substitute(root->name,".","::"); //Java/C# scope->internal - usingCd = getClass(name); // try direct lookup first, this is needed to get + usingCd = getClassMutable(name); // try direct lookup first, this is needed to get // builtin STL classes to properly resolve, e.g. // vector -> std::vector if (usingCd==0) { SymbolResolver resolver(fd); - usingCd = const_cast<ClassDef*>(resolver.resolveClass(nd,name)); // try via resolving (see also bug757509) + usingCd = resolver.resolveClassMutable(nd,name); // try via resolving (see also bug757509) } if (usingCd==0) { - usingCd = Doxygen::hiddenClasses->find(name); // check if it is already hidden + usingCd = ClassDef::make_mutable(Doxygen::hiddenClasses->find(name)); // check if it is already hidden } //printf("%s -> %p\n",root->name.data(),usingCd); @@ -1862,7 +1885,7 @@ static void findUsingDeclImports(const Entry *root) QCString fullName=removeRedundantWhiteSpace(root->parent()->name); fullName=stripAnonymousNamespaceScope(fullName); fullName=stripTemplateSpecifiersFromScope(fullName); - ClassDef *cd = getClass(fullName); + ClassDefMutable *cd = getClassMutable(fullName); if (cd) { //printf("found class %s\n",cd->name().data()); @@ -1893,7 +1916,7 @@ static void findUsingDeclImports(const Entry *root) } const ArgumentList &templAl = md->templateArguments(); const ArgumentList &al = md->templateArguments(); - std::unique_ptr<MemberDef> newMd { createMemberDef( + std::unique_ptr<MemberDefMutable> newMd { createMemberDef( fileName,root->startLine,root->startColumn, md->typeString(),memName,md->argsString(), md->excpString(),root->protection,root->virt, @@ -1973,7 +1996,7 @@ static void findIncludedUsingDirectives() static MemberDef *addVariableToClass( const Entry *root, - ClassDef *cd, + ClassDefMutable *cd, MemberType mtype, const QCString &type, const QCString &name, @@ -2048,11 +2071,12 @@ static MemberDef *addVariableToClass( MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n", // md->getClassDef(),cd,type.data(),md->typeString()); - if (!md->isAlias() && + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->getClassDef()==cd && removeRedundantWhiteSpace(type)==md->typeString()) // member already in the scope @@ -2064,11 +2088,11 @@ static MemberDef *addVariableToClass( { // Objective-C 2.0 property // turn variable into a property md->setProtection(root->protection); - cd->reclassifyMember(md.get(),MemberType_Property); + cd->reclassifyMember(md,MemberType_Property); } - addMemberDocs(root,md.get(),def,0,FALSE,root->spec); + addMemberDocs(root,md,def,0,FALSE,root->spec); //printf(" Member already found!\n"); - return md.get(); + return md; } } } @@ -2080,7 +2104,7 @@ static MemberDef *addVariableToClass( } // new member variable, typedef or enum value - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, prot,Normal,root->stat,related, @@ -2175,7 +2199,7 @@ static MemberDef *addVariableToFile( if (s>=0) { QCString typeValue = ttype.mid(s,l); - ClassDef *cd = getClass(typeValue); + ClassDefMutable *cd = getClassMutable(typeValue); if (cd) { // this typedef should hide compound name cd, so we @@ -2190,15 +2214,11 @@ static MemberDef *addVariableToFile( } // see if the function is inside a namespace - NamespaceDef *nd = 0; + NamespaceDefMutable *nd = 0; if (!scope.isEmpty()) { if (scope.find('@')!=-1) return 0; // anonymous scope! - //nscope=removeAnonymousScopes(scope); - //if (!nscope.isEmpty()) - //{ - nd = getResolvedNamespace(scope); - //} + nd = getResolvedNamespaceMutable(scope); } QCString def; @@ -2262,11 +2282,12 @@ static MemberDef *addVariableToFile( //if (!nscope.isEmpty()) if (!scope.isEmpty()) { - nd = getResolvedNamespace(scope); + nd = getResolvedNamespaceMutable(scope); } - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (!md->isAlias() && + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && ((nd==0 && md->getNamespaceDef()==0 && md->getFileDef() && root->fileName==md->getFileDef()->absFilePath() ) // both variable names in the same file @@ -2292,7 +2313,7 @@ static MemberDef *addVariableToFile( { Debug::print(Debug::Variables,0, " variable already found: scope=%s\n",qPrint(md->getOuterScope()->name())); - addMemberDocs(root,md.get(),def,0,FALSE,root->spec); + addMemberDocs(root,md,def,0,FALSE,root->spec); md->setRefItems(root->sli); // if md is a variable forward declaration and root is the definition that // turn md into the definition @@ -2307,7 +2328,7 @@ static MemberDef *addVariableToFile( { md->setDeclFile(root->fileName,root->startLine,root->startColumn); } - return md.get(); + return md; } } } @@ -2322,7 +2343,7 @@ static MemberDef *addVariableToFile( Debug::print(Debug::Variables,0, " new variable, nd=%s tagInfo=%p!\n",nd?qPrint(nd->name()):"<global>",root->tagInfo()); // new global variable, enum value or typedef - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,0, root->protection, Normal,root->stat,Member, @@ -2618,7 +2639,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) MemberType mtype; type=type.stripWhiteSpace(); - ClassDef *cd=0; + ClassDefMutable *cd=0; bool isRelated=FALSE; bool isMemberOf=FALSE; @@ -2631,7 +2652,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) if (type=="friend class" || type=="friend struct" || type=="friend union") { - cd=getClass(scope); + cd=getClassMutable(scope); if (cd) { addVariableToClass(root, // entry @@ -2682,8 +2703,8 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) scope=root->relates; } - cd=getClass(scope); - if (cd==0 && classScope!=scope) cd=getClass(classScope); + cd=getClassMutable(scope); + if (cd==0 && classScope!=scope) cd=getClassMutable(classScope); if (cd) { MemberDef *md=0; @@ -2701,7 +2722,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) if (si!=-1 && !inlineSimpleStructs) // anonymous scope or type { QCString pScope; - ClassDef *pcd=0; + ClassDefMutable *pcd=0; pScope = scope.left(QMAX(si-2,0)); // scope without tag less parts if (!pScope.isEmpty()) pScope.prepend(annScopePrefix); @@ -2709,7 +2730,7 @@ static void addVariable(const Entry *root,int isFuncPtr=-1) pScope=annScopePrefix.left(annScopePrefix.length()-2); if (name.at(0)!='@') { - if (!pScope.isEmpty() && (pcd=getClass(pScope))) + if (!pScope.isEmpty() && (pcd=getClassMutable(pScope))) { md=addVariableToClass(root, // entry pcd, // class to add member to @@ -2845,7 +2866,7 @@ static void buildVarList(const Entry *root) static void addInterfaceOrServiceToServiceOrSingleton( const Entry *root, - ClassDef *const cd, + ClassDefMutable *cd, QCString const& rname) { FileDef *fd = root->fileDef(); @@ -2857,7 +2878,7 @@ static void addInterfaceOrServiceToServiceOrSingleton( { fileName = root->tagInfo()->tagName; } - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, type, ArgumentList(), root->argList, root->metaData) }; @@ -2941,7 +2962,7 @@ static void buildInterfaceAndServiceList(const Entry *root) if (!rname.isEmpty()) { QCString scope = root->parent()->name; - ClassDef *cd = getClass(scope); + ClassDefMutable *cd = getClassMutable(scope); assert(cd); if (cd && ((ClassDef::Interface == cd->compoundType()) || (ClassDef::Service == cd->compoundType()) || @@ -2977,7 +2998,7 @@ static void buildInterfaceAndServiceList(const Entry *root) // Searches the Entry tree for Function sections. // If found they are stored in their class or in the global list. -static void addMethodToClass(const Entry *root,ClassDef *cd, +static void addMethodToClass(const Entry *root,ClassDefMutable *cd, const QCString &rtype,const QCString &rname,const QCString &rargs, bool isFriend, Protection protection,bool stat,Specifier virt,uint64 spec, @@ -3038,7 +3059,7 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, // ); // adding class member - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, protection,virt, @@ -3134,8 +3155,7 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, //------------------------------------------------------------------------------------------ -void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &sc, - NamespaceDef *nd) +static void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &sc) { QCString scope = sc; Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); @@ -3144,7 +3164,7 @@ void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &s // new global function QCString name=removeRedundantWhiteSpace(rname); - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, root->type,name,root->args,root->exception, root->protection,root->virt,root->stat,Member, @@ -3169,15 +3189,16 @@ void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &s md->setMemberSpecifiers(root->spec); md->setMemberGroupId(root->mGrpId); + NamespaceDefMutable *nd = 0; // see if the function is inside a namespace that was not part of // the name already (in that case nd should be non-zero already) - if (nd==0 && root->parent()->section == Entry::NAMESPACE_SEC ) + if (root->parent()->section == Entry::NAMESPACE_SEC ) { //QCString nscope=removeAnonymousScopes(root->parent()->name); QCString nscope=root->parent()->name; if (!nscope.isEmpty()) { - nd = getResolvedNamespace(nscope); + nd = getResolvedNamespaceMutable(nscope); } } @@ -3282,7 +3303,7 @@ static void buildFunctionList(const Entry *root) QCString scope=root->parent()->name; //stripAnonymousNamespaceScope(root->parent->name); if (!rname.isEmpty() && scope.find('@')==-1) { - ClassDef *cd=0; + ClassDefMutable *cd=0; // check if this function's parent is a class scope=stripTemplateSpecifiersFromScope(scope,FALSE); @@ -3290,14 +3311,13 @@ static void buildFunctionList(const Entry *root) int memIndex=rname.findRev("::"); - cd=getClass(scope); + cd=getClassMutable(scope); if (cd && scope+"::"==rname.left(scope.length()+2)) // found A::f inside A { // strip scope from name rname=rname.right(rname.length()-root->parent()->name.length()-2); } - NamespaceDef *nd = 0; bool isMember=FALSE; if (memIndex!=-1) { @@ -3365,9 +3385,10 @@ static void buildFunctionList(const Entry *root) if ((mn=Doxygen::functionNameLinkedMap->find(rname))) { Debug::print(Debug::Functions,0," --> function %s already found!\n",qPrint(rname)); - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (!md->isAlias()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) { const NamespaceDef *mnd = md->getNamespaceDef(); NamespaceDef *rnd = 0; @@ -3387,7 +3408,7 @@ static void buildFunctionList(const Entry *root) if (rnd) rnsName = rnd->name().copy(); //printf("matching arguments for %s%s %s%s\n", // md->name().data(),md->argsString(),rname.data(),argListToString(root->argList).data()); - ArgumentList &mdAl = md->argumentList(); + const ArgumentList &mdAl = md->argumentList(); const ArgumentList &mdTempl = md->templateArguments(); // in case of template functions, we need to check if the @@ -3445,7 +3466,7 @@ static void buildFunctionList(const Entry *root) { // merge argument lists ArgumentList mergedArgList = root->argList; - mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty()); + mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty()); // merge documentation if (md->documentation().isEmpty() && !root->doc.isEmpty()) { @@ -3485,7 +3506,7 @@ static void buildFunctionList(const Entry *root) // merge ingroup specifiers if (md->getGroupDef()==0 && !root->groups.empty()) { - addMemberToGroups(root,md.get()); + addMemberToGroups(root,md); } else if (md->getGroupDef()!=0 && root->groups.empty()) { @@ -3513,14 +3534,14 @@ static void buildFunctionList(const Entry *root) } if (found) { - md_found = md.get(); + md_found = md; break; } } } if (!found) /* global function is unique with respect to the file */ { - addGlobalFunction(root,rname,scope,nd); + addGlobalFunction(root,rname,scope); } else { @@ -3564,29 +3585,28 @@ static void findFriends() { // there are members with the same name //printf("Function name is also a member name\n"); // for each function with that name - for (const auto &fmd : *fn) + for (const auto &ifmd : *fn) { - const MemberDef *cfmd = fmd.get(); + MemberDefMutable *fmd = MemberDef::make_mutable(ifmd.get()); // for each member with that name - for (const auto &mmd : *mn) + for (const auto &immd : *mn) { - const MemberDef *cmmd = mmd.get(); + MemberDefMutable *mmd = MemberDef::make_mutable(immd.get()); //printf("Checking for matching arguments // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n", // mmd->isRelated(),mmd->isFriend(),mmd->isFunction()); - if ((cmmd->isFriend() || (cmmd->isRelated() && cmmd->isFunction())) && - !fmd->isAlias() && !mmd->isAlias() && - matchArguments2(cmmd->getOuterScope(), cmmd->getFileDef(), &cmmd->argumentList(), - cfmd->getOuterScope(), cfmd->getFileDef(), &cfmd->argumentList(), + if ((mmd->isFriend() || (mmd->isRelated() && mmd->isFunction())) && + matchArguments2(mmd->getOuterScope(), mmd->getFileDef(), &mmd->argumentList(), + fmd->getOuterScope(), fmd->getFileDef(), &fmd->argumentList(), TRUE ) ) // if the member is related and the arguments match then the // function is actually a friend. { - ArgumentList &mmdAl = mmd->argumentList(); - ArgumentList &fmdAl = fmd->argumentList(); - mergeArguments(mmdAl,fmdAl); + const ArgumentList &mmdAl = mmd->argumentList(); + const ArgumentList &fmdAl = fmd->argumentList(); + mergeArguments(const_cast<ArgumentList&>(mmdAl),const_cast<ArgumentList&>(fmdAl)); if (!fmd->documentation().isEmpty()) { mmd->setDocumentation(fmd->documentation(),fmd->docFile(),fmd->docLine()); @@ -3653,19 +3673,21 @@ static void transferFunctionDocumentation() { //printf("memberName=%s count=%d\n",mn->memberName(),mn->count()); /* find a matching function declaration and definition for this function */ - for (const auto &mdec : *mn) + for (const auto &imdec : *mn) { - if (mdec->isPrototype() || - (mdec->isVariable() && mdec->isExternal()) - ) + MemberDefMutable *mdec = MemberDef::make_mutable(imdec.get()); + if (mdec && + (mdec->isPrototype() || + (mdec->isVariable() && mdec->isExternal()) + )) { - for (const auto &mdef : *mn) + for (const auto &imdef : *mn) { - if (mdec!=mdef && - !mdec->isAlias() && !mdef->isAlias() && + MemberDefMutable *mdef = MemberDef::make_mutable(imdef.get()); + if (mdef && mdec!=mdef && mdec->getNamespaceDef()==mdef->getNamespaceDef()) { - combineDeclarationAndDefinition(mdec.get(),mdef.get()); + combineDeclarationAndDefinition(mdec,mdef); } } } @@ -3679,30 +3701,33 @@ static void transferFunctionReferences() { for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *mdef=0,*mdec=0; + MemberDefMutable *mdef=0,*mdec=0; /* find a matching function declaration and definition for this function */ - for (const auto &md_p : *mn) + for (const auto &imd : *mn) { - MemberDef *md = md_p.get(); - if (md->isPrototype()) - mdec=md; - else if (md->isVariable() && md->isExternal()) - mdec=md; + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) + { + if (md->isPrototype()) + mdec=md; + else if (md->isVariable() && md->isExternal()) + mdec=md; - if (md->isFunction() && !md->isStatic() && !md->isPrototype()) - mdef=md; - else if (md->isVariable() && !md->isExternal() && !md->isStatic()) - mdef=md; + if (md->isFunction() && !md->isStatic() && !md->isPrototype()) + mdef=md; + else if (md->isVariable() && !md->isExternal() && !md->isStatic()) + mdef=md; + } if (mdef && mdec) break; } - if (mdef && mdec && !mdef->isAlias() && !mdec->isAlias()) + if (mdef && mdec) { - ArgumentList &mdefAl = mdef->argumentList(); - ArgumentList &mdecAl = mdec->argumentList(); + const ArgumentList &mdefAl = mdef->argumentList(); + const ArgumentList &mdecAl = mdec->argumentList(); if ( - matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),&mdefAl, - mdec->getOuterScope(),mdec->getFileDef(),&mdecAl, + matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),const_cast<ArgumentList*>(&mdefAl), + mdec->getOuterScope(),mdec->getFileDef(),const_cast<ArgumentList*>(&mdecAl), TRUE ) ) /* match found */ @@ -3726,32 +3751,37 @@ static void transferRelatedFunctionDocumentation() { /* find a matching function declaration and definition for this function */ // for each global function - for (const auto &md : *mn) + for (const auto &imd : *mn) { - //printf(" Function '%s'\n",md->name().data()); - MemberName *rmn; - if ((rmn=Doxygen::memberNameLinkedMap->find(md->name()))) // check if there is a member with the same name + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) { - //printf(" Member name found\n"); - // for each member with the same name - for (const auto &rmd : *rmn) + //printf(" Function '%s'\n",md->name().data()); + MemberName *rmn; + if ((rmn=Doxygen::memberNameLinkedMap->find(md->name()))) // check if there is a member with the same name { - //printf(" Member found: related='%d'\n",rmd->isRelated()); - if ((rmd->isRelated() || rmd->isForeign()) && // related function - !md->isAlias() && !rmd->isAlias() && - matchArguments2( md->getOuterScope(), md->getFileDef(), &md->argumentList(), - rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(), - TRUE - ) - ) + //printf(" Member name found\n"); + // for each member with the same name + for (const auto &irmd : *rmn) { - //printf(" Found related member '%s'\n",md->name().data()); - if (rmd->relatedAlso()) - md->setRelatedAlso(rmd->relatedAlso()); - else if (rmd->isForeign()) - md->makeForeign(); - else - md->makeRelated(); + MemberDefMutable *rmd = MemberDef::make_mutable(irmd.get()); + //printf(" Member found: related='%d'\n",rmd->isRelated()); + if (rmd && + (rmd->isRelated() || rmd->isForeign()) && // related function + matchArguments2( md->getOuterScope(), md->getFileDef(), &md->argumentList(), + rmd->getOuterScope(),rmd->getFileDef(),&rmd->argumentList(), + TRUE + ) + ) + { + //printf(" Found related member '%s'\n",md->name().data()); + if (rmd->relatedAlso()) + md->setRelatedAlso(rmd->relatedAlso()); + else if (rmd->isForeign()) + md->makeForeign(); + else + md->makeRelated(); + } } } } @@ -3834,8 +3864,8 @@ static ClassDef *findClassWithinClassContext(Definition *context,ClassDef *cd,co static void findUsedClassesForClass(const Entry *root, Definition *context, - ClassDef *masterCd, - ClassDef *instanceCd, + ClassDefMutable *masterCd, + ClassDefMutable *instanceCd, bool isArtificial, const std::unique_ptr<ArgumentList> &actualArgs = std::unique_ptr<ArgumentList>(), QDict<int> *templateNames=0 @@ -3869,7 +3899,7 @@ static void findUsedClassesForClass(const Entry *root, { // find the type (if any) that matches usedClassName SymbolResolver resolver(masterCd->getFileDef()); - const ClassDef *typeCd = resolver.resolveClass(masterCd,usedClassName,false,true); + const ClassDefMutable *typeCd = resolver.resolveClassMutable(masterCd,usedClassName,false,true); //printf("====> usedClassName=%s -> typeCd=%s\n", // usedClassName.data(),typeCd?typeCd->name().data():"<none>"); if (typeCd) @@ -3905,7 +3935,7 @@ static void findUsedClassesForClass(const Entry *root, found=TRUE; Debug::print(Debug::Classes,0," New used class '%s'\n", qPrint(usedName)); - ClassDef *usedCd = Doxygen::hiddenClasses->find(usedName); + ClassDefMutable *usedCd = ClassDef::make_mutable(Doxygen::hiddenClasses->find(usedName)); if (usedCd==0) { usedCd = createClassDef( @@ -3928,7 +3958,7 @@ static void findUsedClassesForClass(const Entry *root, if (!found) { - ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName); + ClassDefMutable *usedCd=ClassDef::make_mutable(findClassWithinClassContext(context,masterCd,usedName)); //printf("Looking for used class %s: result=%s master=%s\n", // usedName.data(),usedCd?usedCd->name().data():"<none>",masterCd?masterCd->name().data():"<none>"); @@ -3948,7 +3978,7 @@ static void findUsedClassesForClass(const Entry *root, } if (!found && !type.isEmpty()) // used class is not documented in any scope { - ClassDef *usedCd = Doxygen::hiddenClasses->find(type); + ClassDefMutable *usedCd = ClassDef::make_mutable(Doxygen::hiddenClasses->find(type)); if (usedCd==0 && !Config_getBool(HIDE_UNDOC_RELATIONS)) { if (type.right(2)=="(*" || type.right(2)=="(^") // type is a function pointer @@ -3980,8 +4010,8 @@ static void findUsedClassesForClass(const Entry *root, static void findBaseClassesForClass( const Entry *root, Definition *context, - ClassDef *masterCd, - ClassDef *instanceCd, + ClassDefMutable *masterCd, + ClassDefMutable *instanceCd, FindBaseClassRelation_Mode mode, bool isArtificial, const std::unique_ptr<ArgumentList> &actualArgs = std::unique_ptr<ArgumentList>(), @@ -4037,7 +4067,7 @@ static void findBaseClassesForClass( static bool findTemplateInstanceRelation(const Entry *root, Definition *context, - ClassDef *templateClass,const QCString &templSpec, + ClassDefMutable *templateClass,const QCString &templSpec, QDict<int> *templateNames, bool isArtificial) { @@ -4062,8 +4092,9 @@ static bool findTemplateInstanceRelation(const Entry *root, if (existingClass) return TRUE; bool freshInstance=FALSE; - ClassDef *instanceClass = templateClass->insertTemplateInstance( - root->fileName,root->startLine,root->startColumn,templSpec,freshInstance); + ClassDefMutable *instanceClass = ClassDef::make_mutable( + templateClass->insertTemplateInstance( + root->fileName,root->startLine,root->startColumn,templSpec,freshInstance)); if (isArtificial) instanceClass->setArtificial(TRUE); instanceClass->setLanguage(root->lang); @@ -4198,7 +4229,7 @@ static int findEndOfTemplate(const QCString &s,int startPos) static bool findClassRelation( const Entry *root, Definition *context, - ClassDef *cd, + ClassDefMutable *cd, const BaseInfo *bi, QDict<int> *templateNames, FindBaseClassRelation_Mode mode, @@ -4249,12 +4280,11 @@ static bool findClassRelation( // (removeRedundantWhiteSpace(baseClassName),TRUE, // &stripped); SymbolResolver resolver(cd->getFileDef()); - ClassDef *baseClass=const_cast<ClassDef*>( - resolver.resolveClass(explicitGlobalScope ? Doxygen::globalScope : context, + ClassDefMutable *baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context, baseClassName, mode==Undocumented, true - )); + ); const MemberDef *baseClassTypeDef = resolver.getTypedef(); QCString templSpec = resolver.getTemplateSpec(); //printf("baseClassName=%s baseClass=%p cd=%p explicitGlobalScope=%d\n", @@ -4293,7 +4323,7 @@ static bool findClassRelation( if (baseClass==0 && (root->lang==SrcLangExt_CSharp || root->lang==SrcLangExt_Java)) { // for Java/C# strip the template part before looking for matching - baseClass = Doxygen::genericsDict->find(baseClassName.left(i)); + baseClass = ClassDef::make_mutable(Doxygen::genericsDict->find(baseClassName.left(i))); //printf("looking for '%s' result=%p\n",baseClassName.data(),baseClass); } if (baseClass==0 && i!=-1) @@ -4305,14 +4335,13 @@ static bool findClassRelation( //printf("baseClass==0 i=%d e=%d\n",i,e); if (e!=-1) // end of template was found at e { - templSpec=removeRedundantWhiteSpace(baseClassName.mid(i,e-i)); - baseClassName=baseClassName.left(i)+baseClassName.right(baseClassName.length()-e); - baseClass=const_cast<ClassDef*>( - resolver.resolveClass(explicitGlobalScope ? Doxygen::globalScope : context, + templSpec = removeRedundantWhiteSpace(baseClassName.mid(i,e-i)); + baseClassName = baseClassName.left(i)+baseClassName.right(baseClassName.length()-e); + baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context, baseClassName, mode==Undocumented, true - )); + ); baseClassTypeDef = resolver.getTypedef(); //printf("baseClass=%p -> baseClass=%s templSpec=%s\n", // baseClass,baseClassName.data(),templSpec.data()); @@ -4325,7 +4354,7 @@ static bool findClassRelation( // derived from a template argument) { //printf("baseClass=%s templSpec=%s\n",baseClass->name().data(),templSpec.data()); - ClassDef *templClass=getClass(baseClass->name()+templSpec); + ClassDefMutable *templClass=getClassMutable(baseClass->name()+templSpec); if (templClass) { // use the template instance instead of the template base. @@ -4341,12 +4370,11 @@ static bool findClassRelation( { // replace any namespace aliases replaceNamespaceAliases(baseClassName,si); - baseClass=const_cast<ClassDef*>( - resolver.resolveClass(explicitGlobalScope ? Doxygen::globalScope : context, + baseClass = resolver.resolveClassMutable(explicitGlobalScope ? Doxygen::globalScope : context, baseClassName, mode==Undocumented, true - )); + ); baseClassTypeDef = resolver.getTypedef(); QCString tmpTemplSpec = resolver.getTemplateSpec(); found=baseClass!=0 && baseClass!=cd; @@ -4363,7 +4391,7 @@ static bool findClassRelation( if (!found) { - baseClass=findClassWithinClassContext(context,cd,baseClassName); + baseClass=ClassDef::make_mutable(findClassWithinClassContext(context,cd,baseClassName)); //printf("findClassWithinClassContext(%s,%s)=%p\n", // cd->name().data(),baseClassName.data(),baseClass); found = baseClass!=0 && baseClass!=cd; @@ -4376,7 +4404,7 @@ static bool findClassRelation( auto it = Doxygen::namespaceAliasMap.find(baseClassName.data()); if (it!=Doxygen::namespaceAliasMap.end()) // see if it is indeed a class. { - baseClass=getClass(it->second.c_str()); + baseClass=getClassMutable(it->second.c_str()); found = baseClass!=0 && baseClass!=cd; } } @@ -4449,7 +4477,7 @@ static bool findClassRelation( baseClass=0; if (isATemplateArgument) { - baseClass=Doxygen::hiddenClasses->find(baseClassName); + baseClass=ClassDef::make_mutable(Doxygen::hiddenClasses->find(baseClassName)); if (baseClass==0) { baseClass=createClassDef(root->fileName,root->startLine,root->startColumn, @@ -4462,7 +4490,7 @@ static bool findClassRelation( } else { - baseClass=Doxygen::classSDict->find(baseClassName); + baseClass=ClassDef::make_mutable(Doxygen::classSDict->find(baseClassName)); //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n", // baseClassName.data(),baseClass,biName.data(),templSpec.data()); if (baseClass==0) @@ -4602,7 +4630,14 @@ static QCString extractClassName(const Entry *root) static void findInheritedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + for (cli.toFirst();cli.current();++cli) + { + ClassDefMutable *cdm = ClassDef::make_mutable(cli.current()); + if (cdm) + { + cdm->setVisited(FALSE); + } + } for (const auto &kv : g_classEntries) { const Entry *root = kv.second; @@ -4611,8 +4646,12 @@ static void findInheritedTemplateInstances() Debug::print(Debug::Classes,0," Inheritance: Class %s : \n",qPrint(bName)); if ((cd=getClass(bName))) { - //printf("Class %s %d\n",cd->name().data(),root->extends->count()); - findBaseClassesForClass(root,cd,cd,cd,TemplateInstances,FALSE); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + //printf("Class %s %d\n",cd->name().data(),root->extends->count()); + findBaseClassesForClass(root,cd,cdm,cdm,TemplateInstances,FALSE); + } } } } @@ -4620,7 +4659,14 @@ static void findInheritedTemplateInstances() static void findUsedTemplateInstances() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + for (cli.toFirst();cli.current();++cli) + { + ClassDefMutable *cdm = ClassDef::make_mutable(cli.current()); + if (cdm) + { + cdm->setVisited(FALSE); + } + } for (const auto &kv : g_classEntries) { const Entry *root = kv.second; @@ -4629,8 +4675,12 @@ static void findUsedTemplateInstances() Debug::print(Debug::Classes,0," Usage: Class %s : \n",qPrint(bName)); if ((cd=getClass(bName))) { - findUsedClassesForClass(root,cd,cd,cd,TRUE); - cd->addTypeConstraints(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + findUsedClassesForClass(root,cd,cdm,cdm,TRUE); + cdm->addTypeConstraints(); + } } } } @@ -4638,15 +4688,22 @@ static void findUsedTemplateInstances() static void computeClassRelations() { ClassSDict::Iterator cli(*Doxygen::classSDict); - for (cli.toFirst();cli.current();++cli) cli.current()->setVisited(FALSE); + for (cli.toFirst();cli.current();++cli) + { + ClassDefMutable *cdm = ClassDef::make_mutable(cli.current()); + if (cdm) + { + cdm->setVisited(FALSE); + } + } for (const auto &kv : g_classEntries) { const Entry *root = kv.second; - ClassDef *cd; + ClassDefMutable *cd; QCString bName = extractClassName(root); Debug::print(Debug::Classes,0," Relations: Class %s : \n",qPrint(bName)); - if ((cd=getClass(bName))) + if ((cd=getClassMutable(bName))) { findBaseClassesForClass(root,cd,cd,cd,DocumentedOnly,FALSE); } @@ -4676,65 +4733,69 @@ static void computeTemplateClassRelations() const Entry *root = kv.second; QCString bName=stripAnonymousNamespaceScope(root->name); bName=stripTemplateSpecifiersFromScope(bName); - ClassDef *cd=getClass(bName); + ClassDefMutable *cd=getClassMutable(bName); // strip any anonymous scopes first QDict<ClassDef> *templInstances = 0; if (cd && (templInstances=cd->getTemplateInstances())) { Debug::print(Debug::Classes,0," Template class %s : \n",qPrint(cd->name())); QDictIterator<ClassDef> tdi(*templInstances); - ClassDef *tcd; - for (tdi.toFirst();(tcd=tdi.current());++tdi) // for each template instance - { - Debug::print(Debug::Classes,0," Template instance %s : \n",qPrint(tcd->name())); - QCString templSpec = tdi.currentKey(); - std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec); - for (const BaseInfo &bi : root->extends) - { - // check if the base class is a template argument - BaseInfo tbi = bi; - const ArgumentList &tl = cd->templateArguments(); - if (!tl.empty()) + ClassDef *itcd; + for (tdi.toFirst();(itcd=tdi.current());++tdi) // for each template instance + { + ClassDefMutable *tcd=ClassDef::make_mutable(itcd); + if (tcd) + { + Debug::print(Debug::Classes,0," Template instance %s : \n",qPrint(tcd->name())); + QCString templSpec = tdi.currentKey(); + std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(tcd->getLanguage(),templSpec); + for (const BaseInfo &bi : root->extends) { - QDict<int> *baseClassNames = tcd->getTemplateBaseClassNames(); - QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi.name); - // for each template name that we inherit from we need to - // substitute the formal with the actual arguments - QDict<int> *actualTemplateNames = new QDict<int>(17); - actualTemplateNames->setAutoDelete(TRUE); - QDictIterator<int> qdi(*templateNames); - for (qdi.toFirst();qdi.current();++qdi) + // check if the base class is a template argument + BaseInfo tbi = bi; + const ArgumentList &tl = cd->templateArguments(); + if (!tl.empty()) { - int templIndex = *qdi.current(); - Argument actArg; - bool hasActArg=FALSE; - if (templIndex<(int)templArgs->size()) + QDict<int> *baseClassNames = tcd->getTemplateBaseClassNames(); + QDict<int> *templateNames = getTemplateArgumentsInName(tl,bi.name); + // for each template name that we inherit from we need to + // substitute the formal with the actual arguments + QDict<int> *actualTemplateNames = new QDict<int>(17); + actualTemplateNames->setAutoDelete(TRUE); + QDictIterator<int> qdi(*templateNames); + for (qdi.toFirst();qdi.current();++qdi) { - actArg=templArgs->at(templIndex); - hasActArg=TRUE; + int templIndex = *qdi.current(); + Argument actArg; + bool hasActArg=FALSE; + if (templIndex<(int)templArgs->size()) + { + actArg=templArgs->at(templIndex); + hasActArg=TRUE; + } + if (hasActArg && + baseClassNames!=0 && + baseClassNames->find(actArg.type)!=0 && + actualTemplateNames->find(actArg.type)==0 + ) + { + actualTemplateNames->insert(actArg.type,new int(templIndex)); + } } - if (hasActArg && - baseClassNames!=0 && - baseClassNames->find(actArg.type)!=0 && - actualTemplateNames->find(actArg.type)==0 - ) + delete templateNames; + + tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs); + // find a documented base class in the correct scope + if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE)) { - actualTemplateNames->insert(actArg.type,new int(templIndex)); + // no documented base class -> try to find an undocumented one + findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE); } + delete actualTemplateNames; } - delete templateNames; - - tbi.name = substituteTemplateArgumentsInString(bi.name,tl,templArgs); - // find a documented base class in the correct scope - if (!findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,DocumentedOnly,FALSE)) - { - // no documented base class -> try to find an undocumented one - findClassRelation(root,cd,tcd,&tbi,actualTemplateNames,Undocumented,TRUE); - } - delete actualTemplateNames; } } - } // class has no base classes + } } } } @@ -4748,7 +4809,11 @@ static void computeMemberReferences() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - cd->computeAnchors(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->computeAnchors(); + } } for (const auto &fn : *Doxygen::inputNameLinkedMap) { @@ -4761,7 +4826,11 @@ static void computeMemberReferences() NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { - nd->computeAnchors(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->computeAnchors(); + } } GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; @@ -4779,9 +4848,10 @@ static void addListReferences() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - if (!cd->isAlias()) + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) { - cd->addListReferences(); + cdm->addListReferences(); } } @@ -4797,9 +4867,10 @@ static void addListReferences() NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { - if (!nd->isAlias()) + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) { - nd->addListReferences(); + ndm->addListReferences(); } } @@ -4861,7 +4932,7 @@ static void generateXRefPages() // over_load is set the standard overload text is added. static void addMemberDocs(const Entry *root, - MemberDef *md, const char *funcDecl, + MemberDefMutable *md, const char *funcDecl, const ArgumentList *al, bool over_load, uint64 spec @@ -4877,7 +4948,7 @@ static void addMemberDocs(const Entry *root, md->enableCallerGraph(root->callerGraph); md->enableReferencedByRelation(root->referencedByRelation); md->enableReferencesRelation(root->referencesRelation); - ClassDef *cd=md->getClassDef(); + ClassDefMutable *cd=md->getClassDefMutable(); const NamespaceDef *nd=md->getNamespaceDef(); QCString fullName; if (cd) @@ -4892,17 +4963,17 @@ static void addMemberDocs(const Entry *root, // TODO determine scope based on root not md Definition *rscope = md->getOuterScope(); - ArgumentList &mdAl = md->argumentList(); + const ArgumentList &mdAl = md->argumentList(); if (al) { ArgumentList mergedAl = *al; //printf("merging arguments (1) docs=%d\n",root->doc.isEmpty()); - mergeArguments(mdAl,mergedAl,!root->doc.isEmpty()); + mergeArguments(const_cast<ArgumentList&>(mdAl),mergedAl,!root->doc.isEmpty()); } else { if ( - matchArguments2( md->getOuterScope(), md->getFileDef(), &mdAl, + matchArguments2( md->getOuterScope(), md->getFileDef(),const_cast<ArgumentList*>(&mdAl), rscope,rfd,&root->argList, TRUE ) @@ -4910,7 +4981,7 @@ static void addMemberDocs(const Entry *root, { //printf("merging arguments (2)\n"); ArgumentList mergedArgList = root->argList; - mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty()); + mergeArguments(const_cast<ArgumentList&>(mdAl),mergedArgList,!root->doc.isEmpty()); } } if (over_load) // the \overload keyword was used @@ -5132,7 +5203,7 @@ static bool findGlobalMember(const Entry *root, if (matching) // add docs to the member { Debug::print(Debug::FindMembers,0,"5. Match found\n"); - addMemberDocs(root,md->resolveAlias(),decl,&root->argList,FALSE,root->spec); + addMemberDocs(root,MemberDef::make_mutable(md->resolveAlias()),decl,&root->argList,FALSE,root->spec); found=TRUE; break; } @@ -5330,13 +5401,13 @@ static void addLocalObjCMethod(const Entry *root, uint64 spec) { //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); - ClassDef *cd=0; - if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(scopeName))) + ClassDefMutable *cd=0; + if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClassMutable(scopeName))) { Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n" " scopeName=%s\n",qPrint(root->name),qPrint(scopeName)); //printf("Local objective C method '%s' of class '%s' found\n",root->name.data(),cd->name().data()); - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Member, @@ -5400,9 +5471,11 @@ static void addMemberFunction(const Entry *root, int count=0; int noMatchCount=0; bool memFound=FALSE; - for (const auto &md : *mn) + for (const auto &imd : *mn) { - ClassDef *cd=md->getClassDef(); + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md==0) continue; + ClassDefMutable *cd=md->getClassDefMutable(); Debug::print(Debug::FindMembers,0, "3. member definition found, " "scope needed='%s' scope='%s' args='%s' fileName=%s\n", @@ -5551,7 +5624,7 @@ static void addMemberFunction(const Entry *root, } if (matching) { - addMemberDocs(root,md.get(),funcDecl,0,overloaded,spec); + addMemberDocs(root,md,funcDecl,0,overloaded,spec); count++; memFound=TRUE; } @@ -5578,7 +5651,7 @@ static void addMemberFunction(const Entry *root, //printf("Assume template class\n"); for (const auto &md : *mn) { - ClassDef *ccd=md->getClassDef(); + ClassDefMutable *ccd=md->getClassDefMutable(); MemberDef *cmd=md.get(); //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); if (ccd!=0 && rightScopeMatch(ccd->name(),className)) @@ -5618,7 +5691,7 @@ static void addMemberFunction(const Entry *root, { // we didn't find an actual match on argument lists, but there is only 1 member with this // name in the same scope, so that has to be the one. - addMemberDocs(root,umd,funcDecl,0,overloaded,spec); + addMemberDocs(root,MemberDef::make_mutable(umd),funcDecl,0,overloaded,spec); return; } else if (candidates>1 && ecd && emd) @@ -5626,7 +5699,7 @@ static void addMemberFunction(const Entry *root, // we didn't find a unique match using type resolution, // but one of the matches has the exact same signature so // we take that one. - addMemberDocs(root,emd,funcDecl,0,overloaded,spec); + addMemberDocs(root,MemberDef::make_mutable(emd),funcDecl,0,overloaded,spec); return; } } @@ -5654,7 +5727,7 @@ static void addMemberFunction(const Entry *root, warnMsg+="Possible candidates:\n"; for (const auto &md : *mn) { - ClassDef *cd=md->getClassDef(); + const ClassDef *cd=md->getClassDef(); if (cd!=0 && rightScopeMatch(cd->name(),className)) { const ArgumentList &templAl = md->templateArguments(); @@ -5696,7 +5769,7 @@ static void addMemberFunction(const Entry *root, static void addMemberSpecialization(const Entry *root, MemberName *mn, - ClassDef *cd, + ClassDefMutable *cd, const QCString &funcType, const QCString &funcName, const QCString &funcArgs, @@ -5718,7 +5791,7 @@ static void addMemberSpecialization(const Entry *root, MemberType mtype=MemberType_Function; ArgumentList tArgList; // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, declMd ? declMd->protection() : root->protection, @@ -5772,7 +5845,7 @@ static void addOverloaded(const Entry *root,MemberName *mn, } if (sameClass) { - ClassDef *cd = mn->front()->getClassDef(); + ClassDefMutable *cd = mn->front()->getClassDefMutable(); MemberType mtype; if (root->mtype==Signal) mtype=MemberType_Signal; else if (root->mtype==Slot) mtype=MemberType_Slot; @@ -5783,7 +5856,7 @@ static void addOverloaded(const Entry *root,MemberName *mn, std::unique_ptr<ArgumentList> tArgList = getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt,root->stat,Related, @@ -6037,7 +6110,7 @@ static void findMember(const Entry *root, //printf("new scope='%s'\n",scopeName.data()); QCString tempScopeName=scopeName; - ClassDef *cd=getClass(scopeName); + ClassDefMutable *cd=getClassMutable(scopeName); if (cd) { if (funcSpec.isEmpty()) @@ -6193,19 +6266,20 @@ static void findMember(const Entry *root, " scopeName=%s className=%s\n",qPrint(scopeName),qPrint(className)); if (className.isEmpty()) className=relates; //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); - if ((cd=getClass(scopeName))) + if ((cd=getClassMutable(scopeName))) { bool newMember=TRUE; // assume we have a new member - MemberDef *mdDefine=0; + MemberDefMutable *mdDefine=0; { mn = Doxygen::functionNameLinkedMap->find(funcName); if (mn) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (md->isDefine()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->isDefine()) { - mdDefine = md.get(); + mdDefine = md; break; } } @@ -6221,10 +6295,11 @@ static void findMember(const Entry *root, else { // see if we got another member with matching arguments - MemberDef *rmd_found = 0; - for (const auto &rmd : *mn) + MemberDefMutable *rmd_found = 0; + for (const auto &irmd : *mn) { - if (!rmd->isAlias()) + MemberDefMutable *rmd = MemberDef::make_mutable(irmd.get()); + if (rmd) { const ArgumentList &rmdAl = rmd->argumentList(); @@ -6235,7 +6310,7 @@ static void findMember(const Entry *root, TRUE); if (!newMember) { - rmd_found = rmd.get(); + rmd_found = rmd; } } } @@ -6278,7 +6353,7 @@ static void findMember(const Entry *root, // this accurately reflects the template arguments of // the related function, which don't have to do with // those of the related class. - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt, @@ -6320,10 +6395,11 @@ static void findMember(const Entry *root, MemberName *rmn=Doxygen::functionNameLinkedMap->find(funcName); if (rmn) { - const MemberDef *rmd_found=0; - for (const auto &rmd : *rmn) + const MemberDefMutable *rmd_found=0; + for (const auto &irmd : *rmn) { - if (!rmd->isAlias()) + MemberDefMutable *rmd = MemberDef::make_mutable(irmd.get()); + if (rmd) { const ArgumentList &rmdAl = rmd->argumentList(); // check for matching argument lists @@ -6334,7 +6410,7 @@ static void findMember(const Entry *root, ) { found=TRUE; - rmd_found = rmd.get(); + rmd_found = rmd; break; } } @@ -6655,9 +6731,9 @@ static void findEnums(const Entry *root) { if (root->section==Entry::ENUM_SEC) { - ClassDef *cd=0; - FileDef *fd=0; - NamespaceDef *nd=0; + ClassDefMutable *cd=0; + FileDef *fd=0; + NamespaceDefMutable *nd=0; MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; @@ -6672,7 +6748,7 @@ static void findEnums(const Entry *root) { scope=root->name.left(i); // extract scope name=root->name.right(root->name.length()-i-2); // extract name - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } else // no scope, check the scope in which the docs where found { @@ -6681,7 +6757,7 @@ static void findEnums(const Entry *root) ) // found enum docs inside a compound { scope=root->parent()->name; - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } name=root->name; } @@ -6694,7 +6770,7 @@ static void findEnums(const Entry *root) scope=mergeScopes(scope,root->relates); else scope=root->relates.copy(); - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } if (cd && !name.isEmpty()) // found a enum inside a compound @@ -6719,7 +6795,7 @@ static void findEnums(const Entry *root) if (!name.isEmpty()) { // new enum type - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( root->fileName,root->startLine,root->startColumn, 0,name,0,0, root->protection,Normal,FALSE, @@ -6823,9 +6899,9 @@ static void addEnumValuesToEnums(const Entry *root) if (root->section==Entry::ENUM_SEC) // non anonymous enumeration { - ClassDef *cd=0; - FileDef *fd=0; - NamespaceDef *nd=0; + ClassDefMutable *cd=0; + FileDef *fd=0; + NamespaceDefMutable *nd=0; MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; @@ -6839,7 +6915,7 @@ static void addEnumValuesToEnums(const Entry *root) { scope=root->name.left(i); // extract scope name=root->name.right(root->name.length()-i-2); // extract name - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } else // no scope, check the scope in which the docs where found { @@ -6848,7 +6924,7 @@ static void addEnumValuesToEnums(const Entry *root) ) // found enum docs inside a compound { scope=root->parent()->name; - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } name=root->name; } @@ -6856,11 +6932,11 @@ static void addEnumValuesToEnums(const Entry *root) if (!root->relates.isEmpty()) { // related member, prefix user specified scope isRelated=TRUE; - if (getClass(root->relates)==0 && !scope.isEmpty()) + if (getClassMutable(root->relates)==0 && !scope.isEmpty()) scope=mergeScopes(scope,root->relates); else scope=root->relates.copy(); - if ((cd=getClass(scope))==0) nd=getResolvedNamespace(scope); + if ((cd=getClassMutable(scope))==0) nd=getResolvedNamespaceMutable(scope); } if (cd && !name.isEmpty()) // found a enum inside a compound @@ -6892,17 +6968,18 @@ static void addEnumValuesToEnums(const Entry *root) { struct EnumValueInfo { - EnumValueInfo(const QCString &n,std::unique_ptr<MemberDef> &md) : + EnumValueInfo(const QCString &n,std::unique_ptr<MemberDefMutable> &md) : name(n), member(std::move(md)) {} QCString name; - std::unique_ptr<MemberDef> member; + std::unique_ptr<MemberDefMutable> member; }; std::vector< EnumValueInfo > extraMembers; // for each enum in this list - for (const auto &md : *mn) + for (const auto &imd : *mn) { + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); // use raw pointer in this loop, since we modify mn and can then invalidate mdp. - if (!md->isAlias() && md->isEnumerate() && !root->children().empty()) + if (md && md->isEnumerate() && !root->children().empty()) { //printf(" enum with %d children\n",root->children()->count()); for (const auto &e : root->children()) @@ -6934,7 +7011,7 @@ static void addEnumValuesToEnums(const Entry *root) { fileName = e->tagInfo()->tagName; } - std::unique_ptr<MemberDef> fmd { createMemberDef( + std::unique_ptr<MemberDefMutable> fmd { createMemberDef( fileName,e->startLine,e->startColumn, e->type,e->name,e->args,0, e->protection, Normal,e->stat,Member, @@ -6956,7 +7033,7 @@ static void addEnumValuesToEnums(const Entry *root) fmd->setRefItems(e->sli); fmd->setAnchor(); md->insertEnumField(fmd.get()); - fmd->setEnumScope(md.get(),TRUE); + fmd->setEnumScope(md,TRUE); extraMembers.push_back(EnumValueInfo(e->name,fmd)); } } @@ -6968,9 +7045,10 @@ static void addEnumValuesToEnums(const Entry *root) if (!e->name.isEmpty() && (fmn=emnsd->find(e->name))) // get list of members with the same name as the field { - for (const auto &fmd : *fmn) + for (const auto &ifmd : *fmn) { - if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope + MemberDefMutable *fmd = MemberDef::make_mutable(ifmd.get()); + if (fmd && fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope { //printf("found enum value with same name %s in scope %s\n", // fmd->name().data(),fmd->getOuterScope()->name().data()); @@ -6979,8 +7057,8 @@ static void addEnumValuesToEnums(const Entry *root) const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace { - md->insertEnumField(fmd.get()); - fmd->setEnumScope(md.get()); + md->insertEnumField(fmd); + fmd->setEnumScope(md); } } else if (isGlobal) @@ -6988,19 +7066,19 @@ static void addEnumValuesToEnums(const Entry *root) const FileDef *ffd=fmd->getFileDef(); if (ffd==fd) // enum value has file scope { - md->insertEnumField(fmd.get()); - fmd->setEnumScope(md.get()); + md->insertEnumField(fmd); + fmd->setEnumScope(md); } } else if (isRelated && cd) // reparent enum value to // match the enum's scope { - md->insertEnumField(fmd.get()); // add field def to list - fmd->setEnumScope(md.get()); // cross ref with enum name + md->insertEnumField(fmd); // add field def to list + fmd->setEnumScope(md); // cross ref with enum name fmd->setEnumClassScope(cd); // cross ref with enum name fmd->setOuterScope(cd); fmd->makeRelated(); - cd->insertMember(fmd.get()); + cd->insertMember(fmd); } else { @@ -7009,8 +7087,8 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("Inserting enum field %s in enum scope %s\n", // fmd->name().data(),md->name().data()); - md->insertEnumField(fmd.get()); // add field def to list - fmd->setEnumScope(md.get()); // cross ref with enum name + md->insertEnumField(fmd); // add field def to list + fmd->setEnumScope(md); // cross ref with enum name } } } @@ -7068,7 +7146,7 @@ static void findEnumDocumentation(const Entry *root) if (!scope.isEmpty()) scope.prepend("::"); scope.prepend(root->parent()->name); } - ClassDef *cd=getClass(scope); + const ClassDef *cd=getClass(scope); if (!name.isEmpty()) { @@ -7080,10 +7158,10 @@ static void findEnumDocumentation(const Entry *root) MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { - cd=md->getClassDef(); - if (cd && cd->name()==className && md->isEnumerate()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && (cd=md->getClassDef()) && cd->name()==className && md->isEnumerate()) { // documentation outside a compound overrides the documentation inside it #if 0 @@ -7119,7 +7197,7 @@ static void findEnumDocumentation(const Entry *root) const GroupDef *gd=md->getGroupDef(); if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { - addMemberToGroups(root,md.get()); + addMemberToGroups(root,md); } found=TRUE; @@ -7138,9 +7216,10 @@ static void findEnumDocumentation(const Entry *root) MemberName *mn=Doxygen::functionNameLinkedMap->find(name); if (mn) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (md->isEnumerate()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->isEnumerate()) { md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); @@ -7152,7 +7231,7 @@ static void findEnumDocumentation(const Entry *root) const GroupDef *gd=md->getGroupDef(); if (gd==0 && !root->groups.empty()) // member not grouped but out-of-line documentation is { - addMemberToGroups(root,md.get()); + addMemberToGroups(root,md); } found=TRUE; @@ -7181,9 +7260,10 @@ static void findDEV(const MemberNameLinkedMap &mnsd) for (const auto &mn : mnsd) { // for each member definition - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (md->isEnumerate()) // member is an enum + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->isEnumerate()) // member is an enum { const MemberList *fmdl = md->enumFieldList(); int documentedEnumValues=0; @@ -7229,17 +7309,18 @@ static void addMembersToIndex() for (const auto &mn : *Doxygen::functionNameLinkedMap) { // for each member definition - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (!md->isAlias()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) { if (md->getNamespaceDef()) { - addNamespaceMemberNameToIndex(md.get()); + addNamespaceMemberNameToIndex(md); } else { - addFileMemberNameToIndex(md.get()); + addFileMemberNameToIndex(md); } } } @@ -7254,18 +7335,26 @@ static void vhdlCorrectMemberProperties() for (const auto &mn : *Doxygen::memberNameLinkedMap) { // for each member definition - for (const auto &md : *mn) + for (const auto &imd : *mn) { - VhdlDocGen::correctMemberProperties(md.get()); + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) + { + VhdlDocGen::correctMemberProperties(md); + } } } // for each member name for (const auto &mn : *Doxygen::functionNameLinkedMap) { // for each member definition - for (const auto &md : *mn) + for (const auto &imd : *mn) { - VhdlDocGen::correctMemberProperties(md.get()); + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) + { + VhdlDocGen::correctMemberProperties(md); + } } } } @@ -7281,60 +7370,65 @@ static void computeMemberRelations() for (const auto &mn : *Doxygen::memberNameLinkedMap) { // for each member with a specific name - for (const auto &md : *mn) + for (const auto &imd : *mn) { - // for each other member with the same name - for ( const auto &bmd : *mn) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) { - if (md!=bmd) + // for each other member with the same name + for ( const auto &ibmd : *mn) { - const ClassDef *mcd = md->getClassDef(); - if (mcd && !mcd->baseClasses().empty()) + MemberDefMutable *bmd = MemberDef::make_mutable(ibmd.get()); + if (bmd && md!=bmd) { - const ClassDef *bmcd = bmd->getClassDef(); - //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", - // mcd->name().data(),md->name().data(),md.get(), - // bmcd->name().data(),bmd->name().data(),bmd.get() - // ); - if (bmcd && mcd && bmcd!=mcd && - (bmd->virtualness()!=Normal || - bmd->getLanguage()==SrcLangExt_Python || bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || - bmcd->compoundType()==ClassDef::Interface || bmcd->compoundType()==ClassDef::Protocol - ) && - md->isFunction() && - mcd->isLinkable() && - bmcd->isLinkable() && - mcd->isBaseClass(bmcd,TRUE)) + const ClassDef *mcd = md->getClassDef(); + if (mcd && !mcd->baseClasses().empty()) { - //printf(" derived scope\n"); - const ArgumentList &bmdAl = bmd->argumentList(); - const ArgumentList &mdAl = md->argumentList(); - //printf(" Base argList='%s'\n Super argList='%s'\n", - // argListToString(bmdAl).data(), - // argListToString(mdAl).data() + const ClassDef *bmcd = bmd->getClassDef(); + //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", + // mcd->name().data(),md->name().data(),md.get(), + // bmcd->name().data(),bmd->name().data(),bmd.get() // ); - if ( - matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl, - md->getOuterScope(), md->getFileDef(), &mdAl, - TRUE - ) - ) + if (bmcd && mcd && bmcd!=mcd && + (bmd->virtualness()!=Normal || + bmd->getLanguage()==SrcLangExt_Python || bmd->getLanguage()==SrcLangExt_Java || bmd->getLanguage()==SrcLangExt_PHP || + bmcd->compoundType()==ClassDef::Interface || bmcd->compoundType()==ClassDef::Protocol + ) && + md->isFunction() && + mcd->isLinkable() && + bmcd->isLinkable() && + mcd->isBaseClass(bmcd,TRUE)) { - //printf("match!\n"); - MemberDef *rmd; - if ((rmd=md->reimplements())==0 || - minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) + //printf(" derived scope\n"); + const ArgumentList &bmdAl = bmd->argumentList(); + const ArgumentList &mdAl = md->argumentList(); + //printf(" Base argList='%s'\n Super argList='%s'\n", + // argListToString(bmdAl).data(), + // argListToString(mdAl).data() + // ); + if ( + matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),&bmdAl, + md->getOuterScope(), md->getFileDef(), &mdAl, + TRUE + ) ) { - //printf("setting (new) reimplements member\n"); - md->setReimplements(bmd.get()); + //printf("match!\n"); + MemberDef *rmd; + if ((rmd=md->reimplements())==0 || + minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) + ) + { + //printf("setting (new) reimplements member\n"); + md->setReimplements(bmd); + } + //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); + bmd->insertReimplementedBy(md); + } + else + { + //printf("no match!\n"); } - //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); - bmd->insertReimplementedBy(md.get()); - } - else - { - //printf("no match!\n"); } } } @@ -7374,7 +7468,11 @@ static void createTemplateInstanceMembers() // for each instance of the template for (qdi.toFirst();(tcd=qdi.current());++qdi) { - tcd->addMembersToTemplateInstance(cd,qdi.currentKey()); + ClassDefMutable *tcdm = ClassDef::make_mutable(tcd); + if (tcdm) + { + tcdm->addMembersToTemplateInstance(cd,qdi.currentKey()); + } } } } @@ -7393,7 +7491,7 @@ static void mergeCategories() if (i!=-1) // it is an Objective-C category { QCString baseName=cd->name().left(i); - ClassDef *baseClass=Doxygen::classSDict->find(baseName); + ClassDefMutable *baseClass=ClassDef::make_mutable(Doxygen::classSDict->find(baseName)); if (baseClass) { //printf("*** merging members of category %s into %s\n", @@ -7417,14 +7515,22 @@ static void buildCompleteMemberLists() cd->subClasses().empty() && // is a root of the hierarchy !cd->baseClasses().empty()) // and has at least one base class { - //printf("*** merging members for %s\n",cd->name().data()); - cd->mergeMembers(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + //printf("*** merging members for %s\n",cd->name().data()); + cdm->mergeMembers(); + } } } // now sort the member list of all members for all classes. for (cli.toFirst();(cd=cli.current());++cli) { - cd->sortAllMembersList(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->sortAllMembersList(); + } } } @@ -7735,7 +7841,7 @@ static void buildDefineList() { for (const auto &def : it->second) { - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( def.fileName,def.lineNr,def.columnNr, "#define",def.name,def.args,0, Public,Normal,FALSE,Member,MemberType_Define, @@ -7769,7 +7875,11 @@ static void sortMemberLists() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - cd->sortMemberLists(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->sortMemberLists(); + } } // sort namespace member lists @@ -7777,7 +7887,11 @@ static void sortMemberLists() NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { - nd->sortMemberLists(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->sortMemberLists(); + } } // sort file member lists @@ -7811,9 +7925,10 @@ static void computeTooltipTexts() { for (const auto &kv : Doxygen::symbolMap) { - if (!isSymbolHidden(kv.second) && kv.second->isLinkableInProject()) + DefinitionMutable *dm = Definition::make_mutable(kv.second); + if (!isSymbolHidden(dm) && dm->isLinkableInProject()) { - kv.second->computeTooltip(); + dm->computeTooltip(); } } } @@ -7826,7 +7941,11 @@ static void setAnonymousEnumType() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - cd->setAnonymousEnumType(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->setAnonymousEnumType(); + } } } @@ -7838,14 +7957,22 @@ static void countMembers() ClassDef *cd=0; for (cli.toFirst();(cd=cli.current());++cli) { - cd->countMembers(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->countMembers(); + } } NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd=0; for (nli.toFirst();(nd=nli.current());++nli) { - nd->countMembers(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->countMembers(); + } } for (const auto &fn : *Doxygen::inputNameLinkedMap) @@ -7873,7 +8000,7 @@ static void generateClassList(ClassSDict &classSDict) ClassSDict::Iterator cli(classSDict); for ( ; cli.current() ; ++cli ) { - ClassDef *cd=cli.current(); + ClassDefMutable *cd=ClassDef::make_mutable(cli.current()); //printf("cd=%s getOuterScope=%p global=%p\n",cd->name().data(),cd->getOuterScope(),Doxygen::globalScope); if (cd && @@ -7909,11 +8036,12 @@ static void inheritDocumentation() { for (const auto &mn : *Doxygen::memberNameLinkedMap) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); //static int count=0; //printf("%04d Member '%s'\n",count++,md->qualifiedName().data()); - if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) + if (md && md->documentation().isEmpty() && md->briefDescription().isEmpty()) { // no documentation yet MemberDef *bmd = md->reimplements(); while (bmd && bmd->documentation().isEmpty() && @@ -7966,7 +8094,11 @@ static void combineUsingRelations() } for (nli.toFirst() ; (nd=nli.current()) ; ++nli ) { - nd->combineUsingRelations(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->combineUsingRelations(); + } } } @@ -7979,7 +8111,11 @@ static void addMembersToMemberGroup() ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { - cd->addMembersToMemberGroup(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->addMembersToMemberGroup(); + } } // for each file for (const auto &fn : *Doxygen::inputNameLinkedMap) @@ -7994,7 +8130,11 @@ static void addMembersToMemberGroup() NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { - nd->addMembersToMemberGroup(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->addMembersToMemberGroup(); + } } // for each group GroupSDict::Iterator gli(*Doxygen::groupSDict); @@ -8014,7 +8154,11 @@ static void distributeMemberGroupDocumentation() ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { - cd->distributeMemberGroupDocumentation(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->distributeMemberGroupDocumentation(); + } } // for each file for (const auto &fn : *Doxygen::inputNameLinkedMap) @@ -8029,7 +8173,11 @@ static void distributeMemberGroupDocumentation() NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { - nd->distributeMemberGroupDocumentation(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->distributeMemberGroupDocumentation(); + } } // for each group GroupSDict::Iterator gli(*Doxygen::groupSDict); @@ -8049,7 +8197,11 @@ static void findSectionsInDocumentation() ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { - cd->findSectionsInDocumentation(); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->findSectionsInDocumentation(); + } } // for each file for (const auto &fn : *Doxygen::inputNameLinkedMap) @@ -8064,7 +8216,11 @@ static void findSectionsInDocumentation() NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { - nd->findSectionsInDocumentation(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->findSectionsInDocumentation(); + } } // for each group GroupSDict::Iterator gli(*Doxygen::groupSDict); @@ -8109,9 +8265,10 @@ static void flushCachedTemplateRelations() for (const auto &fn : *Doxygen::functionNameLinkedMap) { // for each function with that name - for (const auto &fmd : *fn) + for (const auto &ifmd : *fn) { - if (fmd->isTypedefValCached()) + MemberDefMutable *fmd = MemberDef::make_mutable(ifmd.get()); + if (fmd && fmd->isTypedefValCached()) { const ClassDef *cd = fmd->getCachedTypedefVal(); if (cd->isTemplate()) fmd->invalidateTypedefValCache(); @@ -8122,9 +8279,10 @@ static void flushCachedTemplateRelations() for (const auto &nm : *Doxygen::memberNameLinkedMap) { // for each function with that name - for (const auto &md : *nm) + for (const auto &imd : *nm) { - if (md->isTypedefValCached()) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->isTypedefValCached()) { const ClassDef *cd = md->getCachedTypedefVal(); if (cd->isTemplate()) md->invalidateTypedefValCache(); @@ -8165,18 +8323,26 @@ static void flushUnresolvedRelations() for (const auto &fn : *Doxygen::functionNameLinkedMap) { // for each function with that name - for (const auto &fmd : *fn) + for (const auto &ifmd : *fn) { - fmd->invalidateCachedArgumentTypes(); + MemberDefMutable *fmd = MemberDef::make_mutable(ifmd.get()); + if (fmd) + { + fmd->invalidateCachedArgumentTypes(); + } } } // for each class method name for (const auto &nm : *Doxygen::memberNameLinkedMap) { // for each function with that name - for (const auto &md : *nm) + for (const auto &imd : *nm) { - md->invalidateCachedArgumentTypes(); + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md) + { + md->invalidateCachedArgumentTypes(); + } } } @@ -8195,7 +8361,7 @@ static void findDefineDocumentation(Entry *root) if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file { - std::unique_ptr<MemberDef> md { createMemberDef(root->tagInfo()->tagName,1,1, + std::unique_ptr<MemberDefMutable> md { createMemberDef(root->tagInfo()->tagName,1,1, "#define",root->name,root->args,0, Public,Normal,FALSE,Member,MemberType_Define, ArgumentList(),ArgumentList(),"") }; @@ -8217,9 +8383,10 @@ static void findDefineDocumentation(Entry *root) } if (count==1) { - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (md->memberType()==MemberType_Define) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->memberType()==MemberType_Define) { md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocsForDefinition(!root->proto); @@ -8234,7 +8401,7 @@ static void findDefineDocumentation(Entry *root) md->setMaxInitLines(root->initLines); md->setRefItems(root->sli); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); - addMemberToGroups(root,md.get()); + addMemberToGroups(root,md); } } } @@ -8247,27 +8414,18 @@ static void findDefineDocumentation(Entry *root) // multiple defines don't know where to add docs // but maybe they are in different files together with their documentation { - for (const auto &md : *mn) + for (const auto &imd : *mn) { - if (md->memberType()==MemberType_Define) + MemberDefMutable *md = MemberDef::make_mutable(imd.get()); + if (md && md->memberType()==MemberType_Define) { const FileDef *fd=md->getFileDef(); if (fd && fd->absFilePath()==root->fileName) // doc and define in the same file assume they belong together. { -#if 0 - if (md->documentation().isEmpty()) -#endif - { - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setDocsForDefinition(!root->proto); - } -#if 0 - if (md->briefDescription().isEmpty()) -#endif - { - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - } + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setDocsForDefinition(!root->proto); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); if (md->inbodyDocumentation().isEmpty()) { md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); @@ -8278,7 +8436,7 @@ static void findDefineDocumentation(Entry *root) md->setRefItems(root->sli); md->setLanguage(root->lang); if (root->mGrpId!=-1) md->setMemberGroupId(root->mGrpId); - addMemberToGroups(root,md.get()); + addMemberToGroups(root,md); } } } @@ -8750,19 +8908,23 @@ static void generateNamespaceClassDocs(ClassSDict *d) ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { - if ( ( cd->isLinkableInProject() && - cd->templateMaster()==0 - ) // skip external references, anonymous compounds and - // template instances and nested classes - && !cd->isHidden() && !cd->isEmbeddedInOuterScope() - ) + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) { - msg("Generating docs for compound %s...\n",cd->name().data()); + if ( ( cd->isLinkableInProject() && + cd->templateMaster()==0 + ) // skip external references, anonymous compounds and + // template instances and nested classes + && !cd->isHidden() && !cd->isEmbeddedInOuterScope() + ) + { + msg("Generating docs for compound %s...\n",cd->name().data()); - cd->writeDocumentation(*g_outputList); - cd->writeMemberList(*g_outputList); + cdm->writeDocumentation(*g_outputList); + cdm->writeMemberList(*g_outputList); + } + cdm->writeDocumentationForInnerClasses(*g_outputList); } - cd->writeDocumentationForInnerClasses(*g_outputList); } } @@ -8780,8 +8942,12 @@ static void generateNamespaceDocs() if (nd->isLinkableInProject()) { - msg("Generating docs for namespace %s\n",nd->name().data()); - nd->writeDocumentation(*g_outputList); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + msg("Generating docs for namespace %s\n",nd->name().data()); + ndm->writeDocumentation(*g_outputList); + } } generateNamespaceClassDocs(nd->getClassSDict()); @@ -10531,14 +10697,22 @@ static void writeTagFile() ClassDef *cd; for ( ; (cd=cli.current()) ; ++cli ) { - if (cd->isLinkableInProject()) cd->writeTagFile(tagFile); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm && cdm->isLinkableInProject()) + { + cdm->writeTagFile(tagFile); + } } // for each namespace NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for ( ; (nd=nli.current()) ; ++nli ) { - if (nd->isLinkableInProject()) nd->writeTagFile(tagFile); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm && nd->isLinkableInProject()) + { + ndm->writeTagFile(tagFile); + } } // for each group GroupSDict::Iterator gli(*Doxygen::groupSDict); diff --git a/src/doxygen.h b/src/doxygen.h index b48a92c..8ab8679 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -63,6 +63,7 @@ class FormulaDict; class FormulaNameDict; class Preprocessor; struct MemberGroupInfo; +class NamespaceDefMutable; typedef QList<QCString> StringList; typedef QListIterator<QCString> StringListIterator; @@ -117,7 +118,7 @@ class Doxygen static StringDict aliasDict; static QIntDict<MemberGroupInfo> memGrpInfoDict; static StringUnorderedSet expandAsDefinedSet; - static NamespaceDef *globalScope; + static NamespaceDefMutable *globalScope; static QCString htmlFileExtension; static bool parseSourcesNeeded; static SearchIndexIntf *searchIndex; diff --git a/src/filedef.cpp b/src/filedef.cpp index 3279179..aa6d598 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -1895,7 +1895,11 @@ void FileDefImpl::combineUsingRelations() LinkedRefMap<const NamespaceDef> usingDirList = m_usingDirList; for (auto &nd : usingDirList) { - const_cast<NamespaceDef*>(nd)->combineUsingRelations(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->combineUsingRelations(); + } } for (auto &nd : usingDirList) @@ -2010,7 +2014,14 @@ void FileDefImpl::addMemberToList(MemberListType lt,MemberDef *md) { ml->setInFile(TRUE); } - if (ml->listType()&MemberListType_declarationLists) md->setSectionList(this,ml); + if (ml->listType()&MemberListType_declarationLists) + { + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->setSectionList(this,ml); + } + } } void FileDefImpl::sortMemberLists() diff --git a/src/filedef.h b/src/filedef.h index 505625d..900399d 100644 --- a/src/filedef.h +++ b/src/filedef.h @@ -63,7 +63,7 @@ struct IncludeInfo * The member writeDocumentation() can be used to generate the page of * documentation to HTML and LaTeX. */ -class FileDef : virtual public Definition +class FileDef : virtual public DefinitionMutable { public: ~FileDef() {} diff --git a/src/fortrancode.l b/src/fortrancode.l index f8f246a..39dc721 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -297,7 +297,11 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") } if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); + MemberDefMutable *mdm = MemberDef::make_mutable(yyextra->currentMemberDef); + if (mdm) + { + mdm->incrementFlowKeyWordCount(); + } } /* font class is defined e.g. in doxygen.css */ startFontClass(yyscanner,"keywordflow"); @@ -1233,7 +1237,7 @@ static bool getLink(yyscan_t yyscanner,UseSDict *usedict, // dictionary with use if (yyextra->currentDefinition && yyextra->currentMemberDef && md!=yyextra->currentMemberDef && yyextra->insideBody && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,md); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } writeMultiLineCodeLink(yyscanner,ol,md,text ? text : memberText); addToSearchIndex(yyscanner, text ? text : memberText); diff --git a/src/groupdef.cpp b/src/groupdef.cpp index 7cd6cf2..4574b37 100644 --- a/src/groupdef.cpp +++ b/src/groupdef.cpp @@ -396,13 +396,14 @@ bool GroupDefImpl::insertMember(MemberDef *md,bool docOnly) sameScope // both are found in the same scope ) { - if (srcMd->getGroupAlias()==0) + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm && srcMd->getGroupAlias()==0) { - md->setGroupAlias(srcMd); + mdm->setGroupAlias(srcMd); } - else if (md!=srcMd->getGroupAlias()) + else if (mdm && md!=srcMd->getGroupAlias()) { - md->setGroupAlias(srcMd->getGroupAlias()); + mdm->setGroupAlias(srcMd->getGroupAlias()); } return FALSE; // member is the same as one that is already added } @@ -1437,9 +1438,10 @@ void addClassToGroups(const Entry *root,ClassDef *cd) GroupDef *gd=0; if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) { - if (gd->addClass(cd)) + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm && gd->addClass(cdm)) { - cd->makePartOfGroup(gd); + cdm->makePartOfGroup(gd); } //printf("Compound %s: in group %s\n",cd->name().data(),gd->groupTitle()); } @@ -1455,7 +1457,14 @@ void addNamespaceToGroups(const Entry *root,NamespaceDef *nd) //printf("group '%s'\n",s->data()); if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) { - if (gd->addNamespace(nd)) nd->makePartOfGroup(gd); + if (gd->addNamespace(nd)) + { + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->makePartOfGroup(gd); + } + } //printf("Namespace %s: in group %s\n",nd->name().data(),s->data()); } } @@ -1595,13 +1604,16 @@ void addMemberToGroups(const Entry *root,MemberDef *md) bool success = fgd->insertMember(md); if (success) { - //printf("insertMember successful\n"); - md->setGroupDef(fgd,pri,root->fileName,root->startLine, - !root->doc.isEmpty()); - ClassDef *cd = md->getClassDefOfAnonymousType(); - if (cd) + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + //printf("insertMember successful\n"); + mdm->setGroupDef(fgd,pri,root->fileName,root->startLine,!root->doc.isEmpty()); + } + ClassDefMutable *cdm = ClassDef::make_mutable(mdm->getClassDefOfAnonymousType()); + if (cdm) { - cd->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0); + cdm->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0); } } } diff --git a/src/groupdef.h b/src/groupdef.h index 82fa004..b9e0740 100644 --- a/src/groupdef.h +++ b/src/groupdef.h @@ -43,7 +43,7 @@ class MemberDef; class FTextStream; /** A model of a group of symbols. */ -class GroupDef : virtual public Definition +class GroupDef : virtual public DefinitionMutable { public: ~GroupDef() {} diff --git a/src/index.cpp b/src/index.cpp index e9619ad..7dacc14 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -254,7 +254,7 @@ QCString fixSpaces(const QCString &s) return substitute(s," "," "); } -void startTitle(OutputList &ol,const char *fileName,const Definition *def) +void startTitle(OutputList &ol,const char *fileName,const DefinitionMutable *def) { ol.startHeaderSection(); if (def) def->writeSummaryLinks(ol); @@ -1576,7 +1576,8 @@ static void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool ClassDef *cd; for (;(cd=cli.current());++cli) { - if (cd->getLanguage()==SrcLangExt_VHDL) + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm && cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS @@ -1587,7 +1588,7 @@ static void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS) { QCString n=cd->name(); - cd->setClassName(n.data()); + cdm->setClassName(n.data()); } } diff --git a/src/index.h b/src/index.h index f571375..6cca60d 100644 --- a/src/index.h +++ b/src/index.h @@ -1,12 +1,12 @@ /****************************************************************************** * - * + * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -23,6 +23,7 @@ #include <qcstring.h> class Definition; +class DefinitionMutable; class MemberDef; class OutputList; class FTextStream; @@ -36,7 +37,7 @@ class IndexIntf virtual void finalize() = 0; virtual void incContentsDepth() = 0; virtual void decContentsDepth() = 0; - virtual void addContentsItem(bool isDir, const char *name, const char *ref, + virtual void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor, bool separateIndex, bool addToNavIndex,const Definition *def) = 0; virtual void addIndexItem(const Definition *context,const MemberDef *md, @@ -73,7 +74,7 @@ class IndexList : public IndexIntf /** Creates a list of indexes */ IndexList() { m_intfs.setAutoDelete(TRUE); m_enabled=TRUE; } /** Add an index generator to the list */ - void addIndex(IndexIntf *intf) + void addIndex(IndexIntf *intf) { m_intfs.append(intf); } void disable() { m_enabled = FALSE; } @@ -83,25 +84,25 @@ class IndexList : public IndexIntf { return m_enabled; } // IndexIntf implementation - void initialize() + void initialize() { foreach(&IndexIntf::initialize); } - void finalize() + void finalize() { foreach(&IndexIntf::finalize); } void incContentsDepth() { if (m_enabled) foreach(&IndexIntf::incContentsDepth); } void decContentsDepth() { if (m_enabled) foreach(&IndexIntf::decContentsDepth); } - void addContentsItem(bool isDir, const char *name, const char *ref, + void addContentsItem(bool isDir, const char *name, const char *ref, const char *file, const char *anchor,bool separateIndex=FALSE,bool addToNavIndex=FALSE, const Definition *def=0) { if (m_enabled) foreach(&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); } void addIndexItem(const Definition *context,const MemberDef *md,const char *sectionAnchor=0,const char *title=0) { if (m_enabled) foreach(&IndexIntf::addIndexItem,context,md,sectionAnchor,title); } - void addIndexFile(const char *name) + void addIndexFile(const char *name) { if (m_enabled) foreach(&IndexIntf::addIndexFile,name); } - void addImageFile(const char *name) + void addImageFile(const char *name) { if (m_enabled) foreach(&IndexIntf::addImageFile,name); } - void addStyleSheetFile(const char *name) + void addStyleSheetFile(const char *name) { if (m_enabled) foreach(&IndexIntf::addStyleSheetFile,name); } private: @@ -244,7 +245,7 @@ extern int documentedDirs; extern int documentedHtmlFiles; extern int documentedPages; -void startTitle(OutputList &ol,const char *fileName,const Definition *def=0); +void startTitle(OutputList &ol,const char *fileName,const DefinitionMutable *def=0); void endTitle(OutputList &ol,const char *fileName,const char *name); void startFile(OutputList &ol,const char *name,const char *manName, const char *title,HighlightedItem hli=HLI_None, diff --git a/src/memberdef.cpp b/src/memberdef.cpp index 8f3341c..fe7b1bd 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -47,7 +47,7 @@ //----------------------------------------------------------------------------- -class MemberDefImpl : public DefinitionImpl, public MemberDef +class MemberDefImpl : public DefinitionImpl, public MemberDefMutable { public: MemberDefImpl(const char *defFileName,int defLine,int defColumn, @@ -76,15 +76,11 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef virtual int initializerLines() const; virtual uint64 getMemberSpecifiers() const; virtual const MemberList *getSectionList(const Definition *) const; - virtual QCString displayDefinition() const; + virtual QCString displayDefinition() const; virtual const ClassDef *getClassDef() const; - virtual ClassDef *getClassDef(); virtual const FileDef *getFileDef() const; - virtual FileDef *getFileDef(); virtual const NamespaceDef* getNamespaceDef() const; - virtual NamespaceDef* getNamespaceDef(); virtual const GroupDef *getGroupDef() const; - virtual GroupDef *getGroupDef(); virtual ClassDef *accessorClass() const; virtual const char *getReadAccessor() const; virtual const char *getWriteAccessor() const; @@ -242,7 +238,7 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef virtual int getDeclColumn() const; virtual void setMemberType(MemberType t); virtual void setDefinition(const char *d); - virtual void setFileDef(FileDef *fd); + virtual void setFileDef(const FileDef *fd); virtual void setAnchor(); virtual void setProtection(Protection p); virtual void setMemberSpecifiers(uint64 s); @@ -250,9 +246,9 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef virtual void setInitializer(const char *i); virtual void setBitfields(const char *s); virtual void setMaxInitLines(int lines); - virtual void setMemberClass(ClassDef *cd); + virtual void setMemberClass(const ClassDef *cd); virtual void setSectionList(const Definition *container,MemberList *sl); - virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, + virtual void setGroupDef(const GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine,bool hasDocs, MemberDef *member=0); virtual void setReadAccessor(const char *r); @@ -281,7 +277,7 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef virtual void setTypeConstraints(const ArgumentList &al); virtual void setType(const char *t); virtual void setAccessorType(ClassDef *cd,const char *t); - virtual void setNamespace(NamespaceDef *nd); + virtual void setNamespace(const NamespaceDef *nd); virtual void setMemberGroup(MemberGroup *grp); virtual void setMemberGroupId(int id); virtual void makeImplementationDetail(); @@ -323,7 +319,7 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef virtual void warnIfUndocumented() const; virtual void warnIfUndocumentedParams() const; virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const; - virtual MemberDef *createTemplateInstanceMember(const ArgumentList &formalArgs, + virtual MemberDefMutable *createTemplateInstanceMember(const ArgumentList &formalArgs, const std::unique_ptr<ArgumentList> &actualArgs) const; virtual void findSectionsInDocumentation(); virtual void writeLink(OutputList &ol, @@ -364,7 +360,7 @@ class MemberDefImpl : public DefinitionImpl, public MemberDef uchar m_isDestructorCached; // 0 = not cached, 1=FALSE, 2=TRUE }; -MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn, +MemberDefMutable *createMemberDef(const char *defFileName,int defLine,int defColumn, const char *type,const char *name,const char *args, const char *excp,Protection prot,Specifier virt,bool stat, Relationship related,MemberType t,const ArgumentList &tal, @@ -429,7 +425,7 @@ class MemberDefAliasImpl : public DefinitionAliasImpl, public MemberDef { return getMdAlias()->getFileDef(); } virtual const NamespaceDef* getNamespaceDef() const { return getMdAlias()->getNamespaceDef(); } - virtual ClassDef *accessorClass() const + virtual const ClassDef *accessorClass() const { return getMdAlias()->accessorClass(); } virtual const char *getReadAccessor() const { return getMdAlias()->getReadAccessor(); } @@ -738,95 +734,13 @@ class MemberDefAliasImpl : public DefinitionAliasImpl, public MemberDef virtual int getDeclColumn() const { return getMdAlias()->getDeclColumn(); } - // non-const getters should not be called - virtual ClassDef *getClassDef() - { err("non-const getClassDef() called on aliased member. Please report as a bug.\n"); return 0; } - virtual FileDef *getFileDef() - { err("non-const getFileDef() called on aliased member. Please report as a bug.\n"); return 0; } - virtual NamespaceDef* getNamespaceDef() - { err("non-const getNamespaceDef() called on aliased member. Please report as a bug.\n"); return 0; } - virtual GroupDef *getGroupDef() - { err("non-const getGroupDef() called on aliased member. Please report as a bug.\n"); return 0; } - virtual ArgumentList &argumentList() - { err("non-const argumentList() called on aliased member. Please report as bug.\n"); - static ArgumentList dummy; return dummy; - } - - virtual void setEnumBaseType(const QCString &type) {} - virtual void setMemberType(MemberType t) {} - virtual void setDefinition(const char *d) {} - virtual void setFileDef(FileDef *fd) {} - virtual void setAnchor() {} - virtual void setProtection(Protection p) {} - virtual void setMemberSpecifiers(uint64 s) {} - virtual void mergeMemberSpecifiers(uint64 s) {} - virtual void setInitializer(const char *i) {} - virtual void setBitfields(const char *s) {} - virtual void setMaxInitLines(int lines) {} - virtual void setMemberClass(ClassDef *cd) {} - virtual void setSectionList(const Definition *c,MemberList *sl) {} - virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, - const QCString &fileName,int startLine,bool hasDocs, - MemberDef *member=0) {} - virtual void setReadAccessor(const char *r) {} - virtual void setWriteAccessor(const char *w) {} - virtual void setTemplateSpecialization(bool b) {} - virtual void makeRelated() {} - virtual void makeForeign() {} - virtual void setInheritsDocsFrom(MemberDef *md) {} - virtual void setTagInfo(const TagInfo *i) {} - virtual void setArgsString(const char *as) {} - virtual void setReimplements(MemberDef *md) {} - virtual void insertReimplementedBy(MemberDef *md) {} - virtual void setRelatedAlso(ClassDef *cd) {} - virtual void insertEnumField(MemberDef *md) {} - virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE) {} - virtual void setEnumClassScope(ClassDef *cd) {} - virtual void setDocumentedEnumValues(bool value) {} - virtual void setAnonymousEnumType(const MemberDef *md) {} - virtual bool addExample(const char *anchor,const char *name,const char *file) { return FALSE; } - virtual void setPrototype(bool p,const QCString &df,int line, int column) {} - virtual void setExplicitExternal(bool b,const QCString &df,int line,int column) {} - virtual void setDeclFile(const QCString &df,int line,int column) {} - virtual void moveArgumentList(std::unique_ptr<ArgumentList> al) {} - virtual void moveDeclArgumentList(std::unique_ptr<ArgumentList> al) {} - virtual void setDefinitionTemplateParameterLists(const ArgumentLists &lists) {} - virtual void setTypeConstraints(const ArgumentList &al) {} - virtual void setType(const char *t) {} - virtual void setAccessorType(ClassDef *cd,const char *t) {} - virtual void setNamespace(NamespaceDef *nd) {} + virtual void warnIfUndocumented() const {} + virtual void warnIfUndocumentedParams() const {} + virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const {} virtual void setMemberGroup(MemberGroup *grp) { m_memberGroup = grp; } - virtual void setMemberGroupId(int id) {} - virtual void makeImplementationDetail() {} - virtual void setFromAnonymousScope(bool b) const {} - virtual void setFromAnonymousMember(MemberDef *m) {} - virtual void enableCallGraph(bool e) {} - virtual void enableCallerGraph(bool e) {} - virtual void enableReferencedByRelation(bool e) {} - virtual void enableReferencesRelation(bool e) {} - virtual void setTemplateMaster(MemberDef *mt) {} - virtual void addListReference(Definition *d) {} - virtual void setDocsForDefinition(bool b) {} - virtual void setGroupAlias(const MemberDef *md) {} - virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType) {} - virtual void invalidateTypedefValCache() {} - virtual void invalidateCachedArgumentTypes() {} - virtual void setMemberDefinition(MemberDef *md) {} - virtual void setMemberDeclaration(MemberDef *md) {} - virtual void setAnonymousUsed() const {} - virtual void copyArgumentNames(MemberDef *bmd) {} - virtual void setCategory(ClassDef *) {} - virtual void setCategoryRelation(MemberDef *) {} - virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) {} - virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) {} - virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) {} - virtual void setHidden(bool b) {} - virtual void addToSearchIndex() const {} - virtual void findSectionsInDocumentation() {} - virtual MemberDef *createTemplateInstanceMember(const ArgumentList &formalArgs, + virtual MemberDefMutable *createTemplateInstanceMember(const ArgumentList &formalArgs, const std::unique_ptr<ArgumentList> &actualArgs) const { return getMdAlias()->createTemplateInstanceMember(formalArgs,actualArgs); } - virtual void incrementFlowKeyWordCount() {} virtual void writeDeclaration(OutputList &ol, const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, @@ -839,19 +753,6 @@ class MemberDefAliasImpl : public DefinitionAliasImpl, public MemberDef { getMdAlias()->writeEnumDeclaration(typeDecl,cd,nd,fd,gd); } - virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol, - const char *scopeName,const Definition *container, - bool inGroup,bool showEnumValues=FALSE,bool - showInline=FALSE) const {} - virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const {} - virtual void writeLink(OutputList &ol, - const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, - bool onlyText=FALSE) const {} - virtual void writeTagFile(FTextStream &) const {} - virtual void warnIfUndocumented() const {} - virtual void warnIfUndocumentedParams() const {} - virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const {} - virtual void resolveUnnamedParameters(const MemberDef *md) {} private: MemberGroup *m_memberGroup; // group's member definition }; @@ -1277,9 +1178,9 @@ class MemberDefImpl::IMPL const ArgumentList &al,const char *meta ); - ClassDef *classDef = 0; // member of or related to - FileDef *fileDef = 0; // member of file definition - NamespaceDef *nspace = 0; // the namespace this member is in. + const ClassDef *classDef = 0; // member of or related to + const FileDef *fileDef = 0; // member of file definition + const NamespaceDef *nspace = 0; // the namespace this member is in. MemberDef *enumScope = 0; // the enclosing scope, if this is an enum field bool livesInsideEnum = false; @@ -1340,7 +1241,7 @@ class MemberDefImpl::IMPL const MemberDef *groupAlias = 0; // Member containing the definition int grpId = 0; // group id MemberGroup *memberGroup = 0; // group's member definition - GroupDef *group = 0; // group in which this member is in + const GroupDef *group = 0; // group in which this member is in Grouping::GroupPri_t grouppri; // priority of this definition QCString groupFileName; // file where this grouping was defined int groupStartLine = 0; // line " " " " " @@ -1643,7 +1544,11 @@ void MemberDefImpl::insertReimplementedBy(MemberDef *md) { if (m_impl->templateMaster) { - m_impl->templateMaster->insertReimplementedBy(md); + MemberDefMutable *mdm = MemberDef::make_mutable(m_impl->templateMaster); + if (mdm) + { + mdm->insertReimplementedBy(md); + } } if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberListType_redefinedBy); if (m_impl->redefinedBy->findRef(md)==-1) @@ -2229,7 +2134,7 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, QCString cfname = getOutputFileBase(); // search for the last anonymous scope in the member type - ClassDef *annoClassDef=getClassDefOfAnonymousType(); + ClassDefMutable *annoClassDef=ClassDef::make_mutable(getClassDefOfAnonymousType()); ol.startMemberDeclaration(); @@ -2407,6 +2312,7 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE); static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL); static bool extractStatic = Config_getBool(EXTRACT_STATIC); + MemberDefMutable *annMemb = MemberDef::make_mutable(m_impl->annMemb); //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation()); if (!name().isEmpty() && // name valid (hasDocumentation() || isReference()) && // has docs @@ -2414,16 +2320,15 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, !(isStatic() && getClassDef()==0 && !extractStatic) // hidden due to static-ness ) { - if (m_impl->annMemb) + if (annMemb) { //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor()); - m_impl->annMemb->writeLink(ol, - m_impl->annMemb->getClassDef(), - m_impl->annMemb->getNamespaceDef(), - m_impl->annMemb->getFileDef(), - m_impl->annMemb->getGroupDef() - ); - m_impl->annMemb->setAnonymousUsed(); + annMemb->writeLink(ol, + annMemb->getClassDef(), + annMemb->getNamespaceDef(), + annMemb->getFileDef(), + annMemb->getGroupDef()); + annMemb->setAnonymousUsed(); setAnonymousUsed(); } else @@ -2444,9 +2349,9 @@ void MemberDefImpl::writeDeclaration(OutputList &ol, // there is a brief member description and brief member // descriptions are enabled or there is no detailed description. { - if (m_impl->annMemb) + if (annMemb) { - m_impl->annMemb->setAnonymousUsed(); + annMemb->setAnonymousUsed(); setAnonymousUsed(); } const ClassDef *rcd = cd; @@ -4296,7 +4201,7 @@ void MemberDefImpl::setAnchor() m_impl->anc = "a"+sigStr; } -void MemberDefImpl::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, +void MemberDefImpl::setGroupDef(const GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine, bool hasDocs,MemberDef *member) { @@ -4316,30 +4221,30 @@ void MemberDefImpl::setEnumScope(MemberDef *md,bool livesInsideEnum) m_impl->livesInsideEnum=livesInsideEnum; if (md->getGroupDef()) { - m_impl->group=md->getGroupDef(); - m_impl->grouppri=md->getGroupPri(); - m_impl->groupFileName=md->getGroupFileName(); - m_impl->groupStartLine=md->getGroupStartLine(); - m_impl->groupHasDocs=md->getGroupHasDocs(); + m_impl->group = const_cast<GroupDef*>(md->getGroupDef()); + m_impl->grouppri = md->getGroupPri(); + m_impl->groupFileName = md->getGroupFileName(); + m_impl->groupStartLine = md->getGroupStartLine(); + m_impl->groupHasDocs = md->getGroupHasDocs(); m_isLinkableCached = 0; } } -void MemberDefImpl::setMemberClass(ClassDef *cd) +void MemberDefImpl::setMemberClass(const ClassDef *cd) { m_impl->classDef=cd; m_isLinkableCached = 0; m_isConstructorCached = 0; - setOuterScope(cd); + setOuterScope(const_cast<ClassDef*>(cd)); } -void MemberDefImpl::setNamespace(NamespaceDef *nd) +void MemberDefImpl::setNamespace(const NamespaceDef *nd) { m_impl->nspace=nd; - setOuterScope(nd); + setOuterScope(const_cast<NamespaceDef*>(nd)); } -MemberDef *MemberDefImpl::createTemplateInstanceMember( +MemberDefMutable *MemberDefImpl::createTemplateInstanceMember( const ArgumentList &formalArgs,const std::unique_ptr<ArgumentList> &actualArgs) const { //printf(" Member %s %s %s\n",typeString(),name().data(),argsString()); @@ -4361,7 +4266,7 @@ MemberDef *MemberDefImpl::createTemplateInstanceMember( methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs); } - MemberDef *imd = createMemberDef( + MemberDefMutable *imd = createMemberDef( getDefFileName(),getDefLine(),getDefColumn(), substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs), methodName, @@ -4730,7 +4635,7 @@ void MemberDefImpl::writeEnumDeclaration(OutputList &typeDecl, if (fmdl) { MemberListIterator mli(*fmdl); - MemberDef *fmd=mli.current(); + MemberDefMutable *fmd=MemberDef::make_mutable(mli.current()); bool fmdVisible = fmd ? fmd->isBriefSectionVisible() : TRUE; while (fmd) { @@ -4774,7 +4679,7 @@ void MemberDefImpl::writeEnumDeclaration(OutputList &typeDecl, bool prevVisible = fmdVisible; ++mli; - fmd=mli.current(); + fmd=MemberDef::make_mutable(mli.current()); if (fmd && (fmdVisible=fmd->isBriefSectionVisible())) { typeDecl.writeString(", "); @@ -5000,31 +4905,16 @@ const ClassDef *MemberDefImpl::getClassDef() const return m_impl->classDef; } -ClassDef *MemberDefImpl::getClassDef() -{ - return m_impl->classDef; -} - const FileDef *MemberDefImpl::getFileDef() const { return m_impl->fileDef; } -FileDef *MemberDefImpl::getFileDef() -{ - return m_impl->fileDef; -} - const NamespaceDef* MemberDefImpl::getNamespaceDef() const { return m_impl->nspace; } -NamespaceDef* MemberDefImpl::getNamespaceDef() -{ - return m_impl->nspace; -} - const char *MemberDefImpl::getReadAccessor() const { return m_impl->read; @@ -5040,11 +4930,6 @@ const GroupDef *MemberDefImpl::getGroupDef() const return m_impl->group; } -GroupDef *MemberDefImpl::getGroupDef() -{ - return m_impl->group; -} - Grouping::GroupPri_t MemberDefImpl::getGroupPri() const { return m_impl->grouppri; @@ -5660,7 +5545,7 @@ void MemberDefImpl::setDefinition(const char *d) m_impl->def=d; } -void MemberDefImpl::setFileDef(FileDef *fd) +void MemberDefImpl::setFileDef(const FileDef *fd) { m_impl->fileDef=fd; m_isLinkableCached = 0; @@ -6010,7 +5895,7 @@ static void transferArgumentDocumentation(ArgumentList &decAl,ArgumentList &defA } } -void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) +void combineDeclarationAndDefinition(MemberDefMutable *mdec,MemberDefMutable *mdef) { //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype()); if ( @@ -6022,12 +5907,10 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef) // mdef, mdef ? mdef->name().data() : "", // mdec, mdec ? mdec->name().data() : ""); - const MemberDef *cmdec = const_cast<const MemberDef*>(mdec); - const MemberDef *cmdef = const_cast<const MemberDef*>(mdef); - ArgumentList &mdefAl = mdef->argumentList(); - ArgumentList &mdecAl = mdec->argumentList(); - if (matchArguments2(cmdef->getOuterScope(),cmdef->getFileDef(),&mdefAl, - cmdec->getOuterScope(),cmdec->getFileDef(),&mdecAl, + ArgumentList &mdefAl = const_cast<ArgumentList&>(mdef->argumentList()); + ArgumentList &mdecAl = const_cast<ArgumentList&>(mdec->argumentList()); + if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),&mdefAl, + mdec->getOuterScope(),mdec->getFileDef(),&mdecAl, TRUE ) ) /* match found */ diff --git a/src/memberdef.h b/src/memberdef.h index cc467ea..13b62a4 100644 --- a/src/memberdef.h +++ b/src/memberdef.h @@ -27,8 +27,8 @@ #include "types.h" #include "definition.h" #include "arguments.h" +#include "classdef.h" -class ClassDef; class NamespaceDef; class GroupDef; class FileDef; @@ -40,6 +40,7 @@ class GroupDef; class QTextStream; class QStrList; struct TagInfo; +class MemberDefMutable; /** A model of a class/file/namespace member symbol. */ class MemberDef : virtual public Definition @@ -54,6 +55,9 @@ class MemberDef : virtual public Definition virtual MemberDef *resolveAlias() = 0; virtual const MemberDef *resolveAlias() const = 0; + static MemberDefMutable *make_mutable(const MemberDef *); + ClassDefMutable *getClassDefMutable() const; + //----------------------------------------------------------------------------------- // ---- getters ----- //----------------------------------------------------------------------------------- @@ -77,25 +81,17 @@ class MemberDef : virtual public Definition virtual QCString displayDefinition() const = 0; // scope query members - virtual const ClassDef *getClassDef() const = 0; - virtual ClassDef *getClassDef() = 0; - virtual const FileDef *getFileDef() const = 0; - virtual FileDef *getFileDef() = 0; - + virtual const ClassDef *getClassDef() const = 0; virtual const NamespaceDef* getNamespaceDef() const = 0; - virtual NamespaceDef* getNamespaceDef() = 0; - - virtual const GroupDef *getGroupDef() const = 0; - virtual GroupDef *getGroupDef() = 0; - - virtual ClassDef *accessorClass() const = 0; + virtual const ClassDef *accessorClass() const = 0; // grabbing the property read/write accessor names virtual const char *getReadAccessor() const = 0; virtual const char *getWriteAccessor() const = 0; // querying the grouping definition + virtual const GroupDef *getGroupDef() const = 0; virtual Grouping::GroupPri_t getGroupPri() const = 0; virtual const char *getGroupFileName() const = 0; virtual int getGroupStartLine() const = 0; @@ -216,7 +212,6 @@ class MemberDef : virtual public Definition virtual bool isDocsForDefinition() const = 0; virtual const MemberDef *getEnumScope() const = 0; virtual const MemberList *enumFieldList() const = 0; - virtual void setEnumBaseType(const QCString &type) = 0; virtual QCString enumBaseType() const = 0; virtual bool hasExamples() const = 0; @@ -225,7 +220,6 @@ class MemberDef : virtual public Definition // argument related members virtual const ArgumentList &argumentList() const = 0; - virtual ArgumentList &argumentList() = 0; virtual const ArgumentList &declArgumentList() const = 0; virtual const ArgumentList &templateArguments() const = 0; virtual const ArgumentLists &definitionTemplateParameterLists() const = 0; @@ -280,15 +274,33 @@ class MemberDef : virtual public Definition virtual int getDeclLine() const = 0; virtual int getDeclColumn() const = 0; + virtual MemberDefMutable *createTemplateInstanceMember(const ArgumentList &formalArgs, + const std::unique_ptr<ArgumentList> &actualArgs) const = 0; + virtual void writeDeclaration(OutputList &ol, + const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, + bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const = 0; + virtual void writeEnumDeclaration(OutputList &typeDecl, const ClassDef *cd, + const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const = 0; + virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const = 0; + virtual void warnIfUndocumented() const = 0; + virtual void warnIfUndocumentedParams() const = 0; + + // TODO: this is not a getter, should be passed at construction + virtual void setMemberGroup(MemberGroup *grp) = 0; +}; + +class MemberDefMutable : virtual public DefinitionMutable, virtual public MemberDef +{ + public: + //----------------------------------------------------------------------------------- // ---- setters ----- //----------------------------------------------------------------------------------- - // set functions virtual void setMemberType(MemberType t) = 0; virtual void setDefinition(const char *d) = 0; - virtual void setFileDef(FileDef *fd) = 0; + virtual void setFileDef(const FileDef *fd) = 0; virtual void setAnchor() = 0; virtual void setProtection(Protection p) = 0; virtual void setMemberSpecifiers(uint64 s) = 0; @@ -296,9 +308,9 @@ class MemberDef : virtual public Definition virtual void setInitializer(const char *i) = 0; virtual void setBitfields(const char *s) = 0; virtual void setMaxInitLines(int lines) = 0; - virtual void setMemberClass(ClassDef *cd) = 0; + virtual void setMemberClass(const ClassDef *cd) = 0; virtual void setSectionList(const Definition *container,MemberList *sl) = 0; - virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri, + virtual void setGroupDef(const GroupDef *gd,Grouping::GroupPri_t pri, const QCString &fileName,int startLine,bool hasDocs, MemberDef *member=0) = 0; virtual void setReadAccessor(const char *r) = 0; @@ -311,6 +323,7 @@ class MemberDef : virtual public Definition virtual void setTagInfo(const TagInfo *i) = 0; virtual void setArgsString(const char *as) = 0; virtual void incrementFlowKeyWordCount() = 0; + virtual void setEnumBaseType(const QCString &type) = 0; // relation to other members virtual void setReimplements(MemberDef *md) = 0; @@ -343,10 +356,9 @@ class MemberDef : virtual public Definition virtual void setAccessorType(ClassDef *cd,const char *t) = 0; // namespace related members - virtual void setNamespace(NamespaceDef *nd) = 0; + virtual void setNamespace(const NamespaceDef *nd) = 0; // member group related members - virtual void setMemberGroup(MemberGroup *grp) = 0; virtual void setMemberGroupId(int id) = 0; virtual void makeImplementationDetail() = 0; @@ -388,8 +400,6 @@ class MemberDef : virtual public Definition // --- actions ---- //----------------------------------------------------------------------------------- - virtual MemberDef *createTemplateInstanceMember(const ArgumentList &formalArgs, - const std::unique_ptr<ArgumentList> &actualArgs) const = 0; virtual void findSectionsInDocumentation() = 0; virtual void addToSearchIndex() const = 0; @@ -397,32 +407,32 @@ class MemberDef : virtual public Definition // --- write output ---- //----------------------------------------------------------------------------------- - virtual void writeDeclaration(OutputList &ol, - const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, - bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const = 0; virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol, const char *scopeName,const Definition *container, bool inGroup,bool showEnumValues=FALSE,bool showInline=FALSE) const = 0; virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const = 0; - virtual void writeEnumDeclaration(OutputList &typeDecl, const ClassDef *cd, - const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const = 0; virtual void writeTagFile(FTextStream &) const = 0; virtual void writeLink(OutputList &ol, const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, bool onlyText=FALSE) const = 0; // write helpers - virtual void warnIfUndocumented() const = 0; - virtual void warnIfUndocumentedParams() const = 0; - virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const = 0; virtual void setAnonymousUsed() const = 0; virtual void setFromAnonymousScope(bool b) const = 0; }; +inline MemberDefMutable *MemberDef::make_mutable(const MemberDef *md) +{ return dynamic_cast<MemberDefMutable*>(const_cast<MemberDef*>(md)); } + +inline ClassDefMutable *MemberDef::getClassDefMutable() const +{ + return ClassDef::make_mutable(getClassDef()); +} + /** Factory method to create a new instance of a MemberDef */ -MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn, +MemberDefMutable *createMemberDef(const char *defFileName,int defLine,int defColumn, const char *type,const char *name,const char *args, const char *excp,Protection prot,Specifier virt,bool stat, Relationship related,MemberType t,const ArgumentList &tal, @@ -430,6 +440,6 @@ MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn, MemberDef *createMemberDefAlias(const Definition *newScope,const MemberDef *aliasMd); -void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef); +void combineDeclarationAndDefinition(MemberDefMutable *mdec,MemberDefMutable *mdef); #endif diff --git a/src/membergroup.cpp b/src/membergroup.cpp index e229835..b47fe71 100644 --- a/src/membergroup.cpp +++ b/src/membergroup.cpp @@ -71,10 +71,14 @@ void MemberGroup::insertMember(MemberDef *md) GroupDef *gd; if (firstMd && !firstMd->isAlias() && (gd=const_cast<GroupDef*>(firstMd->getGroupDef()))) { - md->setGroupDef(gd, firstMd->getGroupPri(), - firstMd->getGroupFileName(), - firstMd->getGroupStartLine(), - firstMd->getGroupHasDocs()); + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->setGroupDef(gd, firstMd->getGroupPri(), + firstMd->getGroupFileName(), + firstMd->getGroupStartLine(), + firstMd->getGroupHasDocs()); + } gd->insertMember(md); } } @@ -112,7 +116,7 @@ void MemberGroup::writeDocumentation(OutputList &ol,const char *scopeName, } void MemberGroup::writeDocumentationPage(OutputList &ol,const char *scopeName, - const Definition *container) const + const DefinitionMutable *container) const { memberList->writeDocumentationPage(ol,scopeName,container); } @@ -217,12 +221,13 @@ void MemberGroup::distributeMemberGroupDocumentation() if (md) // distribute docs of md to other members of the list { //printf("Member %s has documentation!\n",md->name().data()); - MemberDef *omd; - for (li.toFirst();(omd=li.current());++li) + MemberDef *iomd; + for (li.toFirst();(iomd=li.current());++li) { - if (md!=omd && omd->documentation().isEmpty() && - omd->briefDescription().isEmpty() && - omd->inbodyDocumentation().isEmpty() + MemberDefMutable *omd = MemberDef::make_mutable(iomd); + if (omd && md!=omd && omd->documentation().isEmpty() && + omd->briefDescription().isEmpty() && + omd->inbodyDocumentation().isEmpty() ) { //printf("Copying documentation to member %s\n",omd->name().data()); diff --git a/src/membergroup.h b/src/membergroup.h index c10e421..e1dae25 100644 --- a/src/membergroup.h +++ b/src/membergroup.h @@ -35,6 +35,7 @@ class FileDef; class GroupDef; class OutputList; class Definition; +class DefinitionMutable; class FTextStream; class RefItem; @@ -59,7 +60,7 @@ class MemberGroup void writeDocumentation(OutputList &ol,const char *scopeName, const Definition *container,bool showEnumValues,bool showInline) const; void writeDocumentationPage(OutputList &ol,const char *scopeName, - const Definition *container) const; + const DefinitionMutable *container) const; void writeTagFile(FTextStream &); void addGroupedInheritedMembers(OutputList &ol,const ClassDef *cd, MemberListType lt, diff --git a/src/memberlist.cpp b/src/memberlist.cpp index 0c608ff..589aa7e 100644 --- a/src/memberlist.cpp +++ b/src/memberlist.cpp @@ -334,10 +334,14 @@ void MemberList::setAnonymousEnumType() MemberDef *vmd; for ( ; (vmd=vmli.current()) ; ++vmli) { - QCString vtype=vmd->typeString(); - if ((vtype.find(name))!=-1) + MemberDefMutable *vmdm = MemberDef::make_mutable(vmd); + if (vmdm) { - vmd->setAnonymousEnumType(md); + QCString vtype=vmd->typeString(); + if ((vtype.find(name))!=-1) + { + vmdm->setAnonymousEnumType(md); + } } } } @@ -576,7 +580,8 @@ void MemberList::writePlainDeclarations(OutputList &ol, { if (md->fromAnonymousScope() && !md->anonymousDeclShown()) { - md->setFromAnonymousScope(FALSE); + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) mdm->setFromAnonymousScope(FALSE); //printf("anonymous compound members\n"); if (md->isBriefSectionVisible()) { @@ -587,7 +592,7 @@ void MemberList::writePlainDeclarations(OutputList &ol, } md->writeDeclaration(ol,cd,nd,fd,gd,m_inGroup); } - md->setFromAnonymousScope(TRUE); + if (mdm) mdm->setFromAnonymousScope(TRUE); } } } @@ -747,9 +752,13 @@ void MemberList::writeDeclarations(OutputList &ol, } if (inheritedFrom && cd) { - // also add members that of this list type, that are grouped together - // in a separate list in class 'inheritedFrom' - cd->addGroupedInheritedMembers(ol,m_listType,inheritedFrom,inheritId); + const ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + // also add members that of this list type, that are grouped together + // in a separate list in class 'inheritedFrom' + cdm->addGroupedInheritedMembers(ol,m_listType,inheritedFrom,inheritId); + } } //printf("----- end writeDeclaration() ----\n"); } @@ -812,9 +821,13 @@ void MemberList::writeDocumentation(OutputList &ol, { uint overloadCount = *overloadTotalDict.find(md->name()); uint *pCount = overloadCountDict.find(md->name()); - md->writeDocumentation(this,*pCount,overloadCount,ol,scopeName,container, - m_inGroup,showEnumValues,showInline); - (*pCount)++; + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->writeDocumentation(this,*pCount,overloadCount,ol,scopeName,container, + m_inGroup,showEnumValues,showInline); + (*pCount)++; + } } } if (memberGroupList) @@ -847,14 +860,18 @@ void MemberList::writeSimpleDocumentation(OutputList &ol, const MemberDef *md; for ( ; (md=mli.current()) ; ++mli) { - md->writeMemberDocSimple(ol,container); + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->writeMemberDocSimple(ol,container); + } } ol.endMemberDocSimple(cd && cd->isJavaEnum()); } // separate member pages void MemberList::writeDocumentationPage(OutputList &ol, - const char *scopeName, const Definition *container) const + const char *scopeName, const DefinitionMutable *container) const { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); @@ -864,9 +881,11 @@ void MemberList::writeDocumentationPage(OutputList &ol, overloadTotalDict.setAutoDelete(TRUE); overloadCountDict.setAutoDelete(TRUE); MemberListIterator mli(*this); - const MemberDef *md; - for (mli.toFirst() ; (md=mli.current()) ; ++mli) + const MemberDef *imd; + for (mli.toFirst() ; (imd=mli.current()) ; ++mli) { + MemberDefMutable *md = MemberDef::make_mutable(imd); + if (md->isDetailedSectionLinkable()) { uint *pCount = overloadTotalDict.find(md->name()); @@ -882,8 +901,9 @@ void MemberList::writeDocumentationPage(OutputList &ol, } } - for ( mli.toFirst() ; (md=mli.current()) ; ++mli) + for ( mli.toFirst() ; (imd=mli.current()) ; ++mli) { + MemberDefMutable *md = MemberDef::make_mutable(imd); if (md->isDetailedSectionLinkable()) { uint overloadCount = *overloadTotalDict.find(md->name()); @@ -902,6 +922,7 @@ void MemberList::writeDocumentationPage(OutputList &ol, { md->writeDocumentation(this,*pCount,overloadCount,ol,scopeName,container,m_inGroup); (*pCount)++; + ol.endContents(); endFileWithNavPath(container,ol); } @@ -952,9 +973,10 @@ void MemberList::addMemberGroup(MemberGroup *mg) void MemberList::addListReferences(Definition *def) { MemberListIterator mli(*this); - MemberDef *md; - for ( ; (md=mli.current()) ; ++mli) + MemberDef *imd; + for ( ; (imd=mli.current()) ; ++mli) { + MemberDefMutable *md = MemberDef::make_mutable(imd); if (!md->isAlias() && (md->getGroupDef()==0 || def->definitionType()==Definition::TypeGroup)) { md->addListReference(def); @@ -966,8 +988,12 @@ void MemberList::addListReferences(Definition *def) MemberDef *vmd; for ( ; (vmd=vmli.current()) ; ++vmli) { - //printf(" adding %s\n",vmd->name().data()); - vmd->addListReference(def); + MemberDefMutable *vmdm = MemberDef::make_mutable(vmd); + if (vmdm) + { + //printf(" adding %s\n",vmd->name().data()); + vmdm->addListReference(def); + } } } } @@ -986,10 +1012,14 @@ void MemberList::addListReferences(Definition *def) void MemberList::findSectionsInDocumentation(const Definition *d) { MemberListIterator mli(*this); - MemberDef *md; - for ( ; (md=mli.current()) ; ++mli) + MemberDef *imd; + for ( ; (imd=mli.current()) ; ++mli) { - md->findSectionsInDocumentation(); + MemberDefMutable *md = MemberDef::make_mutable(imd); + if (md) + { + md->findSectionsInDocumentation(); + } } if (memberGroupList) { @@ -1068,25 +1098,33 @@ QCString MemberList::listTypeAsString(MemberListType type) void MemberList::writeTagFile(FTextStream &tagFile) { MemberListIterator mli(*this); - MemberDef *md; - for ( ; (md=mli.current()) ; ++mli) + MemberDef *imd; + for ( ; (imd=mli.current()) ; ++mli) { - if (md->getLanguage()!=SrcLangExt_VHDL) + MemberDefMutable *md = MemberDef::make_mutable(imd); + if (md) { - md->writeTagFile(tagFile); - if (md->memberType()==MemberType_Enumeration && md->enumFieldList() && !md->isStrong()) + if (md->getLanguage()!=SrcLangExt_VHDL) { - MemberListIterator vmli(*md->enumFieldList()); - MemberDef *vmd; - for ( ; (vmd=vmli.current()) ; ++vmli) + md->writeTagFile(tagFile); + if (md->memberType()==MemberType_Enumeration && md->enumFieldList() && !md->isStrong()) { - vmd->writeTagFile(tagFile); + MemberListIterator vmli(*md->enumFieldList()); + MemberDef *ivmd; + for ( ; (ivmd=vmli.current()) ; ++vmli) + { + MemberDefMutable *vmd = MemberDef::make_mutable(ivmd); + if (vmd) + { + vmd->writeTagFile(tagFile); + } + } } } - } - else - { - VhdlDocGen::writeTagFile(md,tagFile); + else + { + VhdlDocGen::writeTagFile(md,tagFile); + } } } if (memberGroupList) diff --git a/src/memberlist.h b/src/memberlist.h index b8c723b..7ee8925 100644 --- a/src/memberlist.h +++ b/src/memberlist.h @@ -81,7 +81,7 @@ class MemberList : private QList<MemberDef> bool showEnumValues=FALSE,bool showInline=FALSE) const; void writeSimpleDocumentation(OutputList &ol,const Definition *container) const; void writeDocumentationPage(OutputList &ol, - const char *scopeName, const Definition *container) const; + const char *scopeName, const DefinitionMutable *container) const; void writeTagFile(FTextStream &); bool declVisible() const; void addMemberGroup(MemberGroup *mg); diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index 9ff63c2..6e2cdf8 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -35,7 +35,7 @@ //------------------------------------------------------------------ -class NamespaceDefImpl : public DefinitionImpl, public NamespaceDef +class NamespaceDefImpl : public DefinitionImpl, public NamespaceDefMutable { public: NamespaceDefImpl(const char *defFileName,int defLine,int defColumn, @@ -143,7 +143,7 @@ class NamespaceDefImpl : public DefinitionImpl, public NamespaceDef bool m_inline = false; }; -NamespaceDef *createNamespaceDef(const char *defFileName,int defLine,int defColumn, +NamespaceDefMutable *createNamespaceDef(const char *defFileName,int defLine,int defColumn, const char *name,const char *ref, const char *refFile,const char*type, bool isPublished) @@ -169,18 +169,14 @@ class NamespaceDefAliasImpl : public DefinitionAliasImpl, public NamespaceDef { return getNSAlias()->anchor(); } virtual int numDocMembers() const { return getNSAlias()->numDocMembers(); } - virtual void addUsingDirective(const NamespaceDef *nd) {} virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const { return getNSAlias()->getUsedNamespaces(); } - virtual void addUsingDeclaration(const ClassDef *cd) {} virtual LinkedRefMap<const ClassDef> getUsedClasses() const { return getNSAlias()->getUsedClasses(); } - virtual void combineUsingRelations() {} virtual QCString displayName(bool b=TRUE) const { return getNSAlias()->displayName(b); } virtual QCString localName() const { return getNSAlias()->localName(); } - virtual void setInline(bool isInline) { } virtual bool isConstantGroup() const { return getNSAlias()->isConstantGroup(); } virtual bool isModule() const @@ -222,26 +218,6 @@ class NamespaceDefAliasImpl : public DefinitionAliasImpl, public NamespaceDef virtual QCString compoundTypeString() const { return getNSAlias()->compoundTypeString(); } - // --- setters/actions - virtual void setMetaData(const QCString &m) {} - virtual void insertUsedFile(FileDef *fd) { } - virtual void writeDocumentation(OutputList &ol) {} - virtual void writeMemberPages(OutputList &ol) {} - virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const {} - virtual void writeTagFile(FTextStream &) {} - virtual void insertClass(const ClassDef *cd) {} - virtual void insertNamespace(const NamespaceDef *nd) {} - virtual void insertMember(MemberDef *md) {} - virtual void computeAnchors() {} - virtual void countMembers() {} - virtual void addMembersToMemberGroup() {} - virtual void distributeMemberGroupDocumentation() {} - virtual void findSectionsInDocumentation() {} - virtual void sortMemberLists() {} - virtual void addInnerCompound(const Definition *d) {} - virtual void addListReferences() {} - virtual void setFileName(const QCString &fn) {} - void setVisited(bool v) { m_visited = v; } bool isVisited() const { return m_visited; } @@ -467,6 +443,7 @@ void NamespaceDefImpl::insertMember(MemberDef *md) //printf("%s::insertMember(%s) isInline=%d hasDocs=%d\n",qPrint(name()),qPrint(md->name()), // isInline(),hasDocumentation()); if (md->isHidden()) return; + MemberDefMutable *mdm = MemberDef::make_mutable(md); // if this is an inline namespace that is not documented, then insert the // member in the parent scope instead @@ -477,16 +454,25 @@ void NamespaceDefImpl::insertMember(MemberDef *md) { if (outerScope->definitionType()==Definition::TypeNamespace) { - NamespaceDef *nd = dynamic_cast<NamespaceDef*>(outerScope); - nd->insertMember(md); - md->setNamespace(nd); + NamespaceDefMutable *nd = NamespaceDef::make_mutable(dynamic_cast<NamespaceDef*>(outerScope)); + if (nd) + { + nd->insertMember(md); + if (mdm) + { + mdm->setNamespace(nd); + } + } } else if (outerScope->definitionType()==Definition::TypeFile) { FileDef *fd = dynamic_cast<FileDef*>(outerScope); fd->insertMember(md); - md->setFileDef(fd); - md->setOuterScope(fd); + if (mdm) + { + mdm->setFileDef(fd); + mdm->setOuterScope(fd); + } } } } @@ -556,7 +542,11 @@ void NamespaceDefImpl::insertMember(MemberDef *md) if (outerScope->definitionType()==Definition::TypeNamespace) { aliasMd.reset(createMemberDefAlias(outerScope,md)); - dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd.get()); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(dynamic_cast<NamespaceDef*>(outerScope)); + if (ndm) + { + ndm->insertMember(aliasMd.get()); + } } else if (outerScope->definitionType()==Definition::TypeFile) { @@ -1300,7 +1290,11 @@ void NamespaceDefImpl::combineUsingRelations() LinkedRefMap<const NamespaceDef> usingDirList = m_usingDirList; for (auto &nd : usingDirList) { - const_cast<NamespaceDef*>(nd)->combineUsingRelations(); + NamespaceDefMutable *ndm = NamespaceDef::make_mutable(nd); + if (ndm) + { + ndm->combineUsingRelations(); + } } for (auto &nd : usingDirList) @@ -1445,7 +1439,11 @@ void NamespaceDefImpl::addMemberToList(MemberListType lt,MemberDef *md) if (ml->listType()&MemberListType_declarationLists) { - md->setSectionList(this,ml); + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->setSectionList(this,ml); + } } } diff --git a/src/namespacedef.h b/src/namespacedef.h index 16b34a0..8ce0ef1 100644 --- a/src/namespacedef.h +++ b/src/namespacedef.h @@ -31,6 +31,7 @@ class MemberDef; class MemberGroupSDict; class NamespaceSDict; class FTextStream; +class NamespaceDefMutable; /** An abstract interface of a namespace symbol. */ class NamespaceDef : virtual public Definition @@ -38,54 +39,29 @@ class NamespaceDef : virtual public Definition public: virtual ~NamespaceDef() {} virtual DefType definitionType() const = 0; - virtual QCString getOutputFileBase() const = 0; - virtual QCString anchor() const = 0; - virtual void insertUsedFile(FileDef *fd) = 0; - virtual void writeDocumentation(OutputList &ol) = 0; - virtual void writeMemberPages(OutputList &ol) = 0; - virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0; - virtual void writeTagFile(FTextStream &) = 0; + static NamespaceDefMutable *make_mutable(const NamespaceDef *); - virtual void insertClass(const ClassDef *cd) = 0; - virtual void insertNamespace(const NamespaceDef *nd) = 0; - virtual void insertMember(MemberDef *md) = 0; // md cannot be const, since setSectionList is called on it - - virtual void computeAnchors() = 0; - virtual void countMembers() = 0; + // ---- getters + virtual QCString getOutputFileBase() const = 0; + virtual QCString anchor() const = 0; virtual int numDocMembers() const = 0; - virtual void addUsingDirective(const NamespaceDef *nd) = 0; virtual LinkedRefMap<const NamespaceDef> getUsedNamespaces() const = 0; - virtual void addUsingDeclaration(const ClassDef *cd) = 0; virtual LinkedRefMap<const ClassDef> getUsedClasses() const = 0; - virtual void combineUsingRelations() = 0; virtual QCString displayName(bool=TRUE) const = 0; virtual QCString localName() const = 0; - virtual void setInline(bool isInline) = 0; - virtual bool isConstantGroup() const = 0; virtual bool isModule() const = 0; virtual bool isLibrary() const = 0; virtual bool isInline() const = 0; - virtual bool isLinkableInProject() const = 0; virtual bool isLinkable() const = 0; virtual bool hasDetailedDescription() const = 0; - virtual void addMembersToMemberGroup() = 0; - virtual void distributeMemberGroupDocumentation() = 0; - virtual void findSectionsInDocumentation() = 0; - virtual void sortMemberLists() = 0; - virtual const Definition *findInnerCompound(const char *name) const = 0; - virtual void addInnerCompound(const Definition *d) = 0; - virtual void addListReferences() = 0; - virtual void setFileName(const QCString &fn) = 0; - virtual bool subGrouping() const = 0; - virtual MemberList *getMemberList(MemberListType lt) const = 0; virtual const QList<MemberList> &getMemberLists() const = 0; - virtual MemberDef *getMemberByName(const QCString &) const = 0; + virtual MemberDef *getMemberByName(const QCString &) const = 0; /*! Returns the user defined member groups */ virtual MemberGroupSDict *getMemberGroupSDict() const = 0; @@ -108,13 +84,45 @@ class NamespaceDef : virtual public Definition virtual QCString title() const = 0; virtual QCString compoundTypeString() const = 0; - virtual void setMetaData(const QCString &m) = 0; + // --- visited administation virtual void setVisited(bool v) = 0; virtual bool isVisited() const = 0; }; +class NamespaceDefMutable : virtual public DefinitionMutable, virtual public NamespaceDef +{ + public: + + // --- setters/actions + virtual void setMetaData(const QCString &m) = 0; + virtual void insertUsedFile(FileDef *fd) = 0; + virtual void writeDocumentation(OutputList &ol) = 0; + virtual void writeMemberPages(OutputList &ol) = 0; + virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const = 0; + virtual void writeTagFile(FTextStream &) = 0; + virtual void insertClass(const ClassDef *cd) = 0; + virtual void insertNamespace(const NamespaceDef *nd) = 0; + virtual void insertMember(MemberDef *md) = 0; // md cannot be const, since setSectionList is called on it + virtual void computeAnchors() = 0; + virtual void countMembers() = 0; + virtual void addMembersToMemberGroup() = 0; + virtual void distributeMemberGroupDocumentation() = 0; + virtual void findSectionsInDocumentation() = 0; + virtual void sortMemberLists() = 0; + virtual void addInnerCompound(const Definition *d) = 0; + virtual void addListReferences() = 0; + virtual void setFileName(const QCString &fn) = 0; + virtual void combineUsingRelations() = 0; + virtual void addUsingDirective(const NamespaceDef *nd) = 0; + virtual void addUsingDeclaration(const ClassDef *cd) = 0; + virtual void setInline(bool isInline) = 0; +}; + +inline NamespaceDefMutable *NamespaceDef::make_mutable(const NamespaceDef *nd) +{ return dynamic_cast<NamespaceDefMutable*>(const_cast<NamespaceDef*>(nd)); } + /** Factory method to create new NamespaceDef instance */ -NamespaceDef *createNamespaceDef(const char *defFileName,int defLine,int defColumn, +NamespaceDefMutable *createNamespaceDef(const char *defFileName,int defLine,int defColumn, const char *name,const char *ref=0, const char *refFile=0,const char*type=0, bool isPublished=false); diff --git a/src/pagedef.cpp b/src/pagedef.cpp index 12a7bdc..15f4932 100644 --- a/src/pagedef.cpp +++ b/src/pagedef.cpp @@ -128,15 +128,18 @@ void PageDefImpl::addInnerCompound(const Definition *const_def) { Definition *def = const_cast<Definition*>(const_def); // uck: fix me PageDef *pd = dynamic_cast<PageDef*>(def); - m_subPageDict->append(pd->name(),pd); - def->setOuterScope(this); - if (this==Doxygen::mainPage) + if (pd) { - pd->setNestingLevel(m_nestingLevel); - } - else - { - pd->setNestingLevel(m_nestingLevel+1); + m_subPageDict->append(pd->name(),pd); + pd->setOuterScope(this); + if (this==Doxygen::mainPage) + { + pd->setNestingLevel(m_nestingLevel); + } + else + { + pd->setNestingLevel(m_nestingLevel+1); + } } } } @@ -209,7 +212,11 @@ void PageDefImpl::writeDocumentation(OutputList &ol) { if (getOuterScope()!=Doxygen::globalScope && !Config_getBool(DISABLE_INDEX)) { - getOuterScope()->writeNavigationPath(ol); + DefinitionMutable *outerScope = Definition::make_mutable(getOuterScope()); + if (outerScope) + { + outerScope->writeNavigationPath(ol); + } } ol.endQuickIndices(); } diff --git a/src/pagedef.h b/src/pagedef.h index a1f08a5..dbd1ef1 100644 --- a/src/pagedef.h +++ b/src/pagedef.h @@ -24,7 +24,7 @@ class OutputList; class FTextStream; /** @brief A model of a page symbol. */ -class PageDef : virtual public Definition +class PageDef : virtual public DefinitionMutable { public: virtual ~PageDef() {} diff --git a/src/pycode.l b/src/pycode.l index 66d2149..70a0a51 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -488,7 +488,11 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU {FLOWKW} { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); + MemberDefMutable *mdm = MemberDef::make_mutable(yyextra->currentMemberDef); + if (mdm) + { + mdm->incrementFlowKeyWordCount(); + } } startFontClass(yyscanner,"keywordflow"); codify(yyscanner,yytext); @@ -529,7 +533,11 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU {FLOWKW} { if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction()) { - yyextra->currentMemberDef->incrementFlowKeyWordCount(); + MemberDefMutable *mdm = MemberDef::make_mutable(yyextra->currentMemberDef); + if (mdm) + { + mdm->incrementFlowKeyWordCount(); + } } startFontClass(yyscanner,"keywordflow"); codifyLines(yyscanner,yytext); @@ -1217,7 +1225,7 @@ static bool getLinkInScope(yyscan_t yyscanner, if (yyextra->currentDefinition && yyextra->currentMemberDef && md!=yyextra->currentMemberDef && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } //printf("d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data()); @@ -1327,7 +1335,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (d && d->isLinkable() && md->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,const_cast<MemberDef*>(md)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(md)); } } } @@ -1354,7 +1362,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (d && d->isLinkable() && mmd->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,mmd); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(mmd)); } return; } @@ -1377,7 +1385,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner, if (d && d->isLinkable() && mmd->isLinkable() && yyextra->currentMemberDef && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,mmd); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(mmd)); } return; } @@ -1463,7 +1471,7 @@ static bool findMemberLink(yyscan_t yyscanner, { if (yyextra->currentMemberDef && yyextra->collectXRefs) { - addDocCrossReference(yyextra->currentMemberDef,dynamic_cast<MemberDef*>(sym)); + addDocCrossReference(MemberDef::make_mutable(yyextra->currentMemberDef),MemberDef::make_mutable(dynamic_cast<MemberDef*>(sym))); } } DBG_CTX((stderr,"cd=%s thisCd=%s\n",cd?cd->name().data():"<none>",thisCd?thisCd->name().data():"<none>")); diff --git a/src/symbolresolver.cpp b/src/symbolresolver.cpp index 042a832..7cd6115 100644 --- a/src/symbolresolver.cpp +++ b/src/symbolresolver.cpp @@ -607,10 +607,14 @@ done: //printf("setting cached typedef %p in result %p\n",md,result); //printf("==> %s (%s,%d)\n",result->name().data(),result->getDefFileName().data(),result->getDefLine()); //printf("*pResolvedType=%s\n",pResolvedType?pResolvedType->data():"<none>"); - const_cast<MemberDef*>(md)->cacheTypedefVal(result, + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm) + { + mdm->cacheTypedefVal(result, pTemplSpec ? *pTemplSpec : QCString(), pResolvedType ? *pResolvedType : QCString() ); + } } m_resolvedTypedefs.erase(typedef_it); // remove from the trace list diff --git a/src/symbolresolver.h b/src/symbolresolver.h index e00569d..edbf6fd 100644 --- a/src/symbolresolver.h +++ b/src/symbolresolver.h @@ -18,9 +18,9 @@ #include <memory> #include "qcstring.h" +#include "classdef.h" class Definition; -class ClassDef; class FileDef; class MemberDef; @@ -39,14 +39,25 @@ class SymbolResolver * @param scope The scope to search from. * @param name The name of the symbol. * @param maybeUnlinkable include unlinkable symbols in the search. - * @param myBeHidden include hidden symbols in the search. + * @param mayBeHidden include hidden symbols in the search. * @note As a result of this call the getters getTypedef(), * getTemplateSpec(), and getResolvedType() are set as well. */ const ClassDef *resolveClass(const Definition *scope, const char *name, bool maybeUnlinkable=false, - bool myBeHidden=false); + bool mayBeHidden=false); + + /** Wrapper around resolveClass that returns a mutable interface to + * the class object or a nullptr if the symbol is immutable. + */ + ClassDefMutable *resolveClassMutable(const Definition *scope, + const char *name, + bool mayBeUnlinkable=false, + bool mayBeHidden=false) + { + return ClassDef::make_mutable(resolveClass(scope,name,mayBeUnlinkable,mayBeHidden)); + } /** Checks if symbol \a item is accessible from within \a scope. * @returns -1 if \a item is not accessible or a number indicating how diff --git a/src/util.cpp b/src/util.cpp index 3218621..39bdc94 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1228,6 +1228,7 @@ QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool include // compute the HTML anchors for a list of members +// TODO: make member of MemberList void setAnchors(MemberList *ml) { //int count=0; @@ -1236,17 +1237,10 @@ void setAnchors(MemberList *ml) MemberDef *md; for (;(md=mli.current());++mli) { - if (!md->isReference()) + MemberDefMutable *mdm = MemberDef::make_mutable(md); + if (mdm && !md->isReference()) { - //QCString anchor; - //if (groupId==-1) - // anchor.sprintf("%c%d",id,count++); - //else - // anchor.sprintf("%c%d_%d",id,groupId,count++); - //if (cd) anchor.prepend(escapeCharsInString(cd->name(),FALSE)); - md->setAnchor(); - //printf("setAnchors(): Member %s outputFileBase=%s anchor %s result %s\n", - // md->name().data(),md->getOutputFileBase().data(),anchor.data(),md->anchor().data()); + mdm->setAnchor(); } } } @@ -2298,7 +2292,6 @@ static void findMembersWithSpecificName(const MemberName *mn, bool checkStatics, const FileDef *currentFile, bool checkCV, - const char *forceTagFile, QList<MemberDef> &members) { //printf(" Function with global scope name '%s' args='%s'\n", @@ -2327,7 +2320,7 @@ static void findMembersWithSpecificName(const MemberName *mn, Doxygen::globalScope,fd,argList_p.get(), checkCV); } - if (match && (forceTagFile==0 || md->getReference()==forceTagFile)) + if (match) { //printf("Found match!\n"); members.append(md); @@ -2368,8 +2361,7 @@ bool getDefs(const QCString &scName, const GroupDef *&gd, bool forceEmptyScope, const FileDef *currentFile, - bool checkCV, - const char *forceTagFile + bool checkCV ) { fd=0, md=0, cd=0, nd=0, gd=0; @@ -2468,7 +2460,7 @@ bool getDefs(const QCString &scName, //printf("match=%d\n",match); if (match) { - ClassDef *mcd=mmd->getClassDef(); + const ClassDef *mcd=mmd->getClassDef(); if (mcd) { int m=minClassDistance(fcd,mcd); @@ -2491,7 +2483,7 @@ bool getDefs(const QCString &scName, MemberDef *mmd = mmd_p.get(); //if (mmd->isLinkable()) //{ - ClassDef *mcd=mmd->getClassDef(); + const ClassDef *mcd=mmd->getClassDef(); //printf(" >Class %s found\n",mcd->name().data()); if (mcd) { @@ -2765,11 +2757,11 @@ bool getDefs(const QCString &scName, { QList<MemberDef> members; // search for matches with strict static checking - findMembersWithSpecificName(mn,args,TRUE,currentFile,checkCV,forceTagFile,members); + findMembersWithSpecificName(mn,args,TRUE,currentFile,checkCV,members); if (members.count()==0) // nothing found { // search again without strict static checking - findMembersWithSpecificName(mn,args,FALSE,currentFile,checkCV,forceTagFile,members); + findMembersWithSpecificName(mn,args,FALSE,currentFile,checkCV,members); } //printf("found %d members\n",members.count()); if (members.count()!=1 && args && !qstrcmp(args,"()")) @@ -3560,12 +3552,15 @@ static void initBaseClassHierarchy(const BaseClassList &bcl) { for (const auto &bcd : bcl) { - ClassDef *cd = bcd.classDef; - if (cd->baseClasses().empty()) // no base classes => new root + ClassDefMutable *cd = ClassDef::make_mutable(bcd.classDef); + if (cd) { - initBaseClassHierarchy(cd->baseClasses()); + if (cd->baseClasses().empty()) // no base classes => new root + { + initBaseClassHierarchy(cd->baseClasses()); + } + cd->setVisited(FALSE); } - cd->setVisited(FALSE); } } //---------------------------------------------------------------------------- @@ -3604,8 +3599,12 @@ void initClassHierarchy(ClassSDict *cl) ClassDef *cd; for ( ; (cd=cli.current()); ++cli) { - cd->setVisited(FALSE); - initBaseClassHierarchy(cd->baseClasses()); + ClassDefMutable *cdm = ClassDef::make_mutable(cd); + if (cdm) + { + cdm->setVisited(FALSE); + initBaseClassHierarchy(cd->baseClasses()); + } } } @@ -6869,7 +6868,7 @@ bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile) ); } -void addDocCrossReference(MemberDef *src,MemberDef *dst) +void addDocCrossReference(MemberDefMutable *src,MemberDefMutable *dst) { //printf("--> addDocCrossReference src=%s,dst=%s\n",src->name().data(),dst->name().data()); if (dst->isTypedef() || dst->isEnumerate()) return; // don't add types @@ -6878,12 +6877,12 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) ) { dst->addSourceReferencedBy(src); - MemberDef *mdDef = dst->memberDefinition(); + MemberDefMutable *mdDef = MemberDef::make_mutable(dst->memberDefinition()); if (mdDef) { mdDef->addSourceReferencedBy(src); } - MemberDef *mdDecl = dst->memberDeclaration(); + MemberDefMutable *mdDecl = MemberDef::make_mutable(dst->memberDeclaration()); if (mdDecl) { mdDecl->addSourceReferencedBy(src); @@ -6894,12 +6893,12 @@ void addDocCrossReference(MemberDef *src,MemberDef *dst) ) { src->addSourceReferences(dst); - MemberDef *mdDef = src->memberDefinition(); + MemberDefMutable *mdDef = MemberDef::make_mutable(src->memberDefinition()); if (mdDef) { mdDef->addSourceReferences(dst); } - MemberDef *mdDecl = src->memberDeclaration(); + MemberDefMutable *mdDecl = MemberDef::make_mutable(src->memberDeclaration()); if (mdDecl) { mdDecl->addSourceReferences(dst); @@ -34,6 +34,7 @@ #include "classdef.h" #include "arguments.h" #include "containers.h" +#include "namespacedef.h" //-------------------------------------------------------------------- @@ -152,8 +153,7 @@ bool getDefs(const QCString &scopeName, const GroupDef *&gd, bool forceEmptyScope=FALSE, const FileDef *currentFile=0, - bool checkCV=FALSE, - const char *forceTagFile=0 + bool checkCV=FALSE ); QCString getFileFilter(const char* name,bool isSourceCode); @@ -205,8 +205,16 @@ QCString selectBlock(const QCString& s,const QCString &name,bool which); QCString resolveDefines(const char *n); ClassDef *getClass(const char *key); +inline ClassDefMutable *getClassMutable(const char *key) +{ + return ClassDef::make_mutable(getClass(key)); +} NamespaceDef *getResolvedNamespace(const char *key); +inline NamespaceDefMutable *getResolvedNamespaceMutable(const char *key) +{ + return NamespaceDef::make_mutable(getResolvedNamespace(key)); +} FileDef *findFileDef(const FileNameLinkedMap *fnMap,const char *n, bool &ambig); @@ -456,7 +464,7 @@ QCString getDotImageExtension(); bool fileVisibleInIndex(const FileDef *fd,bool &genSourceFile); -void addDocCrossReference(MemberDef *src,MemberDef *dst); +void addDocCrossReference(MemberDefMutable *src,MemberDefMutable *dst); uint getUtf8Code( const QCString& s, int idx ); uint getUtf8CodeToLower( const QCString& s, int idx ); diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index ddb22f6..b7b3de8 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -71,7 +71,7 @@ static QDict<QCString> g_vhdlKeyDict3(17,FALSE); static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief); static void writeUCFLink(const MemberDef* mdef,OutputList &ol); -static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst, +static void addInstance(ClassDefMutable* entity, ClassDefMutable* arch, ClassDefMutable *inst, const std::shared_ptr<Entry> &cur); //---------- create svg ------------------------------------------------------------- @@ -1712,7 +1712,7 @@ void VhdlDocGen::writeVhdlDeclarations(const MemberList* ml, } -void VhdlDocGen::correctMemberProperties(MemberDef *md) +void VhdlDocGen::correctMemberProperties(MemberDefMutable *md) { if (qstrcmp(md->argsString(),"package")==0) { @@ -1844,7 +1844,7 @@ bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definit return hasParams; } -void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile) +void VhdlDocGen::writeTagFile(MemberDefMutable *mdef,FTextStream &tagFile) { tagFile << " <member kind=\""; if (VhdlDocGen::isGeneric(mdef)) tagFile << "generic"; @@ -1888,7 +1888,7 @@ void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile) /* writes a vhdl type declaration */ -void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, +void VhdlDocGen::writeVHDLDeclaration(const MemberDefMutable* mdef,OutputList &ol, const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, bool /*inGroup*/) { @@ -2198,24 +2198,28 @@ void VhdlDocGen::writePlainVHDLDeclarations( pack.setAutoDelete(TRUE); bool first=TRUE; - MemberDef *md; + MemberDef *imd; MemberListIterator mli(*mlist); - for ( ; (md=mli.current()); ++mli ) + for ( ; (imd=mli.current()); ++mli ) { - int mems=md->getMemberSpecifiers(); - if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) ) - { - if (first) { ol.startMemberList();first=FALSE; } - VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE); - } //if - else if (md->isBriefSectionVisible() && (mems==specifier)) + MemberDefMutable *md = MemberDef::make_mutable(imd); + if (md) { - if (!pack.find(md->name().data())) + int mems=md->getMemberSpecifiers(); + if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) ) { - if (first) ol.startMemberList(),first=FALSE; + if (first) { ol.startMemberList();first=FALSE; } VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE); - pack.append(md->name().data(),new QCString(md->name().data())); - } + } //if + else if (md->isBriefSectionVisible() && (mems==specifier)) + { + if (!pack.find(md->name().data())) + { + if (first) ol.startMemberList(),first=FALSE; + VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE); + pack.append(md->name().data(),new QCString(md->name().data())); + } + } //if } //if } //for if (!first) ol.endMemberList(); @@ -2349,7 +2353,7 @@ void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& -void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname) +void VhdlDocGen::writeSource(const MemberDefMutable *mdef,OutputList& ol,const QCString & cname) { auto intf = Doxygen::parserManager->getCodeParser(".vhd"); // pIntf->resetCodeParserState(); @@ -2679,10 +2683,10 @@ void VhdlDocGen::computeVhdlComponentRelations() entity=cur->type; } - ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity); + ClassDefMutable *classEntity= ClassDef::make_mutable(VhdlDocGen::findVhdlClass(entity.data())); inst=VhdlDocGen::getIndexWord(cur->args.data(),0); - ClassDef *cd=Doxygen::classSDict->find(inst); - ClassDef *ar=Doxygen::classSDict->find(cur->args); + ClassDefMutable *cd=ClassDef::make_mutable(Doxygen::classSDict->find(inst)); + ClassDefMutable *ar=ClassDef::make_mutable(Doxygen::classSDict->find(cur->args)); if (cd==0) { @@ -2697,8 +2701,8 @@ void VhdlDocGen::computeVhdlComponentRelations() } -static void addInstance(ClassDef* classEntity, ClassDef* ar, - ClassDef *cd , const std::shared_ptr<Entry> &cur) +static void addInstance(ClassDefMutable* classEntity, ClassDefMutable* ar, + ClassDefMutable *cd , const std::shared_ptr<Entry> &cur) { QCString bName,n1; @@ -2734,7 +2738,7 @@ static void addInstance(ClassDef* classEntity, ClassDef* ar, ferr: QCString uu=cur->name; - std::unique_ptr<MemberDef> md { createMemberDef( + std::unique_ptr<MemberDefMutable> md { createMemberDef( ar->getDefFileName(), cur->startLine,cur->startColumn, n1,uu,uu, 0, Public, Normal, cur->stat,Member, @@ -2776,22 +2780,22 @@ ferr: } -void VhdlDocGen::writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol ,const MemberDef *mdef) +void VhdlDocGen::writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol ,const MemberDefMutable *mdef) { - int i=mdef->name().find('~'); - if(i>0){ - //sets the real record member name - const_cast<MemberDef*>(mdef)->setName(mdef->name().left(i).data()); - } - - writeLink(mdef,ol); - ol.startBold(); - ol.insertMemberAlign(); - if (!ltype.isEmpty()){ - VhdlDocGen::formatString(ltype,ol,mdef); - } - ol.endBold(); + int i=mdef->name().find('~'); + if (i>0) + { + //sets the real record member name + const_cast<MemberDefMutable*>(mdef)->setName(mdef->name().left(i).data()); + } + writeLink(mdef,ol); + ol.startBold(); + ol.insertMemberAlign(); + if (!ltype.isEmpty()){ + VhdlDocGen::formatString(ltype,ol,mdef); + } + ol.endBold(); } diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index 5442f88..ec25380 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -31,6 +31,7 @@ class Entry; class ClassDef; class MemberList; class MemberDef; +class MemberDefMutable; class FTextStream; class OutputList; class Definition; @@ -144,7 +145,7 @@ class VhdlDocGen static QCString getClassTitle(const ClassDef*); static void writeInlineClassLink(const ClassDef*, OutputList &ol); - static void writeTagFile(MemberDef *mdef,FTextStream &tagFile); + static void writeTagFile(MemberDefMutable *mdef,FTextStream &tagFile); static bool isConstraint(const MemberDef *mdef); static bool isConfig(const MemberDef *mdef); @@ -190,7 +191,7 @@ class VhdlDocGen static void writeVhdlDeclarations(const MemberList*,OutputList&,const GroupDef*,const ClassDef*,const FileDef*,const NamespaceDef*); - static void writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol, + static void writeVHDLDeclaration(const MemberDefMutable* mdef,OutputList &ol, const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd, bool inGroup); @@ -217,9 +218,9 @@ class VhdlDocGen static ClassDef* findArchitecture(const ClassDef *cd); static ClassDef* findArchitecture(QCString identifier, QCString entity_name); - static void correctMemberProperties(MemberDef *md); + static void correctMemberProperties(MemberDefMutable *md); - static void writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname); + static void writeSource(const MemberDefMutable *mdef,OutputList& ol,const QCString & cname); static QCString parseForConfig(QCString & entity,QCString & arch); static QCString parseForBinding(QCString & entity,QCString & arch); @@ -252,7 +253,7 @@ class VhdlDocGen static void writeVhdlLink(const ClassDef* cdd ,OutputList& ol,QCString& type,QCString& name,QCString& beh); static void writeStringLink(const MemberDef *mdef,QCString mem,OutputList& ol); static void writeRecUnitDocu( const MemberDef *md, OutputList& ol,QCString largs); - static void writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol ,const MemberDef *mdef); + static void writeRecordUnit(QCString & largs,QCString & ltype,OutputList& ol,const MemberDefMutable *mdef); }; //------------------------------------------------------------------------------------------------------------------- |