Skip to content

Commit 4a8f03a

Browse files
committed
issue doxygen#11313 Template class specializations are ignored, which leads to invalid links
1 parent d9ac096 commit 4a8f03a

18 files changed

+201
-30
lines changed

src/classdef.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3045,7 +3045,7 @@ void ClassDefImpl::writeDocumentationForInnerClasses(OutputList &ol) const
30453045
for (const auto &innerCd : m_innerClasses)
30463046
{
30473047
if (
3048-
innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
3048+
innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
30493049
protectionLevelVisible(innerCd->protection()) &&
30503050
!innerCd->isEmbeddedInOuterScope()
30513051
)
@@ -3536,7 +3536,7 @@ bool ClassDefImpl::isLinkableInProject() const
35363536
bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES);
35373537
bool extractStatic = Config_getBool(EXTRACT_STATIC);
35383538
bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES);
3539-
if (m_templateMaster)
3539+
if (m_templateMaster && m_implicitTemplateInstance)
35403540
{
35413541
return m_templateMaster->isLinkableInProject();
35423542
}
@@ -3565,7 +3565,7 @@ bool ClassDefImpl::isLinkableInProject() const
35653565

35663566
bool ClassDefImpl::isLinkable() const
35673567
{
3568-
if (m_templateMaster)
3568+
if (m_templateMaster && m_implicitTemplateInstance)
35693569
{
35703570
return m_templateMaster->isLinkable();
35713571
}
@@ -3595,6 +3595,8 @@ bool ClassDefImpl::isVisibleInHierarchy() const
35953595
(m_templateMaster && m_templateMaster->hasDocumentation()) ||
35963596
isReference()
35973597
) &&
3598+
// if this is an implicit template instance then it most be part of the inheritance hierarchy
3599+
(!m_implicitTemplateInstance || !m_inherits.empty() || !m_inheritedBy.empty()) &&
35983600
// is not part of an unnamed namespace or shown anyway
35993601
(!m_isStatic || extractStatic);
36003602
}
@@ -4211,8 +4213,8 @@ QCString ClassDefImpl::getOutputFileBase() const
42114213
}
42124214
}
42134215
}
4214-
AUTO_TRACE("name='{}' m_templateMaster={}",name(),(void*)m_templateMaster);
4215-
if (m_templateMaster)
4216+
AUTO_TRACE("name='{}' m_templateMaster={} m_implicitTemplateInstance={}",name(),(void*)m_templateMaster,m_implicitTemplateInstance);
4217+
if (m_templateMaster && m_implicitTemplateInstance)
42164218
{
42174219
// point to the template of which this class is an instance
42184220
return m_templateMaster->getOutputFileBase();
@@ -4227,7 +4229,7 @@ QCString ClassDefImpl::getInstanceOutputFileBase() const
42274229

42284230
QCString ClassDefImpl::getSourceFileBase() const
42294231
{
4230-
if (m_templateMaster)
4232+
if (m_templateMaster && m_implicitTemplateInstance)
42314233
{
42324234
return m_templateMaster->getSourceFileBase();
42334235
}
@@ -4399,7 +4401,7 @@ void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const Argumen
43994401

44004402
QCString ClassDefImpl::getReference() const
44014403
{
4402-
if (m_templateMaster)
4404+
if (m_templateMaster && m_implicitTemplateInstance)
44034405
{
44044406
return m_templateMaster->getReference();
44054407
}
@@ -4411,7 +4413,7 @@ QCString ClassDefImpl::getReference() const
44114413

44124414
bool ClassDefImpl::isReference() const
44134415
{
4414-
if (m_templateMaster)
4416+
if (m_templateMaster && m_implicitTemplateInstance)
44154417
{
44164418
return m_templateMaster->isReference();
44174419
}
@@ -5156,7 +5158,7 @@ QCString ClassDefImpl::anchor() const
51565158
QCString anc;
51575159
if (isEmbeddedInOuterScope() && !Doxygen::generatingXmlOutput)
51585160
{
5159-
if (m_templateMaster)
5161+
if (m_templateMaster && m_implicitTemplateInstance)
51605162
{
51615163
// point to the template of which this class is an instance
51625164
anc = m_templateMaster->getOutputFileBase();

src/defgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ static void generateDEFForClass(const ClassDef *cd,TextStream &t)
332332

333333
if (cd->isReference()) return; // skip external references.
334334
if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
335-
if (cd->templateMaster()!=nullptr) return; // skip generated template instances.
335+
if (cd->isImplicitTemplateInstance()) return; // skip generated template instances.
336336

337337
t << cd->compoundTypeString() << " = {\n";
338338
t << " cp-id = '" << cd->getOutputFileBase() << "';\n";

src/docbookgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ DB_GEN_C2("IndexSection " << is)
652652
for (const auto &cd : *Doxygen::classLinkedMap)
653653
{
654654
if (cd->isLinkableInProject() &&
655-
cd->templateMaster()==nullptr &&
655+
!cd->isImplicitTemplateInstance() &&
656656
!cd->isEmbeddedInOuterScope() &&
657657
!cd->isAlias()
658658
)

src/dotnode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ void DotNode::writeBox(TextStream &t,
537537
else // (!m_classDef->hasDocumentation() && !hasNonReachableChildren)
538538
{
539539
labCol = "grey75";
540-
if (m_classDef->templateMaster() && m_classDef->templateMaster()->hasDocumentation())
540+
if (m_classDef->templateMaster() && m_classDef->isImplicitTemplateInstance() && m_classDef->templateMaster()->hasDocumentation())
541541
{
542542
labCol = "gray40";
543543
}

src/doxygen.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8984,6 +8984,7 @@ static void countMembers()
89848984

89858985
static void generateDocsForClassList(const std::vector<ClassDefMutable*> &classList)
89868986
{
8987+
AUTO_TRACE();
89878988
std::size_t numThreads = static_cast<std::size_t>(Config_getInt(NUM_PROC_THREADS));
89888989
if (numThreads>1) // multi threaded processing
89898990
{
@@ -9000,7 +9001,7 @@ static void generateDocsForClassList(const std::vector<ClassDefMutable*> &classL
90009001
{
90019002
//printf("cd=%s getOuterScope=%p global=%p\n",qPrint(cd->name()),cd->getOuterScope(),Doxygen::globalScope);
90029003
if (cd->getOuterScope()==nullptr || // <-- should not happen, but can if we read an old tag file
9003-
cd->getOuterScope()==Doxygen::globalScope // only look at global classes
9004+
cd->getOuterScope()==Doxygen::globalScope // only look at global classes
90049005
)
90059006
{
90069007
auto ctx = std::make_shared<DocContext>(cd,*g_outputList);
@@ -9011,7 +9012,7 @@ static void generateDocsForClassList(const std::vector<ClassDefMutable*> &classL
90119012
// skip external references, anonymous compounds and
90129013
// template instances
90139014
if (!ctx->cd->isHidden() && !ctx->cd->isEmbeddedInOuterScope() &&
9014-
ctx->cd->isLinkableInProject() && ctx->cd->templateMaster()==nullptr)
9015+
ctx->cd->isLinkableInProject() && !ctx->cd->isImplicitTemplateInstance())
90159016
{
90169017
ctx->cd->writeDocumentation(ctx->ol);
90179018
ctx->cd->writeMemberList(ctx->ol);
@@ -9042,7 +9043,7 @@ static void generateDocsForClassList(const std::vector<ClassDefMutable*> &classL
90429043
// skip external references, anonymous compounds and
90439044
// template instances
90449045
if ( !cd->isHidden() && !cd->isEmbeddedInOuterScope() &&
9045-
cd->isLinkableInProject() && cd->templateMaster()==nullptr)
9046+
cd->isLinkableInProject() && !cd->isImplicitTemplateInstance())
90469047
{
90479048
msg("Generating docs for compound %s...\n",qPrint(cd->displayName()));
90489049

@@ -9062,7 +9063,13 @@ static void addClassAndNestedClasses(std::vector<ClassDefMutable*> &list,ClassDe
90629063
for (const auto &innerCdi : cd->getClasses())
90639064
{
90649065
ClassDefMutable *innerCd = toClassDefMutable(innerCdi);
9065-
if (innerCd && innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
9066+
if (innerCd)
9067+
{
9068+
AUTO_TRACE("innerCd={} isLinkable={} isImplicitTemplateInstance={} protectLevelVisible={} embeddedInOuterScope={}",
9069+
innerCd->name(),innerCd->isLinkableInProject(),innerCd->isImplicitTemplateInstance(),protectionLevelVisible(innerCd->protection()),
9070+
innerCd->isEmbeddedInOuterScope());
9071+
}
9072+
if (innerCd && innerCd->isLinkableInProject() && !innerCd->isImplicitTemplateInstance() &&
90669073
protectionLevelVisible(innerCd->protection()) &&
90679074
!innerCd->isEmbeddedInOuterScope()
90689075
)
@@ -10017,7 +10024,7 @@ static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)
1001710024
auto processFile = [ctx]()
1001810025
{
1001910026
if ( ( ctx->cdm->isLinkableInProject() &&
10020-
ctx->cdm->templateMaster()==nullptr
10027+
!ctx->cdm->isImplicitTemplateInstance()
1002110028
) // skip external references, anonymous compounds and
1002210029
// template instances and nested classes
1002310030
&& !ctx->cdm->isHidden() && !ctx->cdm->isEmbeddedInOuterScope()
@@ -10048,7 +10055,7 @@ static void generateNamespaceClassDocs(const ClassLinkedRefMap &classList)
1004810055
if (cdm)
1004910056
{
1005010057
if ( ( cd->isLinkableInProject() &&
10051-
cd->templateMaster()==nullptr
10058+
!cd->isImplicitTemplateInstance()
1005210059
) // skip external references, anonymous compounds and
1005310060
// template instances and nested classes
1005410061
&& !cd->isHidden() && !cd->isEmbeddedInOuterScope()

src/latexgen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ void LatexGenerator::startIndexSection(IndexSection is)
10201020
for (const auto &cd : *Doxygen::classLinkedMap)
10211021
{
10221022
if (cd->isLinkableInProject() &&
1023-
cd->templateMaster()==nullptr &&
1023+
!cd->isImplicitTemplateInstance() &&
10241024
!cd->isEmbeddedInOuterScope() &&
10251025
!cd->isAlias()
10261026
)
@@ -1192,7 +1192,7 @@ void LatexGenerator::endIndexSection(IndexSection is)
11921192
for (const auto &cd : *Doxygen::classLinkedMap)
11931193
{
11941194
if (cd->isLinkableInProject() &&
1195-
cd->templateMaster()==nullptr &&
1195+
!cd->isImplicitTemplateInstance() &&
11961196
!cd->isEmbeddedInOuterScope() &&
11971197
!cd->isAlias()
11981198
)

src/perlmodgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1749,7 +1749,7 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd)
17491749

17501750
if (cd->isReference()) return; // skip external references.
17511751
if (cd->isAnonymous()) return; // skip anonymous compounds.
1752-
if (cd->templateMaster()!=nullptr) return; // skip generated template instances.
1752+
if (cd->isImplicitTemplateInstance()) return; // skip generated template instances.
17531753

17541754
m_output.openHash()
17551755
.addFieldQuotedString("name", cd->name());

src/rtfgen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ void RTFGenerator::startIndexSection(IndexSection is)
870870
for (const auto &cd : *Doxygen::classLinkedMap)
871871
{
872872
if (cd->isLinkableInProject() &&
873-
cd->templateMaster()==nullptr &&
873+
!cd->isImplicitTemplateInstance() &&
874874
!cd->isEmbeddedInOuterScope() &&
875875
!cd->isAlias()
876876
)

src/searchindex_js.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ static void addMemberToSearchIndex(const MemberDef *md)
196196
const GroupDef *gd=nullptr;
197197
if (isLinkable &&
198198
(
199-
((cd=md->getClassDef()) && cd->isLinkable() && cd->templateMaster()==nullptr) ||
199+
((cd=md->getClassDef()) && cd->isLinkable() && !cd->isImplicitTemplateInstance()) ||
200200
((gd=md->getGroupDef()) && gd->isLinkable())
201201
)
202202
)

src/sqlite3gen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1936,7 +1936,7 @@ static void generateSqlite3ForClass(const ClassDef *cd)
19361936
if (cd->isReference()) return; // skip external references.
19371937
if (cd->isHidden()) return; // skip hidden classes.
19381938
if (cd->isAnonymous()) return; // skip anonymous compounds.
1939-
if (cd->templateMaster()!=nullptr) return; // skip generated template instances.
1939+
if (cd->isImplicitTemplateInstance()) return; // skip generated template instances.
19401940

19411941
struct Refid refid = insertRefid(cd->getOutputFileBase());
19421942

0 commit comments

Comments
 (0)