Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
/share/mrdocs/clang/
/docs/modules/reference
/.gdbinit
/.lldbinit
/.lldbinit
/.github/node_modules/
53 changes: 36 additions & 17 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,23 +212,15 @@ traverseMembers(InfoTy& I, DeclTy const* DC)
!std::derived_from<DeclTy, clang::FunctionDecl> &&
std::derived_from<DeclTy, clang::DeclContext>)
{
// We only need members of regular symbols and see-below namespaces
// - If symbol is SeeBelow we want the members if it's a namespace
MRDOCS_CHECK_OR(
I.Extraction != ExtractionMode::SeeBelow ||
I.Kind == SymbolKind::Namespace);

// - If symbol is a Dependency, we only want the members if
// the traversal mode is BaseClass
MRDOCS_CHECK_OR(
I.Extraction != ExtractionMode::Dependency ||
mode_ == TraversalMode::BaseClass);

// - If symbol is ImplementationDefined, we only want the members if
// the traversal mode is BaseClass
MRDOCS_CHECK_OR(
I.Extraction != ExtractionMode::ImplementationDefined ||
mode_ == TraversalMode::BaseClass);
// Only traverse hidden members (dep/impl-defined/see-below records) when
// we're already visiting a base class tree.
if (mode_ != TraversalMode::BaseClass)
{
MRDOCS_CHECK_OR(
I.Extraction == ExtractionMode::Regular
|| (I.Extraction == ExtractionMode::SeeBelow
&& I.Kind == SymbolKind::Namespace));
}

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

// When inheriting base members, only revisit bases whose extraction mode
// isn’t regular so we pick up their members/docs.
if (config_->inheritBaseMembers != PublicSettings::BaseMemberInheritance::Never)
{
if (auto const* baseDecl = BT->getAsCXXRecordDecl())
{
if (auto const* baseDef = baseDecl->getDefinition();
Comment on lines +678 to +682

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor extract-implicit-specializations when visiting base classes

Base-class traversal now unconditionally calls getDefinition()/traverse(baseDef) whenever base-member inheritance is enabled, but this block no longer checks config_->extractImplicitSpecializations. With extract-implicit-specializations: false (the documented way to avoid instantiating implicit template specializations), a derived type such as struct A : B<int> will still instantiate and traverse the implicit specialization B<int> because this code runs before the guarded specialization handling. That bypasses the user setting and forces implicit specializations to be extracted even when explicitly disabled.

Useful? React with 👍 / 👎.

baseDef)
{
if (auto const* baseInfo = find(baseDef);
baseInfo)
{
if (baseInfo->Extraction != ExtractionMode::Regular)
{
ScopeExitRestore s(mode_, TraversalMode::BaseClass);
traverse(baseDef);
}
}
else
{
ScopeExitRestore s(mode_, TraversalMode::BaseClass);
traverse(baseDef);
}
}
}
}

// If we're going to copy the members from the specialization,
// we need to instantiate and traverse the specialization
// as a dependency.
Expand Down
20 changes: 15 additions & 5 deletions src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ shouldCopy(Config const& config, Symbol const& M)
{
if (config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyDependencies)
{
return M.Extraction == ExtractionMode::Dependency;
return M.Extraction != ExtractionMode::Regular;
}
return config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyAll;
}
Expand All @@ -98,6 +98,16 @@ inheritBaseMembers(
std::vector<SymbolID>& derived,
std::vector<SymbolID> const& base)
{
Symbol const* derivedInfo = nullptr;
auto const getDerivedInfo = [&]() -> Symbol const*
{
if (!derivedInfo)
{
derivedInfo = corpus_.find(derivedId);
}
return derivedInfo;
};

for (SymbolID const& otherID: base)
{
// Find the info from the base class
Expand Down Expand Up @@ -164,12 +174,12 @@ inheritBaseMembers(
toBase16Str(otherInfo.id)));
derived.push_back(otherCopy->id);
// Get the extraction mode from the derived class
if (otherCopy->Extraction == ExtractionMode::Dependency)
if (otherCopy->Extraction == ExtractionMode::Dependency ||
otherCopy->Extraction == ExtractionMode::ImplementationDefined)
{
Symbol* derivedInfoPtr = corpus_.find(derivedId);
Symbol const* derivedInfoPtr = getDerivedInfo();
MRDOCS_CHECK_OR_CONTINUE(derivedInfoPtr);
Symbol const& derivedInfo = *derivedInfoPtr;
otherCopy->Extraction = derivedInfo.Extraction;
otherCopy->Extraction = derivedInfoPtr->Extraction;
}
corpus_.info_.insert(std::move(otherCopy));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
|===
| Name
| link:#A[`A`]
| link:#B[`B`]
| link:#B-00[`B`]
|===

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

=== Base Classes
Expand All @@ -32,7 +32,7 @@ struct A
|===
|Name|Description

| `link:#B[B&lt;int&gt;]`
| `link:#B-00[B&lt;int&gt;]`
|
|===

Expand All @@ -41,10 +41,10 @@ struct A
[cols=1]
|===
| Name
| link:#B-value[`value`]
| link:#B-00-value[`value`]
|===

[#B]
[#B-00]
== B

=== Synopsis
Expand All @@ -62,7 +62,7 @@ struct B;
[cols=1]
|===
| Name
| link:#B-value[`value`]
| link:#B-00-value[`value`]
|===

=== Derived Classes
Expand All @@ -75,8 +75,8 @@ struct B;
|
|===

[#B-value]
== link:#B[B]::value
[#B-00-value]
== link:#B-00[B]::value

=== Synopsis

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ <h2>Types</h2>
<tbody>
<tr>
<td><a href="#A"><code>A</code></a> </td></tr><tr>
<td><a href="#B"><code>B</code></a> </td></tr>
<td><a href="#B-00"><code>B</code></a> </td></tr>
</tbody>
</table>

Expand All @@ -34,7 +34,7 @@ <h3>Synopsis</h3>
Declared in <code>&lt;no-extract-implicit-specializations.cpp&gt;</code></div>
<pre>
<code class="source-code cpp">struct A
: <a href="#B">B&lt;int&gt;</a></code>
: <a href="#B-00">B&lt;int&gt;</a></code>
</pre>
</div>
<div>
Expand All @@ -47,7 +47,7 @@ <h2>Base Classes</h2>
</tr>
</thead>
<tbody>
<tr><td><code><a href="#B">B&lt;int&gt;</a></code></td><td></td></tr>
<tr><td><code><a href="#B-00">B&lt;int&gt;</a></code></td><td></td></tr>
</tbody>
</table>
</div>
Expand All @@ -60,7 +60,7 @@ <h2>Member Functions</h2>
</thead>
<tbody>
<tr>
<td><a href="#B-value"><code>value</code></a> </td></tr>
<td><a href="#B-00-value"><code>value</code></a> </td></tr>
</tbody>
</table>

Expand All @@ -69,7 +69,7 @@ <h2>Member Functions</h2>
</div>
<div>
<div>
<h2 id="B">B</h2>
<h2 id="B-00">B</h2>
</div>
<div>
<h3>Synopsis</h3>
Expand All @@ -89,7 +89,7 @@ <h2>Member Functions</h2>
</thead>
<tbody>
<tr>
<td><a href="#B-value"><code>value</code></a> </td></tr>
<td><a href="#B-00-value"><code>value</code></a> </td></tr>
</tbody>
</table>

Expand All @@ -113,7 +113,7 @@ <h2>Derived Classes</h2>
</div>
<div>
<div>
<h2 id="B-value">B::value</h2>
<h2 id="B-00-value">B::value</h2>
</div>
<div>
<h3>Synopsis</h3>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
= Reference
:mrdocs:

[#index]
== Global namespace

=== Types

[cols=1]
|===
| Name
| link:#derived[`derived`]
|===

[#derived]
== derived

=== Synopsis

Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
struct derived
: &sol;&ast; implementation-defined &ast;&sol;
----

=== Base Classes

[cols="1,4"]
|===
|Name|Description

| `&sol;&ast; implementation-defined &ast;&sol;`
|
|===

=== Member Functions

[cols="1,4"]
|===
| Name| Description
| link:#derived-do_it[`do&lowbar;it`]
| Do the thing
| link:#derived-own[`own`]
|
|===

[#derived-do_it]
== link:#derived[derived]::do&lowbar;it

Do the thing

=== Synopsis

Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
void
do&lowbar;it();
----

[#derived-own]
== link:#derived[derived]::own

=== Synopsis

Declared in `&lt;impl&hyphen;defined&hyphen;base&period;cpp&gt;`

[source,cpp,subs="verbatim,replacements,macros,-callouts"]
----
void
own();
----


[.small]#Created with https://www.mrdocs.com[MrDocs]#
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Repro for cppalliance/mrdocs#1107: documentation carried from hidden bases.
namespace detail {

struct base_detail {
/// Do the thing
void do_it();
};

} // detail

struct derived : detail::base_detail
{
void own();
};
Loading
Loading