Skip to content

Commit 05f5852

Browse files
committed
fix(metadata): copy impl-defined base docs
fix #1107
1 parent fdff573 commit 05f5852

23 files changed

+896
-237
lines changed

src/lib/AST/ASTVisitor.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -212,23 +212,15 @@ traverseMembers(InfoTy& I, DeclTy const* DC)
212212
!std::derived_from<DeclTy, clang::FunctionDecl> &&
213213
std::derived_from<DeclTy, clang::DeclContext>)
214214
{
215-
// We only need members of regular symbols and see-below namespaces
216-
// - If symbol is SeeBelow we want the members if it's a namespace
217-
MRDOCS_CHECK_OR(
218-
I.Extraction != ExtractionMode::SeeBelow ||
219-
I.Kind == SymbolKind::Namespace);
220-
221-
// - If symbol is a Dependency, we only want the members if
222-
// the traversal mode is BaseClass
223-
MRDOCS_CHECK_OR(
224-
I.Extraction != ExtractionMode::Dependency ||
225-
mode_ == TraversalMode::BaseClass);
226-
227-
// - If symbol is ImplementationDefined, we only want the members if
228-
// the traversal mode is BaseClass
229-
MRDOCS_CHECK_OR(
230-
I.Extraction != ExtractionMode::ImplementationDefined ||
231-
mode_ == TraversalMode::BaseClass);
215+
// Only traverse hidden members (dep/impl-defined/see-below records) when
216+
// we're already visiting a base class tree.
217+
if (mode_ != TraversalMode::BaseClass)
218+
{
219+
MRDOCS_CHECK_OR(
220+
I.Extraction == ExtractionMode::Regular
221+
|| (I.Extraction == ExtractionMode::SeeBelow
222+
&& I.Kind == SymbolKind::Namespace));
223+
}
232224

233225
// There are many implicit declarations, especially in the
234226
// translation unit declaration, so we preemtively skip them here.
@@ -681,6 +673,33 @@ populate(
681673
clang::QualType const BT = B.getType();
682674
auto BaseType = toType(BT, BaseClass);
683675

676+
// When inheriting base members, only revisit bases whose extraction mode
677+
// isn’t regular so we pick up their members/docs.
678+
if (config_->inheritBaseMembers != PublicSettings::BaseMemberInheritance::Never)
679+
{
680+
if (auto const* baseDecl = BT->getAsCXXRecordDecl())
681+
{
682+
if (auto const* baseDef = baseDecl->getDefinition();
683+
baseDef)
684+
{
685+
if (auto const* baseInfo = find(baseDef);
686+
baseInfo)
687+
{
688+
if (baseInfo->Extraction != ExtractionMode::Regular)
689+
{
690+
ScopeExitRestore s(mode_, TraversalMode::BaseClass);
691+
traverse(baseDef);
692+
}
693+
}
694+
else
695+
{
696+
ScopeExitRestore s(mode_, TraversalMode::BaseClass);
697+
traverse(baseDef);
698+
}
699+
}
700+
}
701+
}
702+
684703
// If we're going to copy the members from the specialization,
685704
// we need to instantiate and traverse the specialization
686705
// as a dependency.

src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ shouldCopy(Config const& config, Symbol const& M)
8585
{
8686
if (config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyDependencies)
8787
{
88-
return M.Extraction == ExtractionMode::Dependency;
88+
return M.Extraction != ExtractionMode::Regular;
8989
}
9090
return config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyAll;
9191
}
@@ -98,6 +98,16 @@ inheritBaseMembers(
9898
std::vector<SymbolID>& derived,
9999
std::vector<SymbolID> const& base)
100100
{
101+
Symbol const* derivedInfo = nullptr;
102+
auto const getDerivedInfo = [&]() -> Symbol const*
103+
{
104+
if (!derivedInfo)
105+
{
106+
derivedInfo = corpus_.find(derivedId);
107+
}
108+
return derivedInfo;
109+
};
110+
101111
for (SymbolID const& otherID: base)
102112
{
103113
// Find the info from the base class
@@ -164,12 +174,12 @@ inheritBaseMembers(
164174
toBase16Str(otherInfo.id)));
165175
derived.push_back(otherCopy->id);
166176
// Get the extraction mode from the derived class
167-
if (otherCopy->Extraction == ExtractionMode::Dependency)
177+
if (otherCopy->Extraction == ExtractionMode::Dependency ||
178+
otherCopy->Extraction == ExtractionMode::ImplementationDefined)
168179
{
169-
Symbol* derivedInfoPtr = corpus_.find(derivedId);
180+
Symbol const* derivedInfoPtr = getDerivedInfo();
170181
MRDOCS_CHECK_OR_CONTINUE(derivedInfoPtr);
171-
Symbol const& derivedInfo = *derivedInfoPtr;
172-
otherCopy->Extraction = derivedInfo.Extraction;
182+
otherCopy->Extraction = derivedInfoPtr->Extraction;
173183
}
174184
corpus_.info_.insert(std::move(otherCopy));
175185
}

test-files/golden-tests/config/extract-implicit-specializations/no-extract-implicit-specializations.adoc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
|===
1111
| Name
1212
| link:#A[`A`]
13-
| link:#B[`B`]
13+
| link:#B-00[`B`]
1414
|===
1515

1616
[#A]
@@ -23,7 +23,7 @@ Declared in `&lt;no&hyphen;extract&hyphen;implicit&hyphen;specializations&period
2323
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
2424
----
2525
struct A
26-
: link:#B[B&lt;int&gt;]
26+
: link:#B-00[B&lt;int&gt;]
2727
----
2828

2929
=== Base Classes
@@ -32,7 +32,7 @@ struct A
3232
|===
3333
|Name|Description
3434

35-
| `link:#B[B&lt;int&gt;]`
35+
| `link:#B-00[B&lt;int&gt;]`
3636
|
3737
|===
3838

@@ -41,10 +41,10 @@ struct A
4141
[cols=1]
4242
|===
4343
| Name
44-
| link:#B-value[`value`]
44+
| link:#B-00-value[`value`]
4545
|===
4646

47-
[#B]
47+
[#B-00]
4848
== B
4949

5050
=== Synopsis
@@ -62,7 +62,7 @@ struct B;
6262
[cols=1]
6363
|===
6464
| Name
65-
| link:#B-value[`value`]
65+
| link:#B-00-value[`value`]
6666
|===
6767

6868
=== Derived Classes
@@ -75,8 +75,8 @@ struct B;
7575
|
7676
|===
7777

78-
[#B-value]
79-
== link:#B[B]::value
78+
[#B-00-value]
79+
== link:#B-00[B]::value
8080

8181
=== Synopsis
8282

test-files/golden-tests/config/extract-implicit-specializations/no-extract-implicit-specializations.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ <h2>Types</h2>
1919
<tbody>
2020
<tr>
2121
<td><a href="#A"><code>A</code></a> </td></tr><tr>
22-
<td><a href="#B"><code>B</code></a> </td></tr>
22+
<td><a href="#B-00"><code>B</code></a> </td></tr>
2323
</tbody>
2424
</table>
2525

@@ -34,7 +34,7 @@ <h3>Synopsis</h3>
3434
Declared in <code>&lt;no-extract-implicit-specializations.cpp&gt;</code></div>
3535
<pre>
3636
<code class="source-code cpp">struct A
37-
: <a href="#B">B&lt;int&gt;</a></code>
37+
: <a href="#B-00">B&lt;int&gt;</a></code>
3838
</pre>
3939
</div>
4040
<div>
@@ -47,7 +47,7 @@ <h2>Base Classes</h2>
4747
</tr>
4848
</thead>
4949
<tbody>
50-
<tr><td><code><a href="#B">B&lt;int&gt;</a></code></td><td></td></tr>
50+
<tr><td><code><a href="#B-00">B&lt;int&gt;</a></code></td><td></td></tr>
5151
</tbody>
5252
</table>
5353
</div>
@@ -60,7 +60,7 @@ <h2>Member Functions</h2>
6060
</thead>
6161
<tbody>
6262
<tr>
63-
<td><a href="#B-value"><code>value</code></a> </td></tr>
63+
<td><a href="#B-00-value"><code>value</code></a> </td></tr>
6464
</tbody>
6565
</table>
6666

@@ -69,7 +69,7 @@ <h2>Member Functions</h2>
6969
</div>
7070
<div>
7171
<div>
72-
<h2 id="B">B</h2>
72+
<h2 id="B-00">B</h2>
7373
</div>
7474
<div>
7575
<h3>Synopsis</h3>
@@ -89,7 +89,7 @@ <h2>Member Functions</h2>
8989
</thead>
9090
<tbody>
9191
<tr>
92-
<td><a href="#B-value"><code>value</code></a> </td></tr>
92+
<td><a href="#B-00-value"><code>value</code></a> </td></tr>
9393
</tbody>
9494
</table>
9595

@@ -113,7 +113,7 @@ <h2>Derived Classes</h2>
113113
</div>
114114
<div>
115115
<div>
116-
<h2 id="B-value">B::value</h2>
116+
<h2 id="B-00-value">B::value</h2>
117117
</div>
118118
<div>
119119
<h3>Synopsis</h3>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
= Reference
2+
:mrdocs:
3+
4+
[#index]
5+
== Global namespace
6+
7+
=== Types
8+
9+
[cols=1]
10+
|===
11+
| Name
12+
| link:#derived[`derived`]
13+
|===
14+
15+
[#derived]
16+
== derived
17+
18+
=== Synopsis
19+
20+
Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`
21+
22+
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
23+
----
24+
struct derived
25+
: &sol;&ast; implementation-defined &ast;&sol;
26+
----
27+
28+
=== Base Classes
29+
30+
[cols="1,4"]
31+
|===
32+
|Name|Description
33+
34+
| `&sol;&ast; implementation-defined &ast;&sol;`
35+
|
36+
|===
37+
38+
=== Member Functions
39+
40+
[cols="1,4"]
41+
|===
42+
| Name| Description
43+
| link:#derived-do_it[`do&lowbar;it`]
44+
| Do the thing
45+
| link:#derived-own[`own`]
46+
|
47+
|===
48+
49+
[#derived-do_it]
50+
== link:#derived[derived]::do&lowbar;it
51+
52+
Do the thing
53+
54+
=== Synopsis
55+
56+
Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`
57+
58+
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
59+
----
60+
void
61+
do&lowbar;it();
62+
----
63+
64+
[#derived-own]
65+
== link:#derived[derived]::own
66+
67+
=== Synopsis
68+
69+
Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`
70+
71+
[source,cpp,subs="verbatim,replacements,macros,-callouts"]
72+
----
73+
void
74+
own();
75+
----
76+
77+
78+
[.small]#Created with https://www.mrdocs.com[MrDocs]#
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Repro for cppalliance/mrdocs#1107: documentation carried from hidden bases.
2+
namespace detail {
3+
4+
struct base_detail {
5+
/// Do the thing
6+
void do_it();
7+
};
8+
9+
} // detail
10+
11+
struct derived : detail::base_detail
12+
{
13+
void own();
14+
};

0 commit comments

Comments
 (0)