summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <dimitri@stack.nl>2013-06-06 20:08:42 (GMT)
committerDimitri van Heesch <dimitri@stack.nl>2013-06-06 20:08:42 (GMT)
commita577a27e8da5de7b89b9ef39e9492502efd25eaa (patch)
tree217b92c9413e0697b20874f633df692c7fbd9b66
parent8295d3ffb8c112972fb13c2911b8a15e45498b6c (diff)
downloadDoxygen-a577a27e8da5de7b89b9ef39e9492502efd25eaa.zip
Doxygen-a577a27e8da5de7b89b9ef39e9492502efd25eaa.tar.gz
Doxygen-a577a27e8da5de7b89b9ef39e9492502efd25eaa.tar.bz2
Bug 700740 - Doxygen does not create links on C++ 11 style enum classes
-rw-r--r--src/code.l6
-rw-r--r--src/memberdef.cpp14
-rw-r--r--src/memberdef.h1
-rw-r--r--src/util.cpp155
4 files changed, 138 insertions, 38 deletions
diff --git a/src/code.l b/src/code.l
index 01636fa..d38f492 100644
--- a/src/code.l
+++ b/src/code.l
@@ -863,7 +863,7 @@ static bool getLinkInScope(const QCString &c, // scope
}
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
- md->getBodyDef() : md->getOuterScope();
+ md->getFileDef() : md->getOuterScope();
if (md->getGroupDef()) d = md->getGroupDef();
if (d && d->isLinkable())
{
@@ -1000,7 +1000,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName
if (md)
{
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
- md->getBodyDef() : md->getOuterScope();
+ md->getFileDef() : md->getOuterScope();
if (md->getGroupDef()) d = md->getGroupDef();
if (d && d->isLinkable() && md->isLinkable() && g_currentMemberDef)
{
@@ -1098,7 +1098,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const
g_theCallContext.setClass(typeClass);
Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
- xmd->getBodyDef() : xmd->getOuterScope();
+ xmd->getFileDef() : xmd->getOuterScope();
if (xmd->getGroupDef()) xd = xmd->getGroupDef();
if (xd && xd->isLinkable())
{
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index c5bf787..deed432 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -3795,6 +3795,12 @@ QCString MemberDef::qualifiedName() const
qm+="]";
return qm;
}
+ else if (m_impl->enumScope && m_impl->enumScope->isStrong())
+ {
+ return m_impl->enumScope->qualifiedName()+
+ getLanguageSpecificSeparator(getLanguage())+
+ localName();
+ }
else
{
return Definition::qualifiedName();
@@ -4139,6 +4145,13 @@ bool MemberDef::isStrong() const
return (m_impl->memSpec&Entry::Strong)!=0;
}
+bool MemberDef::isStrongEnumValue() const
+{
+ return m_impl->mtype==MemberType_EnumValue &&
+ m_impl->enumScope &&
+ m_impl->enumScope->isStrong();
+}
+
bool MemberDef::isUnretained() const
{
return (m_impl->memSpec&Entry::Unretained)!=0;
@@ -4845,4 +4858,3 @@ void combineDeclarationAndDefinition(MemberDef *mdec,MemberDef *mdef)
}
}
-
diff --git a/src/memberdef.h b/src/memberdef.h
index 8c88f7c..fc2bb44 100644
--- a/src/memberdef.h
+++ b/src/memberdef.h
@@ -169,6 +169,7 @@ class MemberDef : public Definition
bool hasMultiLineInitializer() const;
bool protectionVisible() const;
bool showInCallGraph() const;
+ bool isStrongEnumValue() const;
// output info
bool isLinkableInProject() const;
diff --git a/src/util.cpp b/src/util.cpp
index 0c36fc0..6ac1585 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -1873,20 +1873,24 @@ int findParameterList(const QString &name)
bool rightScopeMatch(const QCString &scope, const QCString &name)
{
+ int sl=scope.length();
+ int nl=name.length();
return (name==scope || // equal
- (scope.right(name.length())==name && // substring
- scope.at(scope.length()-name.length()-1)==':' // scope
- )
- );
+ (scope.right(nl)==name && // substring
+ sl-nl>1 && scope.at(sl-nl-1)==':' && scope.at(sl-nl-2)==':' // scope
+ )
+ );
}
bool leftScopeMatch(const QCString &scope, const QCString &name)
{
+ int sl=scope.length();
+ int nl=name.length();
return (name==scope || // equal
- (scope.left(name.length())==name && // substring
- scope.at(name.length())==':' // scope
- )
- );
+ (scope.left(nl)==name && // substring
+ sl>nl+1 && scope.at(nl)==':' && scope.at(nl+1)==':' // scope
+ )
+ );
}
@@ -3972,8 +3976,9 @@ bool getDefs(const QCString &scName,
className=mScope;
}
- ClassDef *fcd=getResolvedClass(Doxygen::globalScope,0,className);
- //printf("Trying class scope %s: %p\n",className.data(),fcd);
+ MemberDef *tmd=0;
+ ClassDef *fcd=getResolvedClass(Doxygen::globalScope,0,className,&tmd);
+ //printf("Trying class scope %s: fcd=%p tmd=%p\n",className.data(),fcd,tmd);
// todo: fill in correct fileScope!
if (fcd && // is it a documented class
fcd->isLinkable()
@@ -3991,30 +3996,30 @@ bool getDefs(const QCString &scName,
}
for (mmli.toFirst();(mmd=mmli.current());++mmli)
{
- //if (mmd->isLinkable())
- //{
- ArgumentList *mmdAl = mmd->argumentList();
- bool match=args==0 ||
- matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
- fcd,fcd->getFileDef(),argList,
- checkCV
- );
- //printf("match=%d\n",match);
- if (match)
+ if (!mmd->isStrongEnumValue())
{
- ClassDef *mcd=mmd->getClassDef();
- if (mcd)
+ ArgumentList *mmdAl = mmd->argumentList();
+ bool match=args==0 ||
+ matchArguments2(mmd->getOuterScope(),mmd->getFileDef(),mmdAl,
+ fcd,fcd->getFileDef(),argList,
+ checkCV
+ );
+ //printf("match=%d\n",match);
+ if (match)
{
- int m=minClassDistance(fcd,mcd);
- if (m<mdist && mcd->isLinkable())
+ ClassDef *mcd=mmd->getClassDef();
+ if (mcd)
{
- mdist=m;
- cd=mcd;
- md=mmd;
+ int m=minClassDistance(fcd,mcd);
+ if (m<mdist && mcd->isLinkable())
+ {
+ mdist=m;
+ cd=mcd;
+ md=mmd;
+ }
}
}
}
- //}
}
if (argList)
{
@@ -4047,7 +4052,7 @@ bool getDefs(const QCString &scName,
//printf(" >Succes=%d\n",mdist<maxInheritanceDepth);
if (mdist<maxInheritanceDepth)
{
- if (!md->isLinkable())
+ if (!md->isLinkable() || md->isStrongEnumValue())
{
md=0; // avoid returning things we cannot link to
cd=0;
@@ -4061,6 +4066,34 @@ bool getDefs(const QCString &scName,
}
}
}
+ if (tmd && tmd->isEnumerate() && tmd->isStrong()) // scoped enum
+ {
+ //printf("Found scoped enum!\n");
+ MemberList *tml = tmd->enumFieldList();
+ if (tml)
+ {
+ MemberListIterator tmi(*tml);
+ MemberDef *emd;
+ for (;(emd=tmi.current());++tmi)
+ {
+ if (emd->localName()==mName)
+ {
+ if (emd->isLinkable())
+ {
+ cd=tmd->getClassDef();
+ md=emd;
+ }
+ else
+ {
+ cd=0;
+ md=0;
+ }
+ //printf("result cd=%p md=%p\n",cd,md);
+ return TRUE;
+ }
+ }
+ }
+ }
/* go to the parent scope */
if (scopeOffset==0)
{
@@ -4075,6 +4108,7 @@ bool getDefs(const QCString &scName,
}
if (mn && scopeName.isEmpty() && mScope.isEmpty()) // Maybe a related function?
{
+ //printf("Global symbol\n");
MemberListIterator mmli(*mn);
MemberDef *mmd, *fuzzy_mmd = 0;
ArgumentList *argList = 0;
@@ -4108,7 +4142,7 @@ bool getDefs(const QCString &scName,
mmd = mmd ? mmd : fuzzy_mmd;
- if (mmd)
+ if (mmd && !mmd->isStrongEnumValue())
{
md = mmd;
cd = mmd->getClassDef();
@@ -4142,7 +4176,8 @@ bool getDefs(const QCString &scName,
fnd->isLinkable()
)
{
- //printf("Function inside existing namespace `%s'\n",namespaceName.data());
+ //printf("Symbol inside existing namespace `%s' count=%d\n",
+ // namespaceName.data(),mn->count());
bool found=FALSE;
MemberListIterator mmli(*mn);
MemberDef *mmd;
@@ -4150,7 +4185,26 @@ bool getDefs(const QCString &scName,
{
//printf("mmd->getNamespaceDef()=%p fnd=%p\n",
// mmd->getNamespaceDef(),fnd);
- if (mmd->getNamespaceDef()==fnd /* && mmd->isLinkable() */ )
+ MemberDef *emd = mmd->getEnumScope();
+ if (emd && emd->isStrong())
+ {
+ //printf("yes match %s<->%s!\n",mScope.data(),emd->localName().data());
+ if (emd->getNamespaceDef()==fnd &&
+ rightScopeMatch(mScope,emd->localName()))
+ {
+ //printf("found it!\n");
+ nd=fnd;
+ md=mmd;
+ found=TRUE;
+ }
+ else
+ {
+ md=0;
+ cd=0;
+ return FALSE;
+ }
+ }
+ else if (mmd->getNamespaceDef()==fnd /* && mmd->isLinkable() */ )
{ // namespace is found
bool match=TRUE;
ArgumentList *argList=0;
@@ -4206,6 +4260,35 @@ bool getDefs(const QCString &scName,
}
}
}
+ else
+ {
+ //printf("not a namespace\n");
+ bool found=FALSE;
+ MemberListIterator mmli(*mn);
+ MemberDef *mmd;
+ for (mmli.toFirst();((mmd=mmli.current()) && !found);++mmli)
+ {
+ MemberDef *tmd = mmd->getEnumScope();
+ //printf("try member %s tmd=%s\n",mmd->name().data(),tmd?tmd->name().data():"<none>");
+ int ni=namespaceName.findRev("::");
+ bool notInNS = tmd && ni==-1 && tmd->getNamespaceDef()==0;
+ bool sameNS = tmd && tmd->getNamespaceDef() && namespaceName.left(ni)==tmd->getNamespaceDef()->name();
+ //printf("notInNS=%d sameNS=%d\n",notInNS,sameNS);
+ if (tmd && tmd->isStrong() && // C++11 enum class
+ (notInNS || sameNS) &&
+ namespaceName.length()>0 // enum is part of namespace so this should not be empty
+ )
+ {
+ md=mmd;
+ fd=mmd->getFileDef();
+ gd=mmd->getGroupDef();
+ if (gd && gd->isLinkable()) fd=0; else gd=0;
+ //printf("Found scoped enum %s fd=%p gd=%p\n",
+ // mmd->name().data(),fd,gd);
+ return TRUE;
+ }
+ }
+ }
if (scopeOffset==0)
{
scopeOffset=-1;
@@ -4238,8 +4321,10 @@ bool getDefs(const QCString &scName,
//printf("member is linkable md->name()=`%s'\n",md->name().data());
fd=md->getFileDef();
gd=md->getGroupDef();
+ MemberDef *tmd = md->getEnumScope();
if (
- (gd && gd->isLinkable()) || (fd && fd->isLinkable())
+ (gd && gd->isLinkable()) || (fd && fd->isLinkable()) ||
+ (tmd && tmd->isStrong())
)
{
members.append(md);
@@ -4252,7 +4337,8 @@ bool getDefs(const QCString &scName,
{
md=members.last();
}
- if (md) // found a matching global member
+ if (md && (md->getEnumScope()==0 || !md->getEnumScope()->isStrong()))
+ // found a matching global member, that is not a scoped enum value (or uniquely matches)
{
fd=md->getFileDef();
gd=md->getGroupDef();
@@ -4466,6 +4552,7 @@ bool resolveRef(/* in */ const char *scName,
{
//printf("after getDefs checkScope=%d nameStr=%s cd=%p nd=%p\n",checkScope,nameStr.data(),cd,nd);
if (checkScope && md && md->getOuterScope()==Doxygen::globalScope &&
+ !md->isStrongEnumValue() &&
(!scopeStr.isEmpty() || nameStr.find("::")>0))
{
// we did find a member, but it is a global one while we were explicitly