diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/clangparser.cpp | 8 | ||||
-rw-r--r-- | src/classdef.cpp | 62 | ||||
-rw-r--r-- | src/code.l | 40 | ||||
-rw-r--r-- | src/context.cpp | 36 | ||||
-rw-r--r-- | src/doxygen.cpp | 1926 | ||||
-rw-r--r-- | src/doxygen.h | 6 | ||||
-rw-r--r-- | src/fortrancode.l | 193 | ||||
-rw-r--r-- | src/membername.cpp | 43 | ||||
-rw-r--r-- | src/membername.h | 42 | ||||
-rw-r--r-- | src/namespacedef.cpp | 138 | ||||
-rw-r--r-- | src/pre.l | 15 | ||||
-rw-r--r-- | src/searchindex.cpp | 20 | ||||
-rw-r--r-- | src/util.cpp | 80 |
13 files changed, 1204 insertions, 1405 deletions
diff --git a/src/clangparser.cpp b/src/clangparser.cpp index aece641..1ff30b0 100644 --- a/src/clangparser.cpp +++ b/src/clangparser.cpp @@ -731,16 +731,14 @@ void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd, void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text) { - MemberName *mn=Doxygen::functionNameSDict->find(text); + MemberName *mn=Doxygen::functionNameLinkedMap->find(text); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isDefine()) { - writeMultiLineCodeLink(ol,fd,line,column,md,text); + writeMultiLineCodeLink(ol,fd,line,column,md.get(),text); return; } } diff --git a/src/classdef.cpp b/src/classdef.cpp index 95f01c1..52d2f49 100644 --- a/src/classdef.cpp +++ b/src/classdef.cpp @@ -66,8 +66,8 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual ClassDef *resolveAlias() { return this; } virtual DefType definitionType() const { return TypeClass; } virtual QCString getOutputFileBase() const; - virtual QCString getInstanceOutputFileBase() const; - virtual QCString getSourceFileBase() const; + virtual QCString getInstanceOutputFileBase() const; + virtual QCString getSourceFileBase() const; virtual QCString getReference() const; virtual bool isReference() const; virtual bool isLocal() const; @@ -149,7 +149,7 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0); virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0); - virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); + virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); virtual void insertMember(MemberDef *); virtual void insertUsedFile(FileDef *); virtual bool addExample(const char *anchor,const char *name, const char *file); @@ -2233,7 +2233,7 @@ void ClassDefImpl::writeTagFile(FTextStream &tagFile) { if (!isLinkableInProject()) return; tagFile << " <compound kind=\""; - if (isFortran() && (compoundTypeString() == "type")) + if (isFortran() && (compoundTypeString() == "type")) tagFile << "struct"; else tagFile << compoundTypeString(); @@ -3908,16 +3908,6 @@ void ClassDefImpl::mergeCategory(ClassDef *category) //printf("Existing member %s\n",srcMni->memberName()); MemberInfo *dstMi = dstMni->getFirst(); MemberInfo *srcMi = srcMni->getFirst(); - //if (dstMi) - //{ - // Protection prot = dstMi->prot; - // if (makePrivate || isExtension) - // { - // prot = Private; - // removeMemberFromLists(dstMi->memberDef); - // internalInsertMember(dstMi->memberDef,prot,FALSE); - // } - //} if (srcMi && dstMi) { combineDeclarationAndDefinition(srcMi->memberDef,dstMi->memberDef); @@ -3941,13 +3931,13 @@ void ClassDefImpl::mergeCategory(ClassDef *category) //printf("Adding '%s'\n",mi->memberDef->name().data()); Protection prot = mi->prot; //if (makePrivate) prot = Private; - MemberDef *newMd = mi->memberDef->deepCopy(); + std::unique_ptr<MemberDef> newMd { mi->memberDef->deepCopy() }; if (newMd) { //printf("Copying member %s\n",mi->memberDef->name().data()); newMd->moveTo(this); - MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited); + MemberInfo *newMi=new MemberInfo(newMd.get(),prot,mi->virt,mi->inherited); newMi->scopePath=mi->scopePath; newMi->ambigClass=mi->ambigClass; newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope; @@ -3955,29 +3945,20 @@ void ClassDefImpl::mergeCategory(ClassDef *category) // also add the newly created member to the global members list - MemberName *mn; QCString name = newMd->name(); - if ((mn=Doxygen::memberNameSDict->find(name))) - { - mn->append(newMd); - } - else - { - mn = new MemberName(newMd->name()); - mn->append(newMd); - Doxygen::memberNameSDict->append(name,mn); - } - + MemberName *mn = Doxygen::memberNameLinkedMap->add(name); + newMd->setCategory(category); newMd->setCategoryRelation(mi->memberDef); - mi->memberDef->setCategoryRelation(newMd); + mi->memberDef->setCategoryRelation(newMd.get()); if (makePrivate || isExtension) { - newMd->makeImplementationDetail(); + newMd->makeImplementationDetail(); } - internalInsertMember(newMd,prot,FALSE); + internalInsertMember(newMd.get(),prot,FALSE); + mn->push_back(std::move(newMd)); } - } + } // add it to the dictionary dstMnd->append(newMni->memberName(),newMni); @@ -4276,8 +4257,8 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t ArgumentList actualArguments; stringToArgumentList(getLanguage(),templSpec,actualArguments); MemberDef *md = mi->memberDef; - MemberDef *imd = md->createTemplateInstanceMember( - cd->templateArguments(),actualArguments); + std::unique_ptr<MemberDef> imd { md->createTemplateInstanceMember( + cd->templateArguments(),actualArguments) }; //printf("%s->setMemberClass(%p)\n",imd->name().data(),this); imd->setMemberClass(this); imd->setTemplateMaster(md); @@ -4286,19 +4267,14 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *t imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine()); imd->setMemberSpecifiers(md->getMemberSpecifiers()); imd->setMemberGroupId(md->getMemberGroupId()); - insertMember(imd); + insertMember(imd.get()); //printf("Adding member=%s %s%s to class %s templSpec %s\n", // imd->typeString(),imd->name().data(),imd->argsString(), // imd->getClassDef()->name().data(),templSpec); // insert imd in the list of all members //printf("Adding member=%s class=%s\n",imd->name().data(),name().data()); - MemberName *mn = Doxygen::memberNameSDict->find(imd->name()); - if (mn==0) - { - mn = new MemberName(imd->name()); - Doxygen::memberNameSDict->append(imd->name(),mn); - } - mn->append(imd); + MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name()); + mn->push_back(std::move(imd)); } } } @@ -4836,7 +4812,7 @@ void ClassDefImpl::writeMemberDeclarations(OutputList &ol,MemberListType lt,cons MemberList * ml = getMemberList(lt); MemberList * ml2 = getMemberList((MemberListType)lt2); if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function - { + { static const ClassDef *cdef; if (cdef!=this) { // only one inline link @@ -2759,24 +2759,22 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) } // look for a global member - if ((mn=Doxygen::functionNameSDict->find(name))) + if ((mn=Doxygen::functionNameLinkedMap->find(name))) { //printf("global var '%s'\n",name.data()); - if (mn->count()==1) // global defined only once + if (mn->size()==1) // global defined only once { - MemberDef *md=mn->getFirst(); + const std::unique_ptr<MemberDef> &md=mn->front(); if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef) { yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); - return md; + return md.get(); } return 0; } - else if (mn->count()>1) // global defined more than once + else if (mn->size()>1) // global defined more than once { - MemberNameIterator it(*mn); - MemberDef *md; - for (;(md=it.current());++it) + for (const auto &md : *mn) { //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n", // mn,md, @@ -2791,7 +2789,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name) { yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope())); //printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data()); - return md; + return md.get(); } } return 0; @@ -3235,7 +3233,7 @@ static void generateMemberLink(yyscan_t yyscanner, if (vcd && vcd->isLinkable()) { //printf("Found class %s for variable '%s'\n",yyextra->classScope.data(),varName.data()); - MemberName *vmn=Doxygen::memberNameSDict->find(varName); + MemberName *vmn=Doxygen::memberNameLinkedMap->find(varName); if (vmn==0) { int vi; @@ -3244,16 +3242,13 @@ static void generateMemberLink(yyscan_t yyscanner, { ClassDef *jcd = getClass(vn.left(vi)); vn=vn.right(vn.length()-vi-2); - vmn=Doxygen::memberNameSDict->find(vn); + vmn=Doxygen::memberNameLinkedMap->find(vn); //printf("Trying name '%s' scope=%s\n",vn.data(),scope.data()); if (vmn) { - MemberNameIterator vmni(*vmn); - const MemberDef *vmd; - for (;(vmd=vmni.current());++vmni) + for (const auto &vmd : *vmn) { - if (/*(vmd->isVariable() || vmd->isFunction()) && */ - vmd->getClassDef()==jcd) + if (vmd->getClassDef()==jcd) { //printf("Found variable type=%s\n",vmd->typeString()); const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); @@ -3269,12 +3264,9 @@ static void generateMemberLink(yyscan_t yyscanner, if (vmn) { //printf("There is a variable with name '%s'\n",varName); - MemberNameIterator vmni(*vmn); - const MemberDef *vmd; - for (;(vmd=vmni.current());++vmni) + for (const auto &vmd : *vmn) { - if (/*(vmd->isVariable() || vmd->isFunction()) && */ - vmd->getClassDef()==vcd) + if (vmd->getClassDef()==vcd) { //printf("Found variable type=%s\n",vmd->typeString()); const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope()); @@ -3677,14 +3669,14 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx) if (QCString(ictx->method->typeString())=="id") { // see if the method name is unique, if so we link to it - MemberName *mn=Doxygen::memberNameSDict->find(ctx->methodName); + MemberName *mn=Doxygen::memberNameLinkedMap->find(ctx->methodName); //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n", // mn==0?-1:(int)mn->count(), // ictx->method->name().data(), // ctx->methodName.data()); - if (mn && mn->count()==1) // member name unique + if (mn && mn->size()==1) // member name unique { - ctx->method = mn->getFirst(); + ctx->method = mn->front().get(); } } else diff --git a/src/context.cpp b/src/context.cpp index bc1bbc0..0577531 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -7988,21 +7988,17 @@ class GlobalsIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); if (fd && fd->isLinkableInProject() && !md->name().isEmpty() && !md->getNamespaceDef() && md->isLinkableInProject()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } @@ -8145,21 +8141,17 @@ class ClassMembersIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const ClassDef *cd = md->getClassDef(); if (cd && cd->isLinkableInProject() && cd->templateMaster()==0 && md->isLinkableInProject() && !md->name().isEmpty()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } @@ -8304,21 +8296,17 @@ class NamespaceMembersIndexContext::Private if (!listRef) { TemplateList *list = TemplateList::alloc(); - MemberName *mn; - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { const NamespaceDef *nd=md->getNamespaceDef(); if (nd && nd->isLinkableInProject() && !md->name().isEmpty() && md->isLinkableInProject()) { - if (filter==0 || (md->*filter)()) + if (filter==0 || (md.get()->*filter)()) { - list->append(MemberContext::alloc(md)); + list->append(MemberContext::alloc(md.get())); } } } diff --git a/src/doxygen.cpp b/src/doxygen.cpp index cabc5ce..c1b8745 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -120,8 +120,8 @@ extern void initResources(); ClassSDict *Doxygen::classSDict = 0; ClassSDict *Doxygen::hiddenClasses = 0; NamespaceSDict *Doxygen::namespaceSDict = 0; -MemberNameSDict *Doxygen::memberNameSDict = 0; -MemberNameSDict *Doxygen::functionNameSDict = 0; +MemberNameLinkedMap *Doxygen::memberNameLinkedMap = 0; +MemberNameLinkedMap *Doxygen::functionNameLinkedMap = 0; FileNameLinkedMap *Doxygen::inputNameLinkedMap = 0; GroupSDict *Doxygen::groupSDict = 0; PageSDict *Doxygen::pageSDict = 0; @@ -2050,12 +2050,10 @@ static MemberDef *addVariableToClass( // see if the member is already found in the same scope // (this may be the case for a static member that is initialized // outside the class) - MemberName *mn=Doxygen::memberNameSDict->find(name); + MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("md->getClassDef()=%p cd=%p type=[%s] md->typeString()=[%s]\n", // md->getClassDef(),cd,type.data(),md->typeString()); @@ -2071,11 +2069,11 @@ static MemberDef *addVariableToClass( { // Objective-C 2.0 property // turn variable into a property md->setProtection(root->protection); - cd->reclassifyMember(md,MemberType_Property); + cd->reclassifyMember(md.get(),MemberType_Property); } - addMemberDocs(root,md,def,0,FALSE,root->spec); + addMemberDocs(root,md.get(),def,0,FALSE,root->spec); //printf(" Member already found!\n"); - return md; + return md.get(); } } } @@ -2087,12 +2085,12 @@ static MemberDef *addVariableToClass( } // new member variable, typedef or enum value - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, prot,Normal,root->stat,related, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - ArgumentList(), root->metaData); + ArgumentList(), root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); // also sets outer scope (i.e. getOuterScope()) //md->setDefFile(root->fileName); @@ -2121,38 +2119,24 @@ static MemberDef *addVariableToClass( md->setArtificial(root->artificial); md->setLanguage(root->lang); md->setId(root->id); - addMemberToGroups(root,md); - //if (root->mGrpId!=-1) - //{ - // printf("memberdef %s in memberGroup %d\n",name.data(),root->mGrpId); - // md->setMemberGroup(memberGroupDict[root->mGrpId]); - // + addMemberToGroups(root,md.get()); md->setBodyDef(root->fileDef()); - //printf(" Adding member=%s\n",md->name().data()); - // add the member to the global list - if (mn) - { - mn->append(md); - } - else // new variable name - { - mn = new MemberName(name); - mn->append(md); - //printf("Adding memberName=%s\n",mn->memberName()); - //Doxygen::memberNameDict.insert(name,mn); - //Doxygen::memberNameList.append(mn); - Doxygen::memberNameSDict->append(name,mn); - // add the member to the class - } //printf(" New member adding to %s (%p)!\n",cd->name().data(),cd); - cd->insertMember(md); + cd->insertMember(md.get()); md->setRefItems(root->sli); //TODO: insert FileDef instead of filename strings. cd->insertUsedFile(root->fileDef()); root->markAsProcessed(); - return md; + + //printf(" Adding member=%s\n",md->name().data()); + // add the member to the global list + MemberDef *result = md.get(); + mn = Doxygen::memberNameLinkedMap->add(name); + mn->push_back(std::move(md)); + + return result; } //---------------------------------------------------------------------- @@ -2277,7 +2261,7 @@ static MemberDef *addVariableToFile( } def.stripPrefix("static "); - MemberName *mn=Doxygen::functionNameSDict->find(name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(name); if (mn) { //QCString nscope=removeAnonymousScopes(scope); @@ -2287,9 +2271,7 @@ static MemberDef *addVariableToFile( { nd = getResolvedNamespace(scope); } - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (!md->isAlias() && ((nd==0 && md->getNamespaceDef()==0 && md->getFileDef() && @@ -2317,7 +2299,7 @@ static MemberDef *addVariableToFile( { Debug::print(Debug::Variables,0, " variable already found: scope=%s\n",qPrint(md->getOuterScope()->name())); - addMemberDocs(root,md,def,0,FALSE,root->spec); + addMemberDocs(root,md.get(),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 @@ -2332,7 +2314,7 @@ static MemberDef *addVariableToFile( { md->setDeclFile(root->fileName,root->startLine,root->startColumn); } - return md; + return md.get(); } } } @@ -2347,12 +2329,12 @@ 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 - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,0, root->protection, Normal,root->stat,Member, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - ArgumentList(), root->metaData); + ArgumentList(), root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberSpecifiers(root->spec); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -2378,13 +2360,13 @@ static MemberDef *addVariableToFile( md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); md->setBodyDef(fd); } - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); md->setRefItems(root->sli); if (nd && !nd->isAnonymous()) { md->setNamespace(nd); - nd->insertMember(md); + nd->insertMember(md.get()); } // add member to the file (we do this even if we have already inserted @@ -2392,22 +2374,17 @@ static MemberDef *addVariableToFile( if (fd) { md->setFileDef(fd); - fd->insertMember(md); + fd->insertMember(md.get()); } - // add member definition to the list of globals - if (mn) - { - mn->append(md); - } - else - { - mn = new MemberName(name); - mn->append(md); - Doxygen::functionNameSDict->append(name,mn); - } root->markAsProcessed(); - return md; + + // add member definition to the list of globals + MemberDef *result = md.get(); + mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(md)); + + return result; } /*! See if the return type string \a type is that of a function pointer @@ -2882,10 +2859,10 @@ static void addInterfaceOrServiceToServiceOrSingleton( { fileName = root->tagInfo()->tagName; } - MemberDef *const md = createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName, root->startLine, root->startColumn, root->type, rname, "", "", root->protection, root->virt, root->stat, Member, - type, ArgumentList(), root->argList, root->metaData); + type, ArgumentList(), root->argList, root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -2917,21 +2894,9 @@ static void addInterfaceOrServiceToServiceOrSingleton( qPrint(def) ); - // add member to the global list of all members - MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(rname))) - { - mn->append(md); - } - else - { - mn = new MemberName(rname); - mn->append(md); - Doxygen::memberNameSDict->append(rname,mn); - } // add member to the class cd - cd->insertMember(md); + cd->insertMember(md.get()); // also add the member as a "base" (to get nicer diagrams) // "optional" interface/service get Protected which turns into dashed line BaseInfo base(rname, @@ -2940,9 +2905,13 @@ static void addInterfaceOrServiceToServiceOrSingleton( // add file to list of used files cd->insertUsedFile(fd); - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); root->markAsProcessed(); md->setRefItems(root->sli); + + // add member to the global list of all members + MemberName *mn = Doxygen::memberNameLinkedMap->add(rname); + mn->push_back(std::move(md)); } static void buildInterfaceAndServiceList(const Entry *root) @@ -3066,7 +3035,7 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, // ); // adding class member - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( fileName,root->startLine,root->startColumn, type,name,args,root->exception, protection,virt, @@ -3074,7 +3043,7 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, relates.isEmpty() ? Member : root->relatesType == MemberOf ? Foreign : Related, mtype,!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - root->argList, root->metaData); + root->argList, root->metaData) }; md->setTagInfo(root->tagInfo()); md->setMemberClass(cd); md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -3146,30 +3115,142 @@ static void addMethodToClass(const Entry *root,ClassDef *cd, qPrint(def) ); + // add member to the class cd + cd->insertMember(md.get()); + // add file to list of used files + cd->insertUsedFile(fd); + + addMemberToGroups(root,md.get()); + root->markAsProcessed(); + md->setRefItems(root->sli); + // add member to the global list of all members //printf("Adding member=%s class=%s\n",md->name().data(),cd->name().data()); - MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(name))) + MemberName *mn = Doxygen::memberNameLinkedMap->add(name); + mn->push_back(std::move(md)); +} + +//------------------------------------------------------------------------------------------ + +void addGlobalFunction(const Entry *root,const QCString &rname,const QCString &sc, + NamespaceDef *nd) +{ + QCString scope = sc; + Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); + //printf("New function type='%s' name='%s' args='%s' bodyLine=%d\n", + // root->type.data(),rname.data(),root->args.data(),root->bodyLine); + + // new global function + QCString name=removeRedundantWhiteSpace(rname); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + root->type,name,root->args,root->exception, + root->protection,root->virt,root->stat,Member, + MemberType_Function, + !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), + root->argList,root->metaData) }; + + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + //md->setDefFile(root->fileName); + //md->setDefLine(root->startLine); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->setDocsForDefinition(!root->proto); + md->setTypeConstraints(root->typeConstr); + //md->setBody(root->body); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->addSectionsToDefinition(root->anchors); + md->setMemberSpecifiers(root->spec); + md->setMemberGroupId(root->mGrpId); + + // 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 ) + { + //QCString nscope=removeAnonymousScopes(root->parent()->name); + QCString nscope=root->parent()->name; + if (!nscope.isEmpty()) + { + nd = getResolvedNamespace(nscope); + } + } + + if (!scope.isEmpty()) + { + QCString sep = getLanguageSpecificSeparator(root->lang); + if (sep!="::") + { + scope = substitute(scope,"::",sep); + } + scope+=sep; + } + + QCString def; + //QCString optArgs = root->argList.empty() ? QCString() : root->args; + if (!root->type.isEmpty()) { - mn->append(md); + def=root->type+" "+scope+name; //+optArgs; } else { - mn = new MemberName(name); - mn->append(md); - Doxygen::memberNameSDict->append(name,mn); + def=scope+name; //+optArgs; } + Debug::print(Debug::Functions,0, + " Global Function:\n" + " '%s' '%s'::'%s' '%s' proto=%d\n" + " def='%s'\n", + qPrint(root->type), + qPrint(root->parent()->name), + qPrint(rname), + qPrint(root->args), + root->proto, + qPrint(def) + ); + md->setDefinition(def); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + //if (root->mGrpId!=-1) + //{ + // md->setMemberGroup(memberGroupDict[root->mGrpId]); + //} - // add member to the class cd - cd->insertMember(md); - // add file to list of used files - cd->insertUsedFile(fd); - - addMemberToGroups(root,md); - root->markAsProcessed(); md->setRefItems(root->sli); + if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') + { + // add member to namespace + md->setNamespace(nd); + nd->insertMember(md.get()); + } + if (fd) + { + // add member to the file (we do this even if we have already + // inserted it into the namespace) + md->setFileDef(fd); + fd->insertMember(md.get()); + } + + addMemberToGroups(root,md.get()); + if (root->relatesType == Simple) // if this is a relatesalso command, + // allow find Member to pick it up + { + root->markAsProcessed(); // Otherwise we have finished with this entry. + } + + // add member to the list of file members + //printf("Adding member=%s\n",md->name().data()); + MemberName *mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(md)); } +//------------------------------------------------------------------------------------------ static void buildFunctionList(const Entry *root) { @@ -3280,12 +3361,11 @@ static void buildFunctionList(const Entry *root) */ bool found=FALSE; MemberName *mn; - MemberDef *md=0; - if ((mn=Doxygen::functionNameSDict->find(rname))) + MemberDef *md_found=0; + if ((mn=Doxygen::functionNameLinkedMap->find(rname))) { Debug::print(Debug::Functions,0," --> function %s already found!\n",qPrint(rname)); - MemberNameIterator mni(*mn); - for (mni.toFirst();(!found && (md=mni.current()));++mni) + for (const auto &md : *mn) { if (!md->isAlias()) { @@ -3407,7 +3487,7 @@ static void buildFunctionList(const Entry *root) // merge ingroup specifiers if (md->getGroupDef()==0 && !root->groups.empty()) { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } else if (md->getGroupDef()!=0 && root->groups.empty()) { @@ -3433,129 +3513,16 @@ static void buildFunctionList(const Entry *root) } } } + if (found) + { + md_found = md.get(); + break; + } } } if (!found) /* global function is unique with respect to the file */ { - Debug::print(Debug::Functions,0," --> new function %s found!\n",qPrint(rname)); - //printf("New function type='%s' name='%s' args='%s' bodyLine=%d\n", - // root->type.data(),rname.data(),root->args.data(),root->bodyLine); - - // new global function - QCString name=removeRedundantWhiteSpace(rname); - md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - root->type,name,root->args,root->exception, - root->protection,root->virt,root->stat,Member, - MemberType_Function, - !root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList(), - root->argList,root->metaData); - - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - //md->setDefFile(root->fileName); - //md->setDefLine(root->startLine); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->setDocsForDefinition(!root->proto); - md->setTypeConstraints(root->typeConstr); - //md->setBody(root->body); - md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->addSectionsToDefinition(root->anchors); - md->setMemberSpecifiers(root->spec); - md->setMemberGroupId(root->mGrpId); - - // 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 ) - { - //QCString nscope=removeAnonymousScopes(root->parent()->name); - QCString nscope=root->parent()->name; - if (!nscope.isEmpty()) - { - nd = getResolvedNamespace(nscope); - } - } - - if (!scope.isEmpty()) - { - QCString sep = getLanguageSpecificSeparator(root->lang); - if (sep!="::") - { - scope = substitute(scope,"::",sep); - } - scope+=sep; - } - - QCString def; - //QCString optArgs = root->argList.empty() ? QCString() : root->args; - if (!root->type.isEmpty()) - { - def=root->type+" "+scope+name; //+optArgs; - } - else - { - def=scope+name; //+optArgs; - } - Debug::print(Debug::Functions,0, - " Global Function:\n" - " '%s' '%s'::'%s' '%s' proto=%d\n" - " def='%s'\n", - qPrint(root->type), - qPrint(root->parent()->name), - qPrint(rname), - qPrint(root->args), - root->proto, - qPrint(def) - ); - md->setDefinition(def); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - //if (root->mGrpId!=-1) - //{ - // md->setMemberGroup(memberGroupDict[root->mGrpId]); - //} - - md->setRefItems(root->sli); - if (nd && !nd->name().isEmpty() && nd->name().at(0)!='@') - { - // add member to namespace - md->setNamespace(nd); - nd->insertMember(md); - } - if (fd) - { - // add member to the file (we do this even if we have already - // inserted it into the namespace) - md->setFileDef(fd); - fd->insertMember(md); - } - - // add member to the list of file members - //printf("Adding member=%s\n",md->name().data()); - if ((mn=Doxygen::functionNameSDict->find(name))) - { - mn->append(md); - } - else - { - mn = new MemberName(name); - mn->append(md); - Doxygen::functionNameSDict->append(name,mn); - } - addMemberToGroups(root,md); - if (root->relatesType == Simple) // if this is a relatesalso command, - // allow find Member to pick it up - { - root->markAsProcessed(); // Otherwise we have finished with this entry. - } + addGlobalFunction(root,rname,scope,nd); } else { @@ -3564,7 +3531,7 @@ static void buildFunctionList(const Entry *root) { // add member to the file (we do this even if we have already // inserted it into the namespace) - fd->insertMember(md); + fd->insertMember(md_found); } } @@ -3591,25 +3558,21 @@ static void buildFunctionList(const Entry *root) static void findFriends() { //printf("findFriends()\n"); - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) // for each global function name { //printf("Function name='%s'\n",fn->memberName()); MemberName *mn; - if ((mn=Doxygen::memberNameSDict->find(fn->memberName()))) + if ((mn=Doxygen::memberNameLinkedMap->find(fn->memberName()))) { // there are members with the same name //printf("Function name is also a member name\n"); - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { - const MemberDef *cfmd = const_cast<const MemberDef*>(fmd); - MemberNameIterator mni(*mn); - MemberDef *mmd; - for (;(mmd=mni.current());++mni) // for each member with that name + const MemberDef *cfmd = fmd.get(); + // for each member with that name + for (const auto &mmd : *mn) { - const MemberDef *cmmd = const_cast<const MemberDef*>(mmd); + const MemberDef *cmmd = mmd.get(); //printf("Checking for matching arguments // mmd->isRelated()=%d mmd->isFriend()=%d mmd->isFunction()=%d\n", // mmd->isRelated(),mmd->isFriend(),mmd->isFunction()); @@ -3688,28 +3651,23 @@ static void transferFunctionDocumentation() //printf("---- transferFunctionDocumentation()\n"); // find matching function declaration and definitions. - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { //printf("memberName=%s count=%d\n",mn->memberName(),mn->count()); - MemberDef *mdef=0,*mdec=0; - MemberNameIterator mni1(*mn); /* find a matching function declaration and definition for this function */ - for (;(mdec=mni1.current());++mni1) + for (const auto &mdec : *mn) { if (mdec->isPrototype() || (mdec->isVariable() && mdec->isExternal()) ) { - MemberNameIterator mni2(*mn); - for (;(mdef=mni2.current());++mni2) + for (const auto &mdef : *mn) { if (mdec!=mdef && !mdec->isAlias() && !mdef->isAlias() && mdec->getNamespaceDef()==mdef->getNamespaceDef()) { - combineDeclarationAndDefinition(mdec,mdef); + combineDeclarationAndDefinition(mdec.get(),mdef.get()); } } } @@ -3721,24 +3679,23 @@ static void transferFunctionDocumentation() static void transferFunctionReferences() { - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md,*mdef=0,*mdec=0; - MemberNameIterator mni(*mn); + MemberDef *mdef=0,*mdec=0; /* find a matching function declaration and definition for this function */ - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isPrototype()) - mdec=md; + mdec=md.get(); else if (md->isVariable() && md->isExternal()) - mdec=md; + mdec=md.get(); if (md->isFunction() && !md->isStatic() && !md->isPrototype()) - mdef=md; + mdef=md.get(); else if (md->isVariable() && !md->isExternal() && !md->isStatic()) - mdef=md; + mdef=md.get(); + + if (mdef && mdec) break; } if (mdef && mdec) { @@ -3815,23 +3772,19 @@ static void transferRelatedFunctionDocumentation() { // find match between function declaration and definition for // related functions - MemberNameSDict::Iterator mnli(*Doxygen::functionNameSDict); - MemberName *mn; - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); /* find a matching function declaration and definition for this function */ - for (mni.toFirst();(md=mni.current());++mni) // for each global function + // for each global function + for (const auto &md : *mn) { //printf(" Function '%s'\n",md->name().data()); MemberName *rmn; - if ((rmn=Doxygen::memberNameSDict->find(md->name()))) // check if there is a member with the same name + if ((rmn=Doxygen::memberNameLinkedMap->find(md->name()))) // check if there is a member with the same name { //printf(" Member name found\n"); - MemberDef *rmd; - MemberNameIterator rmni(*rmn); - for (rmni.toFirst();(rmd=rmni.current());++rmni) // for each member with the same name + // for each member with the same name + for (const auto &rmd : *rmn) { //printf(" Member found: related='%d'\n",rmd->isRelated()); if ((rmd->isRelated() || rmd->isForeign()) && // related function @@ -5152,19 +5105,17 @@ static bool findGlobalMember(const Entry *root, QCString n=name; if (n.isEmpty()) return FALSE; if (n.find("::")!=-1) return FALSE; // skip undefined class members - MemberName *mn=Doxygen::functionNameSDict->find(n+tempArg); // look in function dictionary + MemberName *mn=Doxygen::functionNameLinkedMap->find(n+tempArg); // look in function dictionary if (mn==0) { - mn=Doxygen::functionNameSDict->find(n); // try without template arguments + mn=Doxygen::functionNameLinkedMap->find(n); // try without template arguments } if (mn) // function name defined { Debug::print(Debug::FindMembers,0,"3. Found symbol scope\n"); //int count=0; - MemberNameIterator mni(*mn); - MemberDef *md; bool found=FALSE; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { const NamespaceDef *nd=0; if (md->isAlias() && md->getOuterScope() && @@ -5200,11 +5151,11 @@ static bool findGlobalMember(const Entry *root, NamespaceDef *rnd = 0; if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName); - const ArgumentList &mdAl = const_cast<const MemberDef *>(md)->argumentList(); + const ArgumentList &mdAl = const_cast<const MemberDef *>(md.get())->argumentList(); bool matching= (mdAl.empty() && root->argList.empty()) || md->isVariable() || md->isTypedef() || /* in case of function pointers */ - matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md)->getFileDef(),mdAl, + matchArguments2(md->getOuterScope(),const_cast<const MemberDef *>(md.get())->getFileDef(),mdAl, rnd ? rnd : Doxygen::globalScope,fd,root->argList, FALSE); @@ -5230,7 +5181,7 @@ static bool findGlobalMember(const Entry *root, // put the comment block at the first syntactically matching member. if (matching && md->isStatic() && md->getDefFileName()!=root->fileName && - mn->count()>1) + mn->size()>1) { matching = FALSE; } @@ -5253,6 +5204,7 @@ static bool findGlobalMember(const Entry *root, Debug::print(Debug::FindMembers,0,"5. Match found\n"); addMemberDocs(root,md->resolveAlias(),decl,&root->argList,FALSE,root->spec); found=TRUE; + break; } } } @@ -5262,10 +5214,10 @@ static bool findGlobalMember(const Entry *root, if (!root->argList.empty()) fullFuncDecl+=argListToString(root->argList,TRUE); QCString warnMsg = QCString("no matching file member found for \n")+substitute(fullFuncDecl,"%","%%"); - if (mn->count()>0) + if (mn->size()>0) { warnMsg+="\nPossible candidates:\n"; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { warnMsg+=" '"; warnMsg+=substitute(md->declaration(),"%","%%"); @@ -5439,7 +5391,506 @@ static void substituteTemplatesInArgList( // ); } +//------------------------------------------------------------------------------------------- + +static void addLocalObjCMethod(const Entry *root, + const QCString &scopeName, + const QCString &funcType,const QCString &funcName,const QCString &funcArgs, + const QCString &exceptions,const QCString &funcDecl, + uint64 spec) +{ + //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); + ClassDef *cd=0; + if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(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( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,Member, + MemberType_Function,ArgumentList(),root->argList,root->metaData) }; + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->makeImplementationDetail(); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + cd->insertUsedFile(fd); + md->setRefItems(root->sli); + + MemberName *mn = Doxygen::memberNameLinkedMap->add(root->name); + mn->push_back(std::move(md)); + } + else + { + // local objective C method found for class without interface + } +} + +//------------------------------------------------------------------------------------------- + +static void addMemberFunction(const Entry *root, + MemberName *mn, + const QCString &scopeName, + const QCString &namespaceName, + const QCString &className, + const QCString &funcTyp, + const QCString &funcName, + const QCString &funcArgs, + const QCString &funcTempList, + const QCString &exceptions, + const QCString &type, + const QCString &args, + bool isFriend, + uint64 spec, + const QCString &relates, + const QCString &funcDecl, + bool overloaded, + bool isFunc) +{ + QCString funcType = funcTyp; + int count=0; + int noMatchCount=0; + bool memFound=FALSE; + for (const auto &md : *mn) + { + ClassDef *cd=md->getClassDef(); + Debug::print(Debug::FindMembers,0, + "3. member definition found, " + "scope needed='%s' scope='%s' args='%s' fileName=%s\n", + qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>", + qPrint(md->argsString()), + qPrint(root->fileName)); + //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data()); + FileDef *fd=root->fileDef(); + NamespaceDef *nd=0; + if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); + + //printf("scopeName %s->%s\n",scopeName.data(), + // stripTemplateSpecifiersFromScope(scopeName,FALSE).data()); + + const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); + if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) + { + // don't be fooled by anonymous scopes + tcd=cd; + } + //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n", + // scopeName.data(),nd?nd->name().data():"<none>",tcd,tcd?tcd->name().data():"",cd); + + if (cd && tcd==cd) // member's classes match + { + Debug::print(Debug::FindMembers,0, + "4. class definition %s found\n",cd->name().data()); + + // get the template parameter lists found at the member declaration + std::vector<ArgumentList> declTemplArgs = cd->getTemplateParameterLists(); + const ArgumentList &templAl = md->templateArguments(); + if (!templAl.empty()) + { + declTemplArgs.push_back(templAl); + } + + // get the template parameter lists found at the member definition + const std::vector<ArgumentList> &defTemplArgs = root->tArgLists; + //printf("defTemplArgs=%p\n",defTemplArgs); + + // do we replace the decl argument lists with the def argument lists? + bool substDone=FALSE; + ArgumentList argList; + + /* substitute the occurrences of class template names in the + * argument list before matching + */ + const ArgumentList &mdAl = md->argumentList(); + if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size()) + { + /* the function definition has template arguments + * and the class definition also has template arguments, so + * we must substitute the template names of the class by that + * of the function definition before matching. + */ + substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList); + + substDone=TRUE; + } + else /* no template arguments, compare argument lists directly */ + { + argList = mdAl; + } + + Debug::print(Debug::FindMembers,0, + "5. matching '%s'<=>'%s' className=%s namespaceName=%s\n", + qPrint(argListToString(argList,TRUE)),qPrint(argListToString(root->argList,TRUE)), + qPrint(className),qPrint(namespaceName) + ); + + bool matching= + md->isVariable() || md->isTypedef() || // needed for function pointers + matchArguments2( + md->getClassDef(),md->getFileDef(),argList, + cd,fd,root->argList, + TRUE); + + if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC)) + { + matching = FALSE; // don't match methods and attributes with the same name + } + + // for template member we also need to check the return type + if (!md->templateArguments().empty() && !root->tArgLists.empty()) + { + QCString memType = md->typeString(); + memType.stripPrefix("static "); // see bug700696 + funcType=substitute(stripTemplateSpecifiersFromScope(funcType,TRUE), + className+"::",""); // see bug700693 & bug732594 + memType=substitute(stripTemplateSpecifiersFromScope(memType,TRUE), + className+"::",""); // see bug758900 + Debug::print(Debug::FindMembers,0, + "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", + qPrint(md->typeString()),qPrint(funcType), + md->templateArguments().size(),root->tArgLists.back().size()); + if (md->templateArguments().size()!=root->tArgLists.back().size() || + qstrcmp(memType,funcType)) + { + //printf(" ---> no matching\n"); + matching = FALSE; + } + } + bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0; + bool classIsTemplate = scopeIsTemplate(md->getClassDef()); + bool mdIsTemplate = md->templateArguments().hasParameters(); + bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate; + bool rootIsTemplate = !root->tArgLists.empty(); + //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate); + if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457 + (mdIsTemplate || rootIsTemplate) && // either md or root is a template + ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate)) + ) + { + // Method with template return type does not match method without return type + // even if the parameters are the same. See also bug709052 + Debug::print(Debug::FindMembers,0, + "5b. Comparing return types: template v.s. non-template\n"); + matching = FALSE; + } + + + Debug::print(Debug::FindMembers,0, + "6. match results of matchArguments2 = %d substDone=%d\n",matching,substDone); + + if (substDone) // found a new argument list + { + if (matching) // replace member's argument list + { + md->setDefinitionTemplateParameterLists(root->tArgLists); + md->setArgumentList(argList); + } + else // no match + { + if (!funcTempList.isEmpty() && + isSpecialization(declTemplArgs,defTemplArgs)) + { + // check if we are dealing with a partial template + // specialization. In this case we add it to the class + // even though the member arguments do not match. + + addMethodToClass(root,cd,type,md->name(),args,isFriend, + md->protection(),md->isStatic(),md->virtualness(),spec,relates); + return; + } + } + } + if (matching) + { + addMemberDocs(root,md.get(),funcDecl,0,overloaded,spec); + count++; + memFound=TRUE; + } + } + else if (cd && cd!=tcd) // we did find a class with the same name as cd + // but in a different namespace + { + noMatchCount++; + } + + if (memFound) break; + } + if (count==0 && root->parent() && + root->parent()->section==Entry::OBJCIMPL_SEC) + { + addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec); + return; + } + if (count==0 && !(isFriend && funcType=="class")) + { + int candidates=0; + const ClassDef *ecd = 0, *ucd = 0; + MemberDef *emd = 0, *umd = 0; + //printf("Assume template class\n"); + for (const auto &md : *mn) + { + ClassDef *ccd=md->getClassDef(); + MemberDef *cmd=md.get(); + //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); + if (ccd!=0 && rightScopeMatch(ccd->name(),className)) + { + const ArgumentList &templAl = md->templateArguments(); + if (!root->tArgLists.empty() && !templAl.empty() && + root->tArgLists.back().size()<=templAl.size()) + { + Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); + addMethodToClass(root,ccd,type,md->name(),args,isFriend, + root->protection,root->stat,root->virt,spec,relates); + return; + } + if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) + { // exact argument list match -> remember + ucd = ecd = ccd; + umd = emd = cmd; + Debug::print(Debug::FindMembers,0, + "7. new candidate className=%s scope=%s args=%s exact match\n", + qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); + } + else // arguments do not match, but member name and scope do -> remember + { + ucd = ccd; + umd = cmd; + Debug::print(Debug::FindMembers,0, + "7. new candidate className=%s scope=%s args=%s no match\n", + qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); + } + candidates++; + } + } + static bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); + if (!strictProtoMatching) + { + if (candidates==1 && ucd && umd) + { + // 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); + return; + } + else if (candidates>1 && ecd && emd) + { + // 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); + return; + } + } + + QCString warnMsg = "no "; + if (noMatchCount>1) warnMsg+="uniquely "; + warnMsg+="matching class member found for \n"; + + for (const ArgumentList &al : root->tArgLists) + { + warnMsg+=" template "; + warnMsg+=tempArgListToString(al,root->lang); + warnMsg+='\n'; + } + QCString fullFuncDecl=funcDecl.copy(); + if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); + + warnMsg+=" "; + warnMsg+=fullFuncDecl; + warnMsg+='\n'; + + if (candidates>0) + { + warnMsg+="Possible candidates:\n"; + for (const auto &md : *mn) + { + ClassDef *cd=md->getClassDef(); + if (cd!=0 && rightScopeMatch(cd->name(),className)) + { + const ArgumentList &templAl = md->templateArguments(); + warnMsg+=" '"; + if (templAl.hasParameters()) + { + warnMsg+="template "; + warnMsg+=tempArgListToString(templAl,root->lang); + warnMsg+='\n'; + warnMsg+=" "; + } + if (md->typeString()) + { + warnMsg+=md->typeString(); + warnMsg+=' '; + } + QCString qScope = cd->qualifiedNameWithTemplateParameters(); + if (!qScope.isEmpty()) + warnMsg+=qScope+"::"+md->name(); + if (md->argsString()) + warnMsg+=md->argsString(); + if (noMatchCount>1) + { + warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + + " of file "+md->getDefFileName(); + } + else + warnMsg += "'"; + + warnMsg+='\n'; + } + } + } + warn_simple(root->fileName,root->startLine,warnMsg); + } +} + +//------------------------------------------------------------------------------------------- + +static void addMemberSpecialization(const Entry *root, + MemberName *mn, + ClassDef *cd, + const QCString &funcType, + const QCString &funcName, + const QCString &funcArgs, + const QCString &funcDecl, + const QCString &exceptions, + uint64 spec + ) +{ + MemberDef *declMd=0; + for (const auto &md : *mn) + { + if (md->getClassDef()==cd) + { + // TODO: we should probably also check for matching arguments + declMd = md.get(); + break; + } + } + MemberType mtype=MemberType_Function; + ArgumentList tArgList; + // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); + std::unique_ptr<MemberDef> md { createMemberDef( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + declMd ? declMd->protection() : root->protection, + root->virt,root->stat,Member, + mtype,tArgList,root->argList,root->metaData) }; + //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->setMemberClass(cd); + md->setTemplateSpecialization(TRUE); + md->setTypeConstraints(root->typeConstr); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + md->setDocumentation(root->doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + md->setRefItems(root->sli); + + mn->push_back(std::move(md)); +} + +//------------------------------------------------------------------------------------------- + +static void addOverloaded(const Entry *root,MemberName *mn,ClassDef *cd, + const QCString &funcType,const QCString &funcName,const QCString &funcArgs, + const QCString &funcDecl,const QCString &exceptions,uint64 spec) +{ + // for unique overloaded member we allow the class to be + // omitted, this is to be Qt compatible. Using this should + // however be avoided, because it is error prone + bool sameClass=false; + if (mn->size()>0) + { + // check if all members with the same name are also in the same class + sameClass = std::equal(mn->begin()+1,mn->end(),mn->begin(), + [](const auto &md1,const auto &md2) + { return md1->getClassDef()->name()==md2->getClassDef()->name(); }); + } + if (sameClass) + { + ClassDef *cd = mn->front()->getClassDef(); + MemberType mtype; + if (root->mtype==Signal) mtype=MemberType_Signal; + else if (root->mtype==Slot) mtype=MemberType_Slot; + else if (root->mtype==DCOP) mtype=MemberType_DCOP; + else mtype=MemberType_Function; + + // new overloaded member function + 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( + root->fileName,root->startLine,root->startColumn, + funcType,funcName,funcArgs,exceptions, + root->protection,root->virt,root->stat,Related, + mtype,tArgList,root->argList,root->metaData) }; + md->setTagInfo(root->tagInfo()); + md->setLanguage(root->lang); + md->setId(root->id); + md->setTypeConstraints(root->typeConstr); + md->setMemberClass(cd); + md->setDefinition(funcDecl); + md->enableCallGraph(root->callGraph); + md->enableCallerGraph(root->callerGraph); + md->enableReferencedByRelation(root->referencedByRelation); + md->enableReferencesRelation(root->referencesRelation); + QCString doc=getOverloadDocs(); + doc+="<p>"; + doc+=root->doc; + md->setDocumentation(doc,root->docFile,root->docLine); + md->setBriefDescription(root->brief,root->briefFile,root->briefLine); + md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); + md->setDocsForDefinition(!root->proto); + md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); + md->addSectionsToDefinition(root->anchors); + md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); + FileDef *fd=root->fileDef(); + md->setBodyDef(fd); + md->setMemberSpecifiers(spec); + md->setMemberGroupId(root->mGrpId); + cd->insertMember(md.get()); + cd->insertUsedFile(fd); + md->setRefItems(root->sli); + + mn->push_back(std::move(md)); + } +} + +//------------------------------------------------------------------------------------------- /*! This function tries to find a member (in a documented class/file/namespace) * that corresponds to the function/variable declaration given in \a funcDecl. @@ -5768,365 +6219,27 @@ static void findMember(const Entry *root, } if (!funcTempList.isEmpty()) // try with member specialization { - mn=Doxygen::memberNameSDict->find(funcName+funcTempList); + mn=Doxygen::memberNameLinkedMap->find(funcName+funcTempList); } if (mn==0) // try without specialization { - mn=Doxygen::memberNameSDict->find(funcName); + mn=Doxygen::memberNameLinkedMap->find(funcName); } if (!isRelated && mn) // function name already found { Debug::print(Debug::FindMembers,0, - "2. member name exists (%d members with this name)\n",mn->count()); + "2. member name exists (%d members with this name)\n",mn->size()); if (!className.isEmpty()) // class name is valid { if (funcSpec.isEmpty()) // not a member specialization { - int count=0; - int noMatchCount=0; - MemberNameIterator mni(*mn); - MemberDef *md; - bool memFound=FALSE; - for (mni.toFirst();!memFound && (md=mni.current());++mni) - { - cd=md->getClassDef(); - Debug::print(Debug::FindMembers,0, - "3. member definition found, " - "scope needed='%s' scope='%s' args='%s' fileName=%s\n", - qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>", - qPrint(md->argsString()), - qPrint(root->fileName)); - //printf("Member %s (member scopeName=%s) (this scopeName=%s) classTempList=%s\n",md->name().data(),cd->name().data(),scopeName.data(),classTempList.data()); - FileDef *fd=root->fileDef(); - NamespaceDef *nd=0; - if (!namespaceName.isEmpty()) nd=getResolvedNamespace(namespaceName); - - //printf("scopeName %s->%s\n",scopeName.data(), - // stripTemplateSpecifiersFromScope(scopeName,FALSE).data()); - - const ClassDef *tcd=findClassDefinition(fd,nd,scopeName); - if (tcd==0 && cd && stripAnonymousNamespaceScope(cd->name())==scopeName) - { - // don't be fooled by anonymous scopes - tcd=cd; - } - //printf("Looking for %s inside nd=%s result=%p (%s) cd=%p\n", - // scopeName.data(),nd?nd->name().data():"<none>",tcd,tcd?tcd->name().data():"",cd); - - if (cd && tcd==cd) // member's classes match - { - Debug::print(Debug::FindMembers,0, - "4. class definition %s found\n",cd->name().data()); - - // get the template parameter lists found at the member declaration - std::vector<ArgumentList> declTemplArgs = cd->getTemplateParameterLists(); - const ArgumentList &templAl = md->templateArguments(); - if (!templAl.empty()) - { - declTemplArgs.push_back(templAl); - } - - // get the template parameter lists found at the member definition - const std::vector<ArgumentList> &defTemplArgs = root->tArgLists; - //printf("defTemplArgs=%p\n",defTemplArgs); - - // do we replace the decl argument lists with the def argument lists? - bool substDone=FALSE; - ArgumentList argList; - - /* substitute the occurrences of class template names in the - * argument list before matching - */ - const ArgumentList &mdAl = md->argumentList(); - if (declTemplArgs.size()>0 && declTemplArgs.size()==defTemplArgs.size()) - { - /* the function definition has template arguments - * and the class definition also has template arguments, so - * we must substitute the template names of the class by that - * of the function definition before matching. - */ - substituteTemplatesInArgList(declTemplArgs,defTemplArgs,mdAl,argList); - - substDone=TRUE; - } - else /* no template arguments, compare argument lists directly */ - { - argList = mdAl; - } - - Debug::print(Debug::FindMembers,0, - "5. matching '%s'<=>'%s' className=%s namespaceName=%s\n", - qPrint(argListToString(argList,TRUE)),qPrint(argListToString(root->argList,TRUE)), - qPrint(className),qPrint(namespaceName) - ); - - bool matching= - md->isVariable() || md->isTypedef() || // needed for function pointers - matchArguments2( - md->getClassDef(),md->getFileDef(),argList, - cd,fd,root->argList, - TRUE); - - if (md->getLanguage()==SrcLangExt_ObjC && md->isVariable() && (root->section&Entry::FUNCTION_SEC)) - { - matching = FALSE; // don't match methods and attributes with the same name - } - - // for template member we also need to check the return type - if (!md->templateArguments().empty() && !root->tArgLists.empty()) - { - QCString memType = md->typeString(); - memType.stripPrefix("static "); // see bug700696 - funcType=substitute(stripTemplateSpecifiersFromScope(funcType,TRUE), - className+"::",""); // see bug700693 & bug732594 - memType=substitute(stripTemplateSpecifiersFromScope(memType,TRUE), - className+"::",""); // see bug758900 - Debug::print(Debug::FindMembers,0, - "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n", - qPrint(md->typeString()),qPrint(funcType), - md->templateArguments().size(),root->tArgLists.back().size()); - if (md->templateArguments().size()!=root->tArgLists.back().size() || - qstrcmp(memType,funcType)) - { - //printf(" ---> no matching\n"); - matching = FALSE; - } - } - bool rootIsUserDoc = (root->section&Entry::MEMBERDOC_SEC)!=0; - bool classIsTemplate = scopeIsTemplate(md->getClassDef()); - bool mdIsTemplate = md->templateArguments().hasParameters(); - bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate; - bool rootIsTemplate = !root->tArgLists.empty(); - //printf("classIsTemplate=%d mdIsTemplate=%d rootIsTemplate=%d\n",classIsTemplate,mdIsTemplate,rootIsTemplate); - if (!rootIsUserDoc && // don't check out-of-line @fn references, see bug722457 - (mdIsTemplate || rootIsTemplate) && // either md or root is a template - ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate)) - ) - { - // Method with template return type does not match method without return type - // even if the parameters are the same. See also bug709052 - Debug::print(Debug::FindMembers,0, - "5b. Comparing return types: template v.s. non-template\n"); - matching = FALSE; - } - - - Debug::print(Debug::FindMembers,0, - "6. match results of matchArguments2 = %d substDone=%d\n",matching,substDone); - - if (substDone) // found a new argument list - { - if (matching) // replace member's argument list - { - md->setDefinitionTemplateParameterLists(root->tArgLists); - md->setArgumentList(argList); - } - else // no match - { - if (!funcTempList.isEmpty() && - isSpecialization(declTemplArgs,defTemplArgs)) - { - // check if we are dealing with a partial template - // specialization. In this case we add it to the class - // even though the member arguments do not match. - - addMethodToClass(root,cd,type,md->name(),args,isFriend, - md->protection(),md->isStatic(),md->virtualness(),spec,relates); - return; - } - } - } - if (matching) - { - addMemberDocs(root,md,funcDecl,0,overloaded,spec); - count++; - memFound=TRUE; - } - } - else if (cd && cd!=tcd) // we did find a class with the same name as cd - // but in a different namespace - { - noMatchCount++; - } - } - if (count==0 && root->parent() && - root->parent()->section==Entry::OBJCIMPL_SEC) - { - goto localObjCMethod; - } - if (count==0 && !(isFriend && funcType=="class")) - { - int candidates=0; - const ClassDef *ecd = 0, *ucd = 0; - MemberDef *emd = 0, *umd = 0; - if (mn->count()>0) - { - //printf("Assume template class\n"); - for (mni.toFirst();(md=mni.current());++mni) - { - ClassDef *ccd=md->getClassDef(); - MemberDef *cmd=md; - //printf("ccd->name()==%s className=%s\n",ccd->name().data(),className.data()); - if (ccd!=0 && rightScopeMatch(ccd->name(),className)) - { - const ArgumentList &templAl = md->templateArguments(); - if (!root->tArgLists.empty() && !templAl.empty() && - root->tArgLists.back().size()<=templAl.size()) - { - Debug::print(Debug::FindMembers,0,"7. add template specialization\n"); - addMethodToClass(root,ccd,type,md->name(),args,isFriend, - root->protection,root->stat,root->virt,spec,relates); - return; - } - if (md->argsString()==argListToString(root->argList,TRUE,FALSE)) - { // exact argument list match -> remember - ucd = ecd = ccd; - umd = emd = cmd; - Debug::print(Debug::FindMembers,0, - "7. new candidate className=%s scope=%s args=%s exact match\n", - qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); - } - else // arguments do not match, but member name and scope do -> remember - { - ucd = ccd; - umd = cmd; - Debug::print(Debug::FindMembers,0, - "7. new candidate className=%s scope=%s args=%s no match\n", - qPrint(className),qPrint(ccd->name()),qPrint(md->argsString())); - } - candidates++; - } - } - } - static bool strictProtoMatching = Config_getBool(STRICT_PROTO_MATCHING); - if (!strictProtoMatching) - { - if (candidates==1 && ucd && umd) - { - // 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); - return; - } - else if (candidates>1 && ecd && emd) - { - // 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); - return; - } - } - - QCString warnMsg = "no "; - if (noMatchCount>1) warnMsg+="uniquely "; - warnMsg+="matching class member found for \n"; - - for (const ArgumentList &al : root->tArgLists) - { - warnMsg+=" template "; - warnMsg+=tempArgListToString(al,root->lang); - warnMsg+='\n'; - } - - QCString fullFuncDecl=funcDecl.copy(); - if (isFunc) fullFuncDecl+=argListToString(root->argList,TRUE); - - warnMsg+=" "; - warnMsg+=fullFuncDecl; - warnMsg+='\n'; - - if (candidates>0) - { - warnMsg+="Possible candidates:\n"; - for (mni.toFirst();(md=mni.current());++mni) - { - cd=md->getClassDef(); - if (cd!=0 && rightScopeMatch(cd->name(),className)) - { - const ArgumentList &templAl = md->templateArguments(); - warnMsg+=" '"; - if (templAl.hasParameters()) - { - warnMsg+="template "; - warnMsg+=tempArgListToString(templAl,root->lang); - warnMsg+='\n'; - warnMsg+=" "; - } - if (md->typeString()) - { - warnMsg+=md->typeString(); - warnMsg+=' '; - } - QCString qScope = cd->qualifiedNameWithTemplateParameters(); - if (!qScope.isEmpty()) - warnMsg+=qScope+"::"+md->name(); - if (md->argsString()) - warnMsg+=md->argsString(); - if (noMatchCount>1) - { - warnMsg+="' at line "+QCString().setNum(md->getDefLine()) + - " of file "+md->getDefFileName(); - } - else - warnMsg += "'"; - - warnMsg+='\n'; - } - } - } - warn_simple(root->fileName,root->startLine,warnMsg); - } + addMemberFunction(root,mn,scopeName,namespaceName,className,funcType,funcName, + funcArgs,funcTempList,exceptions, + type,args,isFriend,spec,relates,funcDecl,overloaded,isFunc); } else if (cd) // member specialization { - MemberNameIterator mni(*mn); - MemberDef *declMd=0; - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) - { - if (md->getClassDef()==cd) - { - // TODO: we should probably also check for matching arguments - declMd = md; - break; - } - } - MemberType mtype=MemberType_Function; - ArgumentList tArgList; - // getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - declMd ? declMd->protection() : root->protection, - root->virt,root->stat,Member, - mtype,tArgList,root->argList,root->metaData); - //printf("new specialized member %s args='%s'\n",md->name().data(),funcArgs.data()); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->setMemberClass(cd); - md->setTemplateSpecialization(TRUE); - md->setTypeConstraints(root->typeConstr); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - mn->append(md); - cd->insertMember(md); - md->setRefItems(root->sli); + addMemberSpecialization(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec); } else { @@ -6136,68 +6249,7 @@ static void findMember(const Entry *root, } else if (overloaded) // check if the function belongs to only one class { - // for unique overloaded member we allow the class to be - // omitted, this is to be Qt compatible. Using this should - // however be avoided, because it is error prone - MemberNameIterator mni(*mn); - MemberDef *md=mni.toFirst(); - ASSERT(md); - cd=md->getClassDef(); - ASSERT(cd); - className=cd->name(); - ++mni; - bool unique=TRUE; - for (;(md=mni.current());++mni) - { - const ClassDef *lcd=md->getClassDef(); - if (className!=lcd->name()) unique=FALSE; - } - if (unique) - { - MemberType mtype; - if (root->mtype==Signal) mtype=MemberType_Signal; - else if (root->mtype==Slot) mtype=MemberType_Slot; - else if (root->mtype==DCOP) mtype=MemberType_DCOP; - else mtype=MemberType_Function; - - // new overloaded member function - ArgumentList tArgList = - getTemplateArgumentsFromName(cd->name()+"::"+funcName,root->tArgLists); - //printf("new related member %s args='%s'\n",md->name().data(),funcArgs.data()); - md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - root->protection,root->virt,root->stat,Related, - mtype,tArgList,root->argList,root->metaData); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->setTypeConstraints(root->typeConstr); - md->setMemberClass(cd); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - QCString doc=getOverloadDocs(); - doc+="<p>"; - doc+=root->doc; - md->setDocumentation(doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - mn->append(md); - cd->insertMember(md); - cd->insertUsedFile(fd); - md->setRefItems(root->sli); - } + addOverloaded(root,mn,cd,funcType,funcName,funcArgs,funcDecl,exceptions,spec); } else // unrelated function with the same name as a member { @@ -6221,35 +6273,34 @@ static void findMember(const Entry *root, if ((cd=getClass(scopeName))) { bool newMember=TRUE; // assume we have a new member - bool newMemberName=FALSE; MemberDef *mdDefine=0; bool isDefine=FALSE; { - mn = Doxygen::functionNameSDict->find(funcName); + mn = Doxygen::functionNameLinkedMap->find(funcName); if (mn) { - MemberNameIterator mni(*mn); - mdDefine = mni.current(); - while (mdDefine && !isDefine) + for (const auto &md : *mn) { - isDefine = isDefine || mdDefine->isDefine(); - if (!isDefine) { ++mni; mdDefine=mni.current(); } + if (md->isDefine()) + { + mdDefine = md.get(); + break; + } } } } FileDef *fd=root->fileDef(); - if ((mn=Doxygen::memberNameSDict->find(funcName))==0) + if ((mn=Doxygen::memberNameLinkedMap->find(funcName))==0) { - mn=new MemberName(funcName); - newMemberName=TRUE; // we create a new member name + mn=Doxygen::memberNameLinkedMap->add(funcName); } else { - MemberNameIterator mni(*mn); - MemberDef *rmd; - while ((rmd=mni.current()) && newMember) // see if we got another member with matching arguments + // see if we got another member with matching arguments + MemberDef *rmd_found = 0; + for (const auto &rmd : *mn) { const ArgumentList &rmdAl = rmd->argumentList(); @@ -6258,13 +6309,16 @@ static void findMember(const Entry *root, !matchArguments2(rmd->getOuterScope(),rmd->getFileDef(),rmdAl, cd,fd,root->argList, TRUE); - if (newMember) ++mni; + if (!newMember) + { + rmd_found = rmd.get(); + } } - if (!newMember && rmd) // member already exists as rmd -> add docs + if (rmd_found) // member already exists as rmd -> add docs { //printf("addMemberDocs for related member %s\n",root->name.data()); //rmd->setMemberDefTemplateArguments(root->mtArgList); - addMemberDocs(root,rmd,funcDecl,0,overloaded,spec); + addMemberDocs(root,rmd_found,funcDecl,0,overloaded,spec); } } @@ -6299,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. - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( root->fileName,root->startLine,root->startColumn, funcType,funcName,funcArgs,exceptions, root->protection,root->virt, @@ -6308,7 +6362,7 @@ static void findMember(const Entry *root, mtype, (!root->tArgLists.empty() ? root->tArgLists.back() : ArgumentList()), funcArgs.isEmpty() ? ArgumentList() : root->argList, - root->metaData); + root->metaData) }; if (isDefine && mdDefine) { @@ -6330,8 +6384,6 @@ static void findMember(const Entry *root, md->setTagInfo(root->tagInfo()); - - //printf("Related member name='%s' decl='%s' bodyLine='%d'\n", // funcName.data(),funcDecl.data(),root->bodyLine); @@ -6340,12 +6392,11 @@ static void findMember(const Entry *root, bool found=FALSE; if (root->bodyLine==-1) { - MemberName *rmn=Doxygen::functionNameSDict->find(funcName); + MemberName *rmn=Doxygen::functionNameLinkedMap->find(funcName); if (rmn) { - MemberNameIterator rmni(*rmn); - const MemberDef *rmd; - while ((rmd=rmni.current()) && !found) // see if we got another member with matching arguments + const MemberDef *rmd_found=0; + for (const auto &rmd : *rmn) { const ArgumentList &rmdAl = rmd->argumentList(); // check for matching argument lists @@ -6356,13 +6407,14 @@ static void findMember(const Entry *root, ) { found=TRUE; + rmd_found = rmd.get(); + break; } - if (!found) ++rmni; } - if (rmd) // member found -> copy line number info + if (rmd_found) // member found -> copy line number info { - md->setBodySegment(rmd->getDefLine(),rmd->getStartBodyLine(),rmd->getEndBodyLine()); - md->setBodyDef(rmd->getBodyDef()); + md->setBodySegment(rmd_found->getDefLine(),rmd_found->getStartBodyLine(),rmd_found->getEndBodyLine()); + md->setBodyDef(rmd_found->getBodyDef()); //md->setBodyMember(rmd); } } @@ -6395,22 +6447,16 @@ static void findMember(const Entry *root, md->setLanguage(root->lang); md->setId(root->id); //md->setMemberDefTemplateArguments(root->mtArgList); - mn->append(md); - cd->insertMember(md); + cd->insertMember(md.get()); cd->insertUsedFile(fd); md->setRefItems(root->sli); if (root->relatesType == Duplicate) md->setRelatedAlso(cd); if (!isDefine) { - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); } //printf("Adding member=%s\n",md->name().data()); - if (newMemberName) - { - //Doxygen::memberNameList.append(mn); - //Doxygen::memberNameDict.insert(funcName,mn); - Doxygen::memberNameSDict->append(funcName,mn); - } + mn->push_back(std::move(md)); } if (root->relatesType == Duplicate) { @@ -6436,57 +6482,7 @@ static void findMember(const Entry *root, } else if (root->parent() && root->parent()->section==Entry::OBJCIMPL_SEC) { -localObjCMethod: - //printf("scopeName='%s' className='%s'\n",scopeName.data(),className.data()); - if (Config_getBool(EXTRACT_LOCAL_METHODS) && (cd=getClass(scopeName))) - { - Debug::print(Debug::FindMembers,0,"4. Local objective C method %s\n" - " scopeName=%s className=%s\n",qPrint(root->name),qPrint(scopeName),qPrint(className)); - //printf("Local objective C method '%s' of class '%s' found\n",root->name.data(),cd->name().data()); - MemberDef *md=createMemberDef( - root->fileName,root->startLine,root->startColumn, - funcType,funcName,funcArgs,exceptions, - root->protection,root->virt,root->stat,Member, - MemberType_Function,ArgumentList(),root->argList,root->metaData); - md->setTagInfo(root->tagInfo()); - md->setLanguage(root->lang); - md->setId(root->id); - md->makeImplementationDetail(); - md->setMemberClass(cd); - md->setDefinition(funcDecl); - md->enableCallGraph(root->callGraph); - md->enableCallerGraph(root->callerGraph); - md->enableReferencedByRelation(root->referencedByRelation); - md->enableReferencesRelation(root->referencesRelation); - md->setDocumentation(root->doc,root->docFile,root->docLine); - md->setBriefDescription(root->brief,root->briefFile,root->briefLine); - md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); - md->setDocsForDefinition(!root->proto); - md->setPrototype(root->proto,root->fileName,root->startLine,root->startColumn); - md->addSectionsToDefinition(root->anchors); - md->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine); - FileDef *fd=root->fileDef(); - md->setBodyDef(fd); - md->setMemberSpecifiers(spec); - md->setMemberGroupId(root->mGrpId); - cd->insertMember(md); - cd->insertUsedFile(fd); - md->setRefItems(root->sli); - if ((mn=Doxygen::memberNameSDict->find(root->name))) - { - mn->append(md); - } - else - { - mn = new MemberName(root->name); - mn->append(md); - Doxygen::memberNameSDict->append(root->name,mn); - } - } - else - { - // local objective C method found for class without interface - } + addLocalObjCMethod(root,scopeName,funcType,funcName,funcArgs,exceptions,funcDecl,spec); } else // unrelated not overloaded member found { @@ -6731,11 +6727,10 @@ static void findEnums(const Entry *root) { if (root->section==Entry::ENUM_SEC) { - MemberDef *md=0; ClassDef *cd=0; FileDef *fd=0; NamespaceDef *nd=0; - MemberNameSDict *mnsd=0; + MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; bool isMemberOf=FALSE; @@ -6778,31 +6773,31 @@ static void findEnums(const Entry *root) { //printf("Enum '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; - mnsd=Doxygen::memberNameSDict; + mnsd=Doxygen::memberNameLinkedMap; isGlobal=FALSE; } else if (nd) // found enum inside namespace { - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } else // found a global enum { fd=root->fileDef(); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } if (!name.isEmpty()) { // new enum type - md = createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( root->fileName,root->startLine,root->startColumn, 0,name,0,0, root->protection,Normal,FALSE, isMemberOf ? Foreign : isRelated ? Related : Member, MemberType_Enumeration, - ArgumentList(),ArgumentList(),root->metaData); + ArgumentList(),ArgumentList(),root->metaData) }; md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); md->setId(root->id); @@ -6843,7 +6838,7 @@ static void findEnums(const Entry *root) //printf("definition=%s\n",md->definition()); defSet=TRUE; md->setNamespace(nd); - nd->insertMember(md); + nd->insertMember(md.get()); } // even if we have already added the enum to a namespace, we still @@ -6859,7 +6854,7 @@ static void findEnums(const Entry *root) if (fd) { md->setFileDef(fd); - fd->insertMember(md); + fd->insertMember(md.get()); } } else if (cd) @@ -6872,7 +6867,7 @@ static void findEnums(const Entry *root) { md->setDefinition(cd->name()+"::"+name+baseType); } - cd->insertMember(md); + cd->insertMember(md.get()); cd->insertUsedFile(fd); } md->setDocumentation(root->doc,root->docFile,root->docLine); @@ -6881,21 +6876,10 @@ static void findEnums(const Entry *root) md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine); //printf("Adding member=%s\n",md->name().data()); - MemberName *mn; - if ((mn=(*mnsd)[name])) - { - // this is used if the same enum is in multiple namespaces/classes - mn->append(md); - } - else // new enum name - { - mn = new MemberName(name); - mn->append(md); - mnsd->append(name,mn); - //printf("add %s to new memberName. Now %d members\n", - // name.data(),mn->count()); - } - addMemberToGroups(root,md); + addMemberToGroups(root,md.get()); + + MemberName *mn = mnsd->add(name); + mn->push_back(std::move(md)); } } else @@ -6914,7 +6898,7 @@ static void addEnumValuesToEnums(const Entry *root) ClassDef *cd=0; FileDef *fd=0; NamespaceDef *nd=0; - MemberNameSDict *mnsd=0; + MemberNameLinkedMap *mnsd=0; bool isGlobal; bool isRelated=FALSE; //printf("Found enum with name '%s' relates=%s\n",root->name.data(),root->relates.data()); @@ -6955,20 +6939,20 @@ static void addEnumValuesToEnums(const Entry *root) { //printf("Enum in class '%s'::'%s'\n",cd->name().data(),name.data()); fd=0; - mnsd=Doxygen::memberNameSDict; + mnsd=Doxygen::memberNameLinkedMap; isGlobal=FALSE; } else if (nd && !nd->isAnonymous()) // found enum inside namespace { //printf("Enum in namespace '%s'::'%s'\n",nd->name().data(),name.data()); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } else // found a global enum { fd=root->fileDef(); //printf("Enum in file '%s': '%s'\n",fd->name().data(),name.data()); - mnsd=Doxygen::functionNameSDict; + mnsd=Doxygen::functionNameLinkedMap; isGlobal=TRUE; } @@ -6978,9 +6962,8 @@ static void addEnumValuesToEnums(const Entry *root) MemberName *mn = mnsd->find(name); // for all members with this name if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst(); (md=mni.current()) ; ++mni) // for each enum in this list + // for each enum in this list + for (const auto &md : *mn) { if (!md->isAlias() && md->isEnumerate() && !root->children().empty()) { @@ -7014,11 +6997,11 @@ static void addEnumValuesToEnums(const Entry *root) { fileName = e->tagInfo()->tagName; } - MemberDef *fmd=createMemberDef( + std::unique_ptr<MemberDef> fmd { createMemberDef( fileName,e->startLine,e->startColumn, e->type,e->name,e->args,0, e->protection, Normal,e->stat,Member, - MemberType_EnumValue,ArgumentList(),ArgumentList(),e->metaData); + MemberType_EnumValue,ArgumentList(),ArgumentList(),e->metaData) }; if (md->getClassDef()) fmd->setMemberClass(md->getClassDef()); else if (md->getNamespaceDef()) fmd->setNamespace(md->getNamespaceDef()); else if (md->getFileDef()) fmd->setFileDef(md->getFileDef()); @@ -7035,32 +7018,21 @@ static void addEnumValuesToEnums(const Entry *root) fmd->setExplicitExternal(e->explicitExternal,fileName,e->startLine,e->startColumn); fmd->setRefItems(e->sli); fmd->setAnchor(); - md->insertEnumField(fmd); - fmd->setEnumScope(md,TRUE); - mn=mnsd->find(e->name); - if (mn) - { - mn->append(fmd); - } - else - { - mn = new MemberName(e->name); - mn->append(fmd); - mnsd->append(e->name,mn); - } + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get(),TRUE); + mn=mnsd->add(e->name); + mn->push_back(std::move(fmd)); } } else { //printf("e->name=%s isRelated=%d\n",e->name().data(),isRelated); MemberName *fmn=0; - MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd; - if (!e->name.isEmpty() && (fmn=(*emnsd)[e->name])) + MemberNameLinkedMap *emnsd = isRelated ? Doxygen::functionNameLinkedMap : mnsd; + if (!e->name.isEmpty() && (fmn=emnsd->find(e->name))) // get list of members with the same name as the field { - MemberNameIterator fmni(*fmn); - MemberDef *fmd; - for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni) + for (const auto &fmd : *fmn) { if (fmd->isEnumValue() && fmd->getOuterScope()==md->getOuterScope()) // in same scope { @@ -7071,8 +7043,8 @@ static void addEnumValuesToEnums(const Entry *root) const NamespaceDef *fnd=fmd->getNamespaceDef(); if (fnd==nd) // enum value is inside a namespace { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get()); } } else if (isGlobal) @@ -7080,19 +7052,19 @@ static void addEnumValuesToEnums(const Entry *root) const FileDef *ffd=fmd->getFileDef(); if (ffd==fd) // enum value has file scope { - md->insertEnumField(fmd); - fmd->setEnumScope(md); + md->insertEnumField(fmd.get()); + fmd->setEnumScope(md.get()); } } else if (isRelated && cd) // reparent enum value to // match the enum's scope { - md->insertEnumField(fmd); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + md->insertEnumField(fmd.get()); // add field def to list + fmd->setEnumScope(md.get()); // cross ref with enum name fmd->setEnumClassScope(cd); // cross ref with enum name fmd->setOuterScope(cd); fmd->makeRelated(); - cd->insertMember(fmd); + cd->insertMember(fmd.get()); } else { @@ -7101,8 +7073,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); // add field def to list - fmd->setEnumScope(md); // cross ref with enum name + md->insertEnumField(fmd.get()); // add field def to list + fmd->setEnumScope(md.get()); // cross ref with enum name } } } @@ -7163,12 +7135,10 @@ static void findEnumDocumentation(const Entry *root) { //printf("Enum: scope='%s' name='%s'\n",cd->name(),name.data()); QCString className=cd->name().copy(); - MemberName *mn=Doxygen::memberNameSDict->find(name); + MemberName *mn=Doxygen::memberNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { cd=md->getClassDef(); if (cd && cd->name()==className && md->isEnumerate()) @@ -7207,10 +7177,11 @@ 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); + addMemberToGroups(root,md.get()); } found=TRUE; + break; } } } @@ -7222,12 +7193,10 @@ static void findEnumDocumentation(const Entry *root) else // enum outside class { //printf("Enum outside class: %s grpId=%d\n",name.data(),root->mGrpId); - MemberName *mn=Doxygen::functionNameSDict->find(name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (mni.toFirst();(md=mni.current()) && !found;++mni) + for (const auto &md : *mn) { if (md->isEnumerate()) { @@ -7241,10 +7210,11 @@ 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); + addMemberToGroups(root,md.get()); } found=TRUE; + break; } } } @@ -7263,17 +7233,13 @@ static void findEnumDocumentation(const Entry *root) // search for each enum (member or function) in mnl if it has documented // enum values. -static void findDEV(const MemberNameSDict &mnsd) +static void findDEV(const MemberNameLinkedMap &mnsd) { - MemberName *mn; - MemberNameSDict::Iterator mnli(mnsd); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : mnsd) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->isEnumerate()) // member is an enum { @@ -7300,45 +7266,38 @@ static void findDEV(const MemberNameSDict &mnsd) // values. static void findDocumentedEnumValues() { - findDEV(*Doxygen::memberNameSDict); - findDEV(*Doxygen::functionNameSDict); + findDEV(*Doxygen::memberNameLinkedMap); + findDEV(*Doxygen::functionNameLinkedMap); } //---------------------------------------------------------------------- static void addMembersToIndex() { - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addClassMemberNameToIndex(md); + addClassMemberNameToIndex(md.get()); } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (!md->isAlias()) { if (md->getNamespaceDef()) { - addNamespaceMemberNameToIndex(md); + addNamespaceMemberNameToIndex(md.get()); } else { - addFileMemberNameToIndex(md); + addFileMemberNameToIndex(md.get()); } } } @@ -7349,29 +7308,22 @@ static void addMembersToIndex() static void vhdlCorrectMemberProperties() { - MemberName *mn; - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - VhdlDocGen::correctMemberProperties(md); + VhdlDocGen::correctMemberProperties(md.get()); } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - VhdlDocGen::correctMemberProperties(md); + VhdlDocGen::correctMemberProperties(md.get()); } } } @@ -7384,61 +7336,60 @@ static void vhdlCorrectMemberProperties() static void computeMemberRelations() { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; - for ( ; (mn=mnli.current()) ; ++mnli ) // for each member name + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mdi(*mn); - MemberNameIterator bmdi(*mn); - MemberDef *md; - MemberDef *bmd; - for ( ; (md=mdi.current()) ; ++mdi ) // for each member with a specific name - { - for ( bmdi.toFirst() ; (bmd=bmdi.current()); ++bmdi ) // for each other member with the same name - { - const ClassDef *mcd = md->getClassDef(); - if (mcd && mcd->baseClasses()) - { - const ClassDef *bmcd = bmd->getClassDef(); - //printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n", - // mcd->name().data(),md->name().data(),md, - // bmcd->name().data(),bmd->name().data(),bmd - // ); - if (md!=bmd && 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)) + // for each member with a specific name + for (const auto &md : *mn) + { + // for each other member with the same name + for ( const auto &bmd : *mn) + { + if (md!=bmd) + { + const ClassDef *mcd = md->getClassDef(); + if (mcd && mcd->baseClasses()) { - //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.pointer()).data(), - // argListToString(mdAl.pointer()).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, + // bmcd->name().data(),bmd->name().data(),bmd // ); - 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)) { - 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.pointer()).data(), + // argListToString(mdAl.pointer()).data() + // ); + if ( + matchArguments2(bmd->getOuterScope(),bmd->getFileDef(),bmdAl, + md->getOuterScope(), md->getFileDef(), mdAl, + TRUE + ) ) { - //printf("setting (new) reimplements member\n"); - md->setReimplements(bmd); + MemberDef *rmd; + if ((rmd=md->reimplements())==0 || + minClassDistance(mcd,bmcd)<minClassDistance(mcd,rmd->getClassDef()) + ) + { + //printf("setting (new) reimplements member\n"); + md->setReimplements(bmd.get()); + } + //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); + bmd->insertReimplementedBy(md.get()); } - //printf("%s: add reimplementedBy member %s\n",bmcd->name().data(),mcd->name().data()); - bmd->insertReimplementedBy(md); } } } @@ -7712,13 +7663,9 @@ static void addSourceReferences() } // add source references for member names - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn=0; - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("class member %s: def=%s body=%d link?=%d\n", // md->name().data(), @@ -7733,16 +7680,13 @@ static void addSourceReferences() { //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); - fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md); + fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get()); } } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md=0; - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { FileDef *fd=md->getBodyDef(); //printf("member %s body=[%d,%d] fd=%p link=%d parseSources=%d\n", @@ -7758,7 +7702,7 @@ static void addSourceReferences() { //printf("Found member '%s' in file '%s' at line '%d' def=%s\n", // md->name().data(),fd->name().data(),md->getStartBodyLine(),md->getOuterScope()->name().data()); - fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md); + fd->addSourceRef(md->getStartDefLine(),md->getOuterScope(),md.get()); } } } @@ -7891,14 +7835,9 @@ static void generateClassDocs() static void inheritDocumentation() { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; - //int count=0; - for (;(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*mn); - MemberDef *md; - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { //printf("%04d Member '%s'\n",count++,md->name().data()); if (md->documentation().isEmpty() && md->briefDescription().isEmpty()) @@ -8088,13 +8027,11 @@ static void flushCachedTemplateRelations() } // remove all cached typedef resolutions whose target is a // template class as this may now be a template instance - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { if (fmd->isTypedefValCached()) { @@ -8103,17 +8040,16 @@ static void flushCachedTemplateRelations() } } } - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (;(fn=mnli.current());++mnli) // for each class method name + // for each class method name + for (const auto &nm : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*fn); - MemberDef *fmd; - for (;(fmd=mni.current());++mni) // for each function with that name + // for each function with that name + for (const auto &md : *nm) { - if (fmd->isTypedefValCached()) + if (md->isTypedefValCached()) { - const ClassDef *cd = fmd->getCachedTypedefVal(); - if (cd->isTemplate()) fmd->invalidateTypedefValCache(); + const ClassDef *cd = md->getCachedTypedefVal(); + if (cd->isTemplate()) md->invalidateTypedefValCache(); } } } @@ -8143,25 +8079,22 @@ static void flushUnresolvedRelations() } } - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *fn; - for (;(fn=fnli.current());++fnli) // for each global function name + // for each global function name + for (const auto &fn : *Doxygen::functionNameLinkedMap) { - MemberNameIterator fni(*fn); - MemberDef *fmd; - for (;(fmd=fni.current());++fni) // for each function with that name + // for each function with that name + for (const auto &fmd : *fn) { fmd->invalidateCachedArgumentTypes(); } } - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - for (;(fn=mnli.current());++mnli) // for each class method name + // for each class method name + for (const auto &nm : *Doxygen::memberNameLinkedMap) { - MemberNameIterator mni(*fn); - MemberDef *fmd; - for (;(fmd=mni.current());++mni) // for each function with that name + // for each function with that name + for (const auto &md : *nm) { - fmd->invalidateCachedArgumentTypes(); + md->invalidateCachedArgumentTypes(); } } @@ -8180,40 +8113,29 @@ static void findDefineDocumentation(Entry *root) if (root->tagInfo() && !root->name.isEmpty()) // define read from a tag file { - MemberDef *md=createMemberDef(root->tagInfo()->tagName,1,1, + std::unique_ptr<MemberDef> md { createMemberDef(root->tagInfo()->tagName,1,1, "#define",root->name,root->args,0, Public,Normal,FALSE,Member,MemberType_Define, - ArgumentList(),ArgumentList(),""); + ArgumentList(),ArgumentList(),"") }; md->setTagInfo(root->tagInfo()); md->setLanguage(root->lang); //printf("Searching for '%s' fd=%p\n",filePathName.data(),fd); md->setFileDef(root->parent()->fileDef()); //printf("Adding member=%s\n",md->name().data()); - MemberName *mn; - if ((mn=Doxygen::functionNameSDict->find(root->name))) - { - mn->append(md); - } - else - { - mn = new MemberName(root->name); - mn->append(md); - Doxygen::functionNameSDict->append(root->name,mn); - } + MemberName *mn = Doxygen::functionNameLinkedMap->add(root->name); + mn->push_back(std::move(md)); } - MemberName *mn=Doxygen::functionNameSDict->find(root->name); + MemberName *mn=Doxygen::functionNameLinkedMap->find(root->name); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *md; int count=0; - for (;(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) count++; } if (count==1) { - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) { @@ -8230,7 +8152,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); + addMemberToGroups(root,md.get()); } } } @@ -8243,7 +8165,7 @@ 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 (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { if (md->memberType()==MemberType_Define) { @@ -8274,7 +8196,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); + addMemberToGroups(root,md.get()); } } } @@ -9398,11 +9320,7 @@ int readDir(QFileInfo *fi, { std::unique_ptr<FileDef> fd { createFileDef(cfi->dirPath().utf8()+"/",name) }; FileName *fn=0; - if (!name.isEmpty() && (fn=fnMap->find(name))) - { - fn->push_back(std::move(fd)); - } - else + if (!name.isEmpty()) { fn = fnMap->add(name,cfi->absFilePath().utf8()); fn->push_back(std::move(fd)); @@ -9493,14 +9411,9 @@ int readFileOrDirectory(const char *s, if (fnMap) { std::unique_ptr<FileDef> fd { createFileDef(dirPath+"/",name) }; - FileName *fn=0; - if (!name.isEmpty() && (fn=fnMap->find(name))) - { - fn->push_back(std::move(fd)); - } - else + if (!name.isEmpty()) { - fn = fnMap->add(name,filePath); + FileName *fn = fnMap->add(name,filePath); fn->push_back(std::move(fd)); } } @@ -9800,10 +9713,8 @@ void initDoxygen() #ifdef USE_LIBCLANG Doxygen::clangUsrMap = new QDict<Definition>(50177); #endif - Doxygen::memberNameSDict = new MemberNameSDict(10000); - Doxygen::memberNameSDict->setAutoDelete(TRUE); - Doxygen::functionNameSDict = new MemberNameSDict(10000); - Doxygen::functionNameSDict->setAutoDelete(TRUE); + Doxygen::memberNameLinkedMap = new MemberNameLinkedMap; + Doxygen::functionNameLinkedMap = new MemberNameLinkedMap; Doxygen::groupSDict = new GroupSDict(17); Doxygen::groupSDict->setAutoDelete(TRUE); Doxygen::namespaceSDict = new NamespaceSDict(20); @@ -9892,8 +9803,8 @@ void cleanUpDoxygen() } } - delete Doxygen::memberNameSDict; - delete Doxygen::functionNameSDict; + delete Doxygen::memberNameLinkedMap; + delete Doxygen::functionNameLinkedMap; delete Doxygen::groupSDict; delete Doxygen::classSDict; delete Doxygen::hiddenClasses; @@ -11123,9 +11034,20 @@ void parseInput() findGroupScope(root.get()); g_s.end(); + auto memberNameComp = [](const MemberNameLinkedMap::Ptr &n1,const MemberNameLinkedMap::Ptr &n2) + { + return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()), + n2->memberName()+getPrefixIndex(n2->memberName()) + )<0; + }; + g_s.begin("Sorting lists...\n"); - Doxygen::memberNameSDict->sort(); - Doxygen::functionNameSDict->sort(); + std::sort(Doxygen::memberNameLinkedMap->begin(), + Doxygen::memberNameLinkedMap->end(), + memberNameComp); + std::sort(Doxygen::functionNameLinkedMap->begin(), + Doxygen::functionNameLinkedMap->end(), + memberNameComp); Doxygen::hiddenClasses->sort(); Doxygen::classSDict->sort(); g_s.end(); diff --git a/src/doxygen.h b/src/doxygen.h index f8f09bd..a18ac3b 100644 --- a/src/doxygen.h +++ b/src/doxygen.h @@ -45,7 +45,7 @@ class FileDef; class ClassDef; class ClassSDict; class GenericsSDict; -class MemberNameSDict; +class MemberNameLinkedMap; class FileNameLinkedMap; class NamespaceSDict; class NamespaceDef; @@ -105,9 +105,9 @@ class Doxygen static FileNameLinkedMap *dotFileNameLinkedMap; static FileNameLinkedMap *mscFileNameLinkedMap; static FileNameLinkedMap *diaFileNameLinkedMap; + static MemberNameLinkedMap *memberNameLinkedMap; + static MemberNameLinkedMap *functionNameLinkedMap; static QStrList tagfileList; - static MemberNameSDict *memberNameSDict; - static MemberNameSDict *functionNameSDict; static StringDict namespaceAliasDict; static GroupSDict *groupSDict; static NamespaceSDict *namespaceSDict; diff --git a/src/fortrancode.l b/src/fortrancode.l index 81bf9f6..d7b006f 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -6,8 +6,8 @@ * based on the work of 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. * @@ -20,7 +20,7 @@ @todo - continuation lines not always recognized - merging of use-statements with same module name and different only-names - rename part of use-statement - - links to interface functions + - links to interface functions - references to variables **/ %option never-interactive @@ -84,15 +84,15 @@ int yy_end = 1; #define YY_USER_ACTION {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += static_cast<int>(yyleng);} #define YY_FTN_RESET {yy_old_start = 0; yy_my_start = 0; yy_end = 1;} #define YY_FTN_REJECT {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;} - + //-------------------------------------------------------------------------------- /** data of an use-statement */ -class UseEntry +class UseEntry { - public: + public: QCString module; // just for debug QCStringList onlyNames; /* entries of the ONLY-part */ }; @@ -101,7 +101,7 @@ class UseEntry module name -> list of ONLY/remote entries (module name = name of the module, which can be accessed via use-directive) */ -class UseSDict : public SDict<UseEntry> +class UseSDict : public SDict<UseEntry> { public: UseSDict() : SDict<UseEntry>(17) {} @@ -110,7 +110,7 @@ class UseSDict : public SDict<UseEntry> /** Contains names of used modules and names of local variables. */ -class Scope +class Scope { public: QCStringList useNames; //!< contains names of used modules @@ -121,10 +121,10 @@ class Scope }; /*===================================================================*/ -/* +/* * statics */ - + static QCString docBlock; //!< contents of all lines of a documentation block static QCString currentModule=0; //!< name of the current enclosing module static QCString currentClass=0; //!< name of the current enclosing class @@ -142,7 +142,7 @@ static QCString g_parmType; static QCString g_parmName; static const char * g_inputString; //!< the code fragment as text -static int g_inputPosition; //!< read offset during parsing +static int g_inputPosition; //!< read offset during parsing static int g_inputLines; //!< number of line in the code fragment static int g_yyLineNr; //!< current line number static int g_contLineNr; //!< current, local, line number for continuation determination @@ -233,7 +233,7 @@ static void startCodeLine() //QCString lineNumber,lineAnchor; //lineNumber.sprintf("%05d",g_yyLineNr); //lineAnchor.sprintf("l%05d",g_yyLineNr); - + Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr); //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>"); if (!g_includeCodeFragment && d) @@ -266,7 +266,7 @@ static void startCodeLine() g_code->writeLineNumber(0,0,0,g_yyLineNr); } } - g_code->startCodeLine(g_sourceFileDef); + g_code->startCodeLine(g_sourceFileDef); if (g_currentFontClass) { g_code->startFontClass(g_currentFontClass); @@ -301,7 +301,7 @@ static void codifyLines(char *text) *(p-1)='\0'; g_code->codify(sp); endCodeLine(); - if (g_yyLineNr<g_inputLines) + if (g_yyLineNr<g_inputLines) { startCodeLine(); } @@ -327,7 +327,7 @@ static void codifyLines(QCString str) } /*! 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 + * 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. */ static void writeMultiLineCodeLink(CodeOutputInterface &ol, @@ -338,7 +338,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol, QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); - QCString tooltip; + QCString tooltip; if (!sourceTooltips) // fall back to simple "title" tooltips { tooltip = d->briefDescriptionAsTooltip(); @@ -357,7 +357,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol, //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp); ol.writeCodeLink(ref,file,anchor,sp,tooltip); endCodeLine(); - if (g_yyLineNr<g_inputLines) + if (g_yyLineNr<g_inputLines) { startCodeLine(); } @@ -394,27 +394,27 @@ static bool getFortranNamespaceDefs(const QCString &mname, @param moduleName name of enclosing module or null, if global entry @param cd the entry, if found or null @param usedict dictionary of data of USE-statement - @returns true, if type is found + @returns true, if type is found */ -static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, +static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, ClassDef *&cd, UseSDict *usedict=0) { if (tname.isEmpty()) return FALSE; /* empty name => nothing to link */ //cout << "=== search for type: " << tname << endl; - // search for type - if ((cd=Doxygen::classSDict->find(tname))) + // search for type + if ((cd=Doxygen::classSDict->find(tname))) { //cout << "=== type found in global module" << endl; return TRUE; } - else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname))) + else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname))) { //cout << "=== type found in local module" << endl; return TRUE; } - else + else { UseEntry *use; for (UseSDict::Iterator di(*usedict); (use=di.current()); ++di) @@ -436,9 +436,9 @@ static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName @param moduleName name of enclosing module or null, if global entry @param md the entry, if found or null @param usedict array of data of USE-statement - @returns true, if found + @returns true, if found */ -static bool getFortranDefs(const QCString &memberName, const QCString &moduleName, +static bool getFortranDefs(const QCString &memberName, const QCString &moduleName, MemberDef *&md, UseSDict *usedict=0) { if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */ @@ -453,16 +453,16 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam } // search for function - MemberName *mn = Doxygen::functionNameSDict->find(memberName); + MemberName *mn = Doxygen::functionNameLinkedMap->find(memberName); if (!mn) { - mn = Doxygen::memberNameSDict->find(memberName); + mn = Doxygen::memberNameLinkedMap->find(memberName); } if (mn) // name is known { - MemberNameIterator mli(*mn); - for (mli.toFirst();(md=mli.current());++mli) // all found functions with given name + // all found functions with given name + for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); const GroupDef *gd=md->getGroupDef(); @@ -475,25 +475,26 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam { const NamespaceDef *nspace= md->getNamespaceDef(); - if (nspace == 0) + if (nspace == 0) { // found function in global scope - if(cd == 0) { // Skip if bound to type + if(cd == 0) + { // Skip if bound to type return TRUE; } } - else if (moduleName == nspace->name()) + else if (moduleName == nspace->name()) { // found in local scope return TRUE; } - else + else { // else search in used modules QCString usedModuleName= nspace->name(); UseEntry *ue= usedict->find(usedModuleName); - if (ue) + if (ue) { // check if only-list exists and if current entry exists is this list QCStringList &only= ue->onlyNames; - if (only.isEmpty()) + if (only.isEmpty()) { //cout << " found in module " << usedModuleName << " entry " << memberName << endl; return TRUE; // whole module used @@ -521,9 +522,9 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam gets the link to a generic procedure which depends not on the name, but on the parameter list @todo implementation */ -static bool getGenericProcedureLink(const ClassDef *cd, - const char *memberText, - CodeOutputInterface &ol) +static bool getGenericProcedureLink(const ClassDef *cd, + const char *memberText, + CodeOutputInterface &ol) { (void)cd; (void)memberText; @@ -540,7 +541,7 @@ static bool getLink(UseSDict *usedict, // dictionary with used modules QCString memberName= removeRedundantWhiteSpace(memberText); if (getFortranDefs(memberName, currentModule, md, usedict) && md->isLinkable()) - { + { if (md->isVariable() && (md->getLanguage()!=SrcLangExt_Fortran)) return FALSE; // Non Fortran variables aren't handled yet, // see also linkifyText in util.cpp @@ -549,15 +550,15 @@ static bool getLink(UseSDict *usedict, // dictionary with used modules if (md->getGroupDef()) d = md->getGroupDef(); if (d && d->isLinkable()) { - if (g_currentDefinition && g_currentMemberDef && + if (g_currentDefinition && g_currentMemberDef && md!=g_currentMemberDef && g_insideBody && g_collectXRefs) - { - addDocCrossReference(g_currentMemberDef,md); - } + { + addDocCrossReference(g_currentMemberDef,md); + } writeMultiLineCodeLink(ol,md,text ? text : memberText); addToSearchIndex(text ? text : memberText); return TRUE; - } + } } return FALSE; } @@ -569,16 +570,16 @@ static void generateLink(CodeOutputInterface &ol, char *lname) NamespaceDef *nsd=0; QCString tmp = lname; tmp = removeRedundantWhiteSpace(tmp.lower()); - + // check if lowercase lname is a linkable type or interface if ( (getFortranTypeDefs(tmp, currentModule, cd, useMembers)) && cd->isLinkable() ) { if ( (cd->compoundType() == ClassDef::Class) && // was Entry::INTERFACE_SEC) && - (getGenericProcedureLink(cd, tmp, ol)) ) + (getGenericProcedureLink(cd, tmp, ol)) ) { - //cout << "=== generic procedure resolved" << endl; - } - else + //cout << "=== generic procedure resolved" << endl; + } + else { // write type or interface link writeMultiLineCodeLink(ol,cd,tmp); addToSearchIndex(tmp.data()); @@ -591,11 +592,11 @@ static void generateLink(CodeOutputInterface &ol, char *lname) addToSearchIndex(tmp.data()); } // check for function/variable - else if (getLink(useMembers, tmp, ol, tmp)) + else if (getLink(useMembers, tmp, ol, tmp)) { //cout << "=== found link for lowercase " << lname << endl; } - else + else { // nothing found, just write out the word //startFontClass("charliteral"); //test @@ -611,23 +612,23 @@ static int countLines() const char *p=g_inputString; char c; int count=1; - while ((c=*p)) - { - p++ ; - if (c=='\n') count++; + while ((c=*p)) + { + p++ ; + if (c=='\n') count++; } - if (p>g_inputString && *(p-1)!='\n') + if (p>g_inputString && *(p-1)!='\n') { // last line does not end with a \n, so we add an extra // line and explicitly terminate the line after parsing. - count++, - g_needsTermination=TRUE; - } + count++, + g_needsTermination=TRUE; + } return count; } //---------------------------------------------------------------------------- /** start scope */ -static void startScope() +static void startScope() { DBG_CTX((stderr, "===> startScope %s",yytext)); Scope *scope = new Scope; @@ -635,31 +636,31 @@ static void startScope() } /** end scope */ -static void endScope() +static void endScope() { DBG_CTX((stderr,"===> endScope %s",yytext)); - if (scopeStack.isEmpty()) + if (scopeStack.isEmpty()) { - DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n")); + DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n")); return; } Scope *scope = scopeStack.getLast(); scopeStack.removeLast(); - for ( QCStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) + for ( QCStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) { useMembers->remove(*it); } delete scope; } -static void addUse(const QCString &moduleName) +static void addUse(const QCString &moduleName) { if (!scopeStack.isEmpty()) scopeStack.getLast()->useNames.append(moduleName); } -static void addLocalVar(const QCString &varName) +static void addLocalVar(const QCString &varName) { if (!scopeStack.isEmpty()) { @@ -750,7 +751,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); } /*-------- inner construct ---------------------------------------------------*/ - + <Start>{COMMANDS}/{BS}[,( \t\n] { // highlight /* font class is defined e.g. in doxygen.css */ startFontClass("keyword"); @@ -781,8 +782,8 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); endFontClass(); } -<Start>"implicit"{BS}("none"|{TYPE_SPEC}) { - startFontClass("keywordtype"); +<Start>"implicit"{BS}("none"|{TYPE_SPEC}) { + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); } @@ -792,20 +793,20 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); } /*-------- use statement -------------------------------------------*/ -<Start>"use"{BS_} { - startFontClass("keywordtype"); +<Start>"use"{BS_} { + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(Use); + BEGIN(Use); } <Use>"ONLY" { // TODO: rename - startFontClass("keywordtype"); + startFontClass("keywordtype"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(UseOnly); - } + BEGIN(UseOnly); + } <Use>{ID} { QCString tmp = yytext; tmp = tmp.lower(); @@ -821,7 +822,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") useEntry->module = tmp; useMembers->append(tmp, useEntry); addUse(tmp); - } + } <Use,UseOnly,Import>{BS},{BS} { codifyLines(yytext); } <UseOnly,Import>{BS}&{BS}"\n" { codifyLines(yytext); g_contLineNr++; @@ -859,11 +860,11 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") /*-------- fortran module -----------------------------------------*/ <Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { // startScope(); - startFontClass("keyword"); + startFontClass("keyword"); codifyLines(yytext); endFontClass(); yy_push_state(YY_START); - BEGIN(ClassName); + BEGIN(ClassName); if (!qstricmp(yytext,"module")) currentModule="module"; } <Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { // @@ -924,7 +925,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") startFontClass("keyword"); codifyLines(yytext); endFontClass(); - } + } <Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found startFontClass("keyword"); codifyLines(yytext); @@ -942,7 +943,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") codifyLines(yytext); endFontClass(); } -<Subprog>"("[^)]*")" { // ignore rest of line +<Subprog>"("[^)]*")" { // ignore rest of line codifyLines(yytext); } <Subprog,Subprogend>"\n" { codifyLines(yytext); @@ -978,7 +979,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_code->codify(yytext); endFontClass(); } -<Start>{TYPE_SPEC}/[,:( ] { +<Start>{TYPE_SPEC}/[,:( ] { QCString typ = yytext; typ = removeRedundantWhiteSpace(typ.lower()); if (typ.startsWith("real")) YY_FTN_REJECT; @@ -989,7 +990,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") g_code->codify(yytext); endFontClass(); } -<Start>{ATTR_SPEC} { +<Start>{ATTR_SPEC} { if (QCString(yytext) == "external") { yy_push_state(YY_START); @@ -1051,7 +1052,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") if (!g_isFixedForm) { yy_push_state(YY_START); - BEGIN(DeclContLine); + BEGIN(DeclContLine); } } <DeclContLine>"\n" { // declaration not yet finished @@ -1149,7 +1150,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") yy_end = static_cast<int>(yyleng); // Actually we should see if ! on position 6, can be continuation // but the chance is very unlikely, so no effort to solve it here - docBlock+=yytext; + docBlock+=yytext; } <DocBlock>"\n" { // comment block ends at the end of this line // remove special comment (default config) @@ -1203,7 +1204,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); } - /*------ preprocessor --------------------------------------------*/ + /*------ preprocessor --------------------------------------------*/ <Start>"#".*\n { if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT; g_contLineNr++; @@ -1212,17 +1213,17 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); YY_FTN_RESET } - /*------ variable references? -------------------------------------*/ + /*------ variable references? -------------------------------------*/ -<Start>"%"{BS}{ID} { // ignore references to elements +<Start>"%"{BS}{ID} { // ignore references to elements g_code->codify(yytext); } -<Start>{ID} { +<Start>{ID} { g_insideBody=TRUE; generateLink(*g_code, yytext); g_insideBody=FALSE; } - /*------ strings --------------------------------------------------*/ + /*------ strings --------------------------------------------------*/ <String>\n { // string with \n inside g_contLineNr++; g_str+=yytext; @@ -1231,15 +1232,15 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") endFontClass(); g_str = ""; YY_FTN_RESET - } -<String>\"|\' { // string ends with next quote without previous backspace + } +<String>\"|\' { // string ends with next quote without previous backspace if(yytext[0]!=stringStartSymbol) YY_FTN_REJECT; // single vs double quote g_str+=yytext; startFontClass("stringliteral"); codifyLines(g_str); endFontClass(); yy_pop_state(); - } + } <String>. {g_str+=yytext;} <*>\"|\' { /* string starts */ @@ -1268,7 +1269,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?") } <*>^{BS}"type"{BS}"=" { g_code->codify(yytext); } -<*>. { +<*>. { if (g_isFixedForm && yy_my_start > fixedCommentAfter) { //yy_push_state(YY_START); @@ -1328,7 +1329,7 @@ static void checkContLines(const char *s) g_hasContLine[0] = 0; } -void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, +void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, const MemberDef *,bool,const Definition *searchCtx, @@ -1362,7 +1363,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, else g_inputLines = g_yyLineNr + countLines() - 1; - g_exampleBlock = exBlock; + g_exampleBlock = exBlock; g_exampleName = exName; g_sourceFileDef = fd; if (exBlock && fd==0) @@ -1370,7 +1371,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, // create a dummy filedef for the example g_sourceFileDef = createFileDef("",exName); } - if (g_sourceFileDef) + if (g_sourceFileDef) { setCurrentDoc("l00001"); } diff --git a/src/membername.cpp b/src/membername.cpp index 72809b3..64bf49b 100644 --- a/src/membername.cpp +++ b/src/membername.cpp @@ -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. * @@ -20,30 +20,6 @@ #include "util.h" #include "filedef.h" -MemberName::MemberName(const char *n) : QList<MemberDef>() -{ - name=n; - setAutoDelete(TRUE); -} - -MemberName::~MemberName() -{ -} - -int MemberName::compareValues(const MemberDef *m1, const MemberDef *m2) const -{ - const ClassDef *c1=m1->getClassDef(); - const ClassDef *c2=m2->getClassDef(); - const FileDef *f1=m1->getFileDef(); - const FileDef *f2=m2->getFileDef(); - if (c1 && c2) - return qstrcmp(c1->name(),c2->name()); - else if (f1 && f2) - return qstrcmp(f1->name(),f2->name()); - else - return 0; -} - MemberNameInfo::MemberNameInfo(const char *n) : QList<MemberInfo>() { name=n; @@ -60,18 +36,7 @@ int MemberNameInfo::compareValues(const MemberInfo *m1,const MemberInfo *m2) con return qstrcmp(c1->name(),c2->name()); else if (f1 && f2) return qstrcmp(f1->name(),f2->name()); - else + else return 0; } -MemberNameIterator::MemberNameIterator(const MemberName &mnlist) : - QListIterator<MemberDef>(mnlist) -{ -} - -int MemberNameSDict::compareValues(const MemberName *n1,const MemberName *n2) const -{ - return qstricmp(n1->memberName()+getPrefixIndex(n1->memberName()), - n2->memberName()+getPrefixIndex(n2->memberName()) - ); -} diff --git a/src/membername.h b/src/membername.h index 04ceda0..4094132 100644 --- a/src/membername.h +++ b/src/membername.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. * @@ -21,36 +21,20 @@ #include <qlist.h> #include "memberdef.h" #include "sortdict.h" +#include "linkedmap.h" -/** Class representing all MemberDef objects with the same name */ -class MemberName : public QList<MemberDef> +class MemberName : public std::vector< std::unique_ptr<MemberDef> > { public: - MemberName(const char *name); - ~MemberName(); - const char *memberName() const { return name; } - + MemberName(const char *name) : m_name(name) {} + const char *memberName() const { return m_name; } private: - int compareValues(const MemberDef *item1,const MemberDef *item2) const; - QCString name; + QCString m_name; }; -/** Iterator for MemberDef objects in a MemberName list. */ -class MemberNameIterator : public QListIterator<MemberDef> +/** Ordered dictionary of MemberName objects. */ +class MemberNameLinkedMap : public LinkedMap<MemberName> { - public: - MemberNameIterator( const MemberName &list); -}; - -/** Sorted dictionary of MemberName objects. */ -class MemberNameSDict : public SDict<MemberName> -{ - public: - MemberNameSDict(uint size) : SDict<MemberName>(size) {} - ~MemberNameSDict() {} - - private: - int compareValues(const MemberName *item1,const MemberName *item2) const; }; /** Data associated with a MemberDef in an inheritance relation. */ @@ -64,7 +48,7 @@ struct MemberInfo Specifier virt; bool inherited; QCString scopePath; - QCString ambiguityResolutionScope; + QCString ambiguityResolutionScope; ClassDef *ambigClass; }; @@ -72,7 +56,7 @@ struct MemberInfo class MemberNameInfo : public QList<MemberInfo> { public: - MemberNameInfo(const char *name); + MemberNameInfo(const char *name); ~MemberNameInfo() {} const char *memberName() const { return name; } private: @@ -84,7 +68,7 @@ class MemberNameInfo : public QList<MemberInfo> class MemberNameInfoIterator : public QListIterator<MemberInfo> { public: - MemberNameInfoIterator(const MemberNameInfo &mnii) + MemberNameInfoIterator(const MemberNameInfo &mnii) : QListIterator<MemberInfo>(mnii) {} }; diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp index ee2d878..50e50a6 100644 --- a/src/namespacedef.cpp +++ b/src/namespacedef.cpp @@ -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. * @@ -370,7 +370,7 @@ void NamespaceDefImpl::findSectionsInDocumentation() void NamespaceDefImpl::insertUsedFile(FileDef *fd) { if (fd==0) return; - if (files.find(fd)==-1) + if (files.find(fd)==-1) { if (Config_getBool(SORT_MEMBER_DOCS)) files.inSort(fd); @@ -471,7 +471,7 @@ void NamespaceDefImpl::insertMember(MemberDef *md) // isInline(),hasDocumentation()); if (md->isHidden()) return; - // if this is an inline namespace that is not documented, then insert the + // if this is an inline namespace that is not documented, then insert the // member in the parent scope instead if (isInline() && !hasDocumentation()) { @@ -501,44 +501,44 @@ void NamespaceDefImpl::insertMember(MemberDef *md) allMemberList = new MemberList(MemberListType_allMembersList); m_memberLists.append(allMemberList); } - allMemberList->append(md); + allMemberList->append(md); if (m_allMembersDict==0) { m_allMembersDict = new MemberSDict; } //printf("%s::m_allMembersDict->append(%s)\n",name().data(),md->localName().data()); - m_allMembersDict->append(md->localName(),md); + m_allMembersDict->append(md->localName(),md); //::addNamespaceMemberNameToIndex(md); //static bool sortBriefDocs=Config_getBool(SORT_BRIEF_DOCS); switch(md->memberType()) { - case MemberType_Variable: + case MemberType_Variable: addMemberToList(MemberListType_decVarMembers,md); addMemberToList(MemberListType_docVarMembers,md); break; - case MemberType_Function: + case MemberType_Function: addMemberToList(MemberListType_decFuncMembers,md); addMemberToList(MemberListType_docFuncMembers,md); break; - case MemberType_Typedef: + case MemberType_Typedef: addMemberToList(MemberListType_decTypedefMembers,md); addMemberToList(MemberListType_docTypedefMembers,md); break; - case MemberType_Sequence: + case MemberType_Sequence: addMemberToList(MemberListType_decSequenceMembers,md); addMemberToList(MemberListType_docSequenceMembers,md); break; - case MemberType_Dictionary: + case MemberType_Dictionary: addMemberToList(MemberListType_decDictionaryMembers,md); addMemberToList(MemberListType_docDictionaryMembers,md); break; - case MemberType_Enumeration: + case MemberType_Enumeration: addMemberToList(MemberListType_decEnumMembers,md); addMemberToList(MemberListType_docEnumMembers,md); break; - case MemberType_EnumValue: + case MemberType_EnumValue: break; - case MemberType_Define: + case MemberType_Define: addMemberToList(MemberListType_decDefineMembers,md); addMemberToList(MemberListType_docDefineMembers,md); break; @@ -555,31 +555,23 @@ void NamespaceDefImpl::insertMember(MemberDef *md) Definition *outerScope = getOuterScope(); if (outerScope) { - MemberDef *aliasMd = 0; + std::unique_ptr<MemberDef> aliasMd; if (outerScope->definitionType()==Definition::TypeNamespace) { - aliasMd = createMemberDefAlias(outerScope,md); - dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd); + aliasMd.reset(createMemberDefAlias(outerScope,md)); + dynamic_cast<NamespaceDef*>(outerScope)->insertMember(aliasMd.get()); } else if (outerScope->definitionType()==Definition::TypeFile) { - aliasMd = createMemberDefAlias(outerScope,md); - dynamic_cast<FileDef*>(outerScope)->insertMember(aliasMd); + aliasMd.reset(createMemberDefAlias(outerScope,md)); + dynamic_cast<FileDef*>(outerScope)->insertMember(aliasMd.get()); } if (aliasMd) { MemberName *mn; QCString name = md->name(); - if ((mn=Doxygen::functionNameSDict->find(name))) - { - mn->append(aliasMd); - } - else - { - mn = new MemberName(name); - mn->append(aliasMd); - Doxygen::functionNameSDict->append(name,mn); - } + mn = Doxygen::functionNameLinkedMap->add(name); + mn->push_back(std::move(aliasMd)); } } } @@ -697,7 +689,7 @@ void NamespaceDefImpl::writeDetailedDescription(OutputList &ol,const QCString &t ol.popGeneratorState(); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); - ol.writeAnchor(0,"details"); + ol.writeAnchor(0,"details"); ol.popGeneratorState(); ol.startGroupHeader(); ol.parseText(title); @@ -841,7 +833,7 @@ void NamespaceDefImpl::writeMemberGroups(OutputList &ol) MemberGroup *mg; for (;(mg=mgli.current());++mgli) { - if ((!mg->allMembersInSameSection() || !m_subGrouping) + if ((!mg->allMembersInSameSection() || !m_subGrouping) && mg->header()!="[NOHEADER]") { mg->writeDeclarations(ol,0,this,0,0); @@ -849,7 +841,7 @@ void NamespaceDefImpl::writeMemberGroups(OutputList &ol) } } } - + void NamespaceDefImpl::writeAuthorSection(OutputList &ol) { // write Author section (Man only) @@ -978,7 +970,7 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) addNamespaceAttributes(ol); endTitle(ol,getOutputFileBase(),displayName()); ol.startContents(); - + if (Doxygen::searchIndex) { Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE); @@ -997,82 +989,82 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) { switch (lde->kind()) { - case LayoutDocEntry::BriefDesc: + case LayoutDocEntry::BriefDesc: writeBriefDescription(ol); - break; - case LayoutDocEntry::MemberDeclStart: + break; + case LayoutDocEntry::MemberDeclStart: startMemberDeclarations(ol); - break; - case LayoutDocEntry::NamespaceClasses: + break; + case LayoutDocEntry::NamespaceClasses: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),classSDict); } - break; - case LayoutDocEntry::NamespaceInterfaces: + break; + case LayoutDocEntry::NamespaceInterfaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),interfaceSDict); } - break; - case LayoutDocEntry::NamespaceStructs: + break; + case LayoutDocEntry::NamespaceStructs: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),structSDict); } - break; - case LayoutDocEntry::NamespaceExceptions: + break; + case LayoutDocEntry::NamespaceExceptions: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeClassDeclarations(ol,ls->title(lang),exceptionSDict); } - break; - case LayoutDocEntry::NamespaceNestedNamespaces: + break; + case LayoutDocEntry::NamespaceNestedNamespaces: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),false); } - break; + break; case LayoutDocEntry::NamespaceNestedConstantGroups: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeNamespaceDeclarations(ol,ls->title(lang),true); } break; - case LayoutDocEntry::MemberGroups: + case LayoutDocEntry::MemberGroups: writeMemberGroups(ol); - break; - case LayoutDocEntry::MemberDecl: + break; + case LayoutDocEntry::MemberDecl: { LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde; writeMemberDeclarations(ol,lmd->type,lmd->title(lang)); } - break; - case LayoutDocEntry::MemberDeclEnd: + break; + case LayoutDocEntry::MemberDeclEnd: endMemberDeclarations(ol); break; - case LayoutDocEntry::DetailedDesc: + case LayoutDocEntry::DetailedDesc: { LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde; writeDetailedDescription(ol,ls->title(lang)); } break; - case LayoutDocEntry::MemberDefStart: + case LayoutDocEntry::MemberDefStart: startMemberDocumentation(ol); - break; + break; case LayoutDocEntry::NamespaceInlineClasses: writeInlineClasses(ol); break; - case LayoutDocEntry::MemberDef: + case LayoutDocEntry::MemberDef: { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; writeMemberDocumentation(ol,lmd->type,lmd->title(lang)); } break; - case LayoutDocEntry::MemberDefEnd: + case LayoutDocEntry::MemberDefEnd: endMemberDocumentation(ol); break; - case LayoutDocEntry::AuthorSection: + case LayoutDocEntry::AuthorSection: writeAuthorSection(ol); break; case LayoutDocEntry::ClassIncludes: @@ -1090,16 +1082,16 @@ void NamespaceDefImpl::writeDocumentation(OutputList &ol) case LayoutDocEntry::FileConstantGroups: case LayoutDocEntry::FileIncludes: case LayoutDocEntry::FileIncludeGraph: - case LayoutDocEntry::FileIncludedByGraph: + case LayoutDocEntry::FileIncludedByGraph: case LayoutDocEntry::FileSourceLink: case LayoutDocEntry::FileInlineClasses: - case LayoutDocEntry::GroupClasses: - case LayoutDocEntry::GroupInlineClasses: + case LayoutDocEntry::GroupClasses: + case LayoutDocEntry::GroupInlineClasses: case LayoutDocEntry::GroupNamespaces: - case LayoutDocEntry::GroupDirs: - case LayoutDocEntry::GroupNestedGroups: + case LayoutDocEntry::GroupDirs: + case LayoutDocEntry::GroupNestedGroups: case LayoutDocEntry::GroupFiles: - case LayoutDocEntry::GroupGraph: + case LayoutDocEntry::GroupGraph: case LayoutDocEntry::GroupPageDocs: case LayoutDocEntry::DirSubDirs: case LayoutDocEntry::DirFiles: @@ -1224,10 +1216,10 @@ void NamespaceDefImpl::addUsingDirective(const NamespaceDef *nd) //printf("%p: NamespaceDefImpl::addUsingDirective: %s:%d\n",this,name().data(),usingDirList->count()); } -const NamespaceSDict *NamespaceDefImpl::getUsedNamespaces() const -{ +const NamespaceSDict *NamespaceDefImpl::getUsedNamespaces() const +{ //printf("%p: NamespaceDefImpl::getUsedNamespace: %s:%d\n",this,name().data(),usingDirList?usingDirList->count():0); - return usingDirList; + return usingDirList; } void NamespaceDefImpl::addUsingDeclaration(const Definition *d) @@ -1272,8 +1264,8 @@ void NamespaceDefImpl::addListReferences() const std::vector<RefItem*> &xrefItems = xrefListItems(); addRefItem(xrefItems, qualifiedName(), - getLanguage()==SrcLangExt_Fortran ? - theTranslator->trModule(TRUE,TRUE) : + getLanguage()==SrcLangExt_Fortran ? + theTranslator->trModule(TRUE,TRUE) : theTranslator->trNamespace(TRUE,TRUE), getOutputFileBase(),displayName(), 0, @@ -1307,7 +1299,7 @@ QCString NamespaceDefImpl::displayName(bool includeScope) const result = substitute(result,"::",sep); } //printf("NamespaceDefImpl::displayName() %s->%s lang=%d\n",name().data(),result.data(),lang); - return result; + return result; } QCString NamespaceDefImpl::localName() const @@ -1378,12 +1370,12 @@ bool NamespaceSDict::declVisible() const void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title, bool const isConstantGroup,bool localName) { - + if (count()==0) return; // no namespaces in the list if (Config_getBool(OPTIMIZE_OUTPUT_VHDL)) return; - + SDict<NamespaceDef>::Iterator ni(*this); NamespaceDef *nd; @@ -2797,10 +2797,10 @@ static void addDefine(yyscan_t yyscanner) //printf("addDefine '%s' '%s'\n",state->defName.data(),state->defArgsStr.data()); //ArgumentList *al = new ArgumentList; //stringToArgumentList(state->defArgsStr,al); - MemberDef *md=createMemberDef( + std::unique_ptr<MemberDef> md { createMemberDef( state->yyFileName,state->yyLineNr-state->yyMLines,state->yyColNr, "#define",state->defName,state->defArgsStr,0, - Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),""); + Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),"") }; if (!state->defArgsStr.isEmpty()) { ArgumentList argList; @@ -2838,17 +2838,12 @@ static void addDefine(yyscan_t yyscanner) md->setFileDef(state->inputFileDef); md->setDefinition("#define "+state->defName); - MemberName *mn=Doxygen::functionNameSDict->find(state->defName); - if (mn==0) - { - mn = new MemberName(state->defName); - Doxygen::functionNameSDict->append(state->defName,mn); - } - mn->append(md); + MemberName *mn=Doxygen::functionNameLinkedMap->add(state->defName); if (state->yyFileDef) { - state->yyFileDef->insertMember(md); + state->yyFileDef->insertMember(md.get()); } + mn->push_back(std::move(md)); } static inline void outputChar(yyscan_t yyscanner,char c) diff --git a/src/searchindex.cpp b/src/searchindex.cpp index 00786d6..ec7f7d6 100644 --- a/src/searchindex.cpp +++ b/src/searchindex.cpp @@ -846,34 +846,26 @@ void createJavaScriptSearchIndex() // index class members { - MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict); - MemberName *mn; // for each member name - for (mnli.toFirst();(mn=mnli.current());++mnli) + for (const auto &mn : *Doxygen::memberNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addMemberToSearchIndex(md); + addMemberToSearchIndex(md.get()); } } } // index file/namespace members { - MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict); - MemberName *mn; // for each member name - for (fnli.toFirst();(mn=fnli.current());++fnli) + for (const auto &mn : *Doxygen::functionNameLinkedMap) { - MemberDef *md; - MemberNameIterator mni(*mn); // for each member definition - for (mni.toFirst();(md=mni.current());++mni) + for (const auto &md : *mn) { - addMemberToSearchIndex(md); + addMemberToSearchIndex(md.get()); } } } diff --git a/src/util.cpp b/src/util.cpp index 920e794..7fc98a7 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -408,32 +408,30 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName, { //printf("scope found: %s, look for typedef %s\n", // resScope->qualifiedName().data(),resName.data()); - MemberNameSDict *mnd=0; + MemberNameLinkedMap *mnd=0; if (resScope->definitionType()==Definition::TypeClass) { - mnd=Doxygen::memberNameSDict; + mnd=Doxygen::memberNameLinkedMap; } else { - mnd=Doxygen::functionNameSDict; + mnd=Doxygen::functionNameLinkedMap; } MemberName *mn=mnd->find(resName); if (mn) { - MemberNameIterator mni(*mn); - MemberDef *tmd=0; int minDist=-1; - for (;(tmd=mni.current());++mni) + for (const auto &tmd : *mn) { //printf("Found member %s resScope=%s outerScope=%s mContext=%p\n", // tmd->name().data(), resScope->name().data(), // tmd->getOuterScope()->name().data(), mContext); if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/) { - int dist=isAccessibleFrom(resScope,0,tmd); + int dist=isAccessibleFrom(resScope,0,tmd.get()); if (dist!=-1 && (md==0 || dist<minDist)) { - md = tmd; + md = tmd.get(); minDist = dist; } } @@ -3398,9 +3396,7 @@ static void findMembersWithSpecificName(MemberName *mn, { //printf(" Function with global scope name '%s' args='%s'\n", // mn->memberName(),args); - MemberNameIterator mli(*mn); - const MemberDef *md = 0; - for (mli.toFirst();(md=mli.current());++mli) + for (const auto &md : *mn) { const FileDef *fd=md->getFileDef(); const GroupDef *gd=md->getGroupDef(); @@ -3427,7 +3423,7 @@ static void findMembersWithSpecificName(MemberName *mn, if (match && (forceTagFile==0 || md->getReference()==forceTagFile)) { //printf("Found match!\n"); - members.append(md); + members.append(md.get()); } } } @@ -3509,7 +3505,7 @@ bool getDefs(const QCString &scName, //printf("mScope='%s' mName='%s'\n",mScope.data(),mName.data()); - MemberName *mn = Doxygen::memberNameSDict->find(mName); + MemberName *mn = Doxygen::memberNameLinkedMap->find(mName); //printf("mName=%s mn=%p\n",mName.data(),mn); if ((!forceEmptyScope || scopeName.isEmpty()) && // this was changed for bug638856, forceEmptyScope => empty scopeName @@ -3543,15 +3539,13 @@ bool getDefs(const QCString &scName, ) { //printf(" Found fcd=%p\n",fcd); - MemberNameIterator mmli(*mn); - MemberDef *mmd; int mdist=maxInheritanceDepth; ArgumentList argList; if (args) { stringToArgumentList(fcd->getLanguage(),args,argList); } - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { if (!mmd->isStrongEnumValue()) { @@ -3571,7 +3565,7 @@ bool getDefs(const QCString &scName, { mdist=m; cd=mcd; - md=mmd; + md=mmd.get(); } } } @@ -3581,7 +3575,7 @@ bool getDefs(const QCString &scName, // no exact match found, but if args="()" an arbitrary member will do { //printf(" >Searching for arbitrary member\n"); - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { //if (mmd->isLinkable()) //{ @@ -3595,7 +3589,7 @@ bool getDefs(const QCString &scName, //printf("Class distance %d\n",m); mdist=m; cd=mcd; - md=mmd; + md=mmd.get(); } } //} @@ -3661,8 +3655,7 @@ bool getDefs(const QCString &scName, if (mn && scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function? { //printf("Global symbol\n"); - MemberNameIterator mmli(*mn); - MemberDef *mmd, *fuzzy_mmd = 0; + MemberDef *fuzzy_mmd = 0; ArgumentList argList; bool hasEmptyArgs = args && qstrcmp(args, "()") == 0; @@ -3671,7 +3664,7 @@ bool getDefs(const QCString &scName, stringToArgumentList(SrcLangExt_Cpp, args, argList); } - for (mmli.toFirst(); (mmd = mmli.current()); ++mmli) + for (const auto &mmd : *mn) { if (!mmd->isLinkable() || (!mmd->isRelated() && !mmd->isForeign()) || !mmd->getClassDef()) @@ -3681,6 +3674,7 @@ bool getDefs(const QCString &scName, if (!args) { + fuzzy_mmd = mmd.get(); break; } @@ -3691,21 +3685,20 @@ bool getDefs(const QCString &scName, ) ) { + fuzzy_mmd = mmd.get(); break; } if (!fuzzy_mmd && hasEmptyArgs) { - fuzzy_mmd = mmd; + fuzzy_mmd = mmd.get(); } } - mmd = mmd ? mmd : fuzzy_mmd; - - if (mmd && !mmd->isStrongEnumValue()) + if (fuzzy_mmd && !fuzzy_mmd->isStrongEnumValue()) { - md = mmd; - cd = mmd->getClassDef(); + md = fuzzy_mmd; + cd = fuzzy_mmd->getClassDef(); return TRUE; } } @@ -3714,7 +3707,7 @@ bool getDefs(const QCString &scName, // maybe an namespace, file or group member ? //printf("Testing for global symbol scopeName='%s' mScope='%s' :: mName='%s'\n", // scopeName.data(),mScope.data(),mName.data()); - if ((mn=Doxygen::functionNameSDict->find(mName))) // name is known + if ((mn=Doxygen::functionNameLinkedMap->find(mName))) // name is known { //printf(" >symbol name found\n"); NamespaceDef *fnd=0; @@ -3739,9 +3732,7 @@ bool getDefs(const QCString &scName, //printf("Symbol inside existing namespace '%s' count=%d\n", // namespaceName.data(),mn->count()); bool found=FALSE; - MemberNameIterator mmli(*mn); - const MemberDef *mmd; - for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) + for (const auto &mmd : *mn) { //printf("mmd->getNamespaceDef()=%p fnd=%p\n", // mmd->getNamespaceDef(),fnd); @@ -3754,8 +3745,9 @@ bool getDefs(const QCString &scName, { //printf("found it!\n"); nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } else { @@ -3780,8 +3772,9 @@ bool getDefs(const QCString &scName, if (match) { nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } } } @@ -3789,13 +3782,14 @@ bool getDefs(const QCString &scName, // no exact match found, but if args="()" an arbitrary // member will do { - for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli) + for (const auto &mmd : *mn) { if (mmd->getNamespaceDef()==fnd /*&& mmd->isLinkable() */ ) { nd=fnd; - md=mmd; + md=mmd.get(); found=TRUE; + break; } } } @@ -3818,9 +3812,7 @@ bool getDefs(const QCString &scName, else { //printf("not a namespace\n"); - MemberNameIterator mmli(*mn); - MemberDef *mmd; - for (mmli.toFirst();(mmd=mmli.current());++mmli) + for (const auto &mmd : *mn) { const MemberDef *tmd = mmd->getEnumScope(); //printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>"); @@ -3834,7 +3826,7 @@ bool getDefs(const QCString &scName, namespaceName.length()>0 // enum is part of namespace so this should not be empty ) { - md=mmd; + md=mmd.get(); fd=mmd->getFileDef(); gd=mmd->getGroupDef(); if (gd && gd->isLinkable()) fd=0; else gd=0; @@ -3869,9 +3861,11 @@ bool getDefs(const QCString &scName, { // no exact match found, but if args="()" an arbitrary // member will do - MemberNameIterator mni(*mn); - for (mni.toLast();(md=mni.current());--mni) + //MemberNameIterator mni(*mn); + //for (mni.toLast();(md=mni.current());--mni) + for (auto it = mn->rbegin(); it!=mn->rend(); ++it) { + const auto &md = *it; //printf("Found member '%s'\n",md->name().data()); //printf("member is linkable md->name()='%s'\n",md->name().data()); fd=md->getFileDef(); @@ -3882,7 +3876,7 @@ bool getDefs(const QCString &scName, (tmd && tmd->isStrong()) ) { - members.append(md); + members.append(md.get()); } } } |