Skip to content

Commit 8386ff0

Browse files
committed
issue #11111 Overloaded functions are mixed when their arguments have template with object in other namespace
1 parent 1e24f2c commit 8386ff0

File tree

9 files changed

+381
-31
lines changed

9 files changed

+381
-31
lines changed

src/classdef.cpp

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
303303
void setTemplateMaster(const ClassDef *tm) override;
304304
void setImplicitTemplateInstance(bool b) override;
305305
void setTypeConstraints(const ArgumentList &al) override;
306+
void addMemberToTemplateInstance(const MemberDef *md, const ArgumentList &templateArguments, const QCString &templSpec) override;
306307
void addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const QCString &templSpec) override;
307308
void makeTemplateArgument(bool b=TRUE) override;
308309
void setCategoryOf(ClassDef *cd) override;
@@ -1308,6 +1309,20 @@ void ClassDefImpl::internalInsertMember(MemberDef *md,
13081309
MemberNameInfo *mni = m_allMemberNameInfoLinkedMap.add(md->name());
13091310
mni->push_back(std::make_unique<MemberInfo>(md,prot,md->virtualness(),false,false));
13101311
}
1312+
1313+
// if we already created template instances before inserting this member (i.e. due to a typedef or using statement)
1314+
// then we also need to insert the member in the template instance.
1315+
for (const auto &ti : getTemplateInstances())
1316+
{
1317+
//printf("member %s of class %s with template instance %s\n",qPrint(md->name()),qPrint(name()),
1318+
// qPrint(ti.templSpec));
1319+
ClassDefMutable *cdm = toClassDefMutable(ti.classDef);
1320+
if (cdm)
1321+
{
1322+
cdm->addMemberToTemplateInstance(md,templateArguments(),ti.templSpec);
1323+
}
1324+
}
1325+
13111326
}
13121327

13131328
void ClassDefImpl::insertMember(MemberDef *md)
@@ -4285,6 +4300,8 @@ ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName,
42854300
if (templateClass)
42864301
{
42874302
templateClass->setTemplateMaster(this);
4303+
ArgumentList tal = *stringToArgumentList(getLanguage(),templSpec);
4304+
templateClass->setTemplateArguments(tal);
42884305
templateClass->setOuterScope(getOuterScope());
42894306
templateClass->setHidden(isHidden());
42904307
templateClass->setArtificial(isArtificial());
@@ -4330,34 +4347,40 @@ const TemplateNameMap &ClassDefImpl::getTemplateBaseClassNames() const
43304347
return m_templBaseClassNames;
43314348
}
43324349

4350+
void ClassDefImpl::addMemberToTemplateInstance(const MemberDef *md,
4351+
const ArgumentList &templateArguments,
4352+
const QCString &templSpec)
4353+
{
4354+
auto actualArguments_p = stringToArgumentList(getLanguage(),templSpec);
4355+
auto imd = md->createTemplateInstanceMember(templateArguments,actualArguments_p);
4356+
//printf("%s->setMemberClass(%p)\n",qPrint(imd->name()),this);
4357+
auto mmd = toMemberDefMutable(imd.get());
4358+
mmd->setMemberClass(this);
4359+
mmd->setTemplateMaster(md);
4360+
mmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
4361+
mmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
4362+
mmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
4363+
mmd->setMemberSpecifiers(md->getMemberSpecifiers());
4364+
mmd->setMemberGroupId(md->getMemberGroupId());
4365+
mmd->setArtificial(true);
4366+
insertMember(imd.get());
4367+
//printf("Adding member=%s %s%s to class %s templSpec %s\n",
4368+
// imd->typeString(),qPrint(imd->name()),imd->argsString(),
4369+
// qPrint(imd->getClassDef()->name()),templSpec);
4370+
// insert imd in the list of all members
4371+
//printf("Adding member=%s class=%s\n",qPrint(imd->name()),qPrint(name()));
4372+
MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name());
4373+
mn->push_back(std::move(imd));
4374+
}
4375+
43334376
void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const QCString &templSpec)
43344377
{
43354378
//printf("%s::addMembersToTemplateInstance(%s,%s)\n",qPrint(name()),qPrint(cd->name()),templSpec);
43364379
for (const auto &mni : cd->memberNameInfoLinkedMap())
43374380
{
43384381
for (const auto &mi : *mni)
43394382
{
4340-
auto actualArguments_p = stringToArgumentList(getLanguage(),templSpec);
4341-
MemberDef *md = mi->memberDef();
4342-
auto imd = md->createTemplateInstanceMember(templateArguments,actualArguments_p);
4343-
//printf("%s->setMemberClass(%p)\n",qPrint(imd->name()),this);
4344-
auto mmd = toMemberDefMutable(imd.get());
4345-
mmd->setMemberClass(this);
4346-
mmd->setTemplateMaster(md);
4347-
mmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
4348-
mmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
4349-
mmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
4350-
mmd->setMemberSpecifiers(md->getMemberSpecifiers());
4351-
mmd->setMemberGroupId(md->getMemberGroupId());
4352-
mmd->setArtificial(true);
4353-
insertMember(imd.get());
4354-
//printf("Adding member=%s %s%s to class %s templSpec %s\n",
4355-
// imd->typeString(),qPrint(imd->name()),imd->argsString(),
4356-
// qPrint(imd->getClassDef()->name()),templSpec);
4357-
// insert imd in the list of all members
4358-
//printf("Adding member=%s class=%s\n",qPrint(imd->name()),qPrint(name()));
4359-
MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name());
4360-
mn->push_back(std::move(imd));
4383+
addMemberToTemplateInstance(mi->memberDef(),templateArguments,templSpec);
43614384
}
43624385
}
43634386
// also instantatie members for nested classes

