summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/classdef.cpp685
-rw-r--r--src/classdef.h102
-rw-r--r--src/code.l416
-rw-r--r--src/context.cpp79
-rw-r--r--src/context.h13
-rw-r--r--src/defgen.cpp82
-rw-r--r--src/diagram.cpp132
-rw-r--r--src/doctokenizer.l2
-rw-r--r--src/docvisitor.cpp2
-rw-r--r--src/dotclassgraph.cpp15
-rw-r--r--src/dotgfxhierarchytable.cpp119
-rw-r--r--src/doxygen.cpp10
-rw-r--r--src/index.cpp13
-rw-r--r--src/latexgen.cpp31
-rw-r--r--src/markdown.cpp4
-rw-r--r--src/perlmodgen.cpp28
-rw-r--r--src/pycode.l215
-rw-r--r--src/scopedtypevariant.h292
-rw-r--r--src/searchindex.cpp10
-rw-r--r--src/sqlite3gen.cpp44
-rw-r--r--src/util.cpp219
-rw-r--r--src/util.h70
-rw-r--r--src/vhdldocgen.cpp96
-rw-r--r--src/xmlgen.cpp110
24 files changed, 1313 insertions, 1476 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 5e2b2fa..e797b05e 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -81,8 +81,10 @@ class ClassDefImpl : public DefinitionImpl, public ClassDef
virtual QCString displayName(bool includeScope=TRUE) const;
virtual CompoundType compoundType() const;
virtual QCString compoundTypeString() const;
- virtual BaseClassList *baseClasses() const;
- virtual BaseClassList *subClasses() const;
+ virtual BaseClassList baseClasses() const;
+ virtual void updateBaseClasses(BaseClassList bcd);
+ virtual BaseClassList subClasses() const;
+ virtual void updateSubClasses(BaseClassList bcd);
virtual const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const;
virtual Protection protection() const;
virtual bool isLinkableInProject() const;
@@ -318,9 +320,9 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef
{ return getCdAlias()->compoundType(); }
virtual QCString compoundTypeString() const
{ return getCdAlias()->compoundTypeString(); }
- virtual BaseClassList *baseClasses() const
+ virtual BaseClassList baseClasses() const
{ return getCdAlias()->baseClasses(); }
- virtual BaseClassList *subClasses() const
+ virtual BaseClassList subClasses() const
{ return getCdAlias()->subClasses(); }
virtual const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const
{ return getCdAlias()->memberNameInfoLinkedMap(); }
@@ -510,6 +512,8 @@ class ClassDefAliasImpl : public DefinitionAliasImpl, public ClassDef
virtual void addGroupedInheritedMembers(OutputList &,MemberListType,
const ClassDef *,const QCString &) const {}
virtual void writeTagFile(FTextStream &) {}
+ virtual void updateBaseClasses(BaseClassList) {}
+ virtual void updateSubClasses(BaseClassList) {}
virtual void setVisited(bool visited) const { m_visited = visited; }
virtual bool isVisited() const { return m_visited; }
@@ -567,11 +571,11 @@ class ClassDefImpl::IMPL
/*! List of base class (or super-classes) from which this class derives
* directly.
*/
- BaseClassList *inherits = 0;
+ BaseClassList inherits;
/*! List of sub-classes that directly derive from this class
*/
- BaseClassList *inheritedBy = 0;
+ BaseClassList inheritedBy;
/*! Namespace this class is part of
* (this is the inner most namespace in case of nested namespaces)
@@ -703,8 +707,6 @@ void ClassDefImpl::IMPL::init(const char *defFileName, const char *name,
fileName=ctStr+name;
}
exampleSDict = 0;
- inherits = 0;
- inheritedBy = 0;
incInfo=0;
prot=Public;
nspace=0;
@@ -756,8 +758,6 @@ ClassDefImpl::IMPL::IMPL() : vhdlSummaryTitles(17)
ClassDefImpl::IMPL::~IMPL()
{
- delete inherits;
- delete inheritedBy;
delete exampleSDict;
delete usesImplClassDict;
delete usedByImplClassDict;
@@ -855,13 +855,7 @@ void ClassDefImpl::insertBaseClass(ClassDef *cd,const char *n,Protection p,
Specifier s,const char *t)
{
//printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
- //inherits->inSort(new BaseClassDef(cd,p,s,t));
- if (m_impl->inherits==0)
- {
- m_impl->inherits = new BaseClassList;
- m_impl->inherits->setAutoDelete(TRUE);
- }
- m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
+ m_impl->inherits.push_back(BaseClassDef(cd,n,p,s,t));
m_impl->isSimple = FALSE;
}
@@ -872,12 +866,7 @@ void ClassDefImpl::insertSubClass(ClassDef *cd,Protection p,
//printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
if (!extractPrivate && cd->protection()==Private) return;
- if (m_impl->inheritedBy==0)
- {
- m_impl->inheritedBy = new BaseClassList;
- m_impl->inheritedBy->setAutoDelete(TRUE);
- }
- m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
+ m_impl->inheritedBy.push_back(BaseClassDef(cd,0,p,s,t));
m_impl->isSimple = FALSE;
}
@@ -1287,22 +1276,22 @@ void ClassDefImpl::insertUsedFile(FileDef *fd)
}
}
-static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
+static void writeInheritanceSpecifier(OutputList &ol,const BaseClassDef &bcd)
{
- if (bcd->prot!=Public || bcd->virt!=Normal)
+ if (bcd.prot!=Public || bcd.virt!=Normal)
{
ol.startTypewriter();
ol.docify(" [");
- QStrList sl;
- if (bcd->prot==Protected) sl.append("protected");
- else if (bcd->prot==Private) sl.append("private");
- if (bcd->virt==Virtual) sl.append("virtual");
- const char *s=sl.first();
- while (s)
+ StringVector sl;
+ if (bcd.prot==Protected) sl.push_back("protected");
+ else if (bcd.prot==Private) sl.push_back("private");
+ if (bcd.virt==Virtual) sl.push_back("virtual");
+ bool first=true;
+ for (const auto &s : sl)
{
- ol.docify(s);
- s=sl.next();
- if (s) ol.docify(", ");
+ if (!first) ol.docify(", ");
+ ol.docify(s.c_str());
+ first=false;
}
ol.docify("]");
ol.endTypewriter();
@@ -1660,24 +1649,15 @@ void ClassDefImpl::showUsedFiles(OutputList &ol) const
int ClassDefImpl::countInheritanceNodes() const
{
int count=0;
- BaseClassDef *ibcd;
- if (m_impl->inheritedBy)
+ for (const auto &ibcd : m_impl->inheritedBy)
{
- BaseClassListIterator it(*m_impl->inheritedBy);
- for (;(ibcd=it.current());++it)
- {
- ClassDef *icd=ibcd->classDef;
- if ( icd->isVisibleInHierarchy()) count++;
- }
+ const ClassDef *icd=ibcd.classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
}
- if (m_impl->inherits)
+ for (const auto &ibcd : m_impl->inherits)
{
- BaseClassListIterator it(*m_impl->inherits);
- for (;(ibcd=it.current());++it)
- {
- ClassDef *icd=ibcd->classDef;
- if ( icd->isVisibleInHierarchy()) count++;
- }
+ const ClassDef *icd=ibcd.classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
}
return count;
}
@@ -1727,12 +1707,12 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const
ol.disableAllBut(OutputGenerator::Man);
}
- if (m_impl->inherits && m_impl->inherits->count()>0)
+ if (!m_impl->inherits.empty())
{
ol.startParagraph();
//parseText(ol,theTranslator->trInherits()+" ");
- QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits->count());
+ QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits.size());
QRegExp marker("@[0-9]+");
int index=0,newIndex,matchLen;
// now replace all markers in inheritLine with links to the classes
@@ -1741,15 +1721,15 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const
ol.parseText(inheritLine.mid(index,newIndex-index));
bool ok;
uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
- if (ok && bcd)
+ BaseClassDef &bcd=m_impl->inherits.at(entryIndex);
+ if (ok)
{
- ClassDef *cd=bcd->classDef;
+ ClassDef *cd=bcd.classDef;
// use the class name but with the template arguments as given
// in the inheritance relation
QCString displayName = insertTemplateSpecifierInScope(
- cd->displayName(),bcd->templSpecifiers);
+ cd->displayName(),bcd.templSpecifiers);
if (cd->isLinkable())
{
@@ -1774,10 +1754,10 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const
}
// write subclasses
- if (m_impl->inheritedBy && m_impl->inheritedBy->count()>0)
+ if (!m_impl->inheritedBy.empty())
{
ol.startParagraph();
- QCString inheritLine = theTranslator->trInheritedByList((int)m_impl->inheritedBy->count());
+ QCString inheritLine = theTranslator->trInheritedByList((int)m_impl->inheritedBy.size());
QRegExp marker("@[0-9]+");
int index=0,newIndex,matchLen;
// now replace all markers in inheritLine with links to the classes
@@ -1786,10 +1766,10 @@ void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const
ol.parseText(inheritLine.mid(index,newIndex-index));
bool ok;
uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
- if (ok && bcd)
+ BaseClassDef &bcd=m_impl->inheritedBy.at(entryIndex);
+ if (ok)
{
- ClassDef *cd=bcd->classDef;
+ ClassDef *cd=bcd.classDef;
if (cd->isLinkable())
{
ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
@@ -1935,35 +1915,30 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const
ol.docify("class ");
}
ol.docify(stripScope(name()));
- if (m_impl->inherits)
+ if (!m_impl->inherits.empty())
{
if (m_impl->spec & (Entry::Interface|Entry::Exception))
{
ol.docify(" extends ");
- BaseClassListIterator it(*m_impl->inherits);
- BaseClassDef *ibcd;
- for (;(ibcd=it.current());++it)
+ bool first=true;
+ for (const auto &ibcd : m_impl->inherits)
{
- ClassDef *icd = ibcd->classDef;
+ if (!first) ol.docify(", ");
+ ClassDef *icd = ibcd.classDef;
ol.docify(icd->name());
- if (!it.atLast())
- {
- ol.docify(", ");
- }
+ first=false;
}
}
else
{
// Must be a class.
- bool implements = FALSE;
- BaseClassListIterator it(*m_impl->inherits);
- BaseClassDef *ibcd;
- for (;(ibcd=it.current());++it)
+ bool implements = false;
+ for (const auto &ibcd : m_impl->inherits)
{
- ClassDef *icd = ibcd->classDef;
+ ClassDef *icd = ibcd.classDef;
if (icd->isInterface())
{
- implements = TRUE;
+ implements = true;
}
else
{
@@ -1974,20 +1949,14 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const
if (implements)
{
ol.docify(" implements ");
- bool first = TRUE;
- for (ibcd=it.toFirst();(ibcd=it.current());++it)
+ bool first = true;
+ for (const auto &ibcd : m_impl->inherits)
{
- ClassDef *icd = ibcd->classDef;
+ ClassDef *icd = ibcd.classDef;
if (icd->isInterface())
{
- if (!first)
- {
- ol.docify(", ");
- }
- else
- {
- first = FALSE;
- }
+ if (!first) ol.docify(", ");
+ first = false;
ol.docify(icd->name());
}
}
@@ -2223,32 +2192,27 @@ void ClassDefImpl::writeTagFile(FTextStream &tagFile)
{
tagFile << " <templarg>" << convertToXML(a.name) << "</templarg>" << endl;
}
- if (m_impl->inherits)
+ for (const auto &ibcd : m_impl->inherits)
{
- BaseClassListIterator it(*m_impl->inherits);
- BaseClassDef *ibcd;
- for (it.toFirst();(ibcd=it.current());++it)
+ ClassDef *cd=ibcd.classDef;
+ if (cd && cd->isLinkable())
{
- ClassDef *cd=ibcd->classDef;
- if (cd && cd->isLinkable())
+ if (!Config_getString(GENERATE_TAGFILE).isEmpty())
{
- if (!Config_getString(GENERATE_TAGFILE).isEmpty())
+ tagFile << " <base";
+ if (ibcd.prot==Protected)
{
- tagFile << " <base";
- if (ibcd->prot==Protected)
- {
- tagFile << " protection=\"protected\"";
- }
- else if (ibcd->prot==Private)
- {
- tagFile << " protection=\"private\"";
- }
- if (ibcd->virt==Virtual)
- {
- tagFile << " virtualness=\"virtual\"";
- }
- tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
+ tagFile << " protection=\"protected\"";
+ }
+ else if (ibcd.prot==Private)
+ {
+ tagFile << " protection=\"private\"";
}
+ if (ibcd.virt==Virtual)
+ {
+ tagFile << " virtualness=\"virtual\"";
+ }
+ tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
}
}
}
@@ -3338,29 +3302,29 @@ bool ClassDefImpl::hasNonReferenceSuperClass() const
{
return TRUE; // we're done if this class is not a reference
}
- if (m_impl->inheritedBy)
+ for (const auto &ibcd : m_impl->inheritedBy)
{
- BaseClassListIterator bcli(*m_impl->inheritedBy);
- for ( ; bcli.current() && !found ; ++bcli ) // for each super class
+ ClassDef *bcd=ibcd.classDef;
+ // recurse into the super class branch
+ found = found || bcd->hasNonReferenceSuperClass();
+ if (!found)
{
- ClassDef *bcd=bcli.current()->classDef;
- // recurse into the super class branch
- found = found || bcd->hasNonReferenceSuperClass();
- if (!found)
+ // look for template instances that might have non-reference super classes
+ QDict<ClassDef> *cil = bcd->getTemplateInstances();
+ if (cil)
{
- // look for template instances that might have non-reference super classes
- QDict<ClassDef> *cil = bcd->getTemplateInstances();
- if (cil)
+ QDictIterator<ClassDef> tidi(*cil);
+ for ( ; tidi.current() && !found ; ++tidi) // for each template instance
{
- QDictIterator<ClassDef> tidi(*cil);
- for ( ; tidi.current() && !found ; ++tidi) // for each template instance
- {
- // recurse into the template instance branch
- found = found || tidi.current()->hasNonReferenceSuperClass();
- }
+ // recurse into the template instance branch
+ found = found || tidi.current()->hasNonReferenceSuperClass();
}
}
}
+ else
+ {
+ break;
+ }
}
return found;
}
@@ -3497,21 +3461,12 @@ bool ClassDefImpl::isBaseClass(const ClassDef *bcd, bool followInstances,int lev
err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
return FALSE;
}
- if (baseClasses())
+ for (const auto &bclass : baseClasses())
{
- // Beware: trying to optimise the iterator away using ->first() & ->next()
- // causes bug 625531
- BaseClassListIterator bcli(*baseClasses());
- for ( ; bcli.current() && !found ; ++bcli)
- {
- const ClassDef *ccd=bcli.current()->classDef;
- if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
- //printf("isBaseClass() baseclass %s\n",ccd->name().data());
- if (ccd==bcd)
- found=TRUE;
- else
- found=ccd->isBaseClass(bcd,followInstances,level+1);
- }
+ const ClassDef *ccd = bclass.classDef;
+ if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
+ found = (ccd==bcd) || ccd->isBaseClass(bcd,followInstances,level+1);
+ if (found) break;
}
return found;
}
@@ -3526,17 +3481,11 @@ bool ClassDefImpl::isSubClass(ClassDef *cd,int level) const
err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
return FALSE;
}
- if (subClasses())
+ for (const auto &iscd : subClasses())
{
- BaseClassListIterator bcli(*subClasses());
- for ( ; bcli.current() && !found ; ++bcli)
- {
- ClassDef *ccd=bcli.current()->classDef;
- if (ccd==cd)
- found=TRUE;
- else
- found=ccd->isSubClass(cd,level+1);
- }
+ ClassDef *ccd=iscd.classDef;
+ found = (ccd==cd) || ccd->isSubClass(cd,level+1);
+ if (found) break;
}
return found;
}
@@ -3569,212 +3518,206 @@ void ClassDefImpl::mergeMembers()
//printf(" mergeMembers for %s\n",name().data());
static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
- if (baseClasses())
+ for (const auto &bcd : baseClasses())
{
- //printf(" => has base classes!\n");
- BaseClassListIterator bcli(*baseClasses());
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()) ; ++bcli )
- {
- ClassDef *bClass=bcd->classDef;
+ ClassDef *bClass=bcd.classDef;
- // merge the members in the base class of this inheritance branch first
- bClass->mergeMembers();
+ // merge the members in the base class of this inheritance branch first
+ bClass->mergeMembers();
- const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap();
- MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap;
+ const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap();
+ MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap;
- for (auto &srcMni : srcMnd)
+ for (auto &srcMni : srcMnd)
+ {
+ //printf(" Base member name %s\n",srcMni->memberName());
+ MemberNameInfo *dstMni;
+ if ((dstMni=dstMnd.find(srcMni->memberName())))
+ // a member with that name is already in the class.
+ // the member may hide or reimplement the one in the sub class
+ // or there may be another path to the base class that is already
+ // visited via another branch in the class hierarchy.
{
- //printf(" Base member name %s\n",srcMni->memberName());
- MemberNameInfo *dstMni;
- if ((dstMni=dstMnd.find(srcMni->memberName())))
- // a member with that name is already in the class.
- // the member may hide or reimplement the one in the sub class
- // or there may be another path to the base class that is already
- // visited via another branch in the class hierarchy.
+ for (auto &srcMi : *srcMni)
{
- for (auto &srcMi : *srcMni)
+ MemberDef *srcMd = srcMi->memberDef();
+ bool found=FALSE;
+ bool ambiguous=FALSE;
+ bool hidden=FALSE;
+ const ClassDef *srcCd = srcMd->getClassDef();
+ for (auto &dstMi : *dstMni)
{
- MemberDef *srcMd = srcMi->memberDef();
- bool found=FALSE;
- bool ambiguous=FALSE;
- bool hidden=FALSE;
- const ClassDef *srcCd = srcMd->getClassDef();
- for (auto &dstMi : *dstMni)
+ MemberDef *dstMd = dstMi->memberDef();
+ if (srcMd!=dstMd) // different members
{
- MemberDef *dstMd = dstMi->memberDef();
- if (srcMd!=dstMd) // different members
+ const ClassDef *dstCd = dstMd->getClassDef();
+ //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
+ if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
+ // member is in the same or a base class
{
- const ClassDef *dstCd = dstMd->getClassDef();
- //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
- if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
- // member is in the same or a base class
- {
- ArgumentList &srcAl = srcMd->argumentList();
- ArgumentList &dstAl = dstMd->argumentList();
- found=matchArguments2(
- srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl,
- dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl,
- TRUE
- );
- //printf(" Yes, matching (%s<->%s): %d\n",
- // argListToString(srcMd->argumentList()).data(),
- // argListToString(dstMd->argumentList()).data(),
- // found);
- hidden = hidden || !found;
- }
- else // member is in a non base class => multiple inheritance
- // using the same base class.
- {
- //printf("$$ Existing member %s %s add scope %s\n",
- // dstMi->ambiguityResolutionScope.data(),
- // dstMd->name().data(),
- // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
-
- QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen);
- if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
- {
- dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope());
- }
- ambiguous=TRUE;
- }
+ ArgumentList &srcAl = srcMd->argumentList();
+ ArgumentList &dstAl = dstMd->argumentList();
+ found=matchArguments2(
+ srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl,
+ dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl,
+ TRUE
+ );
+ //printf(" Yes, matching (%s<->%s): %d\n",
+ // argListToString(srcMd->argumentList()).data(),
+ // argListToString(dstMd->argumentList()).data(),
+ // found);
+ hidden = hidden || !found;
}
- else // same members
+ else // member is in a non base class => multiple inheritance
+ // using the same base class.
{
- // do not add if base class is virtual or
- // if scope paths are equal or
- // if base class is an interface (and thus implicitly virtual).
- //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
- if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) ||
- bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() ||
- dstMd->getClassDef()->compoundType()==Interface
- )
- {
- found=TRUE;
- }
- else // member can be reached via multiple paths in the
- // inheritance tree
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
+
+ QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
{
- //printf("$$ Existing member %s %s add scope %s\n",
- // dstMi->ambiguityResolutionScope.data(),
- // dstMd->name().data(),
- // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
-
- QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen);
- if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
- {
- dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope);
- }
- ambiguous=TRUE;
+ dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope());
}
+ ambiguous=TRUE;
}
- if (found) break;
}
- //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n",
- // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass);
-
- // TODO: fix the case where a member is hidden by inheritance
- // of a member with the same name but with another prototype,
- // while there is more than one path to the member in the
- // base class due to multiple inheritance. In this case
- // it seems that the member is not reachable by prefixing a
- // scope name either (according to my compiler). Currently,
- // this case is shown anyway.
- if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
+ else // same members
{
- Protection prot=srcMd->protection();
- if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
- else if (bcd->prot==Private) prot=bcd->prot;
-
- if (inlineInheritedMembers)
+ // do not add if base class is virtual or
+ // if scope paths are equal or
+ // if base class is an interface (and thus implicitly virtual).
+ //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
+ if ((srcMi->virt()!=Normal && dstMi->virt()!=Normal) ||
+ bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() ||
+ dstMd->getClassDef()->compoundType()==Interface
+ )
{
- if (!isStandardFunc(srcMd))
- {
- //printf(" insertMember '%s'\n",srcMd->name().data());
- internalInsertMember(srcMd,prot,FALSE);
- }
+ found=TRUE;
}
-
- Specifier virt=srcMi->virt();
- if (virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
-
- std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE);
- newMi->setScopePath(bClass->name()+sep+srcMi->scopePath());
- if (ambiguous)
+ else // member can be reached via multiple paths in the
+ // inheritance tree
{
- //printf("$$ New member %s %s add scope %s::\n",
- // srcMi->ambiguityResolutionScope.data(),
- // srcMd->name().data(),
- // bClass->name().data());
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
- QCString scope=bClass->name()+sep;
- if (scope!=srcMi->ambiguityResolutionScope().left(scope.length()))
+ QCString scope=dstMi->scopePath().left((uint)dstMi->scopePath().find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
{
- newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope());
+ dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope);
}
+ ambiguous=TRUE;
}
- if (hidden)
+ }
+ if (found) break;
+ }
+ //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n",
+ // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass);
+
+ // TODO: fix the case where a member is hidden by inheritance
+ // of a member with the same name but with another prototype,
+ // while there is more than one path to the member in the
+ // base class due to multiple inheritance. In this case
+ // it seems that the member is not reachable by prefixing a
+ // scope name either (according to my compiler). Currently,
+ // this case is shown anyway.
+ if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
+ {
+ Protection prot=srcMd->protection();
+ if (bcd.prot==Protected && prot==Public) prot=bcd.prot;
+ else if (bcd.prot==Private) prot=bcd.prot;
+
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(srcMd))
{
- if (srcMi->ambigClass()==0)
- {
- newMi->setAmbigClass(bClass);
- newMi->setAmbiguityResolutionScope(bClass->name()+sep);
- }
- else
- {
- newMi->setAmbigClass(srcMi->ambigClass());
- newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep);
- }
+ //printf(" insertMember '%s'\n",srcMd->name().data());
+ internalInsertMember(srcMd,prot,FALSE);
}
- dstMni->push_back(std::move(newMi));
}
- }
- }
- else // base class has a member that is not in the sub class => copy
- {
- // create a deep copy of the list (only the MemberInfo's will be
- // copied, not the actual MemberDef's)
- MemberNameInfo *newMni = dstMnd.add(srcMni->memberName());
- // copy the member(s) from the base to the sub class
- for (auto &mi : *srcMni)
- {
- if (!mi->memberDef()->isFriend()) // don't inherit friends
+ Specifier virt=srcMi->virt();
+ if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt;
+
+ std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE);
+ newMi->setScopePath(bClass->name()+sep+srcMi->scopePath());
+ if (ambiguous)
{
- Protection prot = mi->prot();
- if (bcd->prot==Protected)
+ //printf("$$ New member %s %s add scope %s::\n",
+ // srcMi->ambiguityResolutionScope.data(),
+ // srcMd->name().data(),
+ // bClass->name().data());
+
+ QCString scope=bClass->name()+sep;
+ if (scope!=srcMi->ambiguityResolutionScope().left(scope.length()))
{
- if (prot==Public) prot=Protected;
+ newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope());
}
- else if (bcd->prot==Private)
+ }
+ if (hidden)
+ {
+ if (srcMi->ambigClass()==0)
{
- prot=Private;
+ newMi->setAmbigClass(bClass);
+ newMi->setAmbiguityResolutionScope(bClass->name()+sep);
}
- //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
- // name().data(),mi->memberDef->name().data(),mi->prot,
- // bcd->prot,prot);
-
- if (prot!=Private || extractPrivate)
+ else
{
- Specifier virt=mi->virt();
- if (virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+ newMi->setAmbigClass(srcMi->ambigClass());
+ newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep);
+ }
+ }
+ dstMni->push_back(std::move(newMi));
+ }
+ }
+ }
+ else // base class has a member that is not in the sub class => copy
+ {
+ // create a deep copy of the list (only the MemberInfo's will be
+ // copied, not the actual MemberDef's)
+ MemberNameInfo *newMni = dstMnd.add(srcMni->memberName());
+
+ // copy the member(s) from the base to the sub class
+ for (auto &mi : *srcMni)
+ {
+ if (!mi->memberDef()->isFriend()) // don't inherit friends
+ {
+ Protection prot = mi->prot();
+ if (bcd.prot==Protected)
+ {
+ if (prot==Public) prot=Protected;
+ }
+ else if (bcd.prot==Private)
+ {
+ prot=Private;
+ }
+ //printf("%s::%s: prot=%d bcd.prot=%d result=%d\n",
+ // name().data(),mi->memberDef->name().data(),mi->prot,
+ // bcd.prot,prot);
+
+ if (prot!=Private || extractPrivate)
+ {
+ Specifier virt=mi->virt();
+ if (virt==Normal && bcd.virt!=Normal) virt=bcd.virt;
- if (inlineInheritedMembers)
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(mi->memberDef()))
{
- if (!isStandardFunc(mi->memberDef()))
- {
- //printf(" insertMember '%s'\n",mi->memberDef->name().data());
- internalInsertMember(mi->memberDef(),prot,FALSE);
- }
+ //printf(" insertMember '%s'\n",mi->memberDef->name().data());
+ internalInsertMember(mi->memberDef(),prot,FALSE);
}
- //printf("Adding!\n");
- std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE);
- newMi->setScopePath(bClass->name()+sep+mi->scopePath());
- newMi->setAmbigClass(mi->ambigClass());
- newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope());
- newMni->push_back(std::move(newMi));
}
+ //printf("Adding!\n");
+ std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE);
+ newMi->setScopePath(bClass->name()+sep+mi->scopePath());
+ newMi->setAmbigClass(mi->ambigClass());
+ newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope());
+ newMni->push_back(std::move(newMi));
}
}
}
@@ -3803,28 +3746,20 @@ void ClassDefImpl::mergeCategory(ClassDef *category)
category->setArtificial(TRUE);
// copy base classes/protocols from extension
- if (category->baseClasses())
+ for (const auto &bcd : category->baseClasses())
{
- BaseClassListIterator bcli(*category->baseClasses());
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()) ; ++bcli )
+ insertBaseClass(bcd.classDef,bcd.usedName,bcd.prot,bcd.virt,bcd.templSpecifiers);
+ // correct bcd.classDef so that they do no longer derive from
+ // category, but from this class!
+ BaseClassList scl = bcd.classDef->subClasses();
+ for (auto &scd : scl)
{
- insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
- // correct bcd->classDef so that they do no longer derive from
- // category, but from this class!
- if (bcd->classDef->subClasses())
+ if (scd.classDef==category)
{
- BaseClassListIterator scli(*bcd->classDef->subClasses());
- BaseClassDef *scd;
- for ( ; (scd=scli.current()) ; ++scli )
- {
- if (scd->classDef==category)
- {
- scd->classDef=this;
- }
- }
+ scd.classDef=this;
}
}
+ bcd.classDef->updateSubClasses(scl);
}
}
// make methods private for categories defined in the .m file
@@ -4537,26 +4472,21 @@ int ClassDefImpl::countInheritedDecMembers(MemberListType lt,
// name().data(),lt,process,count,invert);
if ((process^invert) || showAlways)
{
- if (m_impl->inherits)
+ for (const auto &ibcd : m_impl->inherits)
{
- BaseClassListIterator it(*m_impl->inherits);
- BaseClassDef *ibcd;
- for (it.toFirst();(ibcd=it.current());++it)
+ ClassDef *icd=ibcd.classDef;
+ int lt1,lt2;
+ if (icd->isLinkable())
{
- ClassDef *icd=ibcd->classDef;
- int lt1,lt2;
- if (icd->isLinkable())
+ convertProtectionLevel(lt,ibcd.prot,&lt1,&lt2);
+ //printf("%s: convert %d->(%d,%d) prot=%d\n",
+ // icd->name().data(),lt,lt1,lt2,ibcd->prot);
+ if (visitedClasses->find(icd)==0)
{
- convertProtectionLevel(lt,ibcd->prot,&lt1,&lt2);
- //printf("%s: convert %d->(%d,%d) prot=%d\n",
- // icd->name().data(),lt,lt1,lt2,ibcd->prot);
- if (visitedClasses->find(icd)==0)
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
{
- visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
- if (lt1!=-1)
- {
- inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
- }
+ inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
}
}
}
@@ -4678,36 +4608,31 @@ void ClassDefImpl::writeInheritedMemberDeclarations(OutputList &ol,
// name().data(),lt,process,invert,showAlways);
if ((process^invert) || showAlways)
{
- if (m_impl->inherits)
+ for (const auto &ibcd : m_impl->inherits)
{
- BaseClassListIterator it(*m_impl->inherits);
- BaseClassDef *ibcd;
- for (it.toFirst();(ibcd=it.current());++it)
+ ClassDef *icd=ibcd.classDef;
+ if (icd->isLinkable())
{
- ClassDef *icd=ibcd->classDef;
- if (icd->isLinkable())
+ int lt1,lt3;
+ convertProtectionLevel(lt,ibcd.prot,&lt1,&lt3);
+ if (lt2==-1 && lt3!=-1)
{
- int lt1,lt3;
- convertProtectionLevel(lt,ibcd->prot,&lt1,&lt3);
- if (lt2==-1 && lt3!=-1)
- {
- lt2=lt3;
- }
- //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot);
- if (visitedClasses->find(icd)==0)
- {
- visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
- if (lt1!=-1)
- {
- icd->writeMemberDeclarations(ol,(MemberListType)lt1,
- title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
- }
- }
- else
+ lt2=lt3;
+ }
+ //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot);
+ if (visitedClasses->find(icd)==0)
+ {
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
{
- //printf("%s: class already visited!\n",icd->name().data());
+ icd->writeMemberDeclarations(ol,(MemberListType)lt1,
+ title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
}
}
+ else
+ {
+ //printf("%s: class already visited!\n",icd->name().data());
+ }
}
}
}
@@ -4822,16 +4747,26 @@ ClassDefImpl::CompoundType ClassDefImpl::compoundType() const
return m_impl->compType;
}
-BaseClassList *ClassDefImpl::baseClasses() const
+BaseClassList ClassDefImpl::baseClasses() const
{
return m_impl->inherits;
}
-BaseClassList *ClassDefImpl::subClasses() const
+void ClassDefImpl::updateBaseClasses(BaseClassList bcd)
+{
+ m_impl->inherits = bcd;
+}
+
+BaseClassList ClassDefImpl::subClasses() const
{
return m_impl->inheritedBy;
}
+void ClassDefImpl::updateSubClasses(BaseClassList bcd)
+{
+ m_impl->inheritedBy = bcd;
+}
+
const MemberNameInfoLinkedMap &ClassDefImpl::memberNameInfoLinkedMap() const
{
return m_impl->allMemberNameInfoLinkedMap;
diff --git a/src/classdef.h b/src/classdef.h
index d413794..bd06323 100644
--- a/src/classdef.h
+++ b/src/classdef.h
@@ -37,7 +37,6 @@ class ClassSDict;
class OutputList;
class FileDef;
class FileList;
-class BaseClassList;
class NamespaceDef;
class MemberDef;
class ExampleSDict;
@@ -52,6 +51,38 @@ class StringDict;
struct IncludeInfo;
class ClassDefImpl;
class FTextStream;
+class ClassDef;
+
+/** Class that contains information about an inheritance relation.
+ */
+struct BaseClassDef
+{
+ BaseClassDef(ClassDef *cd,const char *n,Protection p, Specifier v,const char *t) :
+ classDef(cd), usedName(n), prot(p), virt(v), templSpecifiers(t) {}
+
+ /** Class definition that this relation inherits from. */
+ ClassDef *classDef;
+
+ /** name used in the inheritance list
+ * (may be a typedef name instead of the class name)
+ */
+ QCString usedName;
+
+ /** Protection level of the inheritance relation:
+ * Public, Protected, or Private
+ */
+ Protection prot;
+
+ /** Virtualness of the inheritance relation:
+ * Normal, or Virtual
+ */
+ Specifier virt;
+
+ /** Template arguments used for the base class */
+ QCString templSpecifiers;
+};
+
+using BaseClassList = std::vector<BaseClassDef>;
/** A abstract class representing of a compound symbol.
*
@@ -126,11 +157,17 @@ class ClassDef : virtual public Definition
/** Returns the list of base classes from which this class directly
* inherits.
*/
- virtual BaseClassList *baseClasses() const = 0;
+ virtual BaseClassList baseClasses() const = 0;
+
+ /** Update the list of base classes to the one passed */
+ virtual void updateBaseClasses(BaseClassList bcd) = 0;
/** Returns the list of sub classes that directly derive from this class
*/
- virtual BaseClassList *subClasses() const = 0;
+ virtual BaseClassList subClasses() const = 0;
+
+ /** Update the list of sub classes to the one passed */
+ virtual void updateSubClasses(BaseClassList bcd) = 0;
/** Returns a dictionary of all members. This includes any inherited
* members. Members are sorted alphabetically.
@@ -480,65 +517,6 @@ class UsesClassDictIterator : public QDictIterator<UsesClassDef>
//------------------------------------------------------------------------
-/** Class that contains information about an inheritance relation.
- */
-struct BaseClassDef
-{
- BaseClassDef(ClassDef *cd,const char *n,Protection p, Specifier v,const char *t) :
- classDef(cd), usedName(n), prot(p), virt(v), templSpecifiers(t) {}
-
- /** Class definition that this relation inherits from. */
- ClassDef *classDef;
-
- /** name used in the inheritance list
- * (may be a typedef name instead of the class name)
- */
- QCString usedName;
-
- /** Protection level of the inheritance relation:
- * Public, Protected, or Private
- */
- Protection prot;
-
- /** Virtualness of the inheritance relation:
- * Normal, or Virtual
- */
- Specifier virt;
-
- /** Template arguments used for the base class */
- QCString templSpecifiers;
-};
-
-/** List of base classes.
- *
- * The classes are alphabetically sorted on name if inSort() is used.
- */
-class BaseClassList : public QList<BaseClassDef>
-{
- public:
- ~BaseClassList() {}
- int compareValues(const BaseClassDef *item1,const BaseClassDef *item2) const
- {
- const ClassDef *c1=item1->classDef;
- const ClassDef *c2=item2->classDef;
- if (c1==0 || c2==0)
- return FALSE;
- else
- return qstricmp(c1->name(),c2->name());
- }
-};
-
-/** Iterator for a list of base classes.
- */
-class BaseClassListIterator : public QListIterator<BaseClassDef>
-{
- public:
- BaseClassListIterator(const BaseClassList &bcl) :
- QListIterator<BaseClassDef>(bcl) {}
-};
-
-//------------------------------------------------------------------------
-
/** Class that contains information about a type constraint relations.
*/
diff --git a/src/code.l b/src/code.l
index 9374b40..dbdaa98 100644
--- a/src/code.l
+++ b/src/code.l
@@ -26,12 +26,14 @@
* includes
*/
+#include <utility>
#include <memory>
#include <algorithm>
#include <unordered_map>
#include <stack>
#include <vector>
#include <string>
+#include <mutex>
#include <stdio.h>
#include <assert.h>
@@ -55,6 +57,7 @@
#include "filename.h"
#include "namespacedef.h"
#include "tooltip.h"
+#include "scopedtypevariant.h"
// Toggle for some debugging info
//#define DBG_CTX(x) fprintf x
@@ -68,10 +71,6 @@
#define USE_STATE2STRING 0
-/* -----------------------------------------------------------------
- * statics
- */
-
// context for an Objective-C method call
struct ObjCCallCtx
{
@@ -87,116 +86,11 @@ struct ObjCCallCtx
int braceCount;
};
-/*! Represents a stack of variable to class mappings as found in the
- * code. Each scope is enclosed in pushScope() and popScope() calls.
- * Variables are added by calling addVariables() and one can search
- * for variable using findVariable().
- */
-class VariableContext
-{
- public:
- static const ClassDef *dummyContext;
-
- using Scope = std::unordered_map<std::string,const ClassDef*>;
-
- void pushScope()
- {
- m_scopes.push_back(Scope());
- DBG_CTX((stderr,"** Push var context %zu\n",m_scopes.size()));
- }
-
- void popScope()
- {
- if (!m_scopes.empty())
- {
- DBG_CTX((stderr,"** Pop var context %zu\n",m_scopes.size()));
- m_scopes.pop_back();
- }
- else
- {
- DBG_CTX((stderr,"** ILLEGAL: Pop var context\n"));
- }
- }
-
- void clear()
- {
- m_scopes.clear();
- m_globalScope.clear();
- }
-
- void addVariable(yyscan_t yyscanner,const QCString &type,const QCString &name);
- const ClassDef *findVariable(const QCString &name);
-
- private:
- Scope m_globalScope;
- std::vector<Scope> m_scopes;
-};
-
-//-------------------------------------------------------------------
-
-class CallContext
-{
- public:
- struct Ctx
- {
- Ctx(QCString name_, QCString type_) : name(name_), type(type_) {}
- QCString name;
- QCString type;
- const Definition *d = 0;
- };
-
- CallContext()
- {
- clear();
- }
-
- void setScope(const Definition *d)
- {
- Ctx &ctx = m_defList.back();
- DBG_CTX((stderr,"** Set call context %s (%p)\n",d==0 ? "<null>" : d->name().data(),d));
- ctx.d=d;
- }
- void pushScope(QCString name_, QCString type_)
- {
- m_defList.push_back(Ctx(name_,type_));
- DBG_CTX((stderr,"** Push call context %zu\n",m_defList.size()));
- }
- void popScope(QCString &name_, QCString &type_)
- {
- if (m_defList.size()>1)
- {
- DBG_CTX((stderr,"** Pop call context %zu\n",m_defList.size()));
- const Ctx &ctx = m_defList.back();
- name_ = ctx.name;
- type_ = ctx.type;
- m_defList.pop_back();
- }
- else
- {
- DBG_CTX((stderr,"** ILLEGAL: Pop call context\n"));
- }
- }
- void clear()
- {
- DBG_CTX((stderr,"** Clear call context\n"));
- m_defList.clear();
- m_defList.push_back(Ctx("",""));
- }
- const Definition *getScope() const
- {
- return m_defList.back().d;
- }
-
- private:
- std::vector<Ctx> m_defList;
-};
-
-
struct codeYY_state
{
CodeOutputInterface * code = 0;
- std::unordered_map< std::string, std::unique_ptr<ClassDef> > codeClassMap;
+ std::unordered_map< std::string, ScopedTypeVariant > codeClassMap;
QCString curClassName;
QStrList curClassBases;
@@ -260,7 +154,7 @@ struct codeYY_state
std::stack<int> classScopeLengthStack;
- int prefixed_with_this_keyword = FALSE;
+ int isPrefixedWithThis = FALSE;
const Definition *searchCtx = 0;
bool collectXRefs = FALSE;
@@ -312,7 +206,7 @@ static void addParmType(yyscan_t yyscanner);
static void addUsingDirective(yyscan_t yyscanner,const char *name);
static void setParameterList(yyscan_t yyscanner,const MemberDef *md);
static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Definition *d);
-static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name);
+static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name);
static void updateCallContextForSmartPointer(yyscan_t yyscanner);
static bool getLinkInScope(yyscan_t yyscanner,const QCString &c, // scope
const QCString &m, // member
@@ -342,7 +236,12 @@ static QCString escapeWord(yyscan_t yyscanner,const char *s);
static QCString escapeComment(yyscan_t yyscanner,const char *s);
static bool skipLanguageSpecificKeyword(yyscan_t yyscanner,const QCString &kw);
static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
+static void addVariable(yyscan_t yyscanner,QCString type,QCString name);
+//-------------------------------------------------------------------
+
+static std::mutex g_searchIndexMutex;
+static std::mutex g_tooltipMutex;
/* -----------------------------------------------------------------
*/
@@ -551,7 +450,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
<ObjCParams>{ID} {
yyextra->code->codify(yytext);
yyextra->parmName=yytext;
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
yyextra->parmType.resize(0);yyextra->parmName.resize(0);
}
<ObjCMethod,ObjCParams,ObjCParamType>{ID} {
@@ -827,7 +726,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
yyextra->name = yytext;
if (yyextra->insideBody)
{
- yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name);
+ addVariable(yyscanner,yyextra->type,yyextra->name);
}
generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
}
@@ -860,8 +759,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
if (getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->curClassName)==0)
{
DBG_CTX((stderr,"Adding new class %s\n",yyextra->curClassName.data()));
- std::unique_ptr<ClassDef> ncd { createClassDef("<code>",1,1,
- yyextra->curClassName,ClassDef::Class,0,0,FALSE) };
+ ScopedTypeVariant var(yyextra->curClassName);
// insert base classes.
char *s=yyextra->curClassBases.first();
while (s)
@@ -870,16 +768,16 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
auto it = yyextra->codeClassMap.find(s);
if (it!=yyextra->codeClassMap.end())
{
- bcd=it->second.get();
+ bcd = dynamic_cast<const ClassDef*>(it->second.globalDef());
}
if (bcd==0) bcd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s);
- if (bcd && bcd!=ncd.get())
+ if (bcd && bcd->name()!=yyextra->curClassName)
{
- ncd->insertBaseClass(const_cast<ClassDef*>(bcd),s,Public,Normal);
+ var.localDef()->insertBaseClass(bcd->name());
}
s=yyextra->curClassBases.next();
}
- yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(ncd)));
+ yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(var)));
}
//printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count());
}
@@ -1005,7 +903,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
<UsingName>\n { codifyLines(yyscanner,yytext); BEGIN(Body); }
<UsingName>. { codifyLines(yyscanner,yytext); BEGIN(Body); }
<Body,FuncCall>"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C#
- yyextra->prefixed_with_this_keyword = TRUE;
+ yyextra->isPrefixedWithThis = TRUE;
}
<Body>{KEYWORD}/([^a-z_A-Z0-9]) {
if (yyextra->lang==SrcLangExt_Java && qstrcmp("internal",yytext) ==0) REJECT;
@@ -1039,7 +937,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
endFontClass(yyscanner);
// insert the variable in the parent scope, see bug 546158
yyextra->theVarContext.popScope();
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
yyextra->theVarContext.pushScope();
yyextra->name.resize(0);yyextra->type.resize(0);
}
@@ -1359,9 +1257,9 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
BEGIN( MemberCall );
}
<MemberCall>{SCOPETNAME}/{BN}*"(" {
- if (yyextra->theCallContext.getScope())
+ if (yyextra->theCallContext.getScope().globalDef())
{
- if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext))
+ if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
{
yyextra->code->codify(yytext);
addToSearchIndex(yyscanner,yytext);
@@ -1385,10 +1283,10 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
}
}
<MemberCall>{SCOPENAME}/{B}* {
- if (yyextra->theCallContext.getScope())
+ if (yyextra->theCallContext.getScope().globalDef())
{
- DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope()));
- if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope(),yytext))
+ DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",yyextra->theCallContext.getScope().globalDef()));
+ if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
{
yyextra->code->codify(yytext);
addToSearchIndex(yyscanner,yytext);
@@ -1435,7 +1333,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
{
//printf("AddVariable: '%s' '%s' context=%d\n",
// yyextra->type.data(),yyextra->name.data(),yyextra->theVarContext.count());
- yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name);
+ addVariable(yyscanner,yyextra->type,yyextra->name);
}
yyextra->name.resize(0);
}
@@ -1665,7 +1563,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
}
<MemberCall2,FuncCall>, {
yyextra->code->codify(yytext);
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
yyextra->parmType.resize(0);yyextra->parmName.resize(0);
}
<MemberCall2,FuncCall>"{" {
@@ -1727,13 +1625,13 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
yyextra->parmType=yyextra->parmName;
yyextra->parmName.resize(0);
}
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
}
else
{
yyextra->parmType = yyextra->parmName;
yyextra->parmName.resize(0);
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
}
yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
yyextra->inForEachExpression = FALSE;
@@ -1762,10 +1660,10 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
if (!yyextra->type.isEmpty())
{
DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",yyextra->type.data(),yyextra->name.data()));
- yyextra->theVarContext.addVariable(yyscanner,yyextra->type,yyextra->name);
+ addVariable(yyscanner,yyextra->type,yyextra->name);
}
yyextra->parmType.resize(0);yyextra->parmName.resize(0);
- yyextra->theCallContext.setScope(0);
+ yyextra->theCallContext.setScope(ScopedTypeVariant());
if (*yytext==';' || yyextra->insideBody)
{
if (!yyextra->insideBody)
@@ -1791,7 +1689,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
{
yyextra->theVarContext.pushScope();
}
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
//yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
yyextra->parmType.resize(0);yyextra->parmName.resize(0);
int index = yyextra->name.findRev("::");
@@ -1865,7 +1763,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
}
<OldStyleArgs>[,;] {
yyextra->code->codify(yytext);
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
if (*yytext==';') yyextra->parmType.resize(0);
yyextra->parmName.resize(0);
}
@@ -2290,7 +2188,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
/*@ ----------------------------------------------------------------------------
*/
-void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const QCString &name)
+static void addVariable(yyscan_t yyscanner,QCString type,QCString name)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
//printf("VariableContext::addVariable(%s,%s)\n",type.data(),name.data());
@@ -2307,102 +2205,44 @@ void VariableContext::addVariable(yyscan_t yyscanner,const QCString &type,const
if (ltype.isEmpty() || lname.isEmpty()) return;
DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n",
ltype.data(),lname.data(),yyextra->currentDefinition?yyextra->currentDefinition->name().data():"<none>"));
- Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back();
- const ClassDef *varType = 0;
auto it = yyextra->codeClassMap.find(ltype.str());
if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block
{
- varType = it->second.get();
- }
- if (varType==0) // look for global class definitions
- {
- varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype);
- }
- int i=0;
- if (varType)
- {
DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data()));
- scope->emplace(std::make_pair(lname.str(),varType)); // add it to a list
+ yyextra->theVarContext.addVariable(lname,std::move(it->second)); // add it to a list
}
- else if ((i=ltype.find('<'))!=-1)
+ else
{
- // probably a template class
- QCString typeName(ltype.left(i));
- const ClassDef* newDef = 0;
- QCString templateArgs(ltype.right(ltype.length() - i));
- it = yyextra->codeClassMap.find(typeName.str());
- if (!typeName.isEmpty())
- {
- if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block
- {
- varType = it->second.get();
- }
- else // otherwise look for global class definitions
- {
- varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,typeName,0,0,TRUE,TRUE);
- }
- }
- if (varType && !varType->templateArguments().empty()) // and it must be a template
- {
- newDef = varType->getVariableInstance( templateArgs );
- }
- if (newDef)
+ const ClassDef *varDef = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype);
+ int i=0;
+ if (varDef)
{
- DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data()));
- scope->emplace(std::make_pair(lname.str(), newDef));
+ DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data()));
+ yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list
}
- else
+ else if ((i=ltype.find('<'))!=-1)
{
- // Doesn't seem to be a template. Try just the base name.
+ // probably a template class
+ QCString typeName(ltype.left(i));
addVariable(yyscanner,typeName,name);
}
- }
- else
- {
- if (!m_scopes.empty()) // for local variables add a dummy entry so the name
- // is hidden to avoid false links to global variables with the same name
- // TODO: make this work for namespaces as well!
- {
- DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data()));
- scope->emplace(std::make_pair(lname.str(),dummyContext));
- }
else
{
- DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
- }
- }
-}
-
-const ClassDef *VariableContext::findVariable(const QCString &name)
-{
- if (name.isEmpty()) return 0;
- const ClassDef *result = 0;
-
- // search from inner to outer scope
- auto it = std::rbegin(m_scopes);
- while (it != std::rend(m_scopes))
- {
- auto it2 = it->find(name.str());
- if (it2 != std::end(*it))
- {
- result = it2->second;
- DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
- return result;
+ if (!yyextra->theVarContext.atGlobalScope()) // for local variables add a dummy entry so the name
+ // is hidden to avoid false links to global variables with the same name
+ // TODO: make this work for namespaces as well!
+ {
+ DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data()));
+ yyextra->theVarContext.addVariable(lname,ScopedTypeVariant());
+ }
+ else
+ {
+ DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
+ }
}
- ++it;
}
- // nothing found -> also try the global scope
- auto it2 = m_globalScope.find(name.str());
- if (it2 != m_globalScope.end())
- {
- result = it2->second;
- }
- DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));
- return result;
}
-const ClassDef *VariableContext::dummyContext = (ClassDef*)0x8;
-
//-------------------------------------------------------------------
/*! add class/namespace name s to the scope */
@@ -2445,6 +2285,7 @@ static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (Doxygen::searchIndex)
{
+ std::lock_guard<std::mutex> lock(g_searchIndexMutex);
if (yyextra->searchCtx)
{
yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
@@ -2461,6 +2302,7 @@ static void addToSearchIndex(yyscan_t yyscanner,const char *text)
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (Doxygen::searchIndex)
{
+ std::lock_guard<std::mutex> lock(g_searchIndexMutex);
yyextra->code->addWord(text,FALSE);
}
}
@@ -2620,8 +2462,11 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,CodeOutputInterface &ol,
const char *text)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
- TooltipManager::instance()->addTooltip(d);
+ bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
+ {
+ std::lock_guard<std::mutex> lock(g_tooltipMutex);
+ TooltipManager::instance()->addTooltip(d);
+ }
QCString ref = d->getReference();
QCString file = d->getOutputFileBase();
QCString anchor = d->anchor();
@@ -2702,7 +2547,7 @@ static void setParameterList(yyscan_t yyscanner,const MemberDef *md)
if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
yyextra->parmType.stripPrefix("const ");
yyextra->parmType=yyextra->parmType.stripWhiteSpace();
- yyextra->theVarContext.addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
+ addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
}
}
@@ -2735,7 +2580,7 @@ static const ClassDef *stripClassName(yyscan_t yyscanner,const char *s,const Def
return 0;
}
-static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
+static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
{
if (name.isEmpty()) return 0;
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
@@ -2754,7 +2599,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
if (md)
{
//printf("name=%s scope=%s\n",locName.data(),scope.data());
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
return md;
}
}
@@ -2767,7 +2612,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
if (md)
{
//printf("name=%s scope=%s\n",locName.data(),scope.data());
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
return md;
}
}
@@ -2775,32 +2620,32 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
}
const MemberName *mn;
- const ClassDef *mcd = yyextra->theVarContext.findVariable(name);
- if (mcd) // local variable
+ const ScopedTypeVariant *mcv = yyextra->theVarContext.findVariable(name);
+ if (mcv)
{
DBG_CTX((stderr,"local variable?\n"));
- if (mcd!=VariableContext::dummyContext)
+ if (mcv->type()!=ScopedTypeVariant::Dummy) // locally found variable
{
- DBG_CTX((stderr,"local var '%s' mcd=%s\n",name.data(),mcd->name().data()));
- yyextra->theCallContext.setScope(mcd);
+ DBG_CTX((stderr,"local var '%s' mcd=%s\n",name.data(),mcv.name().data()));
+ yyextra->theCallContext.setScope(*mcv);
}
}
else
{
DBG_CTX((stderr,"class member? scope=%s\n",yyextra->classScope.data()));
// look for a class member
- mcd = getClass(yyextra->classScope);
+ const ClassDef *mcd = getClass(yyextra->classScope);
if (mcd)
{
DBG_CTX((stderr,"Inside class %s\n",mcd->name().data()));
- MemberDef *md=mcd->getMemberByName(name);
+ const MemberDef *md=mcd->getMemberByName(name);
if (md)
{
DBG_CTX((stderr,"Found member %s\n",md->name().data()));
if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK)
{
DBG_CTX((stderr,"class member '%s' mcd=%s\n",name.data(),mcd->name().data()));
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
}
return md;
}
@@ -2816,7 +2661,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
const std::unique_ptr<MemberDef> &md=mn->front();
if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef)
{
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
return md.get();
}
return 0;
@@ -2836,7 +2681,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
(yyextra->forceTagReference.isEmpty() || yyextra->forceTagReference==md->getReference())
)
{
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
//printf("returning member %s in source file %s\n",md->name().data(),yyextra->sourceFileDef->name().data());
return md.get();
}
@@ -2850,7 +2695,7 @@ static MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &name)
static void updateCallContextForSmartPointer(yyscan_t yyscanner)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- const Definition *d = yyextra->theCallContext.getScope();
+ const Definition *d = yyextra->theCallContext.getScope().globalDef();
//printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>");
const MemberDef *md;
if (d && d->definitionType()==Definition::TypeClass && (md=(dynamic_cast<const ClassDef*>(d))->isSmartPointer()))
@@ -2858,7 +2703,7 @@ static void updateCallContextForSmartPointer(yyscan_t yyscanner)
const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope());
if (ncd)
{
- yyextra->theCallContext.setScope(ncd);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(ncd));
//printf("Found smart pointer call %s->%s!\n",cd->name().data(),ncd->name().data());
}
}
@@ -2904,7 +2749,7 @@ static bool getLinkInScope(yyscan_t yyscanner,
if (md->resolveAlias()->getGroupDef()) d = md->resolveAlias()->getGroupDef();
if (d && d->isLinkable())
{
- yyextra->theCallContext.setScope(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
//printf("yyextra->currentDefinition=%p yyextra->currentMemberDef=%p yyextra->insideBody=%d\n",
// yyextra->currentDefinition,yyextra->currentMemberDef,yyextra->insideBody);
@@ -2981,12 +2826,13 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
{
className = substitute(className,".","::"); // for PHP namespaces
}
- const ClassDef *cd=0,*lcd=0;
+ const ScopedTypeVariant *lcd=0;
+ const ClassDef *cd=0;
const MemberDef *md=0;
bool isLocal=FALSE;
//printf("generateClassOrGlobalLink(className=%s)\n",className.data());
- if (!yyextra->prefixed_with_this_keyword || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable
+ if (!yyextra->isPrefixedWithThis || (lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable
{
const Definition *d = yyextra->currentDefinition;
//printf("d=%s yyextra->sourceFileDef=%s\n",d?d->name().data():"<none>",yyextra->sourceFileDef?yyextra->sourceFileDef->name().data():"<none>");
@@ -3006,7 +2852,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
const NamespaceDef *nd = getResolvedNamespace(className);
if (nd && nd->isLinkable())
{
- yyextra->theCallContext.setScope(nd);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(nd));
addToSearchIndex(yyscanner,className);
writeMultiLineCodeLink(yyscanner,*yyextra->code,nd,clName);
return;
@@ -3026,10 +2872,10 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
else
{
//printf("local variable!\n");
- if (lcd!=VariableContext::dummyContext)
+ if (lcd->type()!=ScopedTypeVariant::Dummy)
{
//printf("non-dummy context lcd=%s!\n",lcd->name().data());
- yyextra->theCallContext.setScope(lcd);
+ yyextra->theCallContext.setScope(*lcd);
// to following is needed for links to a global variable, but is
// no good for a link to a local variable that is also a global symbol.
@@ -3042,7 +2888,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
isLocal=TRUE;
DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
}
- yyextra->prefixed_with_this_keyword = FALSE; // discard the "this" prefix for the next calls
+ yyextra->isPrefixedWithThis = FALSE; // discard the "this" prefix for the next calls
if (cd && cd->isLinkable()) // is it a linkable class
{
@@ -3061,7 +2907,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
}
writeMultiLineCodeLink(yyscanner,ol,cd,clName);
addToSearchIndex(yyscanner,className);
- yyextra->theCallContext.setScope(cd);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(cd));
if (md)
{
const Definition *d = md->getOuterScope()==Doxygen::globalScope ?
@@ -3081,18 +2927,19 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
{
if (md==0) // not found as a typedef
{
+ AccessStack accessStack;
md = setCallContextForVar(yyscanner,clName);
//printf("setCallContextForVar(%s) md=%p yyextra->currentDefinition=%p\n",clName,md,yyextra->currentDefinition);
if (md && yyextra->currentDefinition)
{
DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n",
md->name().data(),yyextra->currentDefinition->name().data(),
- isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md),
+ isAccessibleFrom(accessStack,yyextra->currentDefinition,yyextra->sourceFileDef,md),
md->getOuterScope()->name().data()));
}
if (md && yyextra->currentDefinition &&
- isAccessibleFrom(yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1)
+ isAccessibleFrom(accessStack,yyextra->currentDefinition,yyextra->sourceFileDef,md)==-1)
{
md=0; // variable not accessible
}
@@ -3165,7 +3012,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner,
const ClassDef *typeClass = stripClassName(yyscanner,removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope());
DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass));
- yyextra->theCallContext.setScope(typeClass);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(typeClass));
const Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
xmd->getFileDef() : xmd->getOuterScope();
@@ -3216,7 +3063,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner,
const Definition *innerDef = cd->findInnerCompound(memName);
if (innerDef)
{
- yyextra->theCallContext.setScope(innerDef);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
addToSearchIndex(yyscanner,memName);
writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
return TRUE;
@@ -3230,7 +3077,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner,
const Definition *innerDef = nd->findInnerCompound(memName);
if (innerDef)
{
- yyextra->theCallContext.setScope(innerDef);
+ yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
addToSearchIndex(yyscanner,memName);
writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
return TRUE;
@@ -3251,23 +3098,22 @@ static void generateMemberLink(yyscan_t yyscanner,
if (varName.isEmpty()) return;
// look for the variable in the current context
- const ClassDef *vcd = yyextra->theVarContext.findVariable(varName);
- if (vcd)
+ const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(varName);
+ if (stv)
{
- if (vcd!=VariableContext::dummyContext)
+ if (stv->type()!=ScopedTypeVariant::Dummy)
{
//printf("Class found!\n");
- if (getLink(yyscanner,vcd->name(),memName,ol))
+ if (getLink(yyscanner,stv->name(),memName,ol))
{
//printf("Found result!\n");
return;
}
- if (vcd->baseClasses())
+ if (stv->localDef() && !stv->localDef()->baseClasses().empty())
{
- BaseClassListIterator bcli(*vcd->baseClasses());
- for ( ; bcli.current() ; ++bcli)
+ for (const auto &bcName : stv->localDef()->baseClasses())
{
- if (getLink(yyscanner,bcli.current()->classDef->name(),memName,ol))
+ if (getLink(yyscanner,bcName,memName,ol))
{
//printf("Found result!\n");
return;
@@ -3278,7 +3124,7 @@ static void generateMemberLink(yyscan_t yyscanner,
}
else // variable not in current context, maybe it is in a parent context
{
- vcd = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->classScope);
+ const ClassDef *vcd = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,yyextra->classScope);
if (vcd && vcd->isLinkable())
{
//printf("Found class %s for variable '%s'\n",yyextra->classScope.data(),varName.data());
@@ -3350,7 +3196,6 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
//CodeClassDef *ccd=0;
- const ClassDef *ccd=0;
QCString locScope=yyextra->classScope;
QCString locFunc=removeRedundantWhiteSpace(funcName);
if (yyextra->lang==SrcLangExt_PHP && locFunc.startsWith("self::")) locFunc=locFunc.mid(4);
@@ -3416,37 +3261,31 @@ static void generateFunctionLink(yyscan_t yyscanner,CodeOutputInterface &ol,cons
auto it = yyextra->codeClassMap.find(fullScope.str());
if (it!=yyextra->codeClassMap.end())
{
- ccd = it->second.get();
- }
- if (ccd && ccd->baseClasses())
- {
- BaseClassListIterator bcli(*ccd->baseClasses());
- for ( ; bcli.current() ; ++bcli)
+ ScopedTypeVariant ccd = it->second;
+ if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
{
- if (getLink(yyscanner,bcli.current()->classDef->name(),locFunc,ol,funcName))
+ for (const auto &bcName : ccd.localDef()->baseClasses())
{
- goto exit;
+ if (getLink(yyscanner,bcName,locFunc,ol,funcName))
+ {
+ goto exit;
+ }
}
}
}
}
- if (!locScope.isEmpty())
+ if (!locScope.isEmpty() && fullScope!=locScope)
{
auto it = yyextra->codeClassMap.find(locScope.str());
if (it!=yyextra->codeClassMap.end())
{
- ccd = it->second.get();
- }
- if (fullScope!=locScope && ccd)
- {
- //printf("using classScope %s\n",yyextra->classScope.data());
- if (ccd->baseClasses())
+ ScopedTypeVariant ccd = it->second;
+ if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
{
- BaseClassListIterator bcli(*ccd->baseClasses());
- for ( ; bcli.current() ; ++bcli)
+ for (const auto &bcName : ccd.localDef()->baseClasses())
{
- if (getLink(yyscanner,bcli.current()->classDef->name(),funcWithScope,ol,funcName))
+ if (getLink(yyscanner,bcName,funcWithScope,ol,funcName))
{
goto exit;
}
@@ -3519,8 +3358,8 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx)
{
//printf("Looking for object=%s method=%s\n",ctx->objectTypeOrName.data(),
// ctx->methodName.data());
- const ClassDef *cd = yyextra->theVarContext.findVariable(ctx->objectTypeOrName);
- if (cd==0) // not a local variable
+ const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(ctx->objectTypeOrName);
+ if (stv==0) // not a local variable
{
if (ctx->objectTypeOrName=="self")
{
@@ -3569,9 +3408,13 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx)
else // local variable
{
//printf(" object is local variable\n");
- if (cd!=VariableContext::dummyContext && !ctx->methodName.isEmpty())
+ if (stv->globalDef() && !ctx->methodName.isEmpty())
{
- ctx->method = cd->getMemberByName(ctx->methodName);
+ const ClassDef *cd = dynamic_cast<const ClassDef *>(stv->globalDef());
+ if (cd)
+ {
+ ctx->method = cd->getMemberByName(ctx->methodName);
+ }
//printf(" class=%p method=%p\n",cd,ctx->method);
}
}
@@ -3659,20 +3502,14 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx)
{
cd = cd->categoryOf();
}
- const BaseClassList *bcd = cd->baseClasses();
- if (bcd) // get direct base class (there should be only one)
+ for (const auto &bclass : cd->baseClasses())
{
- BaseClassListIterator bli(*bcd);
- BaseClassDef *bclass;
- for (bli.toFirst();(bclass=bli.current());++bli)
+ if (bclass.classDef->compoundType()!=ClassDef::Protocol)
{
- if (bclass->classDef->compoundType()!=ClassDef::Protocol)
+ ctx->objectType = bclass.classDef;
+ if (ctx->objectType && !ctx->methodName.isEmpty())
{
- ctx->objectType = bclass->classDef;
- if (ctx->objectType && !ctx->methodName.isEmpty())
- {
- ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
- }
+ ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
}
}
}
@@ -3690,7 +3527,6 @@ static void writeObjCMethodCall(yyscan_t yyscanner,ObjCCallCtx *ctx)
}
}
else if (ctx->objectType &&
- ctx->objectType!=VariableContext::dummyContext &&
ctx->objectType->isLinkable()
) // object is class name
{
diff --git a/src/context.cpp b/src/context.cpp
index ee394d4..614cc2d 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -6670,14 +6670,11 @@ class NestingContext::Private : public GenericNodeListContext
}
}
}
- void addDerivedClasses(const BaseClassList *bcl,bool hideSuper)
+ void addDerivedClasses(BaseClassList bcl,bool hideSuper)
{
- if (bcl==0) return;
- BaseClassListIterator bcli(*bcl);
- BaseClassDef *bcd;
- for (bcli.toFirst() ; (bcd=bcli.current()) ; ++bcli)
+ for (const auto &bcd : bcl)
{
- const ClassDef *cd=bcd->classDef;
+ const ClassDef *cd=bcd.classDef;
if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
{
continue;
@@ -6815,7 +6812,7 @@ void NestingContext::addClassHierarchy(const ClassSDict &classSDict,bool rootOnl
p->addClassHierarchy(classSDict,rootOnly);
}
-void NestingContext::addDerivedClasses(const BaseClassList *bcl,bool hideSuper)
+void NestingContext::addDerivedClasses(BaseClassList bcl,bool hideSuper)
{
p->addDerivedClasses(bcl,hideSuper);
}
@@ -8536,29 +8533,24 @@ class InheritanceListContext::Private : public GenericNodeListContext
}
};
-InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses) : RefCountedContext("InheritanceListContext")
+InheritanceListContext::InheritanceListContext(BaseClassList list, bool baseClasses) : RefCountedContext("InheritanceListContext")
{
p = new Private;
- if (list)
+ for (const auto &bcd : list)
{
- BaseClassListIterator li(*list);
- BaseClassDef *bcd;
- for (li.toFirst();(bcd=li.current());++li)
+ const ClassDef *cd=bcd.classDef;
+ QCString name;
+ if (baseClasses)
{
- const ClassDef *cd=bcd->classDef;
- QCString name;
- if (baseClasses)
- {
- name = insertTemplateSpecifierInScope(
- cd->displayName(),bcd->templSpecifiers);
- }
- else
- {
- name = cd->displayName();
- }
- //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses);
- p->addClass(cd,name);
+ name = insertTemplateSpecifierInScope(
+ cd->displayName(),bcd.templSpecifiers);
}
+ else
+ {
+ name = cd->displayName();
+ }
+ //printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses);
+ p->addClass(cd,name);
}
}
@@ -9282,31 +9274,26 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext
int lt2, const QCString &title,bool additionalList,
QPtrDict<void> *visitedClasses)
{
- if (cd->baseClasses())
+ for (const auto &ibcd : cd->baseClasses())
{
- BaseClassListIterator it(*cd->baseClasses());
- BaseClassDef *ibcd;
- for (it.toFirst();(ibcd=it.current());++it)
+ ClassDef *icd=ibcd.classDef;
+ if (icd->isLinkable())
{
- ClassDef *icd=ibcd->classDef;
- if (icd->isLinkable())
+ int lt1,lt3;
+ convertProtectionLevel(lt,ibcd.prot,&lt1,&lt3);
+ if (lt2==-1 && lt3!=-1)
{
- int lt1,lt3;
- convertProtectionLevel(lt,ibcd->prot,&lt1,&lt3);
- if (lt2==-1 && lt3!=-1)
- {
- lt2=lt3;
- }
- if (visitedClasses->find(icd)==0)
+ lt2=lt3;
+ }
+ if (visitedClasses->find(icd)==0)
+ {
+ visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
+ if (lt1!=-1)
{
- visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
- if (lt1!=-1)
- {
- // add member info for members of cd with list type lt
- addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList);
- // recurse down the inheritance tree
- findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses);
- }
+ // add member info for members of cd with list type lt
+ addInheritedMembers(inheritedFrom,icd,lt,(MemberListType)lt1,lt2,title,additionalList);
+ // recurse down the inheritance tree
+ findInheritedMembers(inheritedFrom,icd,(MemberListType)lt1,lt2,title,additionalList,visitedClasses);
}
}
}
diff --git a/src/context.h b/src/context.h
index 7256dc6..473c72f 100644
--- a/src/context.h
+++ b/src/context.h
@@ -21,15 +21,12 @@
#include <qlist.h>
#include <stdio.h>
#include "dirdef.h"
+#include "classdef.h"
class Definition;
-class ClassDef;
-class ClassSDict;
-class BaseClassList;
class PageDef;
class GroupDef;
class NamespaceDef;
-class BaseClassList;
class NamespaceSDict;
class FileDef;
class FileList;
@@ -455,7 +452,7 @@ class ClassInheritanceNodeContext : public RefCountedContext, public TemplateStr
virtual int addRef() { return RefCountedContext::addRef(); }
virtual int release() { return RefCountedContext::release(); }
- void addChildren(const BaseClassList *bcl,bool hideSuper);
+ void addChildren(BaseClassList bcl,bool hideSuper);
private:
ClassInheritanceNodeContext(const ClassDef *);
@@ -553,7 +550,7 @@ class NestingContext : public RefCountedContext, public TemplateListIntf
void addModules(const GroupSDict &modules);
void addModules(const GroupList &modules);
void addClassHierarchy(const ClassSDict &clDict,bool rootOnly);
- void addDerivedClasses(const BaseClassList *bcl,bool hideSuper);
+ void addDerivedClasses(BaseClassList bcl,bool hideSuper);
private:
NestingContext(const NestingNodeContext *parent,int level);
@@ -929,7 +926,7 @@ class InheritanceNodeContext : public RefCountedContext, public TemplateStructIn
class InheritanceListContext : public RefCountedContext, public TemplateListIntf
{
public:
- static InheritanceListContext *alloc(const BaseClassList *list,bool baseClasses)
+ static InheritanceListContext *alloc(BaseClassList list,bool baseClasses)
{ return new InheritanceListContext(list,baseClasses); }
// TemplateListIntf
@@ -940,7 +937,7 @@ class InheritanceListContext : public RefCountedContext, public TemplateListIntf
virtual int release() { return RefCountedContext::release(); }
private:
- InheritanceListContext(const BaseClassList *list,bool baseClasses);
+ InheritanceListContext(BaseClassList list,bool baseClasses);
~InheritanceListContext();
class Private;
Private *p;
diff --git a/src/defgen.cpp b/src/defgen.cpp
index 02f51c5..b01d438 100644
--- a/src/defgen.cpp
+++ b/src/defgen.cpp
@@ -358,60 +358,50 @@ void generateDEFForClass(ClassDef *cd,FTextStream &t)
t << " cp-id = '" << cd->getOutputFileBase() << "';" << endl;
t << " cp-name = '" << cd->name() << "';" << endl;
- if (cd->baseClasses())
+ for (const auto &bcd : cd->baseClasses())
{
- BaseClassListIterator bcli(*cd->baseClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ t << " cp-ref = {" << endl << " ref-type = base;" << endl;
+ t << " ref-id = '"
+ << bcd.classDef->getOutputFileBase() << "';" << endl;
+ t << " ref-prot = ";
+ switch (bcd.prot)
{
- t << " cp-ref = {" << endl << " ref-type = base;" << endl;
- t << " ref-id = '"
- << bcd->classDef->getOutputFileBase() << "';" << endl;
- t << " ref-prot = ";
- switch (bcd->prot)
- {
- case Public: t << "public;" << endl; break;
- case Package: // package scope is not possible
- case Protected: t << "protected;" << endl; break;
- case Private: t << "private;" << endl; break;
- }
- t << " ref-virt = ";
- switch(bcd->virt)
- {
- case Normal: t << "non-virtual;"; break;
- case Virtual: t << "virtual;"; break;
- case Pure: t << "pure-virtual;"; break;
- }
- t << endl << " };" << endl;
+ case Public: t << "public;" << endl; break;
+ case Package: // package scope is not possible
+ case Protected: t << "protected;" << endl; break;
+ case Private: t << "private;" << endl; break;
+ }
+ t << " ref-virt = ";
+ switch(bcd.virt)
+ {
+ case Normal: t << "non-virtual;"; break;
+ case Virtual: t << "virtual;"; break;
+ case Pure: t << "pure-virtual;"; break;
}
+ t << endl << " };" << endl;
}
- if (cd->subClasses())
+ for (const auto &bcd : cd->subClasses())
{
- BaseClassListIterator bcli(*cd->subClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ t << " cp-ref = {" << endl << " ref-type = derived;" << endl;
+ t << " ref-id = '"
+ << bcd.classDef->getOutputFileBase() << "';" << endl;
+ t << " ref-prot = ";
+ switch (bcd.prot)
{
- t << " cp-ref = {" << endl << " ref-type = derived;" << endl;
- t << " ref-id = '"
- << bcd->classDef->getOutputFileBase() << "';" << endl;
- t << " ref-prot = ";
- switch (bcd->prot)
- {
- case Public: t << "public;" << endl; break;
- case Package: // packet scope is not possible!
- case Protected: t << "protected;" << endl; break;
- case Private: t << "private;" << endl; break;
- }
- t << " ref-virt = ";
- switch(bcd->virt)
- {
- case Normal: t << "non-virtual;"; break;
- case Virtual: t << "virtual;"; break;
- case Pure: t << "pure-virtual;"; break;
- }
- t << endl << " };" << endl;
+ case Public: t << "public;" << endl; break;
+ case Package: // packet scope is not possible!
+ case Protected: t << "protected;" << endl; break;
+ case Private: t << "private;" << endl; break;
+ }
+ t << " ref-virt = ";
+ switch (bcd.virt)
+ {
+ case Normal: t << "non-virtual;"; break;
+ case Virtual: t << "virtual;"; break;
+ case Pure: t << "pure-virtual;"; break;
}
+ t << endl << " };" << endl;
}
int numMembers = 0;
diff --git a/src/diagram.cpp b/src/diagram.cpp
index d0b7a08..f2e48d8 100644
--- a/src/diagram.cpp
+++ b/src/diagram.cpp
@@ -1,13 +1,10 @@
/******************************************************************************
*
- *
- *
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 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.
*
@@ -39,7 +36,7 @@
class DiagramItemList;
/** Class representing a single node in the built-in class diagram */
-class DiagramItem
+class DiagramItem
{
public:
DiagramItem(DiagramItem *p,uint number,const ClassDef *cd,
@@ -47,7 +44,7 @@ class DiagramItem
~DiagramItem();
QCString label() const;
QCString fileName() const;
- DiagramItem *parentItem() { return parent; }
+ DiagramItem *parentItem() { return parent; }
DiagramItemList *getChildren() { return children; }
void move(int dx,int dy) { x+=(uint)dx; y+=(uint)dy; }
uint xPos() const { return x; }
@@ -59,7 +56,7 @@ class DiagramItem
Protection protection() const { return prot; }
Specifier virtualness() const { return virt; }
void putInList() { inList=TRUE; }
- bool isInList() const { return inList; }
+ bool isInList() const { return inList; }
const ClassDef *getClassDef() const { return classDef; }
private:
DiagramItemList *children;
@@ -82,14 +79,14 @@ class DiagramItemList : public QList<DiagramItem>
};
/** Class representing a row in the built-in class diagram */
-class DiagramRow : public QList<DiagramItem>
+class DiagramRow : public QList<DiagramItem>
{
public:
- DiagramRow(TreeDiagram *d,uint l) : QList<DiagramItem>()
+ DiagramRow(TreeDiagram *d,uint l) : QList<DiagramItem>()
{
- diagram=d;
+ diagram=d;
level=l;
- setAutoDelete(TRUE);
+ setAutoDelete(TRUE);
}
void insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases,
Protection prot,Specifier virt,const char *ts);
@@ -103,7 +100,7 @@ class DiagramRow : public QList<DiagramItem>
class DiagramRowIterator : public QListIterator<DiagramRow>
{
public:
- DiagramRowIterator(const QList<DiagramRow> &d)
+ DiagramRowIterator(const QList<DiagramRow> &d)
: QListIterator<DiagramRow>(d) {}
};
@@ -261,7 +258,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath,
{
QCString ref=cd->getReference();
t << "<area ";
- if (!ref.isEmpty())
+ if (!ref.isEmpty())
{
t << externalLinkTarget(true);
}
@@ -278,7 +275,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath,
{
t << "title=\"" << convertToHtml(tooltip) << "\" ";
}
- t << "alt=\"" << convertToXML(cd->displayName());
+ t << "alt=\"" << convertToXML(cd->displayName());
t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
t << (x+w) << "," << (y+h) << "\"/>" << endl;
}
@@ -286,7 +283,7 @@ static void writeMapArea(FTextStream &t,const ClassDef *cd,QCString relPath,
//-----------------------------------------------------------------------------
DiagramItem::DiagramItem(DiagramItem *p,uint number,const ClassDef *cd,
- Protection pr,Specifier vi,const char *ts)
+ Protection pr,Specifier vi,const char *ts)
{
parent=p;
x=y=0;
@@ -299,7 +296,7 @@ DiagramItem::DiagramItem(DiagramItem *p,uint number,const ClassDef *cd,
templSpec=ts;
}
-DiagramItem::~DiagramItem()
+DiagramItem::~DiagramItem()
{
delete children;
}
@@ -360,24 +357,18 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases
{
//if (cd->visited) return; // the visit check does not work in case of
// multiple inheritance of the same class!
- DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),
+ DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),
cd,prot,virt,ts);
//cd->visited=TRUE;
if (parent) parent->addChild(di);
di->move((int)(count()*gridWidth),(int)(level*gridHeight));
append(di);
- BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses();
int count=0;
- if (bcl)
+ for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses())
{
/* there are base/sub classes */
- BaseClassListIterator it(*bcl);
- BaseClassDef *bcd;
- for (;(bcd=it.current());++it)
- {
- ClassDef *ccd=bcd->classDef;
- if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;
- }
+ ClassDef *ccd=bcd.classDef;
+ if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;
}
if (count>0 && (prot!=Private || !doBases))
{
@@ -391,17 +382,14 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases
{
row=diagram->at(level+1);
}
- /* insert base classes in the next row */
- BaseClassListIterator it(*bcl);
- BaseClassDef *bcd;
- for (;(bcd=it.current());++it)
+ for (const auto &bcd : doBases ? cd->baseClasses() : cd->subClasses())
{
- ClassDef *ccd=bcd->classDef;
+ ClassDef *ccd=bcd.classDef;
if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/)
{
- row->insertClass(di,ccd,doBases,bcd->prot,
- doBases?bcd->virt:Normal,
- doBases?bcd->templSpecifiers.data():"");
+ row->insertClass(di,ccd,doBases,bcd.prot,
+ doBases?bcd.virt:Normal,
+ doBases?bcd.templSpecifiers.data():"");
}
}
}
@@ -409,7 +397,7 @@ void DiagramRow::insertClass(DiagramItem *parent,const ClassDef *cd,bool doBases
TreeDiagram::TreeDiagram(const ClassDef *root,bool doBases)
{
- setAutoDelete(TRUE);
+ setAutoDelete(TRUE);
DiagramRow *row=new DiagramRow(this,0);
append(row);
row->insertClass(0,root,doBases,Public,Normal,0);
@@ -437,7 +425,7 @@ bool TreeDiagram::layoutTree(DiagramItem *root,uint r)
bool moved=FALSE;
//printf("layoutTree(%s,%d)\n",root->label().data(),r);
- DiagramItemList *dil=root->getChildren();
+ DiagramItemList *dil=root->getChildren();
if (dil->count()>0)
{
uint k;
@@ -543,7 +531,7 @@ uint TreeDiagram::computeRows()
DiagramItem *di;
for (;(di=rit.current());++rit)
{
- if (di->parentItem()!=opi) curListLen=1; else curListLen++;
+ if (di->parentItem()!=opi) curListLen=1; else curListLen++;
if (curListLen>maxListLen) maxListLen=curListLen;
opi=di->parentItem();
}
@@ -574,7 +562,7 @@ void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos)
if (maxXPos) *maxXPos=mx;
}
-void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
+void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
bool doBase,bool bitmap,
uint baseRows,uint superRows,
uint cellWidth,uint cellHeight,
@@ -643,20 +631,20 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
}
}
opi=di->parentItem();
-
+
if (bitmap)
{
bool hasDocs=di->getClassDef()->isLinkable();
writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
- hasDocs,di->getChildren()->count()>0);
- if (!firstRow && generateMap)
+ hasDocs,di->getChildren()->count()>0);
+ if (!firstRow && generateMap)
writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
}
else
{
writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0);
}
-
+
if (doBase) --rit; else ++rit;
}
done=TRUE;
@@ -681,8 +669,8 @@ void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
}
bool hasDocs=di->getClassDef()->isLinkable();
- writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
- if (!firstRow && generateMap)
+ writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
+ if (!firstRow && generateMap)
writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
}
else
@@ -754,12 +742,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
t << protToString(di->protection()) << endl;
if (doBase)
{
- t << "1 " << (di->xPos()/(float)gridWidth) << " "
+ t << "1 " << (di->xPos()/(float)gridWidth) << " "
<< (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
}
else
{
- t << "0 " << (di->xPos()/(float)gridWidth) << " "
+ t << "0 " << (di->xPos()/(float)gridWidth) << " "
<< ((float)superRows-0.25f-di->yPos()/(float)gridHeight)
<< " in\n";
}
@@ -919,12 +907,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
t << protToString(di->protection()) << endl;
if (doBase)
{
- t << "1 " << di->xPos()/(float)gridWidth << " "
+ t << "1 " << di->xPos()/(float)gridWidth << " "
<< (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
}
else
{
- t << "0 " << di->xPos()/(float)gridWidth << " "
+ t << "0 " << di->xPos()/(float)gridWidth << " "
<< ((float)superRows-0.25f-di->yPos()/(float)gridHeight)
<< " in\n";
}
@@ -959,12 +947,12 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
t << protToString(p) << endl;
if (doBase)
{
- t << "0 " << di->xPos()/(float)gridWidth << " "
+ t << "0 " << di->xPos()/(float)gridWidth << " "
<< (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
}
else
{
- t << "1 " << di->xPos()/(float)gridWidth << " "
+ t << "1 " << di->xPos()/(float)gridWidth << " "
<< ((float)superRows-1.75f-di->yPos()/(float)gridHeight)
<< " out\n";
}
@@ -979,14 +967,14 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
uint xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
+ cellWidth/2;
uint xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
- + cellWidth/2;
+ + cellWidth/2;
if (doBase) // base classes
{
- image->drawHorzLine(y,xs,xe,col,mask);
+ image->drawHorzLine(y,xs,xe,col,mask);
}
else // super classes
{
- image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
+ image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
}
}
else
@@ -994,14 +982,14 @@ void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
t << protToString(p) << endl;
if (doBase)
{
- t << first->xPos()/(float)gridWidth << " "
+ t << first->xPos()/(float)gridWidth << " "
<< last->xPos()/(float)gridWidth << " "
- << (first->yPos()/(float)gridHeight+superRows-1)
+ << (first->yPos()/(float)gridHeight+superRows-1)
<< " conn\n";
}
else
{
- t << first->xPos()/(float)gridWidth << " "
+ t << first->xPos()/(float)gridWidth << " "
<< last->xPos()/(float)gridWidth << " "
<< ((float)superRows-first->yPos()/(float)gridHeight)
<< " conn\n";
@@ -1066,22 +1054,22 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
uint rows=baseRows+superRows-1;
uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
-
+
// Estimate the image aspect width and height in pixels.
uint estHeight = rows*40;
uint estWidth = cols*(20+QMAX(baseMaxLabelWidth,superMaxLabelWidth));
//printf("Estimated size %d x %d\n",estWidth,estHeight);
-
+
const float pageWidth = 14.0f; // estimated page width in cm.
// Somewhat lower to deal with estimation
- // errors.
-
+ // errors.
+
// compute the image height in centimeters based on the estimates
float realHeight = QMIN(rows,12); // real height in cm
float realWidth = realHeight * estWidth/(float)estHeight;
if (realWidth>pageWidth) // assume that the page width is about 15 cm
{
- realHeight*=pageWidth/realWidth;
+ realHeight*=pageWidth/realWidth;
realWidth=pageWidth;
}
@@ -1089,11 +1077,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
output << "\\begin{figure}[H]\n"
"\\begin{center}\n"
"\\leavevmode\n";
- output << "\\includegraphics[height=" << realHeight << "cm]{"
+ output << "\\includegraphics[height=" << realHeight << "cm]{"
<< fileName << "}" << endl;
output << "\\end{center}\n"
"\\end{figure}\n";
-
+
//printf("writeFigure rows=%d cols=%d\n",rows,cols);
QCString epsBaseName=(QCString)path+"/"+fileName;
@@ -1105,11 +1093,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
term("Could not open file %s for writing\n",f1.name().data());
}
FTextStream t(&f1);
-
+
//printf("writeEPS() rows=%d cols=%d\n",rows,cols);
-
+
// generate EPS header and postscript variables and procedures
-
+
t << "%!PS-Adobe-2.0 EPSF-2.0\n";
t << "%%Title: ClassName\n";
t << "%%Creator: Doxygen\n";
@@ -1322,11 +1310,11 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
<< " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
<< " max def\n"
<< "boundx scalefactor div boundy scalefactor div scale\n";
-
+
t << "\n% ----- classes -----\n\n";
base->drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0);
super->drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0);
-
+
t << "\n% ----- relations -----\n\n";
base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
@@ -1351,7 +1339,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
void ClassDiagram::writeImage(FTextStream &t,const char *path,
- const char *relPath,const char *fileName,
+ const char *relPath,const char *fileName,
bool generateMap) const
{
uint baseRows=base->computeRows();
@@ -1361,7 +1349,7 @@ void ClassDiagram::writeImage(FTextStream &t,const char *path,
uint lb,ls,xb,xs;
base->computeExtremes(&lb,&xb);
super->computeExtremes(&ls,&xs);
-
+
uint cellWidth = QMAX(lb,ls)+labelHorMargin*2;
uint maxXPos = QMAX(xb,xs);
uint labelVertMargin = 6; //QMAX(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 48d2fa4..1774788 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -84,7 +84,7 @@ static QStack<DocLexerContext> g_lexerStack;
static int g_yyLineNr = 0;
-#define lineCount(s,len) do { for(int i=0;i<len;i++) if (s[i]=='\n') g_yyLineNr++; } while(0)
+#define lineCount(s,len) do { for(int i=0;i<(int)len;i++) if (s[i]=='\n') g_yyLineNr++; } while(0)
#if USE_STATE2STRING
diff --git a/src/docvisitor.cpp b/src/docvisitor.cpp
index 17aefc2..d46d8c0 100644
--- a/src/docvisitor.cpp
+++ b/src/docvisitor.cpp
@@ -40,7 +40,7 @@ CodeParserInterface &DocVisitor::getCodeParser(const char *extension)
{
std::string ext(extension?extension:"");
// for each extension we create a code parser once per visitor, so that
- // the context of the same parser object is reused thoughout multiple passes for instance
+ // the context of the same parser object is reused throughout multiple passes for instance
// for code fragments shown via dontinclude.
auto it = m_p->parserFactoryMap.find(ext);
if (it==m_p->parserFactoryMap.end())
diff --git a/src/dotclassgraph.cpp b/src/dotclassgraph.cpp
index 84b7962..e157ec3 100644
--- a/src/dotclassgraph.cpp
+++ b/src/dotclassgraph.cpp
@@ -266,18 +266,11 @@ void DotClassGraph::buildGraph(const ClassDef *cd,DotNode *n,bool base,int dista
if (m_graphType == Inheritance || m_graphType==Collaboration)
{
- BaseClassList *bcl = base ? cd->baseClasses() : cd->subClasses();
- if (bcl)
+ for (const auto &bcd : base ? cd->baseClasses() : cd->subClasses())
{
- BaseClassListIterator bcli(*bcl);
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()) ; ++bcli )
- {
- //printf("-------- inheritance relation %s->%s templ='%s'\n",
- // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
- addClass(bcd->classDef,n,bcd->prot,0,bcd->usedName,
- bcd->templSpecifiers,base,distance);
- }
+ //printf("-------- inheritance relation %s->%s templ='%s'\n",
+ // cd->name().data(),bcd->classDef->name().data(),bcd->templSpecifiers.data());
+ addClass(bcd.classDef,n,bcd.prot,0,bcd.usedName,bcd.templSpecifiers,base,distance);
}
}
if (m_graphType == Collaboration)
diff --git a/src/dotgfxhierarchytable.cpp b/src/dotgfxhierarchytable.cpp
index 3d56de8..ddd9410 100644
--- a/src/dotgfxhierarchytable.cpp
+++ b/src/dotgfxhierarchytable.cpp
@@ -43,14 +43,14 @@ void DotGfxHierarchyTable::computeTheGraph()
md5stream << " rankdir=\"LR\";" << endl;
for (dnli2.toFirst();(node=dnli2.current());++dnli2)
{
- if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
+ if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
{
node->clearWriteFlag();
}
}
for (dnli2.toFirst();(node=dnli2.current());++dnli2)
{
- if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
+ if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
{
node->write(md5stream,Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE);
}
@@ -107,71 +107,66 @@ void DotGfxHierarchyTable::writeGraph(FTextStream &out,
void DotGfxHierarchyTable::addHierarchy(DotNode *n,const ClassDef *cd,bool hideSuper)
{
//printf("addHierarchy '%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count());
- if (cd->subClasses())
+ for (const auto &bcd : cd->subClasses())
{
- BaseClassListIterator bcli(*cd->subClasses());
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()) ; ++bcli )
+ ClassDef *bClass=bcd.classDef;
+ //printf(" Trying sub class='%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count());
+ if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses()))
{
- ClassDef *bClass=bcd->classDef;
- //printf(" Trying sub class='%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count());
- if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses()))
+ DotNode *bn;
+ //printf(" Node '%s' Found visible class='%s'\n",n->label().data(),
+ // bClass->name().data());
+ if ((bn=m_usedNodes->find(bClass->name()))) // node already present
{
- DotNode *bn;
- //printf(" Node '%s' Found visible class='%s'\n",n->label().data(),
- // bClass->name().data());
- if ((bn=m_usedNodes->find(bClass->name()))) // node already present
+ if (n->children()==0 || n->children()->findRef(bn)==-1) // no arrow yet
{
- if (n->children()==0 || n->children()->findRef(bn)==-1) // no arrow yet
- {
- n->addChild(bn,bcd->prot);
- bn->addParent(n);
- //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
- // n->label().data(),
- // bn->label().data(),
- // bn->children() ? bn->children()->count() : 0,
- // bn->parents() ? bn->parents()->count() : 0
- // );
- }
- //else
- //{
- // printf(" Class already has an arrow!\n");
- //}
+ n->addChild(bn,bcd.prot);
+ bn->addParent(n);
+ //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
+ // n->label().data(),
+ // bn->label().data(),
+ // bn->children() ? bn->children()->count() : 0,
+ // bn->parents() ? bn->parents()->count() : 0
+ // );
}
- else
+ //else
+ //{
+ // printf(" Class already has an arrow!\n");
+ //}
+ }
+ else
+ {
+ QCString tmp_url="";
+ if (bClass->isLinkable() && !bClass->isHidden())
{
- QCString tmp_url="";
- if (bClass->isLinkable() && !bClass->isHidden())
+ tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
+ if (!bClass->anchor().isEmpty())
{
- tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
- if (!bClass->anchor().isEmpty())
- {
- tmp_url+="#"+bClass->anchor();
- }
+ tmp_url+="#"+bClass->anchor();
}
- QCString tooltip = bClass->briefDescriptionAsTooltip();
- bn = new DotNode(getNextNodeNumber(),
+ }
+ QCString tooltip = bClass->briefDescriptionAsTooltip();
+ bn = new DotNode(getNextNodeNumber(),
bClass->displayName(),
tooltip,
tmp_url.data()
- );
- n->addChild(bn,bcd->prot);
- bn->addParent(n);
- //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
- // n->label().data(),
- // bn->label().data(),
- // bn->children() ? bn->children()->count() : 0,
- // bn->parents() ? bn->parents()->count() : 0
- // );
- //printf(" inserting %s (%p)\n",bClass->name().data(),bn);
- m_usedNodes->insert(bClass->name(),bn); // add node to the used list
- }
- if (!bClass->isVisited() && !hideSuper && bClass->subClasses())
- {
- bool wasVisited=bClass->isVisited();
- bClass->setVisited(TRUE);
- addHierarchy(bn,bClass,wasVisited);
- }
+ );
+ n->addChild(bn,bcd.prot);
+ bn->addParent(n);
+ //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
+ // n->label().data(),
+ // bn->label().data(),
+ // bn->children() ? bn->children()->count() : 0,
+ // bn->parents() ? bn->parents()->count() : 0
+ // );
+ //printf(" inserting %s (%p)\n",bClass->name().data(),bn);
+ m_usedNodes->insert(bClass->name(),bn); // add node to the used list
+ }
+ if (!bClass->isVisited() && !hideSuper && !bClass->subClasses().empty())
+ {
+ bool wasVisited=bClass->isVisited();
+ bClass->setVisited(TRUE);
+ addHierarchy(bn,bClass,wasVisited);
}
}
}
@@ -200,7 +195,7 @@ void DotGfxHierarchyTable::addClassList(const ClassSDict *cl)
) // root node in the forest
{
QCString tmp_url="";
- if (cd->isLinkable() && !cd->isHidden())
+ if (cd->isLinkable() && !cd->isHidden())
{
tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
if (!cd->anchor().isEmpty())
@@ -217,8 +212,8 @@ void DotGfxHierarchyTable::addClassList(const ClassSDict *cl)
//m_usedNodes->clear();
m_usedNodes->insert(cd->name(),n);
- m_rootNodes->insert(0,n);
- if (!cd->isVisited() && cd->subClasses())
+ m_rootNodes->insert(0,n);
+ if (!cd->isVisited() && !cd->subClasses().empty())
{
addHierarchy(n,cd,cd->isVisited());
cd->setVisited(TRUE);
@@ -232,7 +227,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound
, m_classType(ct)
{
m_rootNodes = new QList<DotNode>;
- m_usedNodes = new QDict<DotNode>(1009);
+ m_usedNodes = new QDict<DotNode>(1009);
m_usedNodes->setAutoDelete(TRUE);
m_rootSubgraphs = new DotNodeList;
@@ -245,7 +240,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound
// m_usedNodes now contains all nodes in the graph
// color the graph into a set of independent subgraphs
- bool done=FALSE;
+ bool done=FALSE;
int curColor=0;
QListIterator<DotNode> dnli(*m_rootNodes);
while (!done) // there are still nodes to color
@@ -263,7 +258,7 @@ DotGfxHierarchyTable::DotGfxHierarchyTable(const char *prefix,ClassDef::Compound
n->colorConnectedNodes(curColor);
curColor++;
const DotNode *dn=n->findDocNode();
- if (dn!=0)
+ if (dn!=0)
m_rootSubgraphs->inSort(dn);
else
m_rootSubgraphs->inSort(n);
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 16dc0a6..73c4b02 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -7348,7 +7348,7 @@ static void computeMemberRelations()
if (md!=bmd)
{
const ClassDef *mcd = md->getClassDef();
- if (mcd && mcd->baseClasses())
+ if (mcd && !mcd->baseClasses().empty())
{
const ClassDef *bmcd = bmd->getClassDef();
//printf("Check relation between '%s'::'%s' (%p) and '%s'::'%s' (%p)\n",
@@ -7469,8 +7469,8 @@ static void buildCompleteMemberLists()
for (cli.toFirst();(cd=cli.current());++cli)
{
if (// !cd->isReference() && // not an external class
- cd->subClasses()==0 && // is a root of the hierarchy
- cd->baseClasses()) // and has at least one base class
+ cd->subClasses().empty() && // is a root of the hierarchy
+ !cd->baseClasses().empty()) // and has at least one base class
{
//printf("*** merging members for %s\n",cd->name().data());
cd->mergeMembers();
@@ -7647,15 +7647,15 @@ static void generateFileSources()
results.emplace_back(threadPool.queue(processFile));
}
}
+ // first wait until all files are processed
for (auto &f : results)
{
- std::shared_ptr<SourceContext> ctx = f.get();
+ auto ctx = f.get();
if (ctx->generateSourceFile)
{
ctx->fd->writeSourceFooter(ctx->ol);
}
}
-
#else // single threaded version
for (const auto &fn : *Doxygen::inputNameLinkedMap)
{
diff --git a/src/index.cpp b/src/index.cpp
index 4df2ce4..e46a578 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -451,14 +451,13 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
//----------------------------------------------------------------------------
/*! Generates HTML Help tree of classes */
-static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
+static void writeClassTree(OutputList &ol,BaseClassList bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
{
- if (bcl==0) return;
- BaseClassListIterator bcli(*bcl);
+ if (bcl.empty()) return;
bool started=FALSE;
- for ( ; bcli.current() ; ++bcli)
+ for (const auto &bcd : bcl)
{
- ClassDef *cd=bcli.current()->classDef;
+ ClassDef *cd=bcd.classDef;
if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
{
continue;
@@ -513,7 +512,7 @@ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSupe
{
if (cd->getLanguage()==SrcLangExt_VHDL)
{
- ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
+ ftv->addContentsItem(hasChildren,bcd.usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
}
else
{
@@ -963,7 +962,7 @@ static int countClassesInTreeList(const ClassSDict &cl, ClassDef::CompoundType c
{
if (cd->isVisibleInHierarchy()) // should it be visible
{
- if (cd->subClasses()) // should have sub classes
+ if (!cd->subClasses().empty()) // should have sub classes
{
count++;
}
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 3343c1a..1d55dd6 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -666,19 +666,24 @@ static void writeDefaultHeaderPart1(FTextStream &t)
t << "% Headers & footers\n"
"\\usepackage{fancyhdr}\n"
"\\pagestyle{fancyplain}\n"
- "\\fancyhead[LE]{\\fancyplain{}{\\bfseries\\thepage}}\n"
- "\\fancyhead[CE]{\\fancyplain{}{}}\n"
- "\\fancyhead[RE]{\\fancyplain{}{\\bfseries\\leftmark}}\n"
- "\\fancyhead[LO]{\\fancyplain{}{\\bfseries\\rightmark}}\n"
- "\\fancyhead[CO]{\\fancyplain{}{}}\n"
- "\\fancyhead[RO]{\\fancyplain{}{\\bfseries\\thepage}}\n"
- "\\fancyfoot[LE]{\\fancyplain{}{}}\n"
- "\\fancyfoot[CE]{\\fancyplain{}{}}\n"
- "\\fancyfoot[RE]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
- "\\fancyfoot[LO]{\\fancyplain{}{\\bfseries\\scriptsize " << genString << " Doxygen }}\n"
- "\\fancyfoot[CO]{\\fancyplain{}{}}\n"
- "\\fancyfoot[RO]{\\fancyplain{}{}}\n"
- "\\renewcommand{\\footrulewidth}{0.4pt}\n";
+ "\\renewcommand{\\footrulewidth}{0.4pt}\n"
+ "%\n"
+ "\\fancypagestyle{fancyplain}{\n"
+ "\\fancyhf{}\n"
+ "\\fancyhead[LE, RO]{\\bfseries\\thepage}\n"
+ "\\fancyhead[LO]{\\bfseries\\rightmark}\n"
+ "\\fancyhead[RE]{\\bfseries\\leftmark}\n"
+ "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n"
+ "}\n"
+ "%\n"
+ "\\fancypagestyle{plain}{\n"
+ "\\fancyhf{}\n"
+ "\\fancyfoot[LO, RE]{\\bfseries\\scriptsize " << genString << " Doxygen }\n"
+ "\\renewcommand{\\headrulewidth}{0pt}}\n"
+ "%\n"
+ "\\pagestyle{fancyplain}\n"
+ "%\n";
+
if (!Config_getBool(COMPACT_LATEX))
{
t << "\\renewcommand{\\chaptermark}[1]{%\n"
diff --git a/src/markdown.cpp b/src/markdown.cpp
index d7b9186..15e18bc 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -2130,6 +2130,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent)
TRACE(data);
int i=0,end;
//printf("writeCodeBlock: data={%s}\n",QCString(data).left(size).data());
+ // no need for \ilinebr here as the prvious like was empty and was skipped
m_out.addStr("@verbatim\n");
int emptyLines=0;
while (i<size)
@@ -2164,7 +2165,7 @@ int Markdown::writeCodeBlock(const char *data,int size,int refIndent)
break;
}
}
- m_out.addStr("@endverbatim\n");
+ m_out.addStr("@endverbatim\\ilinebr ");
while (emptyLines>0) // write skipped empty lines
{
// add empty line
@@ -2528,6 +2529,7 @@ QCString Markdown::extractPageTitle(QCString &docs,QCString &id, int &prepend)
}
if (i<end1 && isAtxHeader(data+i,end1-i,title,id,FALSE)>0)
{
+ docs+="\n";
docs+=docs_org.mid(end1);
}
else
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
index a6e9f22..ffb0fed 100644
--- a/src/perlmodgen.cpp
+++ b/src/perlmodgen.cpp
@@ -1831,31 +1831,31 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd)
m_output.openHash()
.addFieldQuotedString("name", cd->name());
- if (cd->baseClasses())
+ if (!cd->baseClasses().empty())
{
m_output.openList("base");
- BaseClassListIterator bcli(*cd->baseClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ for (const auto &bcd : cd->baseClasses())
+ {
m_output.openHash()
- .addFieldQuotedString("name", bcd->classDef->displayName())
- .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
- .addFieldQuotedString("protection", getProtectionName(bcd->prot))
+ .addFieldQuotedString("name", bcd.classDef->displayName())
+ .addFieldQuotedString("virtualness", getVirtualnessName(bcd.virt))
+ .addFieldQuotedString("protection", getProtectionName(bcd.prot))
.closeHash();
+ }
m_output.closeList();
}
- if (cd->subClasses())
+ if (!cd->subClasses().empty())
{
m_output.openList("derived");
- BaseClassListIterator bcli(*cd->subClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ for (const auto &bcd : cd->subClasses())
+ {
m_output.openHash()
- .addFieldQuotedString("name", bcd->classDef->displayName())
- .addFieldQuotedString("virtualness", getVirtualnessName(bcd->virt))
- .addFieldQuotedString("protection", getProtectionName(bcd->prot))
+ .addFieldQuotedString("name", bcd.classDef->displayName())
+ .addFieldQuotedString("virtualness", getVirtualnessName(bcd.virt))
+ .addFieldQuotedString("protection", getProtectionName(bcd.prot))
.closeHash();
+ }
m_output.closeList();
}
diff --git a/src/pycode.l b/src/pycode.l
index 68ec265..ea314da 100644
--- a/src/pycode.l
+++ b/src/pycode.l
@@ -52,6 +52,7 @@
#include "filedef.h"
#include "namespacedef.h"
#include "tooltip.h"
+#include "scopedtypevariant.h"
// Toggle for some debugging info
//#define DBG_CTX(x) fprintf x
@@ -62,103 +63,10 @@
#define USE_STATE2STRING 0
-/*! Represents a stack of variable to class mappings as found in the
- * code. Each scope is enclosed in pushScope() and popScope() calls.
- * Variables are added by calling addVariables() and one can search
- * for variable using findVariable().
- */
-class PyVariableContext
-{
- public:
- static const ClassDef *dummyContext;
-
- using Scope = std::unordered_map<std::string,const ClassDef *>;
-
- void pushScope()
- {
- m_scopes.push_back(Scope());
- }
-
- void popScope()
- {
- if (!m_scopes.empty())
- {
- m_scopes.pop_back();
- }
- }
-
- void clear()
- {
- m_scopes.clear();
- m_globalScope.clear();
- }
-
- void clearExceptGlobal()
- {
- m_scopes.clear();
- }
-
- void addVariable(yyscan_t yyscanner, const QCString &type,const QCString &name);
- const ClassDef *findVariable(const QCString &name);
-
- private:
- Scope m_globalScope;
- std::vector<Scope> m_scopes;
-};
-
-class PyCallContext
-{
- public:
- struct Ctx
- {
- Ctx(QCString name_,QCString type_) : name(name_), type(type_) {}
- QCString name;
- QCString type;
- const ClassDef *cd = 0;
- };
-
- PyCallContext()
- {
- clear();
- }
-
- void setClass(const ClassDef *cd)
- {
- Ctx &ctx = m_classList.back();
- ctx.cd=cd;
- }
- void pushScope(const QCString &name_,const QCString type_)
- {
- m_classList.push_back(Ctx(name_,type_));
- }
- void popScope(QCString &name_,QCString &type_)
- {
- if (m_classList.size()>1)
- {
- const Ctx &ctx = m_classList.back();
- name_ = ctx.name;
- type_ = ctx.type;
- m_classList.pop_back();
- }
- }
- void clear()
- {
- m_classList.clear();
- m_classList.push_back(Ctx("",""));
- }
- const ClassDef *getClass() const
- {
- return m_classList.back().cd;
- }
-
- private:
- std::vector<Ctx> m_classList;
-};
-
struct pycodeYY_state
{
- std::unordered_map< std::string, std::unique_ptr<ClassDef> > codeClassMap;
+ std::unordered_map< std::string, ScopedTypeVariant > codeClassMap;
QCString curClassName;
QStrList curClassBases;
@@ -196,8 +104,8 @@ struct pycodeYY_state
QCString docBlock; //!< contents of all lines of a documentation block
bool endComment = FALSE;
- PyVariableContext theVarContext;
- PyCallContext theCallContext;
+ VariableContext theVarContext;
+ CallContext theCallContext;
};
@@ -205,9 +113,6 @@ struct pycodeYY_state
static const char *stateToString(int state);
#endif
-const ClassDef *PyVariableContext::dummyContext = (ClassDef*)0x8;
-
-
static void startCodeLine(yyscan_t yyscanner);
static int countLines(yyscan_t yyscanner);
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor);
@@ -235,6 +140,16 @@ static void findMemberLink(yyscan_t yyscanner, CodeOutputInterface &ol,
static void adjustScopesAndSuites(yyscan_t yyscanner,unsigned indentLength);
static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
+#if 0 // TODO: call me to store local variables and get better syntax highlighting, see code.l
+static void addVariable(yyscan_t yyscanner, QCString type, QCString name);
+#endif
+
+//-------------------------------------------------------------------
+
+static std::mutex g_searchIndexMutex;
+static std::mutex g_tooltipMutex;
+
+//-------------------------------------------------------------------
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
@@ -471,6 +386,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU
// Push a class scope
std::unique_ptr<ClassDef> classDefToAdd { createClassDef("<code>",1,1,yyextra->curClassName,ClassDef::Class,0,0,FALSE) };
+ ScopedTypeVariant var(yyextra->curClassName);
char *s=yyextra->curClassBases.first();
while (s)
{
@@ -479,7 +395,7 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU
auto it = yyextra->codeClassMap.find(s);
if (it != yyextra->codeClassMap.end())
{
- baseDefToAdd = it->second.get();
+ baseDefToAdd = dynamic_cast<const ClassDef*>(it->second.globalDef());
}
// Try to find class in global scope
if (baseDefToAdd==0)
@@ -487,14 +403,14 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU
baseDefToAdd=getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,s);
}
- if (baseDefToAdd && baseDefToAdd!=classDefToAdd.get())
+ if (baseDefToAdd && baseDefToAdd->name()!=yyextra->curClassName)
{
- classDefToAdd->insertBaseClass(const_cast<ClassDef*>(baseDefToAdd),s,Public,Normal);
+ var.localDef()->insertBaseClass(baseDefToAdd->name());
}
s=yyextra->curClassBases.next();
}
- yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(classDefToAdd)));
+ yyextra->codeClassMap.emplace(std::make_pair(yyextra->curClassName.str(),std::move(var)));
// Reset class-parsing variables.
yyextra->curClassName.resize(0);
@@ -892,63 +808,36 @@ TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBU
/*@ ----------------------------------------------------------------------------
*/
-void PyVariableContext::addVariable(yyscan_t yyscanner, const QCString &type,const QCString &name)
+#if 0 // TODO: call me to store local variables and get better syntax highlighting, see code.l
+static void addVariable(yyscan_t yyscanner, QCString type, QCString name)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
//printf("PyVariableContext::addVariable(%s,%s)\n",type.data(),name.data());
QCString ltype = type.simplifyWhiteSpace();
QCString lname = name.simplifyWhiteSpace();
- Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back();
- const ClassDef *varType = 0;
auto it = yyextra->codeClassMap.find(ltype.str());
if (it!=yyextra->codeClassMap.end())
{
- varType = it->second.get();
- }
- if (varType==0)
- {
- varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); // look for global class definitions
- }
- if (varType)
- {
- scope->emplace(std::make_pair(lname.str(),varType)); // add it to a list
+ yyextra->theVarContext.addVariable(lname,std::move(it->second));
}
else
{
- if (!m_scopes.empty()) // for local variable add a dummy entry to avoid linking to a global that is
- // shadowed.
+ const ClassDef *varType = getResolvedClass(yyextra->currentDefinition,yyextra->sourceFileDef,ltype); // look for global class definitions
+ if (varType)
{
- scope->emplace(std::make_pair(lname.str(),dummyContext));
+ yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varType));
}
- }
-}
-
-const ClassDef *PyVariableContext::findVariable(const QCString &name)
-{
- if (name.isEmpty()) return 0;
- const ClassDef *result = 0;
-
- // search from inner to outer scope
- auto it = std::rbegin(m_scopes);
- while (it != std::rend(m_scopes))
- {
- auto it2 = it->find(name.str());
- if (it2 != std::end(*it))
+ else
{
- result = it2->second;
- return result;
+ if (!yyextra->theVarContext.atGlobalScope()) // for local variable add a dummy entry to avoid linking to a global that is shadowed.
+ {
+ yyextra->theVarContext.addVariable(lname.str(),ScopedTypeVariant());
+ }
}
- ++it;
- }
- // nothing found -> also try the global scope
- auto it2 = m_globalScope.find(name.str());
- if (it2 != m_globalScope.end())
- {
- result = it2->second;
}
- return result;
}
+#endif
//-------------------------------------------------------------------------------
@@ -1031,6 +920,7 @@ static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (Doxygen::searchIndex)
{
+ std::lock_guard<std::mutex> lock(g_searchIndexMutex);
if (yyextra->searchCtx)
{
yyextra->code->setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
@@ -1049,6 +939,7 @@ static void addToSearchIndex(yyscan_t yyscanner, const char *text)
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (Doxygen::searchIndex)
{
+ std::lock_guard<std::mutex> lock(g_searchIndexMutex);
yyextra->code->addWord(text,FALSE);
}
}
@@ -1189,7 +1080,10 @@ static void writeMultiLineCodeLink(yyscan_t yyscanner,
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
- TooltipManager::instance()->addTooltip(d);
+ {
+ std::lock_guard<std::mutex> lock(g_tooltipMutex);
+ TooltipManager::instance()->addTooltip(d);
+ }
QCString ref = d->getReference();
QCString file = d->getOutputFileBase();
QCString anchor = d->anchor();
@@ -1310,7 +1204,7 @@ static bool getLinkInScope(yyscan_t yyscanner,
if (md->getGroupDef()) d = md->getGroupDef();
if (d && d->isLinkable())
{
- yyextra->theCallContext.setClass(stripClassName(yyscanner,md->typeString(),md->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
//printf("yyextra->currentDefinition=%p yyextra->currentMemberDef=%p\n",
// yyextra->currentDefinition,yyextra->currentMemberDef);
@@ -1372,8 +1266,9 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",className.data()));
- const ClassDef *cd=0,*lcd=0; /** Class def that we may find */
- const MemberDef *md=0; /** Member def that we may find */
+ const ScopedTypeVariant *lcd = 0;
+ const ClassDef *cd=0; // Class def that we may find
+ const MemberDef *md=0; // Member def that we may find
//bool isLocal=FALSE;
if ((lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable
@@ -1405,9 +1300,9 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
}
else
{
- if (lcd!=PyVariableContext::dummyContext)
+ if (lcd->type()!=ScopedTypeVariant::Dummy)
{
- yyextra->theCallContext.setClass(lcd);
+ yyextra->theCallContext.setScope(*lcd);
}
//isLocal=TRUE;
DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
@@ -1443,7 +1338,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
MemberDef *mmd = mcd->getMemberByName(locName);
if (mmd)
{
- yyextra->theCallContext.setClass(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())));
writeMultiLineCodeLink(yyscanner,ol,mmd,clName);
addToSearchIndex(yyscanner,className);
const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ?
@@ -1466,7 +1361,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
if (mmd)
{
//printf("name=%s scope=%s\n",locName.data(),scope.data());
- yyextra->theCallContext.setClass(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope()));
+ yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())));
writeMultiLineCodeLink(yyscanner,ol,mmd,clName);
addToSearchIndex(yyscanner,className);
const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ?
@@ -1503,8 +1398,7 @@ static void generateFunctionLink(yyscan_t yyscanner,
const char *funcName)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- const ClassDef *ccd=0;
- QCString locScope=yyextra->classScope.copy();
+ QCString locScope=yyextra->classScope;
QCString locFunc=removeRedundantWhiteSpace(funcName);
DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data()));
int i=locFunc.findRev("::");
@@ -1519,17 +1413,16 @@ static void generateFunctionLink(yyscan_t yyscanner,
auto it = yyextra->codeClassMap.find(locScope.str());
if (it!=yyextra->codeClassMap.end())
{
- ccd = it->second.get();
- }
- //printf("using classScope %s\n",yyextra->classScope.data());
- if (ccd && ccd->baseClasses())
- {
- BaseClassListIterator bcli(*ccd->baseClasses());
- for ( ; bcli.current() ; ++bcli)
+ ScopedTypeVariant ccd = it->second;
+ //printf("using classScope %s\n",yyextra->classScope.data());
+ if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
{
- if (getLink(yyscanner,bcli.current()->classDef->name(),locFunc,ol,funcName))
+ for (const auto &bcName : ccd.localDef()->baseClasses())
{
- return;
+ if (getLink(yyscanner,bcName,locFunc,ol,funcName))
+ {
+ return;
+ }
}
}
}
diff --git a/src/scopedtypevariant.h b/src/scopedtypevariant.h
new file mode 100644
index 0000000..2648a3a
--- /dev/null
+++ b/src/scopedtypevariant.h
@@ -0,0 +1,292 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2020 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
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#ifndef SCOPEDTYPEVARIANT_H
+#define SCOPEDTYPEVARIANT_H
+
+#include <utility>
+#include <vector>
+#include <qcstring.h>
+#include "definition.h"
+
+//! Class representing a local class definition found while
+//! generating syntax highlighted code.
+class LocalDef
+{
+ public:
+ void insertBaseClass(QCString name) { m_baseClasses.push_back(name); }
+ std::vector<QCString> baseClasses() const { return m_baseClasses; }
+ private:
+ std::vector<QCString> m_baseClasses;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! Variant class for a scoped type.
+ *
+ * Variants:
+ * - Dummy: a type used for hiding a global type.
+ * - Local: a locally defined type (e.g. found inside a function)
+ * - Global: a globally defined type (processed by doxygen in an earlier pass).
+ */
+class ScopedTypeVariant
+{
+ public:
+ //! possible variant types
+ enum Variant
+ {
+ Global,
+ Local,
+ Dummy
+ };
+ //! default constructor for creating a variant of type Dummy
+ ScopedTypeVariant() : m_variant(Dummy)
+ {
+ m_u.globalDef = 0;
+ }
+ //! constructor for creating a variant of type Global
+ explicit ScopedTypeVariant(const Definition *d)
+ {
+ if (d)
+ {
+ m_name = d->name();
+ m_variant = Global;
+ m_u.globalDef = d;
+ }
+ else
+ {
+ m_variant = Dummy;
+ m_u.globalDef = 0;
+ }
+ }
+ //! constructor for creating a variant of type Local
+ explicit ScopedTypeVariant(QCString name)
+ {
+ m_name = name;
+ m_variant = Local;
+ m_u.localDef = new LocalDef;
+ }
+ //! copy constructor
+ ScopedTypeVariant(const ScopedTypeVariant &stv)
+ {
+ m_variant = stv.m_variant;
+ m_name = stv.m_name;
+ if (m_variant==Local)
+ {
+ m_u.localDef = new LocalDef(*stv.m_u.localDef);
+ }
+ else if (m_variant==Global)
+ {
+ m_u.globalDef = stv.m_u.globalDef;
+ }
+ }
+ //! move constructor
+ ScopedTypeVariant(ScopedTypeVariant && stv) noexcept : ScopedTypeVariant()
+ {
+ swap(*this,stv);
+ }
+ //! assignment operator
+ ScopedTypeVariant &operator=(ScopedTypeVariant stv)
+ {
+ swap(*this,stv);
+ return *this;
+ }
+ //! destructor
+ ~ScopedTypeVariant()
+ {
+ if (m_variant==Local)
+ {
+ delete m_u.localDef;
+ }
+ }
+ //! swap function
+ friend void swap(ScopedTypeVariant &first,ScopedTypeVariant &second)
+ {
+ using std::swap; // enable ADL
+ swap(first.m_variant,second.m_variant);
+ swap(first.m_name,second.m_name);
+ swap(first.m_u.globalDef,second.m_u.globalDef);
+ }
+ //! Turn the variant into a Global type
+ void setGlobal(const Definition *def)
+ {
+ if (m_variant==Local)
+ {
+ delete m_u.localDef;
+ }
+ m_variant = Global;
+ m_name = def->name();
+ m_u.globalDef = def;
+ }
+ //! Turn the variant into a Local type
+ LocalDef *setLocal(QCString name)
+ {
+ if (m_variant==Local)
+ {
+ delete m_u.localDef;
+ }
+ m_variant = Local;
+ m_name = name;
+ m_u.localDef = new LocalDef;
+ return m_u.localDef;
+ }
+ //! Turn the variant into a Dummy type
+ void setDummy()
+ {
+ if (m_variant==Local)
+ {
+ delete m_u.localDef;
+ }
+ m_variant = Dummy;
+ m_name = "";
+ m_u.localDef=0;
+ }
+ Variant type() const { return m_variant; }
+ QCString name() const { return m_name; }
+ LocalDef *localDef() const { return m_variant==Local ? m_u.localDef : 0; }
+ const Definition *globalDef() const { return m_variant==Global ? m_u.globalDef : 0; }
+
+ private:
+ Variant m_variant;
+ QCString m_name;
+ union
+ {
+ const Definition *globalDef;
+ LocalDef *localDef;
+ } m_u;
+};
+
+//-----------------------------------------------------------------------------
+
+/*! Represents a stack of variable to class mappings as found in the
+ * code. Each scope is enclosed in pushScope() and popScope() calls.
+ * Variables are added by calling addVariables() and one can search
+ * for variable using findVariable().
+ */
+class VariableContext
+{
+ public:
+ using Scope = std::unordered_map<std::string,ScopedTypeVariant>;
+
+ void pushScope()
+ {
+ m_scopes.push_back(Scope());
+ }
+ void popScope()
+ {
+ if (!m_scopes.empty())
+ {
+ m_scopes.pop_back();
+ }
+ }
+ void clear()
+ {
+ m_scopes.clear();
+ m_globalScope.clear();
+ }
+ void clearExceptGlobal()
+ {
+ m_scopes.clear();
+ }
+ void addVariable(QCString name,ScopedTypeVariant stv)
+ {
+ Scope *scope = m_scopes.empty() ? &m_globalScope : &m_scopes.back();
+ scope->emplace(std::make_pair(name.str(),std::move(stv))); // add it to a list
+ }
+ const ScopedTypeVariant *findVariable(QCString name)
+ {
+ const ScopedTypeVariant *result = 0;
+ if (name.isEmpty()) return result;
+
+ // search from inner to outer scope
+ auto it = std::rbegin(m_scopes);
+ while (it != std::rend(m_scopes))
+ {
+ auto it2 = it->find(name.str());
+ if (it2 != std::end(*it))
+ {
+ result = &it2->second;
+ return result;
+ }
+ ++it;
+ }
+ // nothing found -> also try the global scope
+ auto it2 = m_globalScope.find(name.str());
+ if (it2 != m_globalScope.end())
+ {
+ result = &it2->second;
+ }
+ return result;
+ }
+ bool atGlobalScope() const { return m_scopes.empty(); }
+
+ private:
+ Scope m_globalScope;
+ std::vector<Scope> m_scopes;
+};
+
+//-----------------------------------------------------------------------------
+
+/** Represents the call context */
+class CallContext
+{
+ public:
+ struct Ctx
+ {
+ Ctx(QCString name_,QCString type_) : name(name_), type(type_) {}
+ QCString name;
+ QCString type;
+ ScopedTypeVariant stv;
+ };
+
+ CallContext()
+ {
+ clear();
+ }
+ void setScope(ScopedTypeVariant stv)
+ {
+ Ctx &ctx = m_stvList.back();
+ ctx.stv=std::move(stv);
+ }
+ void pushScope(const QCString &name_,const QCString type_)
+ {
+ m_stvList.push_back(Ctx(name_,type_));
+ }
+ void popScope(QCString &name_,QCString &type_)
+ {
+ if (m_stvList.size()>1)
+ {
+ const Ctx &ctx = m_stvList.back();
+ name_ = ctx.name;
+ type_ = ctx.type;
+ m_stvList.pop_back();
+ }
+ }
+ void clear()
+ {
+ m_stvList.clear();
+ m_stvList.push_back(Ctx("",""));
+ }
+ const ScopedTypeVariant getScope() const
+ {
+ return m_stvList.back().stv;
+ }
+
+ private:
+ std::vector<Ctx> m_stvList;
+};
+
+
+#endif
diff --git a/src/searchindex.cpp b/src/searchindex.cpp
index 067370b..3045385 100644
--- a/src/searchindex.cpp
+++ b/src/searchindex.cpp
@@ -209,7 +209,7 @@ void SearchIndex::addWord(const char *word,bool hiPriority,bool recurse)
{
//fprintf(stderr,"addWord(%s) at index %d\n",word,idx);
m_index[idx].push_back(IndexWord(wStr));
- it = m_words.insert({ wStr.str(), m_index[idx].size()-1 }).first;
+ it = m_words.insert({ wStr.str(), static_cast<int>(m_index[idx].size())-1 }).first;
}
m_index[idx][it->second].addUrlIndex(m_urlIndex,hiPriority);
int i;
@@ -239,10 +239,10 @@ void SearchIndex::addWord(const char *word,bool hiPriority)
static void writeInt(QFile &f,size_t index)
{
- f.putch(index>>24);
- f.putch((index>>16)&0xff);
- f.putch((index>>8)&0xff);
- f.putch(index&0xff);
+ f.putch(static_cast<int>(index>>24));
+ f.putch(static_cast<int>((index>>16)&0xff));
+ f.putch(static_cast<int>((index>>8)&0xff));
+ f.putch(static_cast<int>(index&0xff));
}
static void writeString(QFile &f,const char *s)
diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp
index 2f72221..235479d 100644
--- a/src/sqlite3gen.cpp
+++ b/src/sqlite3gen.cpp
@@ -2012,37 +2012,27 @@ static void generateSqlite3ForClass(const ClassDef *cd)
step(compounddef_insert);
// + list of direct super classes
- if (cd->baseClasses())
+ for (const auto &bcd : cd->baseClasses())
{
- BaseClassListIterator bcli(*cd->baseClasses());
- const BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
- {
- struct Refid base_refid = insertRefid(bcd->classDef->getOutputFileBase());
- struct Refid derived_refid = insertRefid(cd->getOutputFileBase());
- bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
- bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
- bindIntParameter(compoundref_insert,":prot",bcd->prot);
- bindIntParameter(compoundref_insert,":virt",bcd->virt);
- step(compoundref_insert);
- }
+ struct Refid base_refid = insertRefid(bcd.classDef->getOutputFileBase());
+ struct Refid derived_refid = insertRefid(cd->getOutputFileBase());
+ bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
+ bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
+ bindIntParameter(compoundref_insert,":prot",bcd.prot);
+ bindIntParameter(compoundref_insert,":virt",bcd.virt);
+ step(compoundref_insert);
}
// + list of direct sub classes
- if (cd->subClasses())
- {
- BaseClassListIterator bcli(*cd->subClasses());
- const BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
- {
- struct Refid derived_refid = insertRefid(bcd->classDef->getOutputFileBase());
- struct Refid base_refid = insertRefid(cd->getOutputFileBase());
- bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
- bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
- bindIntParameter(compoundref_insert,":prot",bcd->prot);
- bindIntParameter(compoundref_insert,":virt",bcd->virt);
- step(compoundref_insert);
- }
+ for (const auto &bcd : cd->subClasses())
+ {
+ struct Refid derived_refid = insertRefid(bcd.classDef->getOutputFileBase());
+ struct Refid base_refid = insertRefid(cd->getOutputFileBase());
+ bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
+ bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
+ bindIntParameter(compoundref_insert,":prot",bcd.prot);
+ bindIntParameter(compoundref_insert,":virt",bcd.virt);
+ step(compoundref_insert);
}
// + list of inner classes
diff --git a/src/util.cpp b/src/util.cpp
index 78de1a8..41fcffa 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -429,7 +429,8 @@ QCString resolveTypeDef(const Definition *context,const QCString &qualifiedName,
// tmd->getOuterScope()->name().data(), mContext);
if (tmd->isTypedef() /*&& tmd->getOuterScope()==resScope*/)
{
- int dist=isAccessibleFrom(resScope,0,tmd);
+ AccessStack accessStack;
+ int dist=isAccessibleFrom(accessStack,resScope,0,tmd);
if (dist!=-1 && (md==0 || dist<minDist))
{
md = tmd;
@@ -506,7 +507,6 @@ NamespaceDef *getResolvedNamespace(const char *name)
}
static QDict<MemberDef> g_resolvedTypedefs;
-static QDict<Definition> g_visitedNamespaces;
// forward declaration
static const ClassDef *getResolvedClassRec(const Definition *scope,
@@ -516,8 +516,6 @@ static const ClassDef *getResolvedClassRec(const Definition *scope,
QCString *pTemplSpec,
QCString *pResolvedType
);
-int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope,const Definition *item,
- const QCString &explicitScopePart);
/*! Returns the class representing the value of the typedef represented by \a md
* within file \a fileScope.
@@ -685,8 +683,10 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co
MemberDef *md = dynamic_cast<MemberDef *>(d);
if (md->isTypedef()) // d is a typedef
{
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
// test accessibility of typedef within scope.
- int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,"");
if (distance!=-1 && distance<minDistance)
// definition is accessible and a better match
{
@@ -705,7 +705,9 @@ static QCString substTypedef(const Definition *scope,const FileDef *fileScope,co
if (md->isTypedef()) // d is a typedef
{
// test accessibility of typedef within scope.
- int distance = isAccessibleFromWithExpScope(scope,fileScope,d,"");
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,"");
if (distance!=-1) // definition is accessible
{
bestMatch = md;
@@ -824,12 +826,12 @@ bool accessibleViaUsingClass(const SDict<Definition> *cl,
return FALSE;
}
-bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
+bool accessibleViaUsingNamespace(StringUnorderedSet &visited,
+ const NamespaceSDict *nl,
const FileDef *fileScope,
const Definition *item,
const QCString &explicitScopePart="")
{
- static QDict<void> visitedDict;
if (nl) // check used namespaces for the class
{
NamespaceSDict::Iterator nli(*nl);
@@ -848,17 +850,17 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
if (item->getLanguage()==SrcLangExt_Cpp)
{
QCString key=und->name();
- if (und->getUsedNamespaces() && visitedDict.find(key)==0)
+ if (und->getUsedNamespaces() && visited.find(key.str())==visited.end())
{
- visitedDict.insert(key,(void *)0x08);
+ visited.insert(key.str());
- if (accessibleViaUsingNamespace(und->getUsedNamespaces(),fileScope,item,explicitScopePart))
+ if (accessibleViaUsingNamespace(visited,und->getUsedNamespaces(),fileScope,item,explicitScopePart))
{
//printf("] found it via recursion\n");
return TRUE;
}
- visitedDict.remove(key);
+ visited.erase(key.str());
}
}
//printf("] Try via used namespace done\n");
@@ -867,89 +869,15 @@ bool accessibleViaUsingNamespace(const NamespaceSDict *nl,
return FALSE;
}
-const int MAX_STACK_SIZE = 1000;
-
-/** Helper class representing the stack of items considered while resolving
- * the scope.
- */
-class AccessStack
-{
- public:
- AccessStack() : m_index(0) {}
- void push(const Definition *scope,const FileDef *fileScope,const Definition *item)
- {
- if (m_index<MAX_STACK_SIZE)
- {
- m_elements[m_index].scope = scope;
- m_elements[m_index].fileScope = fileScope;
- m_elements[m_index].item = item;
- m_index++;
- }
- }
- void push(const Definition *scope,const FileDef *fileScope,const Definition *item,const QCString &expScope)
- {
- if (m_index<MAX_STACK_SIZE)
- {
- m_elements[m_index].scope = scope;
- m_elements[m_index].fileScope = fileScope;
- m_elements[m_index].item = item;
- m_elements[m_index].expScope = expScope;
- m_index++;
- }
- }
- void pop()
- {
- if (m_index>0) m_index--;
- }
- bool find(const Definition *scope,const FileDef *fileScope, const Definition *item)
- {
- int i=0;
- for (i=0;i<m_index;i++)
- {
- AccessElem *e = &m_elements[i];
- if (e->scope==scope && e->fileScope==fileScope && e->item==item)
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- bool find(const Definition *scope,const FileDef *fileScope, const Definition *item,const QCString &expScope)
- {
- int i=0;
- for (i=0;i<m_index;i++)
- {
- AccessElem *e = &m_elements[i];
- if (e->scope==scope && e->fileScope==fileScope && e->item==item && e->expScope==expScope)
- {
- return TRUE;
- }
- }
- return FALSE;
- }
-
- private:
- /** Element in the stack. */
- struct AccessElem
- {
- const Definition *scope;
- const FileDef *fileScope;
- const Definition *item;
- QCString expScope;
- };
- int m_index;
- AccessElem m_elements[MAX_STACK_SIZE];
-};
/* Returns the "distance" (=number of levels up) from item to scope, or -1
* if item in not inside scope.
*/
-int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Definition *item)
+int isAccessibleFrom(AccessStack &accessStack,const Definition *scope,const FileDef *fileScope,const Definition *item)
{
//printf("<isAccessibleFrom(scope=%s,item=%s itemScope=%s)\n",
// scope->name().data(),item->name().data(),item->getOuterScope()->name().data());
- static AccessStack accessStack;
if (accessStack.find(scope,fileScope,item))
{
return -1;
@@ -991,7 +919,8 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi
goto done;
}
NamespaceSDict *nl = fileScope->getUsedNamespaces();
- if (accessibleViaUsingNamespace(nl,fileScope,item))
+ StringUnorderedSet visited;
+ if (accessibleViaUsingNamespace(visited,nl,fileScope,item))
{
//printf("> found via used namespace\n");
goto done;
@@ -1014,14 +943,15 @@ int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Defi
goto done;
}
const NamespaceSDict *nl = nscope->getUsedNamespaces();
- if (accessibleViaUsingNamespace(nl,fileScope,item))
+ StringUnorderedSet visited;
+ if (accessibleViaUsingNamespace(visited,nl,fileScope,item))
{
//printf("> found via used namespace\n");
goto done;
}
}
// repeat for the parent scope
- i=isAccessibleFrom(scope->getOuterScope(),fileScope,item);
+ i=isAccessibleFrom(accessStack,scope->getOuterScope(),fileScope,item);
//printf("> result=%d\n",i);
result= (i==-1) ? -1 : i+2;
}
@@ -1046,16 +976,16 @@ done:
* not found and then A::I is searched in the global scope, which matches and
* thus the result is 1.
*/
-int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope,
- const Definition *item,const QCString &explicitScopePart)
+int isAccessibleFromWithExpScope(VisitedNamespaces &visitedNamespaces,
+ AccessStack &accessStack, const Definition *scope,const FileDef *fileScope,
+ const Definition *item,const QCString &explicitScopePart)
{
if (explicitScopePart.isEmpty())
{
// handle degenerate case where there is no explicit scope.
- return isAccessibleFrom(scope,fileScope,item);
+ return isAccessibleFrom(accessStack,scope,fileScope,item);
}
- static AccessStack accessStack;
if (accessStack.find(scope,fileScope,item,explicitScopePart))
{
return -1;
@@ -1104,7 +1034,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
int i=-1;
if (newScope->definitionType()==Definition::TypeNamespace)
{
- g_visitedNamespaces.insert(newScope->name(),newScope);
+ visitedNamespaces.insert({newScope->name().str(),newScope});
// this part deals with the case where item is a class
// A::B::C but is explicit referenced as A::C, where B is imported
// in A via a using directive.
@@ -1132,10 +1062,10 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
const NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
{
- if (g_visitedNamespaces.find(nd->name())==0)
+ if (visitedNamespaces.find(nd->name().str())==visitedNamespaces.end())
{
//printf("Trying for namespace %s\n",nd->name().data());
- i = isAccessibleFromWithExpScope(scope,fileScope,item,nd->name());
+ i = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,item,nd->name());
if (i!=-1)
{
//printf("> found via explicit scope of used namespace\n");
@@ -1148,7 +1078,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
// repeat for the parent scope
if (scope!=Doxygen::globalScope)
{
- i = isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope,
+ i = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope->getOuterScope(),fileScope,
item,explicitScopePart);
}
//printf(" | result=%d\n",i);
@@ -1162,7 +1092,8 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
{
const NamespaceDef *nscope = dynamic_cast<const NamespaceDef*>(scope);
const NamespaceSDict *nl = nscope->getUsedNamespaces();
- if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
+ StringUnorderedSet visited;
+ if (accessibleViaUsingNamespace(visited,nl,fileScope,item,explicitScopePart))
{
//printf("> found in used namespace\n");
goto done;
@@ -1173,7 +1104,8 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
if (fileScope)
{
const NamespaceSDict *nl = fileScope->getUsedNamespaces();
- if (accessibleViaUsingNamespace(nl,fileScope,item,explicitScopePart))
+ StringUnorderedSet visited;
+ if (accessibleViaUsingNamespace(visited,nl,fileScope,item,explicitScopePart))
{
//printf("> found in used namespace\n");
goto done;
@@ -1184,7 +1116,7 @@ int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScop
}
else // continue by looking into the parent scope
{
- int i=isAccessibleFromWithExpScope(scope->getOuterScope(),fileScope,
+ int i=isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope->getOuterScope(),fileScope,
item,explicitScopePart);
//printf("> result=%d\n",i);
result= (i==-1) ? -1 : i+2;
@@ -1225,9 +1157,10 @@ static void getResolvedSymbol(const Definition *scope,
)
)
{
- g_visitedNamespaces.clear();
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
// test accessibility of definition within scope.
- int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
//printf(" %s; distance %s (%p) is %d\n",scope->name().data(),d->name().data(),d,distance);
if (distance!=-1) // definition is accessible
{
@@ -2621,16 +2554,11 @@ int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level)
return -1;
}
int m=maxInheritanceDepth;
- if (cd->baseClasses())
+ for (const auto &bcdi : cd->baseClasses())
{
- BaseClassListIterator bcli(*cd->baseClasses());
- BaseClassDef *bcdi;
- for (;(bcdi=bcli.current());++bcli)
- {
- int mc=minClassDistance(bcdi->classDef,bcd,level+1);
- if (mc<m) m=mc;
- if (m<0) break;
- }
+ int mc=minClassDistance(bcdi.classDef,bcd,level+1);
+ if (mc<m) m=mc;
+ if (m<0) break;
}
return m;
}
@@ -2651,14 +2579,12 @@ Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd,
err("Internal inconsistency: found class %s seem to have a recursive "
"inheritance relation! Please send a bug report to doxygen@gmail.com\n",cd->name().data());
}
- else if (cd->baseClasses())
+ else if (prot!=Private)
{
- BaseClassListIterator bcli(*cd->baseClasses());
- const BaseClassDef *bcdi;
- for (;(bcdi=bcli.current()) && prot!=Private;++bcli)
+ for (const auto &bcdi : cd->baseClasses())
{
- Protection baseProt = classInheritedProtectionLevel(bcdi->classDef,bcd,bcdi->prot,level+1);
- if (baseProt==Private) prot=Private;
+ Protection baseProt = classInheritedProtectionLevel(bcdi.classDef,bcd,bcdi.prot,level+1);
+ if (baseProt==Private) prot=Private;
else if (baseProt==Protected) prot=Protected;
}
}
@@ -2667,14 +2593,12 @@ exit:
return prot;
}
-void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0)
+void trimBaseClassScope(BaseClassList bcl,QCString &s,int level=0)
{
//printf("trimBaseClassScope level=%d '%s'\n",level,s.data());
- BaseClassListIterator bcli(*bcl);
- BaseClassDef *bcd;
- for (;(bcd=bcli.current());++bcli)
+ for (const auto &bcd : bcl)
{
- ClassDef *cd=bcd->classDef;
+ ClassDef *cd=bcd.classDef;
//printf("Trying class %s\n",cd->name().data());
int spos=s.find(cd->name()+"::");
if (spos!=-1)
@@ -2684,8 +2608,10 @@ void trimBaseClassScope(BaseClassList *bcl,QCString &s,int level=0)
);
}
//printf("base class '%s'\n",cd->name().data());
- if (cd->baseClasses())
+ if (!cd->baseClasses().empty())
+ {
trimBaseClassScope(cd->baseClasses(),s,level+1);
+ }
}
}
@@ -4646,14 +4572,12 @@ int getPrefixIndex(const QCString &name)
//----------------------------------------------------------------------------
-static void initBaseClassHierarchy(BaseClassList *bcl)
+static void initBaseClassHierarchy(BaseClassList bcl)
{
- if (bcl==0) return;
- BaseClassListIterator bcli(*bcl);
- for ( ; bcli.current(); ++bcli)
+ for (const auto &bcd : bcl)
{
- ClassDef *cd=bcli.current()->classDef;
- if (cd->baseClasses()==0) // no base classes => new root
+ ClassDef *cd = bcd.classDef;
+ if (cd->baseClasses().empty()) // no base classes => new root
{
initBaseClassHierarchy(cd->baseClasses());
}
@@ -4664,23 +4588,22 @@ static void initBaseClassHierarchy(BaseClassList *bcl)
bool classHasVisibleChildren(const ClassDef *cd)
{
- BaseClassList *bcl;
+ BaseClassList bcl;
if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
{
- if (cd->baseClasses()==0) return FALSE;
+ if (cd->baseClasses().empty()) return FALSE;
bcl=cd->baseClasses();
}
else
{
- if (cd->subClasses()==0) return FALSE;
+ if (cd->subClasses().empty()) return FALSE;
bcl=cd->subClasses();
}
- BaseClassListIterator bcli(*bcl);
- for ( ; bcli.current() ; ++bcli)
+ for (const auto &bcd : bcl)
{
- if (bcli.current()->classDef->isVisibleInHierarchy())
+ if (bcd.classDef->isVisibleInHierarchy())
{
return TRUE;
}
@@ -4704,17 +4627,13 @@ void initClassHierarchy(ClassSDict *cl)
//----------------------------------------------------------------------------
-bool hasVisibleRoot(const BaseClassList *bcl)
+bool hasVisibleRoot(BaseClassList bcl)
{
- if (bcl)
+ for (const auto &bcd : bcl)
{
- BaseClassListIterator bcli(*bcl);
- for ( ; bcli.current(); ++bcli)
- {
- const ClassDef *cd=bcli.current()->classDef;
- if (cd->isVisibleInHierarchy()) return TRUE;
- hasVisibleRoot(cd->baseClasses());
- }
+ const ClassDef *cd=bcd.classDef;
+ if (cd->isVisibleInHierarchy()) return TRUE;
+ hasVisibleRoot(cd->baseClasses());
}
return FALSE;
}
@@ -6850,8 +6769,9 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope,
{
if (d->definitionType()==Definition::TypeMember)
{
- g_visitedNamespaces.clear();
- int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
if (distance!=-1 && distance<minDistance)
{
minDistance = distance;
@@ -6865,8 +6785,9 @@ MemberDef *getMemberFromSymbol(const Definition *scope,const FileDef *fileScope,
{
//printf("unique match!\n");
Definition *d = (Definition *)di;
- g_visitedNamespaces.clear();
- int distance = isAccessibleFromWithExpScope(scope,fileScope,d,explicitScopePart);
+ VisitedNamespaces visitedNamespaces;
+ AccessStack accessStack;
+ int distance = isAccessibleFromWithExpScope(visitedNamespaces,accessStack,scope,fileScope,d,explicitScopePart);
if (distance!=-1 && distance<minDistance)
{
minDistance = distance;
diff --git a/src/util.h b/src/util.h
index 6637554..5324bf7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -23,6 +23,8 @@
*/
#include <memory>
+#include <unordered_map>
+#include <algorithm>
#include <qlist.h>
#include <ctype.h>
@@ -46,7 +48,6 @@ class OutputDocInterface;
class MemberDef;
class ExampleSDict;
class ClassSDict;
-class BaseClassList;
class GroupDef;
class NamespaceSDict;
class ClassList;
@@ -119,6 +120,56 @@ class LetterToIndexMap : public SIntDict<T>
//--------------------------------------------------------------------
+const int MAX_STACK_SIZE = 100;
+
+/** Helper class representing the stack of items considered while resolving
+ * the scope.
+ */
+class AccessStack
+{
+ /** Element in the stack. */
+ struct AccessElem
+ {
+ AccessElem(const Definition *d,const FileDef *f,const Definition *i,QCString e = QCString()) : scope(d), fileScope(f), item(i), expScope(e) {}
+ const Definition *scope;
+ const FileDef *fileScope;
+ const Definition *item;
+ QCString expScope;
+ };
+ public:
+ void push(const Definition *scope,const FileDef *fileScope,const Definition *item)
+ {
+ m_elements.push_back(AccessElem(scope,fileScope,item));
+ }
+ void push(const Definition *scope,const FileDef *fileScope,const Definition *item,const QCString &expScope)
+ {
+ m_elements.push_back(AccessElem(scope,fileScope,item,expScope));
+ }
+ void pop()
+ {
+ if (!m_elements.empty()) m_elements.pop_back();
+ }
+ bool find(const Definition *scope,const FileDef *fileScope, const Definition *item)
+ {
+ auto it = std::find_if(m_elements.begin(),m_elements.end(),
+ [&](const AccessElem &e) { return e.scope==scope && e.fileScope==fileScope && e.item==item; });
+ return it!=m_elements.end();
+ }
+ bool find(const Definition *scope,const FileDef *fileScope, const Definition *item,const QCString &expScope)
+ {
+ auto it = std::find_if(m_elements.begin(),m_elements.end(),
+ [&](const AccessElem &e) { return e.scope==scope && e.fileScope==fileScope && e.item==item && e.expScope==expScope; });
+ return it!=m_elements.end();
+ }
+
+ private:
+ std::vector<AccessElem> m_elements;
+};
+
+using VisitedNamespaces = std::unordered_map<std::string,const Definition *>;
+
+//--------------------------------------------------------------------
+
QCString langToString(SrcLangExt lang);
QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE);
@@ -259,7 +310,7 @@ QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0);
void initClassHierarchy(ClassSDict *cl);
-bool hasVisibleRoot(const BaseClassList *bcl);
+bool hasVisibleRoot(BaseClassList bcl);
bool classHasVisibleChildren(const ClassDef *cd);
bool namespaceHasVisibleChild(const NamespaceDef *nd,bool includeClasses,bool filterClasses,ClassDef::CompoundType ct);
bool classVisibleInIndex(const ClassDef *cd);
@@ -378,10 +429,17 @@ QCString stripExtension(const char *fName);
void replaceNamespaceAliases(QCString &scope,int i);
-int isAccessibleFrom(const Definition *scope,const FileDef *fileScope,const Definition *item);
-
-int isAccessibleFromWithExpScope(const Definition *scope,const FileDef *fileScope,const Definition *item,
- const QCString &explicitScopePart);
+int isAccessibleFrom(AccessStack &accessStack,
+ const Definition *scope,
+ const FileDef *fileScope,
+ const Definition *item);
+
+int isAccessibleFromWithExpScope(VisitedNamespaces &visitedNamespaces,
+ AccessStack &accessStack,
+ const Definition *scope,
+ const FileDef *fileScope,
+ const Definition *item,
+ const QCString &explicitScopePart);
int computeQualifiedIndex(const QCString &name);
diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp
index 12cab2d..ddb22f6 100644
--- a/src/vhdldocgen.cpp
+++ b/src/vhdldocgen.cpp
@@ -234,22 +234,16 @@ void VhdlDocGen::writeOverview()
writeVhdlEntityToolTip(t,cd);
delete port;
- BaseClassList *bl=cd->baseClasses();
- if (bl)
- {
- BaseClassListIterator bcli(*bl);
- BaseClassDef *bcd;
- for ( ; (bcd=bcli.current()) ; ++bcli )
- {
- ClassDef *bClass=bcd->classDef;
- QCString dotn=cd->name()+":";
- dotn+=cd->name();
- QCString csc=bClass->name()+":";
- csc+=bClass->name();
- // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
- writeVhdlDotLink(t,dotn,csc,0);
- }
- }// if bl
+ for (const auto &bcd : cd->baseClasses())
+ {
+ ClassDef *bClass=bcd.classDef;
+ QCString dotn=cd->name()+":";
+ dotn+=cd->name();
+ QCString csc=bClass->name()+":";
+ csc+=bClass->name();
+ // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
+ writeVhdlDotLink(t,dotn,csc,0);
+ }
}// for
endDot(t);
@@ -2846,24 +2840,20 @@ bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int
return FALSE;
}
- if (cd->subClasses())
+ for (const auto &bcd :cd->subClasses())
{
- BaseClassListIterator bcli(*cd->subClasses());
- for ( ; bcli.current() && !found ; ++bcli)
+ const ClassDef *ccd=bcd.classDef;
+ if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
+ //printf("isSubClass() subclass %s\n",ccd->name().data());
+ if (ccd==scd)
{
- const ClassDef *ccd=bcli.current()->classDef;
- if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
- //printf("isSubClass() subclass %s\n",ccd->name().data());
- if (ccd==scd)
- {
- found=TRUE;
- }
- else
+ found=TRUE;
+ }
+ else
+ {
+ if (level <256)
{
- if (level <256)
- {
- found=ccd->isBaseClass(scd,followInstances,level+1);
- }
+ found=ccd->isBaseClass(scd,followInstances,level+1);
}
}
}
@@ -2872,35 +2862,33 @@ bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int
void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
{
- if (cd->baseClasses())
+ BaseClassList bcl = cd->baseClasses();
+ for (auto &bcd : bcl)
{
- BaseClassListIterator bcli(*cd->baseClasses());
- for ( ; bcli.current() ; ++bcli)
+ ClassDef *ccd = bcd.classDef;
+ if (ccd==ent)
{
- ClassDef *ccd=bcli.current()->classDef;
- if (ccd==ent)
+ QCString n = bcd.usedName;
+ int i = n.find('(');
+ if(i<0)
{
- QCString n = bcli.current()->usedName;
- int i = n.find('(');
- if(i<0)
- {
- bcli.current()->usedName.append("(2)");
- return;
- }
- static QRegExp reg("[0-9]+");
- QCString s=n.left(i);
- QCString r=n.right(n.length()-i);
- QCString t=r;
- VhdlDocGen::deleteAllChars(r,')');
- VhdlDocGen::deleteAllChars(r,'(');
- r.setNum(r.toInt()+1);
- t.replace(reg,r.data());
- s.append(t.data());
- bcli.current()->usedName=s;
- bcli.current()->templSpecifiers=t;
+ bcd.usedName.append("(2)");
+ return;
}
+ static QRegExp reg("[0-9]+");
+ QCString s=n.left(i);
+ QCString r=n.right(n.length()-i);
+ QCString t=r;
+ VhdlDocGen::deleteAllChars(r,')');
+ VhdlDocGen::deleteAllChars(r,'(');
+ r.setNum(r.toInt()+1);
+ t.replace(reg,r.data());
+ s.append(t.data());
+ bcd.usedName=s;
+ bcd.templSpecifiers=t;
}
}
+ cd->updateBaseClasses(bcl);
}
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index 5cad4ed..a842841 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -1294,73 +1294,63 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti)
t << " <compoundname>";
writeXMLString(t,cd->name());
t << "</compoundname>" << endl;
- if (cd->baseClasses())
+ for (const auto &bcd : cd->baseClasses())
{
- BaseClassListIterator bcli(*cd->baseClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ t << " <basecompoundref ";
+ if (bcd.classDef->isLinkable())
{
- t << " <basecompoundref ";
- if (bcd->classDef->isLinkable())
- {
- t << "refid=\"" << classOutputFileBase(bcd->classDef) << "\" ";
- }
- t << "prot=\"";
- switch (bcd->prot)
- {
- case Public: t << "public"; break;
- case Protected: t << "protected"; break;
- case Private: t << "private"; break;
- case Package: ASSERT(0); break;
- }
- t << "\" virt=\"";
- switch(bcd->virt)
- {
- case Normal: t << "non-virtual"; break;
- case Virtual: t << "virtual"; break;
- case Pure: t <<"pure-virtual"; break;
- }
- t << "\">";
- if (!bcd->templSpecifiers.isEmpty())
- {
- t << convertToXML(
- insertTemplateSpecifierInScope(
- bcd->classDef->name(),bcd->templSpecifiers)
- );
- }
- else
- {
- t << convertToXML(bcd->classDef->displayName());
- }
- t << "</basecompoundref>" << endl;
+ t << "refid=\"" << classOutputFileBase(bcd.classDef) << "\" ";
+ }
+ t << "prot=\"";
+ switch (bcd.prot)
+ {
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: ASSERT(0); break;
}
+ t << "\" virt=\"";
+ switch(bcd.virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t <<"pure-virtual"; break;
+ }
+ t << "\">";
+ if (!bcd.templSpecifiers.isEmpty())
+ {
+ t << convertToXML(
+ insertTemplateSpecifierInScope(
+ bcd.classDef->name(),bcd.templSpecifiers)
+ );
+ }
+ else
+ {
+ t << convertToXML(bcd.classDef->displayName());
+ }
+ t << "</basecompoundref>" << endl;
}
- if (cd->subClasses())
+ for (const auto &bcd : cd->subClasses())
{
- BaseClassListIterator bcli(*cd->subClasses());
- BaseClassDef *bcd;
- for (bcli.toFirst();(bcd=bcli.current());++bcli)
+ t << " <derivedcompoundref refid=\""
+ << classOutputFileBase(bcd.classDef)
+ << "\" prot=\"";
+ switch (bcd.prot)
{
- t << " <derivedcompoundref refid=\""
- << classOutputFileBase(bcd->classDef)
- << "\" prot=\"";
- switch (bcd->prot)
- {
- case Public: t << "public"; break;
- case Protected: t << "protected"; break;
- case Private: t << "private"; break;
- case Package: ASSERT(0); break;
- }
- t << "\" virt=\"";
- switch(bcd->virt)
- {
- case Normal: t << "non-virtual"; break;
- case Virtual: t << "virtual"; break;
- case Pure: t << "pure-virtual"; break;
- }
- t << "\">" << convertToXML(bcd->classDef->displayName())
- << "</derivedcompoundref>" << endl;
+ case Public: t << "public"; break;
+ case Protected: t << "protected"; break;
+ case Private: t << "private"; break;
+ case Package: ASSERT(0); break;
+ }
+ t << "\" virt=\"";
+ switch (bcd.virt)
+ {
+ case Normal: t << "non-virtual"; break;
+ case Virtual: t << "virtual"; break;
+ case Pure: t << "pure-virtual"; break;
}
+ t << "\">" << convertToXML(bcd.classDef->displayName())
+ << "</derivedcompoundref>" << endl;
}
IncludeInfo *ii=cd->includeInfo();