summaryrefslogtreecommitdiffstats
path: root/src/memberdef.cpp
diff options
context:
space:
mode:
authorVladimír Vondruš <mosra@centrum.cz>2019-01-01 17:01:22 (GMT)
committerVladimír Vondruš <mosra@centrum.cz>2019-01-03 10:32:17 (GMT)
commitd18b3eaf3486e224fa9de7e77b536883952b40b9 (patch)
tree045620bc9c59d68e2fb32bf035f0147e164a360b /src/memberdef.cpp
parent3b2198babbaf8edafe03e5298e7c194763a1f9fa (diff)
downloadDoxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.zip
Doxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.tar.gz
Doxygen-d18b3eaf3486e224fa9de7e77b536883952b40b9.tar.bz2
Implement a new EXTRACT_PRIVATE_VIRTUAL option.
The classic article about virtuality from Herb Sutter [1] suggests that virtual functions are always private and public class interface is never virtual. Until now, it was not really possible to document these functions in Doxygen: * Enabling EXTRACT_PRIVATE would show all internals, not just virtual functions, which is not wanted. * Enabling HIDE_UNDOC_MEMBERS and HIDE_UNDOC_CLASSES would effectively disable warnings about *all* undocumented members, which is not wanted. The usual workaround was to put the members into protected scope just for Doxygen: #ifdef DOXYGEN_GENERATING_OUTPUT protected: #else private: #endif /** @brief Documented private virtual function */ virtual doStuff(); The new EXTRACT_PRIVATE_VIRTUAL option makes these visible (and able to be linked to), but shows them *only* if they are documented. [1] http://www.gotw.ca/publications/mill18.htm
Diffstat (limited to 'src/memberdef.cpp')
-rw-r--r--src/memberdef.cpp17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index a2fcf69..58a2b12 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -1080,6 +1080,7 @@ QCString MemberDef::anchor() const
void MemberDef::_computeLinkableInProject()
{
static bool extractStatic = Config_getBool(EXTRACT_STATIC);
+ static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL);
m_isLinkableCached = 2; // linkable
//printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
if (isHidden())
@@ -1133,7 +1134,7 @@ void MemberDef::_computeLinkableInProject()
m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
return;
}
- if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend)
+ if ((!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=MemberType_Friend) && !(m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual))
{
//printf("private and invisible!\n");
m_isLinkableCached = 1; // hidden due to protection
@@ -1315,6 +1316,7 @@ ClassDef *MemberDef::getClassDefOfAnonymousType()
bool MemberDef::isBriefSectionVisible() const
{
static bool extractStatic = Config_getBool(EXTRACT_STATIC);
+ static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL);
static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
@@ -1365,9 +1367,12 @@ bool MemberDef::isBriefSectionVisible() const
);
// only include members that are non-private unless EXTRACT_PRIVATE is
- // set to YES or the member is part of a group
+ // set to YES or the member is part of a group. And as a special case,
+ // private *documented* virtual members are shown if EXTRACT_PRIVATE_VIRTUAL
+ // is set to YES
bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
- m_impl->mtype==MemberType_Friend
+ m_impl->mtype==MemberType_Friend ||
+ (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual && hasDocs)
);
// hide member if it overrides a member in a superclass and has no
@@ -1639,11 +1644,12 @@ void MemberDef::writeDeclaration(OutputList &ol,
if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
{
static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
+ static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL);
static bool extractStatic = Config_getBool(EXTRACT_STATIC);
//printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation());
if (!(name().isEmpty() || name().at(0)=='@') && // name valid
(hasDocumentation() || isReference()) && // has docs
- !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
+ !(m_impl->prot==Private && !extractPrivate && (m_impl->virt==Normal || !extractPrivateVirtual) && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
!(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness
)
{
@@ -1896,6 +1902,7 @@ bool MemberDef::isDetailedSectionLinkable() const
static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
static bool extractStatic = Config_getBool(EXTRACT_STATIC);
+ static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIVATE_VIRTUAL);
// the member has details documentation for any of the following reasons
bool docFilter =
@@ -1933,7 +1940,7 @@ bool MemberDef::isDetailedSectionLinkable() const
// only include members that are non-private unless EXTRACT_PRIVATE is
// set to YES or the member is part of a group
- bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend;
+ bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend || (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual);
// member is part of an anonymous scope that is the type of
// another member in the list.