src/classdef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ class ClassDefMutable : public DefinitionMutable, public ClassDef
422422
virtual void insertExplicitTemplateInstance(ClassDef *instance,const QCString &spec) = 0;
423423
virtual void insertMember(MemberDef *) = 0;
424424
virtual void insertUsedFile(const FileDef *) = 0;
425+
virtual void addMemberToTemplateInstance(const MemberDef *md, const ArgumentList &templateArguments, const QCString &templSpec) = 0;
425426
virtual void addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const QCString &templSpec) = 0;
426427
virtual bool addExample(const QCString &anchor,const QCString &name, const QCString &file) = 0;
427428
virtual void addUsedClass(ClassDef *cd,const QCString &accessName,Protection prot) = 0;

src/doxygen.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4747,8 +4747,6 @@ static void findTemplateInstanceRelation(const Entry *root,
47474747

47484748
static void resolveTemplateInstanceInType(const Entry *root,const Definition *scope,const MemberDef *md)
47494749
{
4750-
return; // disabled due to regression, need to find a better solutions
4751-
47524750
// For a statement like 'using X = T<A>', add a template instance 'T<A>' as a symbol, so it can
47534751
// be used to match arguments (see issue #11111)
47544752
AUTO_TRACE();
@@ -5906,11 +5904,14 @@ static bool isSpecialization(
59065904
static bool scopeIsTemplate(const Definition *d)
59075905
{
59085906
bool result=FALSE;
5907+
//printf("> scopeIsTemplate(%s)\n",qPrint(d?d->name():"null"));
59095908
if (d && d->definitionType()==Definition::TypeClass)
59105909
{
5911-
result = !(toClassDef(d))->templateArguments().empty() ||
5910+
auto cd = toClassDef(d);
5911+
result = cd->templateArguments().hasParameters() || cd->templateMaster()!=nullptr ||
59125912
scopeIsTemplate(d->getOuterScope());
59135913
}
5914+
//printf("< scopeIsTemplate=%d\n",result);
59145915
return result;
59155916
}
59165917

@@ -6246,6 +6247,7 @@ static void addMemberFunction(const Entry *root,
62466247
}
62476248
else if (defTemplArgs.size()>declTemplArgs.size())
62486249
{
6250+
AUTO_TRACE_ADD("Different number of template arguments {} vs {}",defTemplArgs.size(),declTemplArgs.size());
62496251
// avoid matching a non-template function in a template class against a
62506252
// template function with the same name and parameters, see issue #10184
62516253
substDone = false;

src/memberdef.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable>
309309
void overrideReferencesRelation(bool e) override;
310310
void overrideEnumValues(bool e) override;
311311
void overrideInlineSource(bool e) override;
312-
void setTemplateMaster(MemberDef *mt) override;
312+
void setTemplateMaster(const MemberDef *mt) override;
313313
void setFormalTemplateArguments(const ArgumentList &al) override;
314314
void addListReference(Definition *d) override;
315315
void setDocsForDefinition(bool b) override;
@@ -442,7 +442,7 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable>
442442

443443
ArgumentList m_tArgList; // template argument list of function template
444444
ArgumentList m_typeConstraints; // type constraints for template parameters
445-
MemberDef *m_templateMaster = nullptr;
445+
const MemberDef *m_templateMaster = nullptr;
446446
std::optional<ArgumentList> m_formalTemplateArguments;
447447
ArgumentLists m_defTmpArgLists; // lists of template argument lists
448448
// (for template functions in nested template classes)
@@ -1571,7 +1571,7 @@ void MemberDefImpl::insertReimplementedBy(MemberDef *md)
15711571
{
15721572
if (m_templateMaster)
15731573
{
1574-
MemberDefMutable *mdm = toMemberDefMutable(m_templateMaster);
1574+
MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef *>(m_templateMaster));
15751575
if (mdm)
15761576
{
15771577
mdm->insertReimplementedBy(md);
@@ -5961,7 +5961,7 @@ MemberDef *MemberDefImpl::fromAnonymousMember() const
59615961
return m_annMemb;
59625962
}
59635963

5964-
void MemberDefImpl::setTemplateMaster(MemberDef *mt)
5964+
void MemberDefImpl::setTemplateMaster(const MemberDef *mt)
59655965
{
59665966
m_templateMaster=mt;
59675967
m_isLinkableCached = 0;

src/memberdef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ class MemberDefMutable : public DefinitionMutable, public MemberDef
383383
virtual void overrideInlineSource(bool e) = 0;
384384
virtual void overrideEnumValues(bool e) = 0;
385385

386-
virtual void setTemplateMaster(MemberDef *mt) = 0;
386+
virtual void setTemplateMaster(const MemberDef *mt) = 0;
387387
virtual void setFormalTemplateArguments(const ArgumentList &al) = 0;
388388
virtual void addListReference(Definition *d) = 0;
389389
virtual void setDocsForDefinition(bool b) = 0;

src/util.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4933,8 +4933,13 @@ QCString stripTemplateSpecifiersFromScope(const QCString &fullName,
49334933
*/
49344934
QCString mergeScopes(const QCString &leftScope,const QCString &rightScope)
49354935
{
4936+
AUTO_TRACE("leftScope='{}' rightScope='{}'",leftScope,rightScope);
49364937
// case leftScope=="A" rightScope=="A::B" => result = "A::B"
4937-
if (leftScopeMatch(rightScope,leftScope)) return rightScope;
4938+
if (leftScopeMatch(leftScope,rightScope))
4939+
{
4940+
AUTO_TRACE_EXIT("case1={}",rightScope);
4941+
return rightScope;
4942+
}
49384943
QCString result;
49394944
int i=0,p=static_cast<int>(leftScope.length());
49404945

@@ -4950,12 +4955,17 @@ QCString mergeScopes(const QCString &leftScope,const QCString &rightScope)
49504955
}
49514956
p=i-1;
49524957
}
4953-
if (found) return result;
4958+
if (found)
4959+
{
4960+
AUTO_TRACE_EXIT("case2={}",result);
4961+
return result;
4962+
}
49544963

49554964
// case leftScope=="A" rightScope=="B" => result = "A::B"
49564965
result=leftScope;
49574966
if (!result.isEmpty() && !rightScope.isEmpty()) result+="::";
49584967
result+=rightScope;
4968+
AUTO_TRACE_EXIT("case3={}",result);
49594969
return result;
49604970
}
49614971

testing/105/namespacebb.xml

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="" xml:lang="en-US">
3+
<compounddef id="namespacebb" kind="namespace" language="C++">
4+
<compoundname>bb</compoundname>
5+
<innerclass refid="structbb_1_1_template_struct" prot="public">bb::TemplateStruct</innerclass>
6+
<sectiondef kind="typedef">
7+
<memberdef kind="typedef" id="namespacebb_1a44bdf7017e8db36d4d0cd7df9247dd59" prot="public" static="no">
8+
<type>
9+
<ref refid="structaa_1_1_struct1" kindref="compound">aa::Struct1</ref>
10+
</type>
11+
<definition>using bb::Struct1 = aa::Struct1</definition>
12+
<argsstring/>
13+
<name>Struct1</name>
14+
<qualifiedname>bb::Struct1</qualifiedname>
15+
<briefdescription>
16+
<para>alias of Structt1 in bb </para>
17+
</briefdescription>
18+
<detaileddescription>
19+
</detaileddescription>
20+
<inbodydescription>
21+
</inbodydescription>
22+
<location file="105_using.cpp" line="68" column="2" bodyfile="105_using.cpp" bodystart="68" bodyend="-1"/>
23+
</memberdef>
24+
<memberdef kind="typedef" id="namespacebb_1acc028b753c5b8d09f24d933a1a7ae5cd" prot="public" static="no">
25+
<type>
26+
<ref refid="structaa_1_1_struct2" kindref="compound">aa::Struct2</ref>
27+
</type>
28+
<definition>using bb::Struct2 = aa::Struct2</definition>
29+
<argsstring/>
30+
<name>Struct2</name>
31+
<qualifiedname>bb::Struct2</qualifiedname>
32+
<briefdescription>
33+
<para>alias of Structt2 in bb </para>
34+
</briefdescription>
35+
<detaileddescription>
36+
</detaileddescription>
37+
<inbodydescription>
38+
</inbodydescription>
39+
<location file="105_using.cpp" line="73" column="2" bodyfile="105_using.cpp" bodystart="73" bodyend="-1"/>
40+
</memberdef>
41+
<memberdef kind="typedef" id="namespacebb_1a4b10384eab1514f579b7651c9c4a8564" prot="public" static="no">
42+
<type><ref refid="structbb_1_1_template_struct" kindref="compound">TemplateStruct</ref>&lt; <ref refid="structaa_1_1_struct1" kindref="compound">aa::Struct1</ref> &gt;</type>
43+
<definition>using bb::Struct1Type = TemplateStruct&lt;aa::Struct1&gt;</definition>
44+
<argsstring/>
45+
<name>Struct1Type</name>
46+
<qualifiedname>bb::Struct1Type</qualifiedname>
47+
<briefdescription>
48+
<para><ref refid="namespacebb_1a4b10384eab1514f579b7651c9c4a8564" kindref="member">Struct1Type</ref>. </para>
49+
</briefdescription>
50+
<detaileddescription>
51+
</detaileddescription>
52+
<inbodydescription>
53+
</inbodydescription>
54+
<location file="105_using.cpp" line="78" column="2" bodyfile="105_using.cpp" bodystart="78" bodyend="-1"/>
55+
</memberdef>
56+
<memberdef kind="typedef" id="namespacebb_1afdccfa9acfdee82110ae0d64e7c664fc" prot="public" static="no">
57+
<type><ref refid="structbb_1_1_template_struct" kindref="compound">TemplateStruct</ref>&lt; <ref refid="structaa_1_1_struct2" kindref="compound">aa::Struct2</ref> &gt;</type>
58+
<definition>using bb::Struct2Type = TemplateStruct&lt;aa::Struct2&gt;</definition>
59+
<argsstring/>
60+
<name>Struct2Type</name>
61+
<qualifiedname>bb::Struct2Type</qualifiedname>
62+
<briefdescription>
63+
<para><ref refid="namespacebb_1afdccfa9acfdee82110ae0d64e7c664fc" kindref="member">Struct2Type</ref>. </para>
64+
</briefdescription>
65+
<detaileddescription>
66+
</detaileddescription>
67+
<inbodydescription>
68+
</inbodydescription>
69+
<location file="105_using.cpp" line="83" column="2" bodyfile="105_using.cpp" bodystart="83" bodyend="-1"/>
70+
</memberdef>
71+
</sectiondef>
72+
<sectiondef kind="func">
73+
<memberdef kind="function" id="namespacebb_1a9018bac0330702c2a15bc96c7713637d" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
74+
<type>int</type>
75+
<definition>int bb::FunctionExample</definition>
76+
<argsstring>(Struct1Type arg1, int arg2)</argsstring>
77+
<name>FunctionExample</name>
78+
<qualifiedname>bb::FunctionExample</qualifiedname>
79+
<param>
80+
<type>
81+
<ref refid="namespacebb_1a4b10384eab1514f579b7651c9c4a8564" kindref="member">Struct1Type</ref>
82+
</type>
83+
<declname>arg1</declname>
84+
</param>
85+
<param>
86+
<type>int</type>
87+
<declname>arg2</declname>
88+
</param>
89+
<briefdescription>
90+
<para>FunctionExample (overload 1) </para>
91+
</briefdescription>
92+
<detaileddescription>
93+
<para>
94+
<parameterlist kind="param">
95+
<parameteritem>
96+
<parameternamelist>
97+
<parametername direction="out">arg1</parametername>
98+
</parameternamelist>
99+
<parameterdescription>
100+
<para><ref refid="namespacebb_1a4b10384eab1514f579b7651c9c4a8564" kindref="member">Struct1Type</ref> argument </para>
101+
</parameterdescription>
102+
</parameteritem>
103+
<parameteritem>
104+
<parameternamelist>
105+
<parametername direction="in">arg2</parametername>
106+
</parameternamelist>
107+
<parameterdescription>
108+
<para>int argument</para>
109+
</parameterdescription>
110+
</parameteritem>
111+
</parameterlist>
112+
<simplesect kind="return">
113+
<para>return value </para>
114+
</simplesect>
115+
</para>
116+
</detaileddescription>
117+
<inbodydescription>
118+
</inbodydescription>
119+
<location file="105_using.cpp" line="93" column="5" declfile="105_using.cpp" declline="93" declcolumn="5"/>
120+
</memberdef>
121+
<memberdef kind="function" id="namespacebb_1ada96dde7cf2ee341fc1a2c197de4ccf3" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
122+
<type>int</type>
123+
<definition>int bb::FunctionExample</definition>
124+
<argsstring>(Struct2Type arg1, int arg2)</argsstring>
125+
<name>FunctionExample</name>
126+
<qualifiedname>bb::FunctionExample</qualifiedname>
127+
<param>
128+
<type>
129+
<ref refid="namespacebb_1afdccfa9acfdee82110ae0d64e7c664fc" kindref="member">Struct2Type</ref>
130+
</type>
131+
<declname>arg1</declname>
132+
</param>
133+
<param>
134+
<type>int</type>
135+
<declname>arg2</declname>
136+
</param>
137+
<briefdescription>
138+
<para>FunctionExample (overload 2) </para>
139+
</briefdescription>
140+
<detaileddescription>
141+
<para>
142+
<parameterlist kind="param">
143+
<parameteritem>
144+
<parameternamelist>
145+
<parametername direction="out">arg1</parametername>
146+
</parameternamelist>
147+
<parameterdescription>
148+
<para><ref refid="namespacebb_1afdccfa9acfdee82110ae0d64e7c664fc" kindref="member">Struct2Type</ref> argument </para>
149+
</parameterdescription>
150+
</parameteritem>
151+
<parameteritem>
152+
<parameternamelist>
153+
<parametername direction="in">arg2</parametername>
154+
</parameternamelist>
155+
<parameterdescription>
156+
<para>int argument</para>
157+
</parameterdescription>
158+
</parameteritem>
159+
</parameterlist>
160+
<simplesect kind="return">
161+
<para>return value </para>
162+
</simplesect>
163+
</para>
164+
</detaileddescription>
165+
<inbodydescription>
166+
</inbodydescription>
167+
<location file="105_using.cpp" line="103" column="5" declfile="105_using.cpp" declline="103" declcolumn="5"/>
168+
</memberdef>
169+
</sectiondef>
170+
<briefdescription>
171+
<para>namespace bb </para>
172+
</briefdescription>
173+
<detaileddescription>
174+
</detaileddescription>
175+
<location file="105_using.cpp" line="54" column="1"/>
176+
</compounddef>
177+
</doxygen>

0 commit comments

Comments
 (0)