Skip to content
Draft
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
4 changes: 2 additions & 2 deletions include/mrdocs/Corpus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class MRDOCS_VISIBLE
{
if (!opts.skipInherited)
{
auto MS = allMembers(I);
auto&& MS = allMembers(I);
visitIDs(MS,
std::forward<F>(f),
std::forward<Args>(args)...);
Expand Down Expand Up @@ -257,7 +257,7 @@ class MRDOCS_VISIBLE
}
else /* ordered */
{
auto members0 = allMembers(I);
auto&& members0 = allMembers(I);
static_assert(range_of<decltype(members0), SymbolID>);
std::vector<SymbolID> members;
members.reserve(std::ranges::distance(members0));
Expand Down
2 changes: 2 additions & 0 deletions include/mrdocs/Metadata/Info/Overloads.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct OverloadsInfo final
/// Info about the return type of this function.
Polymorphic<TypeInfo> ReturnType = std::nullopt;

StorageClassKind StorageClass = StorageClassKind::None;

//--------------------------------------------

explicit OverloadsInfo(SymbolID const& ID) noexcept
Expand Down
18 changes: 15 additions & 3 deletions include/mrdocs/Metadata/Info/Record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ tag_invoke(
v = dom::LazyObject(I, domCorpus);
}


inline
auto
allMembers(RecordInterface const& T)
Expand Down Expand Up @@ -275,6 +274,13 @@ tag_invoke(
v = toString(kind);
}

struct MemberInfo
{
AccessKind EffectiveAccess;
InfoKind Kind;
SymbolID id;
};

/** Metadata for struct, class, or union.
*/
struct RecordInfo final
Expand All @@ -301,11 +307,15 @@ struct RecordInfo final
*/
std::vector<BaseInfo> Bases;

/** List of derived classes
/** List of derived classes.
*/
std::vector<SymbolID> Derived;

/** Lists of members.
/** List of members.
*/
std::vector<MemberInfo> Members;

/** Record Interface (NOT part of the Corpus.)
*/
RecordInterface Interface;

Expand Down Expand Up @@ -345,6 +355,7 @@ inline
auto
allMembers(RecordInfo const& T)
{
//return std::views::transform(T.Members, &MemberInfo::id);
return allMembers(T.Interface);
}

Expand Down Expand Up @@ -374,6 +385,7 @@ tag_invoke(
io.map("isTypedef", I.IsTypeDef);
io.map("bases", dom::LazyArray(I.Bases, domCorpus));
io.map("derived", dom::LazyArray(I.Derived, domCorpus));
//io.map("members", dom::LazyArray(I.Members, domCorpus));
io.map("interface", I.Interface);
io.map("template", I.Template);
io.map("friends", dom::LazyArray(I.Friends, domCorpus));
Expand Down
14 changes: 2 additions & 12 deletions src/lib/AST/ASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1770,19 +1770,9 @@ addMember(
RecordInfo& I,
Info const& Member)
{
switch (Member.Access)
if (!std::ranges::contains(I.Members, Member.id, &MemberInfo::id))
{
case AccessKind::Public:
addMember(I.Interface.Public, Member);
break;
case AccessKind::Private:
addMember(I.Interface.Private, Member);
break;
case AccessKind::Protected:
addMember(I.Interface.Protected, Member);
break;
default:
MRDOCS_UNREACHABLE();
I.Members.emplace_back(Member.Access, Member.Kind, Member.id);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/lib/CorpusImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "lib/Metadata/Finalizers/JavadocFinalizer.hpp"
#include "lib/Metadata/Finalizers/NamespacesFinalizer.hpp"
#include "lib/Metadata/Finalizers/OverloadsFinalizer.hpp"
#include "lib/Metadata/Finalizers/RecordsFinalizer.hpp"
#include "lib/Metadata/Finalizers/SortMembersFinalizer.hpp"
#include "lib/Support/Chrono.hpp"
#include "lib/Support/Report.hpp"
Expand Down Expand Up @@ -1025,6 +1026,13 @@ CorpusImpl::finalize()
finalizer.build();
}

// Finalizing record interfaces
{
report::debug(" - Finalizing records");
RecordsFinalizer finalizer(*this);
finalizer.build();
}

// Add auto relates for member functions
{
report::debug(" - Finalizing auto-relates");
Expand Down
103 changes: 43 additions & 60 deletions src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,19 @@

namespace clang::mrdocs {

void
BaseMembersFinalizer::
inheritBaseMembers(RecordInfo& I, RecordInfo const& B, AccessKind const A)
namespace {
bool
shouldCopy(Config const& config, Info const& M)
{
inheritBaseMembers(I.id, I.Interface, B.Interface, A);
if (config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyDependencies)
{
return M.Extraction == ExtractionMode::Dependency;
}
return config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyAll;
}

void
BaseMembersFinalizer::
inheritBaseMembers(
SymbolID const& derivedId,
RecordInterface& derived,
RecordInterface const& base,
AccessKind const A)
AccessKind
effectiveAccess(AccessKind const declaredAccess, AccessKind const A)
{
if (A == AccessKind::Public)
{
Expand All @@ -37,71 +36,43 @@
// members of the derived class and all protected members of the base
// class are accessible as protected members of the derived class.
// Private members of the base are never accessible unless friended.
inheritBaseMembers(derivedId, derived.Public, base.Public);
inheritBaseMembers(derivedId, derived.Protected, base.Protected);
return declaredAccess;
}
else if (A == AccessKind::Protected)
{
// When a class uses protected member access specifier to derive from a
// base, all public and protected members of the base class are
// accessible as protected members of the derived class (private members
// of the base are never accessible unless friended).
inheritBaseMembers(derivedId, derived.Protected, base.Public);
inheritBaseMembers(derivedId, derived.Protected, base.Protected);
return AccessKind::Protected;
}
else if (A == AccessKind::Private && corpus_.config->extractPrivate)
else if (A == AccessKind::Private)
{
// When a class uses private member access specifier to derive from a
// base, all public and protected members of the base class are
// accessible as private members of the derived class (private members
// of the base are never accessible unless friended).
inheritBaseMembers(derivedId, derived.Private, base.Public);
inheritBaseMembers(derivedId, derived.Private, base.Protected);
return AccessKind::Private;
}
}

void
BaseMembersFinalizer::
inheritBaseMembers(
SymbolID const& derivedId,
RecordTranche& derived,
RecordTranche const& base)
{
inheritBaseMembers(derivedId, derived.NamespaceAliases, base.NamespaceAliases);
inheritBaseMembers(derivedId, derived.Typedefs, base.Typedefs);
inheritBaseMembers(derivedId, derived.Records, base.Records);
inheritBaseMembers(derivedId, derived.Enums, base.Enums);
inheritBaseMembers(derivedId, derived.Functions, base.Functions);
inheritBaseMembers(derivedId, derived.StaticFunctions, base.StaticFunctions);
inheritBaseMembers(derivedId, derived.Variables, base.Variables);
inheritBaseMembers(derivedId, derived.StaticVariables, base.StaticVariables);
inheritBaseMembers(derivedId, derived.Concepts, base.Concepts);
inheritBaseMembers(derivedId, derived.Guides, base.Guides);
}

namespace {
bool
shouldCopy(Config const& config, Info const& M)
{
if (config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyDependencies)
{
return M.Extraction == ExtractionMode::Dependency;
}
return config->inheritBaseMembers == PublicSettings::BaseMemberInheritance::CopyAll;
return AccessKind::None;
}
}

void
void
BaseMembersFinalizer::
inheritBaseMembers(
SymbolID const& derivedId,
std::vector<SymbolID>& derived,
std::vector<SymbolID> const& base)
inheritBaseMembers(RecordInfo& I, RecordInfo const& B, AccessKind const A)
{
for (SymbolID const& otherID: base)
SymbolID const& derivedId = I.id;
std::vector<MemberInfo>& derived = I.Members;
std::vector<MemberInfo> const& base = B.Members;

for (auto const& other: base)
{
SymbolID const& otherID = other.id;

// Find the info from the base class
MRDOCS_CHECK_OR_CONTINUE(!contains(derived, otherID));
MRDOCS_CHECK_OR_CONTINUE(!std::ranges::contains(derived, otherID, &MemberInfo::id));
Info* otherInfoPtr = corpus_.find(otherID);
MRDOCS_CHECK_OR_CONTINUE(otherInfoPtr);
Info& otherInfo = *otherInfoPtr;
Expand Down Expand Up @@ -134,7 +105,7 @@
// For other kinds of members, it's a shadow if the names
// are the same
return info.Name == otherInfo.Name;
});
}, &MemberInfo::id);
MRDOCS_CHECK_OR_CONTINUE(shadowIt == derived.end());

// Not a shadow, so inherit the base member
Expand All @@ -148,7 +119,7 @@
// extraction mode to be regular, but that is controversial.
if (otherInfo.Extraction != ExtractionMode::Dependency)
{
derived.push_back(otherID);
derived.emplace_back(effectiveAccess(other.EffectiveAccess, A), other.Kind, otherID);
}
}
else
Expand All @@ -163,7 +134,7 @@
otherCopy->id = SymbolID::createFromString(
std::format("{}-{}", toBase16Str(otherCopy->Parent),
toBase16Str(otherInfo.id)));
derived.push_back(otherCopy->id);
derived.emplace_back(effectiveAccess(other.EffectiveAccess, A), other.Kind, otherCopy->id);
// Get the extraction mode from the derived class
if (otherCopy->Extraction == ExtractionMode::Dependency)
{
Expand Down Expand Up @@ -250,10 +221,22 @@
operator()(*baseRecord);
inheritBaseMembers(I, *baseRecord, baseI.Access);
}
finalizeRecords(I.Interface.Public.Records);
finalizeRecords(I.Interface.Protected.Records);
finalizeRecords(I.Interface.Private.Records);
finalized_.emplace(I.id);

auto RecordMembers =
I.Members |
std::views::filter([this](MemberInfo const& member) {

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 21: C++20

Build Warning - clang++-21 - [-Wunused-lambda-capture]

clang++-21 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 18: C++20

Build Warning - clang++-18 - [-Wunused-lambda-capture]

clang++-18 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Apple-Clang

Build Warning - clang++ - [-Wunused-lambda-capture]

clang++ - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Apple-Clang (ASan)

Build Warning - clang++ - [-Wunused-lambda-capture]

clang++ - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 19: C++20

Build Warning - clang++-19 - [-Wunused-lambda-capture]

clang++-19 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 21: C++20 (MSan)

Build Warning - clang++-21 - [-Wunused-lambda-capture]

clang++-21 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 21: C++20 (ASan)

Build Warning - clang++-21 - [-Wunused-lambda-capture]

clang++-21 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 21: C++20 (UBSan)

Build Warning - clang++-21 - [-Wunused-lambda-capture]

clang++-21 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Clang 20: C++20

Build Warning - clang++-20 - [-Wunused-lambda-capture]

clang++-20 - lambda capture 'this' is not used ([-Wunused-lambda-capture])

Check warning on line 228 in src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp

View workflow job for this annotation

GitHub Actions / Apple-Clang (UBSan)

Build Warning - clang++ - [-Wunused-lambda-capture]

clang++ - lambda capture 'this' is not used ([-Wunused-lambda-capture])
return member.Kind == InfoKind::Record;
}) |
std::ranges::views::transform(&MemberInfo::id);
for (SymbolID const& memberId: RecordMembers)
{
Info* infoPtr = corpus_.find(memberId);
MRDOCS_CHECK_OR_CONTINUE(infoPtr);
auto* record = infoPtr->asRecordPtr();
MRDOCS_CHECK_OR_CONTINUE(record);
operator()(*record);
}
}

} // clang::mrdocs
19 changes: 0 additions & 19 deletions src/lib/Metadata/Finalizers/BaseMembersFinalizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,6 @@ class BaseMembersFinalizer
void
inheritBaseMembers(RecordInfo& I, RecordInfo const& B, AccessKind A);

void
inheritBaseMembers(
SymbolID const& derivedId,
RecordInterface& derived,
RecordInterface const& base,
AccessKind A);

void
inheritBaseMembers(
SymbolID const& derivedId,
RecordTranche& derived,
RecordTranche const& base);

void
inheritBaseMembers(
SymbolID const& derivedId,
std::vector<SymbolID>& derived,
std::vector<SymbolID> const& base);

void
finalizeRecords(std::vector<SymbolID> const& ids);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/Metadata/Finalizers/NamespacesFinalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ operator()(NamespaceInfo& I)
MRDOCS_CHECK_OR(!I.javadoc, FinalizerResult::None);

// 3) Remove empty undocumented namespaces
auto memberIds = allMembers(I);
auto&& memberIds = allMembers(I);
if (std::ranges::empty(memberIds))
{
if (!corpus_.config->extractEmptyNamespaces)
Expand Down
Loading
Loading