summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-11-21 18:59:38 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-11-21 18:59:38 (GMT)
commit61f8521f768165e02a5f28df3fb442e3b91d170b (patch)
tree24848bb3261aefa110ed01e575071fd22a56bf48
parentb2d009555ebce4a6802ac0255c056e880bdb45bd (diff)
downloadDoxygen-61f8521f768165e02a5f28df3fb442e3b91d170b.zip
Doxygen-61f8521f768165e02a5f28df3fb442e3b91d170b.tar.gz
Doxygen-61f8521f768165e02a5f28df3fb442e3b91d170b.tar.bz2
issue #8192: Excluded inline namespace broken after a5792da8
- Further fixes to make classes inside inline namespaces appear in the parent scope again. - Also added a test case to check for regression
-rw-r--r--src/classlist.cpp16
-rw-r--r--src/doxygen.cpp126
-rw-r--r--testing/057/namespacelibrary.xml30
-rw-r--r--testing/057/namespacelibrary_1_1v1.xml28
-rw-r--r--testing/057/namespacelibrary_1_1v2.xml13
-rw-r--r--testing/057_inlinenamespace.cpp19
6 files changed, 175 insertions, 57 deletions
diff --git a/src/classlist.cpp b/src/classlist.cpp
index eae216a..d0f37ce 100644
--- a/src/classlist.cpp
+++ b/src/classlist.cpp
@@ -102,17 +102,15 @@ void ClassSDict::writeDeclaration(OutputList &ol,const ClassDef::CompoundType *f
bool found=FALSE;
for (sdi.toFirst();(cd=sdi.current());++sdi)
{
- ClassDefMutable *cdm = toClassDefMutable(cd);
//printf(" ClassSDict::writeDeclaration for %s\n",cd->name().data());
- if (cdm &&
- !cd->isAnonymous() &&
+ if (!cd->isAnonymous() &&
!cd->isExtension() &&
(cd->protection()!=Private || extractPrivate) &&
(filter==0 || *filter==cd->compoundType())
)
{
//printf("writeDeclarationLink()\n");
- cdm->writeDeclarationLink(ol,found,header,localNames);
+ cd->writeDeclarationLink(ol,found,header,localNames);
}
}
if (found) ol.endMemberList();
@@ -139,9 +137,7 @@ void ClassSDict::writeDocumentation(OutputList &ol,const Definition * container)
// cd->name().data(),cd->getOuterScope(),cd->isLinkableInProject(),cd->isEmbeddedInOuterScope(),
// container,cd->partOfGroups() ? cd->partOfGroups()->count() : 0);
- ClassDefMutable *cdm = toClassDefMutable(cd);
- if (cdm &&
- !cd->isAnonymous() &&
+ if (!cd->isAnonymous() &&
cd->isLinkableInProject() &&
cd->isEmbeddedInOuterScope() &&
!cd->isAlias() &&
@@ -158,7 +154,11 @@ void ClassSDict::writeDocumentation(OutputList &ol,const Definition * container)
ol.endGroupHeader();
found=TRUE;
}
- cdm->writeInlineDocumentation(ol);
+ ClassDefMutable *cdm = toClassDefMutable(cd);
+ if (cdm)
+ {
+ cdm->writeInlineDocumentation(ol);
+ }
}
}
}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 0fb602d..13b275f 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -307,7 +307,7 @@ static bool findClassRelation(
//----------------------------------------------------------------------------
-static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n,
+static Definition *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n,
FileDef *fileScope,const TagInfo *tagInfo);
static void addPageToContext(PageDef *pd,Entry *root)
@@ -321,10 +321,10 @@ static void addPageToContext(PageDef *pd,Entry *root)
}
scope = stripAnonymousNamespaceScope(scope);
scope+="::"+pd->name();
- DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo());
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo());
if (d)
{
- pd->setPageScope(toDefinition(d));
+ pd->setPageScope(d);
}
}
}
@@ -453,7 +453,7 @@ static void findGroupScope(const Entry *root)
}
scope = stripAnonymousNamespaceScope(scope);
scope+="::"+gd->name();
- Definition *d = toDefinition(findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo()));
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,scope,0,root->tagInfo());
if (d)
{
gd->setGroupScope(d);
@@ -716,13 +716,13 @@ static Definition *findScope(Entry *root,int level=0)
* full qualified name \a name. Creates an artificial scope if the scope is
* not found and set the parent/child scope relation if the scope is found.
*/
-static DefinitionMutable *buildScopeFromQualifiedName(const QCString name,
+static Definition *buildScopeFromQualifiedName(const QCString name,
int level,SrcLangExt lang,const TagInfo *tagInfo)
{
//printf("buildScopeFromQualifiedName(%s) level=%d\n",name.data(),level);
int i=0;
int p=0,l;
- DefinitionMutable *prevScope=Doxygen::globalScope;
+ Definition *prevScope=Doxygen::globalScope;
QCString fullScope;
while (i<level)
{
@@ -732,27 +732,27 @@ static DefinitionMutable *buildScopeFromQualifiedName(const QCString name,
if (nsName.isEmpty()) return prevScope;
if (!fullScope.isEmpty()) fullScope+="::";
fullScope+=nsName;
- NamespaceDefMutable *nd=toNamespaceDefMutable(Doxygen::namespaceSDict->find(fullScope));
- DefinitionMutable *innerScope = nd;
- ClassDefMutable *cd=0;
- if (nd==0) cd = getClassMutable(fullScope);
+ NamespaceDef *nd=Doxygen::namespaceSDict->find(fullScope);
+ DefinitionMutable *innerScope = toDefinitionMutable(nd);
+ ClassDef *cd=0;
+ if (nd==0) cd = getClass(fullScope);
if (nd==0 && cd) // scope is a class
{
- innerScope = cd;
+ innerScope = toDefinitionMutable(cd);
}
else if (nd==0 && cd==0 && fullScope.find('<')==-1) // scope is not known and could be a namespace!
{
// introduce bogus namespace
//printf("++ adding dummy namespace %s to %s tagInfo=%p\n",nsName.data(),prevScope->name().data(),tagInfo);
- nd=createNamespaceDef(
+ NamespaceDefMutable *newNd=createNamespaceDef(
"[generated]",1,1,fullScope,
tagInfo?tagInfo->tagName:QCString(),
tagInfo?tagInfo->fileName:QCString());
- nd->setLanguage(lang);
+ newNd->setLanguage(lang);
// add namespace to the list
- Doxygen::namespaceSDict->inSort(fullScope,nd);
- innerScope = nd;
+ Doxygen::namespaceSDict->inSort(fullScope,newNd);
+ innerScope = newNd;
}
else // scope is a namespace
{
@@ -760,8 +760,12 @@ static DefinitionMutable *buildScopeFromQualifiedName(const QCString name,
if (innerScope)
{
// make the parent/child scope relation
- prevScope->addInnerCompound(toDefinition(innerScope));
- innerScope->setOuterScope(toDefinition(prevScope));
+ DefinitionMutable *prevScopeMutable = toDefinitionMutable(prevScope);
+ if (prevScopeMutable)
+ {
+ prevScopeMutable->addInnerCompound(toDefinition(innerScope));
+ }
+ innerScope->setOuterScope(prevScope);
}
else // current scope is a class, so return only the namespace part...
{
@@ -769,17 +773,17 @@ static DefinitionMutable *buildScopeFromQualifiedName(const QCString name,
}
// proceed to the next scope fragment
p=idx+l+2;
- prevScope=innerScope;
+ prevScope=toDefinition(innerScope);
i++;
}
return prevScope;
}
-static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n,
+static Definition *findScopeFromQualifiedName(NamespaceDefMutable *startScope,const QCString &n,
FileDef *fileScope,const TagInfo *tagInfo)
{
//printf("<findScopeFromQualifiedName(%s,%s)\n",startScope ? startScope->name().data() : 0, n.data());
- DefinitionMutable *resultScope=startScope;
+ Definition *resultScope=toDefinition(startScope);
if (resultScope==0) resultScope=Doxygen::globalScope;
QCString scope=stripTemplateSpecifiersFromScope(n,FALSE);
int l1=0,i1;
@@ -793,9 +797,9 @@ static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startS
while ((i2=getScopeFragment(scope,p,&l2))!=-1)
{
QCString nestedNameSpecifier = scope.mid(i1,l1);
- Definition *orgScope = toDefinition(resultScope);
+ Definition *orgScope = resultScope;
//printf(" nestedNameSpecifier=%s\n",nestedNameSpecifier.data());
- resultScope = toDefinitionMutable(toDefinition(resultScope)->findInnerCompound(nestedNameSpecifier));
+ resultScope = const_cast<Definition*>(resultScope->findInnerCompound(nestedNameSpecifier));
//printf(" resultScope=%p\n",resultScope);
if (resultScope==0)
{
@@ -813,7 +817,7 @@ static DefinitionMutable *findScopeFromQualifiedName(NamespaceDefMutable *startS
// N::A::I while looking for A, so we should compare
// resultScope->name() against scope.left(i2+l2)
//printf(" -> result=%s scope=%s\n",resultScope->name().data(),scope.data());
- if (rightScopeMatch(toDefinition(resultScope)->name(),scope.left(i2+l2)))
+ if (rightScopeMatch(resultScope->name(),scope.left(i2+l2)))
{
break;
}
@@ -1166,29 +1170,37 @@ static void resolveClassNestingRelations()
QCString name = stripAnonymousNamespaceScope(icd->name());
//printf("processing=%s, iteration=%d\n",cd->name().data(),iteration);
// also add class to the correct structural context
- DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope,
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,
name,icd->getFileDef(),0);
if (d)
{
//printf("****** adding %s to scope %s in iteration %d\n",cd->name().data(),d->name().data(),iteration);
- d->addInnerCompound(cd);
- cd->setOuterScope(toDefinition(d));
+ DefinitionMutable *dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ dm->addInnerCompound(cd);
+ }
+ cd->setOuterScope(d);
// for inline namespace add an alias of the class to the outer scope
- while (toDefinition(d)->definitionType()==Definition::TypeNamespace)
+ while (d->definitionType()==Definition::TypeNamespace)
{
NamespaceDef *nd = toNamespaceDef(d);
- //printf("d->isInline()=%d\n",nd->isInline());
+ //printf("nd->isInline()=%d\n",nd->isInline());
if (nd && nd->isInline())
{
- d = toDefinitionMutable(toDefinition(d)->getOuterScope());
+ d = d->getOuterScope();
if (d)
{
- ClassDef *aliasCd = createClassDefAlias(toDefinition(d),cd);
- d->addInnerCompound(aliasCd);
- QCString aliasFullName = toDefinition(d)->qualifiedName()+"::"+aliasCd->localName();
- Doxygen::classSDict->append(aliasFullName,aliasCd);
- //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
+ dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ ClassDef *aliasCd = createClassDefAlias(d,cd);
+ dm->addInnerCompound(aliasCd);
+ QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
+ Doxygen::classSDict->append(aliasFullName,aliasCd);
+ //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
+ }
}
}
else
@@ -1213,20 +1225,24 @@ static void resolveClassNestingRelations()
for (cli.toFirst();(icd=cli.current());++cli)
{
ClassDefMutable *cd = toClassDefMutable(icd);
- if (cd && visitedClasses.find(icd)!=visitedClasses.end())
+ if (cd && visitedClasses.find(icd)==visitedClasses.end())
{
QCString name = stripAnonymousNamespaceScope(cd->name());
//printf("processing unresolved=%s, iteration=%d\n",cd->name().data(),iteration);
/// create the scope artificially
// anyway, so we can at least relate scopes properly.
- DefinitionMutable *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0);
+ Definition *d = buildScopeFromQualifiedName(name,name.contains("::"),cd->getLanguage(),0);
if (d && d!=cd && !cd->getDefFileName().isEmpty())
// avoid recursion in case of redundant scopes, i.e: namespace N { class N::C {}; }
// for this case doxygen assumes the existence of a namespace N::N in which C is to be found!
// also avoid warning for stuff imported via a tagfile.
{
- d->addInnerCompound(cd);
- cd->setOuterScope(toDefinition(d));
+ DefinitionMutable *dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ dm->addInnerCompound(cd);
+ }
+ cd->setOuterScope(d);
warn(cd->getDefFileName(),cd->getDefLine(),
"Internal inconsistency: scope for class %s not "
"found!",name.data()
@@ -1553,33 +1569,45 @@ static void buildNamespaceList(const Entry *root)
Doxygen::namespaceSDict->inSort(fullName,nd);
// also add namespace to the correct structural context
- DefinitionMutable *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo);
+ Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo);
//printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"<none>");
if (d==0) // we didn't find anything, create the scope artificially
// anyway, so we can at least relate scopes properly.
{
d = buildScopeFromQualifiedName(fullName,fullName.contains("::"),nd->getLanguage(),tagInfo);
- d->addInnerCompound(nd);
- nd->setOuterScope(toDefinition(d));
+ DefinitionMutable *dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ dm->addInnerCompound(nd);
+ }
+ nd->setOuterScope(d);
// TODO: Due to the order in which the tag file is written
// a nested class can be found before its parent!
}
else
{
- d->addInnerCompound(nd);
- nd->setOuterScope(toDefinition(d));
+ DefinitionMutable *dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ dm->addInnerCompound(nd);
+ }
+ nd->setOuterScope(d);
// in case of d is an inline namespace, alias insert nd in the part scope of d.
- while (toDefinition(d)->definitionType()==Definition::TypeNamespace)
+ while (d->definitionType()==Definition::TypeNamespace)
{
NamespaceDef *pnd = toNamespaceDef(d);
if (pnd && pnd->isInline())
{
- d = toDefinitionMutable(toDefinition(d)->getOuterScope());
+ d = d->getOuterScope();
if (d)
{
- NamespaceDef *aliasNd = createNamespaceDefAlias(toDefinition(d),nd);
- //printf("adding %s to %s\n",qPrint(aliasNd->name()),qPrint(d->name()));
- d->addInnerCompound(aliasNd);
+ dm = toDefinitionMutable(d);
+ if (dm)
+ {
+ NamespaceDef *aliasNd = createNamespaceDefAlias(d,nd);
+ //printf("adding %s to %s\n",qPrint(aliasNd->name()),qPrint(d->name()));
+ dm->addInnerCompound(aliasNd);
+ }
}
}
else
@@ -4471,7 +4499,7 @@ static bool findClassRelation(
si = baseClassName.findRev("::");
if (si!=-1) // class is nested
{
- Definition *sd = toDefinition(findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo()));
+ Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo());
if (sd==0 || sd==Doxygen::globalScope) // outer scope not found
{
baseClass->setArtificial(TRUE); // see bug678139
diff --git a/testing/057/namespacelibrary.xml b/testing/057/namespacelibrary.xml
new file mode 100644
index 0000000..0357e29
--- /dev/null
+++ b/testing/057/namespacelibrary.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
+ <compounddef id="namespacelibrary" kind="namespace" language="C++">
+ <compoundname>library</compoundname>
+ <innerclass refid="classlibrary_1_1v2_1_1foo" prot="public">library::v2::foo</innerclass>
+ <innernamespace refid="namespacelibrary_1_1v1">library::v1</innernamespace>
+ <innernamespace refid="namespacelibrary_1_1v2" inline="yes">library::v2</innernamespace>
+ <innernamespace refid="namespacelibrary_1_1v2_1_1_n_s">library::v2::NS</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="057__inlinenamespace_8cpp_1aba9375172f5b36e1f4fda9b1dec39d90" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void library::v2::func</definition>
+ <argsstring>()</argsstring>
+ <name>func</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_inlinenamespace.cpp" line="16" column="14" declfile="057_inlinenamespace.cpp" declline="16" declcolumn="14"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_inlinenamespace.cpp" line="5" column="1"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespacelibrary_1_1v1.xml b/testing/057/namespacelibrary_1_1v1.xml
new file mode 100644
index 0000000..62eaabb
--- /dev/null
+++ b/testing/057/namespacelibrary_1_1v1.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
+ <compounddef id="namespacelibrary_1_1v1" kind="namespace" language="C++">
+ <compoundname>library::v1</compoundname>
+ <innerclass refid="classlibrary_1_1v1_1_1foo" prot="public">library::v1::foo</innerclass>
+ <innernamespace refid="namespacelibrary_1_1v1_1_1_n_s">library::v1::NS</innernamespace>
+ <sectiondef kind="func">
+ <memberdef kind="function" id="057__inlinenamespace_8cpp_1a2257981298fec15f79c54c28880ac15c" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
+ <type>void</type>
+ <definition>void library::v1::func</definition>
+ <argsstring>()</argsstring>
+ <name>func</name>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <inbodydescription>
+ </inbodydescription>
+ <location file="057_inlinenamespace.cpp" line="10" column="14" declfile="057_inlinenamespace.cpp" declline="10" declcolumn="14"/>
+ </memberdef>
+ </sectiondef>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_inlinenamespace.cpp" line="7" column="5"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057/namespacelibrary_1_1v2.xml b/testing/057/namespacelibrary_1_1v2.xml
new file mode 100644
index 0000000..b4ff956
--- /dev/null
+++ b/testing/057/namespacelibrary_1_1v2.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
+ <compounddef id="namespacelibrary_1_1v2" kind="namespace" inline="yes" language="C++">
+ <compoundname>library::v2</compoundname>
+ <innerclass refid="classlibrary_1_1v2_1_1foo" prot="public">library::v2::foo</innerclass>
+ <innernamespace refid="namespacelibrary_1_1v2_1_1_n_s">library::v2::NS</innernamespace>
+ <briefdescription>
+ </briefdescription>
+ <detaileddescription>
+ </detaileddescription>
+ <location file="057_inlinenamespace.cpp" line="13" column="12"/>
+ </compounddef>
+</doxygen>
diff --git a/testing/057_inlinenamespace.cpp b/testing/057_inlinenamespace.cpp
new file mode 100644
index 0000000..e3ac869
--- /dev/null
+++ b/testing/057_inlinenamespace.cpp
@@ -0,0 +1,19 @@
+// objective: test inline namespaces
+// check: namespacelibrary.xml
+// check: namespacelibrary_1_1v1.xml
+// check: namespacelibrary_1_1v2.xml
+namespace library
+{
+ namespace v1
+ {
+ class foo { public: void member(); };
+ void func();
+ namespace NS {}
+ }
+ inline namespace v2
+ {
+ class foo { public: void member(); };
+ void func();
+ namespace NS {}
+ }
+}