summaryrefslogtreecommitdiffstats
path: root/trunk/src/memberdef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/memberdef.cpp')
-rw-r--r--trunk/src/memberdef.cpp4507
1 files changed, 4507 insertions, 0 deletions
diff --git a/trunk/src/memberdef.cpp b/trunk/src/memberdef.cpp
new file mode 100644
index 0000000..8ea32e0
--- /dev/null
+++ b/trunk/src/memberdef.cpp
@@ -0,0 +1,4507 @@
+/******************************************************************************
+ *
+ *
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <qglobal.h>
+#include <qregexp.h>
+#include <assert.h>
+#include "md5.h"
+#include "memberdef.h"
+#include "membername.h"
+#include "doxygen.h"
+#include "util.h"
+#include "code.h"
+#include "message.h"
+#include "htmlhelp.h"
+#include "language.h"
+#include "outputlist.h"
+#include "example.h"
+#include "membergroup.h"
+#include "groupdef.h"
+#include "defargs.h"
+#include "docparser.h"
+#include "dot.h"
+#include "searchindex.h"
+#include "parserintf.h"
+#include "marshal.h"
+#include "objcache.h"
+#include "vhdlscanner.h"
+#include "vhdldocgen.h"
+#include "arguments.h"
+
+#define START_MARKER 0x4D454D5B // MEM[
+#define END_MARKER 0x4D454D5D // MEM]
+
+#if defined(_OS_WIN32_)
+#define snprintf _snprintf
+#endif
+
+// Put this macro at the start of any method of MemberDef that can directly
+// or indirectly access other MemberDefs. It prevents that the content
+// pointed to by m_impl gets flushed to disk in the middle of the method call!
+#define KEEP_RESIDENT_DURING_CALL makeResident();LockingPtr<MemberDef> lock(this,this)
+
+//-----------------------------------------------------------------------------
+
+int MemberDef::s_indentLevel = 0;
+
+//-----------------------------------------------------------------------------
+
+static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
+{
+ QCString result;
+ QCString clRealName=n;
+ int p=0,i;
+ if ((i=clRealName.find('<'))!=-1)
+ {
+ clRealName=clRealName.left(i); // strip template specialization
+ }
+ if ((i=clRealName.findRev("::"))!=-1)
+ {
+ clRealName=clRealName.right(clRealName.length()-i-2);
+ }
+ while ((i=s.find(clRealName,p))!=-1)
+ {
+ result+=s.mid(p,i-p);
+ uint j=clRealName.length()+i;
+ if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
+ { // add template names
+ //printf("Adding %s+%s\n",clRealName.data(),t.data());
+ result+=clRealName+t;
+ }
+ else
+ { // template names already present
+ //printf("Adding %s\n",clRealName.data());
+ result+=clRealName;
+ }
+ p=i+clRealName.length();
+ }
+ result+=s.right(s.length()-p);
+ //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
+ return result;
+}
+
+static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
+ const QCString & /*scopeName*/,MemberDef *md)
+{
+ LockingPtr<ArgumentList> defArgList=(md->isDocsForDefinition()) ?
+ md->argumentList() : md->declArgumentList();
+ //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
+ if (defArgList==0 || md->isProperty())
+ {
+ return FALSE; // member has no function like argument list
+ }
+ if (!md->isDefine()) ol.docify(" ");
+
+ // simple argument list for tcl
+ if (md->getLanguage()==SrcLangExt_Tcl)
+ {
+ Argument *a=defArgList->first();
+ ol.startParameterName(FALSE);
+ while (a)
+ {
+ if (a->defval.isEmpty())
+ {
+ ol.docify(a->name+" ");
+ }
+ else
+ {
+ ol.docify("?"+a->name+"? ");
+ }
+ a=defArgList->next();
+ }
+ ol.endParameterName(FALSE,FALSE,FALSE);
+ ol.endMemberDocName();
+ return TRUE;
+ }
+
+ //printf("writeDefArgList(%d)\n",defArgList->count());
+ ol.pushGeneratorState();
+ //ol.disableAllBut(OutputGenerator::Html);
+ bool htmlOn = ol.isEnabled(OutputGenerator::Html);
+ bool latexOn = ol.isEnabled(OutputGenerator::Latex);
+ {
+ // html and latex
+ if (htmlOn) ol.enable(OutputGenerator::Html);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+
+ ol.endMemberDocName();
+ ol.startParameterList(!md->isObjCMethod());
+ }
+ ol.enableAll();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Latex);
+ {
+ // other formats
+ if (!md->isObjCMethod()) ol.docify("("); // start argument list
+ ol.endMemberDocName();
+ }
+ ol.popGeneratorState();
+ //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
+
+ Argument *a=defArgList->first();
+ QCString cName;
+ if (cd)
+ {
+ cName=cd->name();
+ int il=cName.find('<');
+ int ir=cName.findRev('>');
+ if (il!=-1 && ir!=-1 && ir>il)
+ {
+ cName=cName.mid(il,ir-il+1);
+ //printf("1. cName=%s\n",cName.data());
+ }
+ else if (cd->templateArguments())
+ {
+ cName=tempArgListToString(cd->templateArguments());
+ //printf("2. cName=%s\n",cName.data());
+ }
+ else // no template specifier
+ {
+ cName.resize(0);
+ }
+ }
+ //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
+
+ bool first=TRUE;
+ bool paramTypeStarted=FALSE;
+ bool isDefine = md->isDefine();
+ while (a)
+ {
+ if (isDefine || first)
+ {
+ ol.startParameterType(first,0);
+ paramTypeStarted=TRUE;
+ if (isDefine)
+ {
+ ol.endParameterType();
+ ol.startParameterName(TRUE);
+ }
+ }
+ QRegExp re(")("),res("(.*\\*");
+ int vp=a->type.find(re);
+ int wp=a->type.find(res);
+
+ // use the following to put the function pointer type before the name
+ bool hasFuncPtrType=FALSE;
+
+ if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
+ {
+ ol.docify(a->attrib+" ");
+ }
+ if (hasFuncPtrType) // argument type is a function pointer
+ {
+ //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
+ QCString n=a->type.left(vp);
+ if (hasFuncPtrType) n=a->type.left(wp);
+ if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
+ }
+ else // non-function pointer type
+ {
+ QCString n=a->type;
+ if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
+ if (a->type!="...")
+ {
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
+ }
+ }
+ if (!isDefine)
+ {
+ if (paramTypeStarted)
+ {
+ ol.endParameterType();
+ paramTypeStarted=FALSE;
+ }
+ ol.startParameterName(defArgList->count()<2);
+ }
+ if (hasFuncPtrType)
+ {
+ ol.docify(a->type.mid(wp,vp-wp));
+ }
+ if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name
+ {
+ //if (!hasFuncPtrType)
+ //{
+ // ol.docify(" ");
+ //}
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.startEmphasis();
+ ol.enable(OutputGenerator::Man);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.endEmphasis();
+ ol.enable(OutputGenerator::Man);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ }
+ if (!a->array.isEmpty())
+ {
+ ol.docify(a->array);
+ }
+ if (hasFuncPtrType) // write the part of the argument type
+ // that comes after the name
+ {
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),
+ md->name(),a->type.right(a->type.length()-vp));
+ }
+ if (!a->defval.isEmpty()) // write the default value
+ {
+ QCString n=a->defval;
+ if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
+ ol.docify(" = ");
+
+ ol.startTypewriter();
+ linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n,FALSE,TRUE,TRUE);
+ ol.endTypewriter();
+
+ }
+ a=defArgList->next();
+ if (a)
+ {
+ if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
+ if (!isDefine)
+ {
+ QCString key;
+ if (md->isObjCMethod() && a->attrib.length()>=2)
+ {
+ //printf("Found parameter keyword %s\n",a->attrib.data());
+ // strip [ and ]
+ key=a->attrib.mid(1,a->attrib.length()-2);
+ if (key!=",") key+=":"; // for normal keywords add colon
+ }
+ ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
+ if (paramTypeStarted)
+ {
+ ol.endParameterType();
+ }
+ ol.startParameterType(FALSE,key);
+ paramTypeStarted=TRUE;
+ }
+ else // isDefine
+ {
+ ol.endParameterName(FALSE,FALSE,TRUE);
+ }
+ }
+ first=FALSE;
+ }
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Latex);
+ if (!md->isObjCMethod()) ol.docify(")"); // end argument list
+ ol.enableAll();
+ if (htmlOn) ol.enable(OutputGenerator::Html);
+ if (latexOn) ol.enable(OutputGenerator::Latex);
+ if (first) ol.startParameterName(defArgList->count()<2);
+ ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
+ ol.popGeneratorState();
+ if (md->extraTypeChars())
+ {
+ ol.docify(md->extraTypeChars());
+ }
+ if (defArgList->constSpecifier)
+ {
+ ol.docify(" const");
+ }
+ if (defArgList->volatileSpecifier)
+ {
+ ol.docify(" volatile");
+ }
+ return TRUE;
+}
+
+static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
+{
+ ol.docify("template<");
+ Argument *a=al->first();
+ while (a)
+ {
+ ol.docify(a->type);
+ ol.docify(" ");
+ ol.docify(a->name);
+ if (a->defval.length()!=0)
+ {
+ ol.docify(" = ");
+ ol.docify(a->defval);
+ }
+ a=al->next();
+ if (a) ol.docify(", ");
+ }
+ ol.docify("> ");
+}
+
+QCString extractDirection(QCString &docs)
+{
+ QRegExp re("\\[[^\\]]+\\]"); // [...]
+ int l=0;
+ if (re.match(docs,0,&l)==0)
+ {
+ int inPos = docs.find("in", 1,FALSE);
+ int outPos = docs.find("out",1,FALSE);
+ bool input = inPos!=-1 && inPos<l;
+ bool output = outPos!=-1 && outPos<l;
+ if (input || output) // in,out attributes
+ {
+ docs = docs.mid(l); // strip attributes
+ if (input && output) return "[in,out]";
+ else if (input) return "[in]";
+ else if (output) return "[out]";
+ }
+ }
+ return QCString();
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+class MemberDefImpl
+{
+ public:
+ MemberDefImpl();
+ ~MemberDefImpl();
+ void init(Definition *def,const char *t,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,
+ MemberDef::MemberType mt,const ArgumentList *tal,
+ const ArgumentList *al
+ );
+
+ ClassDef *classDef; // member of or related to
+ FileDef *fileDef; // member of file definition
+ NamespaceDef *nspace; // the namespace this member is in.
+
+ MemberDef *enumScope; // the enclosing scope, if this is an enum field
+ MemberDef *annEnumType; // the anonymous enum that is the type of this member
+ MemberList *enumFields; // enumeration fields
+
+ MemberDef *redefines; // the members that this member redefines
+ MemberList *redefinedBy; // the list of members that redefine this one
+
+ MemberDef *memDef; // member definition for this declaration
+ MemberDef *memDec; // member declaration for this definition
+ ClassDef *relatedAlso; // points to class marked by relatedAlso
+
+ ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
+
+ QCString type; // return type
+ QCString args; // function arguments/variable array specifiers
+ QCString def; // member definition in code (fully qualified name)
+ QCString anc; // HTML anchor name
+ Specifier virt; // normal/virtual/pure virtual
+ Protection prot; // protection type [Public/Protected/Private]
+ QCString decl; // member declaration in class
+
+ QCString bitfields; // struct member bitfields
+ QCString read; // property read accessor
+ QCString write; // property write accessor
+ QCString exception; // exceptions that can be thrown
+ QCString initializer; // initializer
+ QCString extraTypeChars; // extra type info found after the argument list
+ int initLines; // number of lines in the initializer
+
+ int memSpec; // The specifiers present for this member
+ MemberDef::MemberType mtype; // returns the kind of member
+ int maxInitLines; // when the initializer will be displayed
+ int userInitLines; // result of explicit \hideinitializer or \showinitializer
+ MemberDef *annMemb;
+
+ ArgumentList *defArgList; // argument list of this member definition
+ ArgumentList *declArgList; // argument list of this member declaration
+
+ ArgumentList *tArgList; // template argument list of function template
+ ArgumentList *typeConstraints; // type constraints for template parameters
+ MemberDef *templateMaster;
+ QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
+ // (for template functions in nested template classes)
+
+ ClassDef *cachedAnonymousType; // if the member has an anonymous compound
+ // as its type then this is computed by
+ // getClassDefOfAnonymousType() and
+ // cached here.
+ SDict<MemberList> *classSectionSDict; // not accessible
+
+ MemberDef *groupAlias; // Member containing the definition
+ int grpId; // group id
+ MemberGroup *memberGroup; // group's member definition
+ GroupDef *group; // group in which this member is in
+ Grouping::GroupPri_t grouppri; // priority of this definition
+ QCString groupFileName; // file where this grouping was defined
+ int groupStartLine; // line " " " " "
+ MemberDef *groupMember;
+
+ bool isTypedefValCached;
+ ClassDef *cachedTypedefValue;
+ QCString cachedTypedefTemplSpec;
+ QCString cachedResolvedType;
+
+ // inbody documentation
+ //int inbodyLine;
+ //QCString inbodyFile;
+ //QCString inbodyDocs;
+
+ // documentation inheritance
+ MemberDef *docProvider;
+
+ // to store the output file base from tag files
+ QCString explicitOutputFileBase;
+
+ // objective-c
+ bool implOnly; // function found in implementation but not
+ // in the interface
+ bool hasDocumentedParams;
+ bool hasDocumentedReturnType;
+ bool isDMember;
+ Relationship related; // relationship of this to the class
+ bool stat; // is it a static function?
+ bool proto; // is it a prototype;
+ bool docEnumValues; // is an enum with documented enum values.
+ bool annScope; // member is part of an annoymous scope
+ bool annUsed;
+ bool hasCallGraph;
+ bool hasCallerGraph;
+ bool explExt; // member was explicitly declared external
+ bool tspec; // member is a template specialization
+ bool groupHasDocs; // true if the entry that caused the grouping was documented
+ bool docsForDefinition; // TRUE => documentation block is put before
+ // definition.
+ // FALSE => block is put before declaration.
+ ClassDef *category;
+};
+
+MemberDefImpl::MemberDefImpl() :
+ enumFields(0),
+ redefinedBy(0),
+ exampleSDict(0),
+ defArgList(0),
+ declArgList(0),
+ tArgList(0),
+ typeConstraints(0),
+ defTmpArgLists(0),
+ classSectionSDict(0),
+ category(0)
+{
+}
+
+MemberDefImpl::~MemberDefImpl()
+{
+ delete redefinedBy;
+ delete exampleSDict;
+ delete enumFields;
+ delete defArgList;
+ delete tArgList;
+ delete typeConstraints;
+ delete defTmpArgLists;
+ delete classSectionSDict;
+ delete declArgList;
+}
+
+void MemberDefImpl::init(Definition *def,
+ const char *t,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,
+ MemberDef::MemberType mt,const ArgumentList *tal,
+ const ArgumentList *al
+ )
+{
+ classDef=0;
+ fileDef=0;
+ redefines=0;
+ relatedAlso=0;
+ redefinedBy=0;
+ nspace=0;
+ memDef=0;
+ memDec=0;
+ group=0;
+ grpId=-1;
+ exampleSDict=0;
+ enumFields=0;
+ enumScope=0;
+ defTmpArgLists=0;
+ hasCallGraph = FALSE;
+ hasCallerGraph = FALSE;
+ initLines=0;
+ type=t;
+ if (mt==MemberDef::Typedef) type.stripPrefix("typedef ");
+ // type.stripPrefix("struct ");
+ // type.stripPrefix("class " );
+ // type.stripPrefix("union " );
+ type=removeRedundantWhiteSpace(type);
+ args=a;
+ args=removeRedundantWhiteSpace(args);
+ if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
+
+ memberGroup=0;
+ virt=v;
+ prot=p;
+ related=r;
+ stat=s;
+ mtype=mt;
+ exception=e;
+ proto=FALSE;
+ annScope=FALSE;
+ memSpec=0;
+ annMemb=0;
+ annUsed=FALSE;
+ annEnumType=0;
+ groupAlias=0;
+ explExt=FALSE;
+ tspec=FALSE;
+ cachedAnonymousType=0;
+ maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
+ userInitLines=-1;
+ docEnumValues=FALSE;
+ // copy function template arguments (if any)
+ if (tal)
+ {
+ tArgList = new ArgumentList;
+ tArgList->setAutoDelete(TRUE);
+ ArgumentListIterator ali(*tal);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ tArgList->append(new Argument(*a));
+ }
+ }
+ else
+ {
+ tArgList=0;
+ }
+ //printf("new member al=%p\n",al);
+ // copy function definition arguments (if any)
+ if (al)
+ {
+ defArgList = new ArgumentList;
+ defArgList->setAutoDelete(TRUE);
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data());
+ defArgList->append(new Argument(*a));
+ }
+ defArgList->constSpecifier = al->constSpecifier;
+ defArgList->volatileSpecifier = al->volatileSpecifier;
+ defArgList->pureSpecifier = al->pureSpecifier;
+ //printf("defArgList(%p)->constSpecifier=%d\n",defArgList,defArgList->constSpecifier);
+ }
+ else
+ {
+ defArgList=0;
+ }
+ // convert function declaration arguments (if any)
+ if (!args.isEmpty())
+ {
+ declArgList = new ArgumentList;
+ stringToArgumentList(args,declArgList,&extraTypeChars);
+ //printf("setDeclArgList %s to %s const=%d\n",args.data(),
+ // argListToString(declArgList).data(),declArgList->constSpecifier);
+ }
+ else
+ {
+ declArgList = 0;
+ }
+ templateMaster = 0;
+ classSectionSDict = 0;
+ docsForDefinition = TRUE;
+ isTypedefValCached = FALSE;
+ cachedTypedefValue = 0;
+ //inbodyLine = -1;
+ implOnly=FALSE;
+ groupMember = 0;
+ hasDocumentedParams = FALSE;
+ hasDocumentedReturnType = FALSE;
+ docProvider = 0;
+ isDMember = def->getDefFileName().right(2).lower()==".d";
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+/*! Creates a new member definition.
+ *
+ * \param df File containing the definition of this member.
+ * \param dl Line at which the member definition was found.
+ * \param t A string representing the type of the member.
+ * \param na A string representing the name of the member.
+ * \param a A string representing the arguments of the member.
+ * \param e A string representing the throw clause of the members.
+ * \param p The protection context of the member, possible values are:
+ * \c Public, \c Protected, \c Private.
+ * \param v The degree of `virtualness' of the member, possible values are:
+ * \c Normal, \c Virtual, \c Pure.
+ * \param s A boolean that is true iff the member is static.
+ * \param r The relationship between the class and the member.
+ * \param mt The kind of member. See #MemberDef::MemberType for a list of
+ * all types.
+ * \param tal The template arguments of this member.
+ * \param al The arguments of this member. This is a structured form of
+ * the string past as argument \a a.
+ */
+
+MemberDef::MemberDef(const char *df,int dl,
+ const char *t,const char *na,const char *a,const char *e,
+ Protection p,Specifier v,bool s,Relationship r,MemberType mt,
+ const ArgumentList *tal,const ArgumentList *al
+ ) : Definition(df,dl,removeRedundantWhiteSpace(na))
+{
+ //printf("MemberDef::MemberDef(%s)\n",na);
+ m_storagePos=-1;
+ m_cacheHandle=-1;
+ m_impl = new MemberDefImpl;
+ m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
+ m_flushPending = FALSE;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ m_isDestructorCached = 0;
+}
+
+void MemberDef::moveTo(Definition *scope)
+{
+ setOuterScope(scope);
+ if (scope->definitionType()==Definition::TypeClass)
+ {
+ m_impl->classDef = (ClassDef*)scope;
+ }
+ else if (scope->definitionType()==Definition::TypeFile)
+ {
+ m_impl->fileDef = (FileDef*)scope;
+ }
+ else if (scope->definitionType()==Definition::TypeNamespace)
+ {
+ m_impl->nspace = (NamespaceDef*)scope;
+ }
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+}
+
+
+/*! Destroys the member definition. */
+MemberDef::~MemberDef()
+{
+ delete m_impl;
+ //printf("%p: ~MemberDef()\n",this);
+ m_impl=0;
+ if (m_cacheHandle!=-1)
+ {
+ Doxygen::symbolCache->del(m_cacheHandle);
+ m_cacheHandle=-1;
+ }
+}
+
+void MemberDef::setReimplements(MemberDef *md)
+{
+ makeResident();
+ //if (redefines==0) redefines = new MemberList;
+ //if (redefines->find(md)==-1) redefines->inSort(md);
+
+ m_impl->redefines = md;
+}
+
+void MemberDef::insertReimplementedBy(MemberDef *md)
+{
+ makeResident();
+ if (m_impl->templateMaster)
+ {
+ m_impl->templateMaster->insertReimplementedBy(md);
+ }
+ if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberList::redefinedBy);
+ if (m_impl->redefinedBy->findRef(md)==-1)
+ {
+ m_impl->redefinedBy->inSort(md);
+ }
+}
+
+MemberDef *MemberDef::reimplements() const
+{
+ makeResident();
+ return m_impl->redefines;
+}
+
+LockingPtr<MemberList> MemberDef::reimplementedBy() const
+{
+ makeResident();
+ return LockingPtr<MemberList>(this,m_impl->redefinedBy);
+}
+
+void MemberDef::insertEnumField(MemberDef *md)
+{
+ makeResident();
+ if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberList::enumFields);
+ m_impl->enumFields->append(md);
+}
+
+bool MemberDef::addExample(const char *anchor,const char *nameStr,
+ const char *file)
+{
+ makeResident();
+ //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
+ if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
+ if (m_impl->exampleSDict->find(nameStr)==0)
+ {
+ //printf("Add reference to example %s to member %s\n",nameStr,name.data());
+ Example *e=new Example;
+ e->anchor=anchor;
+ e->name=nameStr;
+ e->file=file;
+ m_impl->exampleSDict->inSort(nameStr,e);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+bool MemberDef::hasExamples()
+{
+ makeResident();
+ if (m_impl->exampleSDict==0)
+ return FALSE;
+ else
+ return m_impl->exampleSDict->count()>0;
+}
+
+QCString MemberDef::getOutputFileBase() const
+{
+ makeResident();
+ static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ QCString baseName;
+ //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
+ // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
+ // m_impl->nspace,m_impl->fileDef);
+ if (!m_impl->explicitOutputFileBase.isEmpty())
+ {
+ return m_impl->explicitOutputFileBase;
+ }
+ else if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (m_impl->group)
+ {
+ baseName=m_impl->group->getOutputFileBase();
+ }
+ else if (m_impl->classDef)
+ {
+ baseName=m_impl->classDef->getOutputFileBase();
+ }
+ else if (m_impl->nspace)
+ {
+ baseName=m_impl->nspace->getOutputFileBase();
+ }
+ else if (m_impl->fileDef)
+ {
+ baseName=m_impl->fileDef->getOutputFileBase();
+ }
+
+ if (baseName.isEmpty())
+ {
+ warn(getDefFileName(),getDefLine(),
+ "warning: Internal inconsistency: member %s does not belong to any"
+ " container!",qPrint(name())
+ );
+ return "dummy";
+ }
+ else if (separateMemberPages)
+ {
+ if (getEnumScope()) // enum value, which is part of enum's documentation
+ {
+ baseName+="_"+getEnumScope()->anchor();
+ }
+ else
+ {
+ baseName+="_"+anchor();
+ }
+ }
+ return baseName;
+}
+
+QCString MemberDef::getReference() const
+{
+ makeResident();
+ QCString ref = Definition::getReference();
+ if (!ref.isEmpty())
+ {
+ return ref;
+ }
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getReference();
+ }
+ else if (m_impl->group)
+ {
+ return m_impl->group->getReference();
+ }
+ else if (m_impl->classDef)
+ {
+ return m_impl->classDef->getReference();
+ }
+ else if (m_impl->nspace)
+ {
+ return m_impl->nspace->getReference();
+ }
+ else if (m_impl->fileDef)
+ {
+ return m_impl->fileDef->getReference();
+ }
+ return "";
+}
+
+QCString MemberDef::anchor() const
+{
+ KEEP_RESIDENT_DURING_CALL;
+ QCString result=m_impl->anc;
+ if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
+ if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
+ if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
+ {
+ result.prepend(m_impl->enumScope->anchor());
+ }
+ if (m_impl->group)
+ {
+ if (m_impl->groupMember)
+ {
+ result=m_impl->groupMember->anchor();
+ }
+ else if (getReference().isEmpty())
+ {
+ result.prepend("g");
+ }
+ }
+ return result;
+}
+
+void MemberDef::_computeLinkableInProject()
+{
+ KEEP_RESIDENT_DURING_CALL;
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ m_isLinkableCached = 2; // linkable
+ //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
+ if (isHidden())
+ {
+ //printf("is hidden\n");
+ m_isLinkableCached = 1;
+ return;
+ }
+ if (m_impl->templateMaster)
+ {
+ //printf("has template master\n");
+ m_isLinkableCached = m_impl->templateMaster->isLinkableInProject() ? 2 : 1;
+ }
+ if (name().isEmpty() || name().at(0)=='@')
+ {
+ //printf("name invalid\n");
+ m_isLinkableCached = 1; // not a valid or a dummy name
+ return;
+ }
+ if (!hasDocumentation() && !isReference())
+ {
+ //printf("no docs or reference\n");
+ m_isLinkableCached = 1; // no documentation
+ return;
+ }
+ if (m_impl->group && !m_impl->group->isLinkableInProject())
+ {
+ //printf("group but group not linkable!\n");
+ m_isLinkableCached = 1; // group but group not linkable
+ return;
+ }
+ if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject())
+ {
+ //printf("in a class but class not linkable!\n");
+ m_isLinkableCached = 1; // in class but class not linkable
+ return;
+ }
+ if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject())
+ {
+ //printf("in a namespace but namespace not linkable!\n");
+ m_isLinkableCached = 1; // in namespace but namespace not linkable
+ return;
+ }
+ if (!m_impl->group && !m_impl->nspace &&
+ !m_impl->related && !m_impl->classDef &&
+ m_impl->fileDef && !m_impl->fileDef->isLinkableInProject())
+ {
+ //printf("in a file but file not linkable!\n");
+ m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
+ return;
+ }
+ if (!protectionLevelVisible(m_impl->prot) && m_impl->mtype!=Friend)
+ {
+ //printf("private and invisible!\n");
+ m_isLinkableCached = 1; // hidden due to protection
+ return;
+ }
+ if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
+ {
+ //printf("static and invisible!\n");
+ m_isLinkableCached = 1; // hidden due to staticness
+ return;
+ }
+ //printf("linkable!\n");
+ return; // linkable!
+}
+
+void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
+{
+ makeResident();
+ Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
+{
+ makeResident();
+ Definition::setBriefDescription(b,briefFile,briefLine);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
+{
+ makeResident();
+ Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setHidden(bool b)
+{
+ makeResident();
+ Definition::setHidden(b);
+ m_isLinkableCached = 0;
+}
+
+bool MemberDef::isLinkableInProject() const
+{
+ if (m_isLinkableCached==0)
+ {
+ MemberDef *that = (MemberDef*)this;
+ that->_computeLinkableInProject();
+ }
+ ASSERT(m_isLinkableCached>0);
+ return m_isLinkableCached==2;
+}
+
+bool MemberDef::isLinkable() const
+{
+ makeResident();
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkable();
+ }
+ else
+ {
+ return isLinkableInProject() || isReference();
+ }
+}
+
+
+void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
+{
+ if (lists)
+ {
+ makeResident();
+ if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
+ m_impl->defTmpArgLists = copyArgumentLists(lists);
+ }
+}
+
+void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
+ FileDef *fd,GroupDef *gd,bool onlyText)
+{
+ KEEP_RESIDENT_DURING_CALL;
+ SrcLangExt lang = getLanguage();
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ QCString n = name();
+ if (!hideScopeNames)
+ {
+ if (m_impl->classDef && gd && !isRelated())
+ {
+ n.prepend(m_impl->classDef->displayName()+sep);
+ }
+ else if (m_impl->nspace && (gd || fd))
+ {
+ n.prepend(m_impl->nspace->displayName()+sep);
+ }
+ }
+
+ if (isObjCMethod())
+ {
+ if (isStatic()) ol.docify("+ "); else ol.docify("- ");
+ }
+ if (!onlyText && isLinkable()) // write link
+ {
+ if (m_impl->mtype==EnumValue && getGroupDef()==0 && // enum value is not grouped
+ getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
+ {
+ GroupDef *enumValGroup = getEnumScope()->getGroupDef();
+ ol.writeObjectLink(enumValGroup->getReference(),
+ enumValGroup->getOutputFileBase(),
+ anchor(),n);
+ }
+ else
+ {
+ ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
+ }
+ }
+ else // write only text
+ {
+ ol.startBold();
+ ol.docify(n);
+ ol.endBold();
+ }
+}
+
+/*! If this member has an anonymous class/struct/union as its type, then
+ * this method will return the ClassDef that describes this return type.
+ */
+ClassDef *MemberDef::getClassDefOfAnonymousType()
+{
+ // split KEEP_RESIDENT_DURING_CALL for performance
+ makeResident();
+ if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
+ LockingPtr<MemberDef> lock(this,this); // since this memberDef can access
+ // other memberDefs prevent it from
+ // being flushed to disk halfway
+
+ QCString cname;
+ if (getClassDef()!=0)
+ {
+ cname=getClassDef()->name().copy();
+ }
+ else if (getNamespaceDef()!=0)
+ {
+ cname=getNamespaceDef()->name().copy();
+ }
+ QCString ltype(m_impl->type);
+ // strip `static' keyword from ltype
+ //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
+ // strip `friend' keyword from ltype
+ ltype.stripPrefix("friend ");
+ static QRegExp r("@[0-9]+");
+ int l,i=r.match(ltype,0,&l);
+ //printf("ltype=`%s' i=%d\n",ltype.data(),i);
+ // search for the last anonymous scope in the member type
+ ClassDef *annoClassDef=0;
+ if (i!=-1) // found anonymous scope in type
+ {
+ int il=i-1,ir=i+l;
+ // extract anonymous scope
+ while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
+ if (il>0) il++; else if (il<0) il=0;
+ while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
+
+ QCString annName = ltype.mid(il,ir-il);
+
+ // if inside a class or namespace try to prepend the scope name
+ if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
+ {
+ QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
+ //printf("Member::writeDeclaration: Trying %s\n",ts.data());
+ annoClassDef=getClass(ts);
+ }
+ // if not found yet, try without scope name
+ if (annoClassDef==0)
+ {
+ QCString ts=stripAnonymousNamespaceScope(annName);
+ //printf("Member::writeDeclaration: Trying %s\n",ts.data());
+ annoClassDef=getClass(ts);
+ }
+ }
+ m_impl->cachedAnonymousType = annoClassDef;
+ return annoClassDef;
+}
+
+/*! This methods returns TRUE iff the brief section (also known as
+ * declaration section) is visible in the documentation.
+ */
+bool MemberDef::isBriefSectionVisible() const
+{
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
+
+ //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
+ // name().data(),
+ // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
+ // "", //getFileDef()->name().data(),
+ // argsString());
+
+ KEEP_RESIDENT_DURING_CALL;
+
+ MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
+ //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
+ //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
+ bool hasDocs = hasDocumentation() ||
+ // part of a documented member group
+ (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
+
+ // only include static members with file/namespace scope if
+ // explicitly enabled in the config file
+ bool visibleIfStatic = !(getClassDef()==0 &&
+ isStatic() &&
+ !extractStatic
+ );
+
+ // only include members is the are documented or
+ // HIDE_UNDOC_MEMBERS is NO in the config file
+ bool visibleIfDocumented = (!hideUndocMembers ||
+ hasDocs ||
+ isDocumentedFriendClass()
+ );
+
+ // hide members with no detailed description and brief descriptions
+ // explicitly disabled.
+ bool visibleIfEnabled = !(hideUndocMembers &&
+ documentation().isEmpty() &&
+ !briefMemberDesc &&
+ !repeatBrief
+ );
+
+ // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
+ bool visibleIfFriendCompound = !(hideFriendCompounds &&
+ isFriend() &&
+ (m_impl->type=="friend class" ||
+ m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"
+ )
+ );
+
+ // only include members that are non-private unless EXTRACT_PRIVATE is
+ // set to YES or the member is part of a group
+ bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
+ m_impl->mtype==Friend
+ );
+
+ // hide member if it overrides a member in a superclass and has no
+ // documentation of its own
+ //bool visibleIfDocVirtual = !reimplements() ||
+ // !Config_getBool("INHERIT_DOCS") ||
+ // hasDocs;
+
+ // true if this member is a constructor or destructor
+ bool cOrDTor = isConstructor() || isDestructor();
+
+ // hide default constructors or destructors (no args) without
+ // documentation
+ bool visibleIfNotDefaultCDTor = !(cOrDTor &&
+ m_impl->defArgList &&
+ (m_impl->defArgList->isEmpty() ||
+ m_impl->defArgList->first()->type == "void"
+ ) &&
+ !hasDocs
+ );
+
+
+ //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
+ // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
+ // "visibleIfFriendCompound=%d !annScope=%d\n",
+ // visibleIfStatic,visibleIfDocumented,
+ // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
+ // visibleIfFriendCompound,!m_impl->annScope);
+
+ bool visible = visibleIfStatic && visibleIfDocumented &&
+ visibleIfEnabled && visibleIfPrivate &&
+ /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
+ visibleIfFriendCompound &&
+ !m_impl->annScope && !isHidden();
+ //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
+ return visible;
+}
+
+
+void MemberDef::writeDeclaration(OutputList &ol,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
+ bool inGroup
+ )
+{
+ //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",name().data(),inGroup);
+
+ // hide enum value, since they appear already as part of the enum, unless they
+ // are explicitly grouped.
+ KEEP_RESIDENT_DURING_CALL;
+ if (!inGroup && m_impl->mtype==EnumValue) return;
+
+ // hide members whose brief section should not be visible
+ //if (!isBriefSectionVisible()) return;
+
+ Definition *d=0;
+ ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
+ if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
+
+ // write tag file information of this member
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
+ {
+ Doxygen::tagFile << " <member kind=\"";
+ switch (m_impl->mtype)
+ {
+ case Define: Doxygen::tagFile << "define"; break;
+ case EnumValue: Doxygen::tagFile << "enumvalue"; break;
+ case Property: Doxygen::tagFile << "property"; break;
+ case Event: Doxygen::tagFile << "event"; break;
+ case Variable: Doxygen::tagFile << "variable"; break;
+ case Typedef: Doxygen::tagFile << "typedef"; break;
+ case Enumeration: Doxygen::tagFile << "enumeration"; break;
+ case Function: Doxygen::tagFile << "function"; break;
+ case Signal: Doxygen::tagFile << "signal"; break;
+ //case Prototype: Doxygen::tagFile << "prototype"; break;
+ case Friend: Doxygen::tagFile << "friend"; break;
+ case DCOP: Doxygen::tagFile << "dcop"; break;
+ case Slot: Doxygen::tagFile << "slot"; break;
+ }
+ if (m_impl->prot!=Public)
+ {
+ Doxygen::tagFile << "\" protection=\"";
+ if (m_impl->prot==Protected) Doxygen::tagFile << "protected";
+ else if (m_impl->prot==Package) Doxygen::tagFile << "package";
+ else /* Private */ Doxygen::tagFile << "private";
+ }
+ if (m_impl->virt!=Normal)
+ {
+ Doxygen::tagFile << "\" virtualness=\"";
+ if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual";
+ else /* Pure */ Doxygen::tagFile << "pure";
+ }
+ if (isStatic())
+ {
+ Doxygen::tagFile << "\" static=\"yes";
+ }
+ Doxygen::tagFile << "\">" << endl;
+ Doxygen::tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
+ Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
+ Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </member>" << endl;
+ }
+
+ // write search index info
+ if (Doxygen::searchIndex && isLinkableInProject())
+ {
+ Doxygen::searchIndex->setCurrentDoc(qualifiedName(),getOutputFileBase(),anchor());
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ Doxygen::searchIndex->addWord(qualifiedName(),FALSE);
+ }
+
+ QCString cname = d->name();
+ QCString cdname = d->displayName();
+ QCString cfname = getOutputFileBase();
+ //QCString osname = cname;
+ // in case of class members that are put in a group the name of the outerscope
+ // differs from the cname.
+ //if (getOuterScope()) osname=getOuterScope()->name();
+
+ //HtmlHelp *htmlHelp=0;
+ //bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
+ //if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
+
+ // search for the last anonymous scope in the member type
+ ClassDef *annoClassDef=getClassDefOfAnonymousType();
+
+ // start a new member declaration
+ bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
+ ///printf("startMemberItem for %s\n",name().data());
+ ol.startMemberItem( anchor(), isAnonymous ? 1 : m_impl->tArgList ? 3 : 0);
+
+ // If there is no detailed description we need to write the anchor here.
+ bool detailsVisible = isDetailedSectionLinkable();
+ if (!detailsVisible && !m_impl->annMemb)
+ {
+ QCString doxyName=name().copy();
+ if (!cname.isEmpty())
+ {
+ doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
+ }
+ QCString doxyArgs=argsString();
+ ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
+
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.disable(OutputGenerator::Latex);
+ ol.docify("\n");
+ ol.popGeneratorState();
+ }
+
+ if (annoClassDef || m_impl->annMemb)
+ {
+ int j;
+ for (j=0;j<s_indentLevel;j++)
+ {
+ ol.writeNonBreakableSpace(3);
+ }
+ }
+
+ // *** write template lists
+ if (m_impl->tArgList)
+ {
+ if (!isAnonymous) ol.startMemberTemplateParams();
+ writeTemplatePrefix(ol,m_impl->tArgList);
+ if (!isAnonymous) ol.endMemberTemplateParams(anchor());
+ }
+
+ // *** write type
+ QCString ltype(m_impl->type);
+ if (m_impl->mtype==Typedef) ltype.prepend("typedef ");
+ // strip `friend' keyword from ltype
+ ltype.stripPrefix("friend ");
+ static QRegExp r("@[0-9]+");
+
+ bool endAnonScopeNeeded=FALSE;
+ int l,i=r.match(ltype,0,&l);
+ if (i!=-1) // member has an anonymous type
+ {
+ //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
+ // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
+
+ if (annoClassDef) // type is an anonymous compound
+ {
+ int ir=i+l;
+ //printf("<<<<<<<<<<<<<<\n");
+ ol.startAnonTypeScope(s_indentLevel++);
+ annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup);
+ //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
+ ol.startMemberItem(anchor(),2);
+ int j;
+ for (j=0;j< s_indentLevel-1;j++)
+ {
+ ol.writeNonBreakableSpace(3);
+ }
+ QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
+ //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data());
+ ol.docify("}");
+ if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
+ {
+ ol.docify(";");
+ }
+ endAnonScopeNeeded=TRUE;
+ }
+ else
+ {
+ if (getAnonymousEnumType()) // type is an anonymous enum
+ {
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ name(), //
+ ltype.left(i), // text
+ TRUE // autoBreak
+ );
+ getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
+ //ol+=*getAnonymousEnumType()->enumDecl();
+ linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE);
+ }
+ else
+ {
+ ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ name(), //
+ ltype, // text
+ TRUE // autoBreak
+ );
+ }
+ }
+ }
+ else if (ltype=="@") // rename type from enum values
+ {
+ ltype="";
+ }
+ else
+ {
+ if (isObjCMethod())
+ {
+ ltype.prepend("(");
+ ltype.append(")");
+ }
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ name(), //
+ ltype, // text
+ TRUE // autoBreak
+ );
+ }
+ bool htmlOn = ol.isEnabled(OutputGenerator::Html);
+ if (htmlOn && Config_getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty())
+ {
+ ol.disable(OutputGenerator::Html);
+ }
+ if (!ltype.isEmpty()) ol.docify(" ");
+ if (htmlOn)
+ {
+ ol.enable(OutputGenerator::Html);
+ }
+
+ if (m_impl->annMemb)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeNonBreakableSpace(3);
+ ol.popGeneratorState();
+ }
+ else
+ {
+ ol.insertMemberAlign(m_impl->tArgList!=0);
+ }
+
+ // *** write name
+ if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
+ {
+ //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
+ if (!(name().isEmpty() || name().at(0)=='@') && // name valid
+ (hasDocumentation() || isReference()) && // has docs
+ !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=Friend) && // hidden due to protection
+ !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness
+ )
+ {
+ if (m_impl->annMemb)
+ {
+ //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
+ m_impl->annMemb->writeLink(ol,
+ m_impl->annMemb->getClassDef(),
+ m_impl->annMemb->getNamespaceDef(),
+ m_impl->annMemb->getFileDef(),
+ m_impl->annMemb->getGroupDef()
+ );
+ m_impl->annMemb->setAnonymousUsed();
+ setAnonymousUsed();
+ }
+ else
+ {
+ //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
+ ClassDef *rcd = cd;
+ if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
+ writeLink(ol,rcd,nd,fd,gd);
+ }
+ }
+ else if (isDocumentedFriendClass())
+ // if the member is an undocumented friend declaration for some class,
+ // then maybe we can link to the class
+ {
+ writeLink(ol,getClass(name()),0,0,0);
+ }
+ else
+ // there is a brief member description and brief member
+ // descriptions are enabled or there is no detailed description.
+ {
+ if (m_impl->annMemb)
+ {
+ m_impl->annMemb->setAnonymousUsed();
+ setAnonymousUsed();
+ }
+ ClassDef *rcd = cd;
+ if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
+ writeLink(ol,rcd,nd,fd,gd,TRUE);
+ }
+ }
+
+ // add to index
+ if (isEnumerate() && name().at(0)=='@')
+ {
+ // don't add to index
+ }
+ else // index member
+ {
+ //static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ //QCString cfname = getOutputFileBase();
+ //QCString cfiname = d->getOutputFileBase();
+ //Doxygen::indexList.addIndexItem(
+ // cname, // level1
+ // name(), // level2
+ // separateMemPages ? cfname : cfiname, // contRef
+ // cfname, // memRef
+ // anchor(), // anchor
+ // this); // memberdef
+ Doxygen::indexList.addIndexItem(d,this);
+ }
+
+ // *** write arguments
+ if (argsString() && !isObjCMethod())
+ {
+ if (!isDefine()) ol.writeString(" ");
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ d, // scope
+ getBodyDef(), // fileScope
+ name(), //
+ argsString(), // text
+ m_impl->annMemb, // autoBreak
+ TRUE, // external
+ FALSE, // keepSpaces
+ s_indentLevel
+ );
+ }
+
+ // *** write exceptions
+ if (excpString())
+ {
+ ol.writeString(" ");
+ ol.docify(excpString());
+ }
+
+ // *** write bitfields
+ if (!m_impl->bitfields.isEmpty()) // add bitfields
+ {
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->bitfields.simplifyWhiteSpace());
+ }
+ else if (hasOneLineInitializer()
+ //!init.isEmpty() && initLines==0 && // one line initializer
+ //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
+ ) // add initializer
+ {
+ if (!isDefine())
+ {
+ ol.writeString(" = ");
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
+ }
+ else
+ {
+ ol.writeNonBreakableSpace(3);
+ linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer);
+ }
+ }
+
+ if (isObjCMethod() && isImplementation())
+ {
+ ol.startTypewriter();
+ ol.docify(" [implementation]");
+ ol.endTypewriter();
+ }
+
+ if (isProperty() && (isSettable() || isGettable()))
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (isGettable()) sl.append("get");
+ if (isSettable()) sl.append("set");
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+
+ if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (isAddable()) sl.append("add");
+ if (isRemovable()) sl.append("remove");
+ if (isRaisable()) sl.append("raise");
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+
+ if (!detailsVisible && !m_impl->annMemb)
+ {
+ ol.endDoxyAnchor(cfname,anchor());
+ }
+
+ //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
+ // name().data(),annoClassDef,annEnumType);
+ ol.endMemberItem();
+ if (endAnonScopeNeeded)
+ {
+ ol.endAnonTypeScope(--s_indentLevel);
+ }
+
+ // write brief description
+ if (!briefDescription().isEmpty() &&
+ Config_getBool("BRIEF_MEMBER_DESC")
+ /* && !annMemb */
+ )
+ {
+ ol.startMemberDescription(anchor());
+ ol.parseDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():d,this,briefDescription(),
+ TRUE,FALSE,0,TRUE,FALSE);
+ if (detailsVisible)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ //ol.endEmphasis();
+ ol.docify(" ");
+ if (m_impl->group!=0 && gd==0) // forward link to the group
+ {
+ ol.startTextLink(getOutputFileBase(),anchor());
+ }
+ else // local link
+ {
+ ol.startTextLink(0,anchor());
+ }
+ ol.endTextLink();
+ //ol.startEmphasis();
+ ol.popGeneratorState();
+ }
+ // for RTF we need to add an extra empty paragraph
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::RTF);
+ ol.startParagraph();
+ ol.endParagraph();
+ ol.popGeneratorState();
+ ol.endMemberDescription();
+ }
+ warnIfUndocumented();
+}
+
+bool MemberDef::isDetailedSectionLinkable() const
+{
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+ static bool alwaysDetailedSec = Config_getBool("ALWAYS_DETAILED_SEC");
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+ static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+
+ KEEP_RESIDENT_DURING_CALL;
+
+ // the member has details documentation for any of the following reasons
+ bool docFilter =
+ // treat everything as documented
+ extractAll ||
+ // has detailed docs
+ !documentation().isEmpty() ||
+ // has inbody docs
+ !inbodyDocumentation().isEmpty() ||
+ // is an enum with values that are documented
+ (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||
+ // is documented enum value
+ (m_impl->mtype==EnumValue && !briefDescription().isEmpty()) ||
+ // has brief description that is part of the detailed description
+ (!briefDescription().isEmpty() && // has brief docs
+ (alwaysDetailedSec && // they are visible in
+ (repeatBrief || // detailed section or
+ !briefMemberDesc // they are explicitly not
+ ) // shown in brief section
+ )
+ ) ||
+ // has a multi-line initialization block
+ //(initLines>0 && initLines<maxInitLines) ||
+ (hasMultiLineInitializer() && !hideUndocMembers) ||
+ // has one or more documented arguments
+ (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
+ // has user comments
+ Doxygen::userComments
+ ;
+
+ // this is not a global static or global statics should be extracted
+ bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
+
+ // 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==Friend;
+
+ // member is part of an anonymous scope that is the type of
+ // another member in the list.
+ //
+ //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
+
+ // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
+ // is true
+ bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
+ isFriend() &&
+ (m_impl->type=="friend class" ||
+ m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"
+ )
+ );
+
+
+ bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
+ //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
+ return result;
+}
+
+bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
+{
+ static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
+ static bool inlineSimpleStructs = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
+ bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
+ bool fileFilter = getNamespaceDef()==0 || !inFile;
+ bool simpleFilter = !hideUndocMembers && inlineSimpleStructs &&
+ getClassDef()!=0 && getClassDef()->isSimple();
+
+ bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
+ !isReference();
+ bool result = visible || simpleFilter;
+ //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
+ // name().data(),result,groupFilter,fileFilter);
+ return result;
+}
+
+/*! Writes the "detailed documentation" section of this member to
+ * all active output formats.
+ */
+void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
+ const char *scName,
+ Definition *container,
+ bool inGroup,
+ bool showEnumValues,
+ bool showInline
+ )
+{
+ // if this member is in a group find the real scope name.
+ bool hasParameterList = FALSE;
+ bool inFile = container->definitionType()==Definition::TypeFile;
+ bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
+
+ //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
+ // name().data(),hasDocs,container->definitionType(),inGroup);
+
+ if ( !hasDocs ) return;
+ if (isEnumValue() && !showEnumValues) return;
+
+ KEEP_RESIDENT_DURING_CALL;
+
+ SrcLangExt lang = getLanguage();
+ //printf("member=%s lang=%d\n",name().data(),lang);
+ bool optVhdl = lang==SrcLangExt_VHDL;
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+
+ QCString scopeName = scName;
+ QCString memAnchor = anchor();
+ QCString ciname = container->name();
+ if (container->definitionType()==TypeGroup)
+ {
+ if (getClassDef()) scopeName=getClassDef()->displayName();
+ else if (getNamespaceDef()) scopeName=getNamespaceDef()->displayName();
+ else if (getFileDef()) scopeName=getFileDef()->displayName();
+ ciname = ((GroupDef *)container)->groupTitle();
+ }
+ else if (container->definitionType()==TypeFile && getNamespaceDef())
+ { // member is in a namespace, but is written as part of the file documentation
+ // as well, so we need to make sure its label is unique.
+ memAnchor.prepend("file_");
+ }
+
+ QCString cname = container->name();
+ QCString cfname = getOutputFileBase();
+ QCString cfiname = container->getOutputFileBase();
+
+ // get member name
+ QCString doxyName=name();
+ // prepend scope if there is any. TODO: make this optional for C only docs
+ if (!scopeName.isEmpty())
+ {
+ doxyName.prepend(scopeName+sep);
+ }
+ QCString doxyArgs=argsString();
+
+ QCString ldef = definition();
+ QCString title = name();
+ //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
+ if (isEnumerate())
+ {
+ if (title.at(0)=='@')
+ {
+ ldef = title = "anonymous enum";
+ }
+ else
+ {
+ ldef.prepend("enum ");
+ }
+ }
+ else if (isEnumValue())
+ {
+ if (ldef.at(0)=='@')
+ {
+ ldef=ldef.mid(2);
+ }
+ }
+ int i=0,l;
+ static QRegExp r("@[0-9]+");
+
+ //----------------------------------------
+
+ ol.pushGeneratorState();
+
+
+ if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
+ {
+ // find enum type and insert it in the definition
+ MemberListIterator vmli(*ml);
+ MemberDef *vmd;
+ bool found=FALSE;
+ for ( ; (vmd=vmli.current()) && !found ; ++vmli)
+ {
+ if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
+ {
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.left(i));
+ vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-i-l));
+
+ found=TRUE;
+ }
+ }
+ if (!found) // anonymous compound
+ {
+ //printf("Anonymous compound `%s'\n",cname.data());
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,name(),showInline);
+ // search for the last anonymous compound name in the definition
+ int si=ldef.find(' '),pi,ei=i+l;
+ if (si==-1) si=0;
+ while ((pi=r.match(ldef,i+l,&l))!=-1)
+ {
+ i=pi;
+ ei=i+l;
+ }
+ // first si characters of ldef contain compound type name
+ ol.startMemberDocName(isObjCMethod());
+ ol.docify(ldef.left(si));
+ ol.docify(" { ... } ");
+ // last ei characters of ldef contain pointer/reference specifiers
+ int ni=ldef.find("::",si);
+ if (ni>=ei) ei=ni+2;
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-ei));
+ }
+ }
+ else // not an enum value
+ {
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+ ol.startMemberDoc(ciname,name(),memAnchor,title,showInline);
+
+ ClassDef *cd=getClassDef();
+ if (!Config_getBool("HIDE_SCOPE_NAMES"))
+ {
+ bool first=TRUE;
+ if (m_impl->defTmpArgLists)
+ // definition has explicit template parameter declarations
+ {
+ QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ if (!first) ol.docify(" ");
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,tal);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+ else // definition gets it template parameters from its class
+ // (since no definition was found)
+ {
+ if (cd && !isTemplateSpecialization())
+ {
+ QList<ArgumentList> tempParamLists;
+ cd->getTemplateParameterLists(tempParamLists);
+ //printf("#tempParamLists=%d\n",tempParamLists.count());
+ QListIterator<ArgumentList> ali(tempParamLists);
+ ArgumentList *tal;
+ for (ali.toFirst();(tal=ali.current());++ali)
+ {
+ if (tal->count()>0)
+ {
+ if (!first) ol.docify(" ");
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,tal);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+ if (m_impl->tArgList) // function template prefix
+ {
+ ol.startMemberDocPrefixItem();
+ writeTemplatePrefix(ol,m_impl->tArgList);
+ ol.endMemberDocPrefixItem();
+ }
+ }
+ }
+
+ ol.startMemberDocName(isObjCMethod());
+ if (cd && cd->isObjectiveC())
+ {
+ // strip scope name
+ int ep = ldef.find("::");
+ if (ep!=-1)
+ {
+ int sp=ldef.findRev(' ',ep);
+ if (sp!=-1)
+ {
+ ldef=ldef.left(sp+1)+ldef.mid(ep+2);
+ }
+ }
+ // strip keywords
+ int dp = ldef.find(':');
+ if (dp!=-1)
+ {
+ ldef=ldef.left(dp+1);
+ }
+ int l=ldef.length();
+ //printf("start >%s<\n",ldef.data());
+ int i=l-1;
+ while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
+ while (i>=0 && isspace((uchar)ldef.at(i))) i--;
+ if (i>0)
+ {
+ // insert braches around the type
+ QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
+ ldef=tmp;
+ }
+ //printf("end >%s< i=%d\n",ldef.data(),i);
+ if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
+ }
+
+ if (optVhdl)
+ {
+ VhdlDocGen::writeVHDLTypeDocumentation(this,container,ol);
+ }
+ else
+ {
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),substitute(ldef,"::",sep));
+ hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
+ }
+
+ if (hasOneLineInitializer()) // add initializer
+ {
+ if (!isDefine())
+ {
+ ol.docify(" = ");
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
+ }
+ else
+ {
+ ol.writeNonBreakableSpace(3);
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer);
+ }
+ }
+ if (excpString()) // add exception list
+ {
+ ol.docify(" ");
+ linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),excpString());
+ }
+ }
+
+ Specifier lvirt=virtualness();
+
+ if ((!isObjCMethod() || isOptional() || isRequired()) &&
+ (protection()!=Public || lvirt!=Normal ||
+ isFriend() || isRelated() ||
+ (isInline() && Config_getBool("INLINE_INFO")) ||
+ isSignal() || isSlot() ||
+ isStatic() ||
+ (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
+ (m_impl->memSpec & ~Entry::Inline)!=0
+ )
+ )
+ {
+ // write the member specifier list
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (optVhdl)
+ {
+ sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
+ }
+ else
+ {
+ if (isFriend()) sl.append("friend");
+ else if (isRelated()) sl.append("related");
+ else
+ {
+ if (Config_getBool("INLINE_INFO") && isInline()) sl.append("inline");
+ if (isExplicit()) sl.append("explicit");
+ if (isMutable()) sl.append("mutable");
+ if (isStatic()) sl.append("static");
+ if (isGettable()) sl.append("get");
+ if (isSettable()) sl.append("set");
+ if (isAddable()) sl.append("add");
+ if (isRemovable()) sl.append("remove");
+ if (isRaisable()) sl.append("raise");
+ if (isReadable()) sl.append("read");
+ if (isWritable()) sl.append("write");
+ if (isFinal()) sl.append("final");
+ if (isAbstract()) sl.append("abstract");
+ if (isOverride()) sl.append("override");
+ if (isInitonly()) sl.append("initonly");
+ if (isSealed()) sl.append("sealed");
+ if (isNew()) sl.append("new");
+ if (isOptional()) sl.append("optional");
+ if (isRequired()) sl.append("required");
+ if (isAssign()) sl.append("assign");
+ else if (isCopy()) sl.append("copy");
+ else if (isRetain()) sl.append("retain");
+
+ if (!isObjCMethod())
+ {
+ if (protection()==Protected) sl.append("protected");
+ else if (protection()==Private) sl.append("private");
+ else if (protection()==Package) sl.append("package");
+
+ if (lvirt==Virtual) sl.append("virtual");
+ else if (lvirt==Pure) sl.append("pure virtual");
+ if (isSignal()) sl.append("signal");
+ if (isSlot()) sl.append("slot");
+ }
+ }
+ if (m_impl->classDef &&
+ container->definitionType()==TypeClass &&
+ m_impl->classDef!=container &&
+ !isRelated()
+ )
+ {
+ sl.append("inherited");
+ }
+ }
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+ else if (isObjCMethod() && isImplementation())
+ {
+ ol.writeLatexSpacing();
+ ol.startTypewriter();
+ ol.docify(" [implementation]");
+ ol.endTypewriter();
+ }
+ if (hasParameterList)
+ {
+ ol.endParameterList();
+ ol.endMemberDoc(TRUE);
+ }
+ else
+ {
+ ol.endMemberDocName();
+ ol.endMemberDoc(FALSE);
+ }
+ ol.endDoxyAnchor(cfname,memAnchor);
+ ol.startIndent();
+
+ // FIXME:PARA
+ //ol.pushGeneratorState();
+ //ol.disable(OutputGenerator::RTF);
+ //ol.newParagraph();
+ //ol.popGeneratorState();
+
+ /* write multi-line initializer (if any) */
+ if (hasMultiLineInitializer()
+ //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
+ // || initLines<userInitLines // explicitly enabled
+ // )
+ )
+ {
+ //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
+ ol.startBold();
+ if (m_impl->mtype==Define)
+ ol.parseText(theTranslator->trDefineValue());
+ else
+ ol.parseText(theTranslator->trInitialValue());
+ ol.endBold();
+ ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
+ pIntf->resetCodeParserState();
+ ol.startCodeFragment();
+ pIntf->parseCode(ol,scopeName,m_impl->initializer,FALSE,0,getFileDef(),
+ -1,-1,TRUE,this,FALSE);
+ ol.endCodeFragment();
+ }
+
+ QCString brief = briefDescription();
+ QCString detailed = documentation();
+ LockingPtr<ArgumentList> docArgList = LockingPtr<ArgumentList>(this,m_impl->defArgList);
+ if (m_impl->templateMaster)
+ {
+ brief = m_impl->templateMaster->briefDescription();
+ detailed = m_impl->templateMaster->documentation();
+ docArgList = m_impl->templateMaster->argumentList();
+ }
+
+ /* write brief description */
+ if (!brief.isEmpty() &&
+ (Config_getBool("REPEAT_BRIEF") ||
+ !Config_getBool("BRIEF_MEMBER_DESC")
+ )
+ )
+ {
+ ol.startParagraph();
+ ol.parseDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():container,this,
+ brief,FALSE,FALSE,0,TRUE,FALSE);
+ ol.endParagraph();
+ }
+
+ /* write detailed description */
+ if (!detailed.isEmpty() ||
+ !inbodyDocumentation().isEmpty())
+ {
+ // write vhdl inline code with or without option INLINE_SOURCE
+ if (optVhdl && VhdlDocGen::isMisc(this))
+ {
+ VhdlDocGen::writeSource(this,ol,cname);
+ return;
+ }
+ else
+ {
+ ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
+ }
+
+ if (!inbodyDocumentation().isEmpty())
+ {
+ ol.parseDoc(inbodyFile(),inbodyLine(),
+ getOuterScope()?getOuterScope():container,this,
+ inbodyDocumentation()+"\n",TRUE,FALSE);
+ }
+ }
+ else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
+ !Config_getBool("BRIEF_MEMBER_DESC")))
+ {
+ if (!inbodyDocumentation().isEmpty())
+ {
+ ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,inbodyDocumentation()+"\n",TRUE,FALSE);
+ }
+ }
+
+
+ //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
+ // defArgList,
+ // defArgList?defArgList->hasDocumentation():-1);
+ if (docArgList!=0 && docArgList->hasDocumentation())
+ {
+ QCString paramDocs;
+ ArgumentListIterator ali(*docArgList);
+ Argument *a;
+ // convert the parameter documentation into a list of @param commands
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ if (a->hasDocumentation())
+ {
+ QCString direction = extractDirection(a->docs);
+ paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
+ }
+ }
+ // feed the result to the documentation parser
+ ol.parseDoc(
+ docFile(),docLine(),
+ getOuterScope()?getOuterScope():container,
+ this, // memberDef
+ paramDocs, // docStr
+ TRUE, // indexWords
+ FALSE // isExample
+ );
+
+ }
+
+ // For enum, we also write the documented enum values
+ if (isEnumerate())
+ {
+ bool first=TRUE;
+ LockingPtr<MemberList> fmdl=enumFieldList();
+ //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
+ if (fmdl!=0)
+ {
+ MemberDef *fmd=fmdl->first();
+ while (fmd)
+ {
+ //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
+ if (fmd->isLinkable())
+ {
+ if (first)
+ {
+ ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
+ ol.startDescForItem();
+ ol.startDescTable();
+ }
+
+ ol.addIndexItem(fmd->name(),ciname);
+ ol.addIndexItem(ciname,fmd->name());
+
+ //Doxygen::indexList.addIndexItem(
+ // ciname, // level1
+ // fmd->name(), // level2
+ // separateMemPages ? cfname : cfiname, // contRef
+ // cfname, // memRef
+ // fmd->anchor(), // anchor
+ // fmd); // memberdef
+ Doxygen::indexList.addIndexItem(container,fmd);
+
+ //ol.writeListItem();
+ ol.startDescTableTitle(); // this enables emphasis!
+ ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
+ first=FALSE;
+ //ol.startEmphasis();
+ ol.docify(fmd->name());
+ //ol.endEmphasis();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.writeString(" ");
+ ol.enableAll();
+ ol.endDoxyAnchor(cfname,fmd->anchor());
+ ol.endDescTableTitle();
+ //ol.newParagraph();
+ ol.startDescTableData();
+
+ if (!fmd->briefDescription().isEmpty())
+ {
+ ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
+ }
+ // FIXME:PARA
+ //if (!fmd->briefDescription().isEmpty() &&
+ // !fmd->documentation().isEmpty())
+ //{
+ // ol.newParagraph();
+ //}
+ if (!fmd->documentation().isEmpty())
+ {
+ ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
+ }
+ ol.endDescTableData();
+ }
+ fmd=fmdl->next();
+ }
+ }
+ if (!first)
+ {
+ //ol.endItemList();
+ ol.endDescTable();
+ ol.endDescForItem();
+ ol.endSimpleSect();
+ ol.writeChar('\n');
+ }
+ }
+
+ MemberDef *bmd=reimplements();
+ ClassDef *bcd=0;
+ if (bmd && (bcd=bmd->getClassDef()))
+ {
+ // write class that contains a member that is reimplemented by this one
+ if (bcd->isLinkable())
+ {
+ ol.startParagraph();
+ QCString reimplFromLine;
+ if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
+ {
+ reimplFromLine = theTranslator->trReimplementedFromList(1);
+ }
+ else
+ {
+ reimplFromLine = theTranslator->trImplementedFromList(1);
+ }
+ int markerPos = reimplFromLine.find("@0");
+ if (markerPos!=-1) // should always pass this.
+ {
+ ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
+ if (bmd->isLinkable()) // replace marker with link
+ {
+ //Definition *bd=bmd->group;
+ //if (bd==0) bd=bcd;
+ ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+ bmd->anchor(),bcd->displayName());
+
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ if ( bmd->isLinkableInProject() )
+ {
+ writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+ }
+ }
+ else
+ {
+ ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ 0,bcd->displayName());
+ if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
+ {
+ writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
+ }
+ }
+ ol.parseText(reimplFromLine.right(
+ reimplFromLine.length()-markerPos-2)); // text right from marker
+
+ }
+ else
+ {
+ err("error: translation error: no marker in trReimplementsFromList()\n");
+ }
+ ol.endParagraph();
+ }
+
+ //ol.writeString(".");
+ }
+
+ LockingPtr<MemberList> bml=reimplementedBy();
+ if (bml!=0)
+ {
+ MemberListIterator mli(*bml);
+ MemberDef *bmd=0;
+ uint count=0;
+ ClassDef *bcd=0;
+ for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
+ {
+ // count the members that directly inherit from md and for
+ // which the member and class are visible in the docs.
+ if ( bmd->isLinkable() && bcd->isLinkable() )
+ {
+ count++;
+ }
+ }
+ if (count>0)
+ {
+ mli.toFirst();
+ // write the list of classes that overwrite this member
+ ol.startParagraph();
+
+ QCString reimplInLine;
+ if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
+ {
+ reimplInLine = theTranslator->trImplementedInList(count);
+ }
+ else
+ {
+ reimplInLine = theTranslator->trReimplementedInList(count);
+ }
+ static QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in reimplInLine with links to the classes
+ while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(reimplInLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ //bmd=bml->at(entryIndex);
+
+ count=0;
+ // find the entryIndex-th documented entry in the inheritance list.
+ for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
+ {
+ if ( bmd->isLinkable() && bcd->isLinkable())
+ {
+ if (count==entryIndex) break;
+ count++;
+ }
+ }
+
+ if (ok && bcd && bmd) // write link for marker
+ {
+ //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
+ // bmd->anchor(),bcd->name());
+ ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
+ bmd->anchor(),bcd->displayName());
+
+ if (bmd->isLinkableInProject() )
+ {
+ writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
+ }
+ }
+ ++mli;
+ index=newIndex+matchLen;
+ }
+ ol.parseText(reimplInLine.right(reimplInLine.length()-index));
+ ol.endParagraph();
+ }
+ }
+
+ // write the list of examples that use this member
+ if (hasExamples())
+ {
+ ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
+ ol.startDescForItem();
+ writeExample(ol,m_impl->exampleSDict);
+ ol.endDescForItem();
+ ol.endSimpleSect();
+ }
+
+ if (m_impl->typeConstraints)
+ {
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+ }
+
+ // write reference to the source
+ writeSourceDef(ol,cname);
+ writeSourceRefs(ol,cname);
+ writeSourceReffedBy(ol,cname);
+ writeInlineCode(ol,cname);
+
+ // write call graph
+ if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH"))
+ && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
+ )
+ {
+ DotCallGraph callGraph(this,FALSE);
+ if (!callGraph.isTrivial() && !callGraph.isTooBig())
+ {
+ msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
+ ol.disable(OutputGenerator::Man);
+ ol.startParagraph();
+ ol.startCallGraph();
+ ol.parseText(theTranslator->trCallGraph());
+ ol.endCallGraph(callGraph);
+ ol.endParagraph();
+ ol.enableAll();
+ }
+ }
+ if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH"))
+ && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
+ )
+ {
+ DotCallGraph callerGraph(this, TRUE);
+ if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
+ {
+ msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
+ ol.disable(OutputGenerator::Man);
+ ol.startParagraph();
+ ol.startCallGraph();
+ ol.parseText(theTranslator->trCallerGraph());
+ ol.endCallGraph(callerGraph);
+ ol.endParagraph();
+ ol.enableAll();
+ }
+ }
+
+ if (Doxygen::userComments)
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
+ "passthru(\"$root/doxynotes --lookup "+
+ getOutputFileBase()+":"+anchor()+"\") ?>";
+ ol.writeString(cmd);
+ ol.popGeneratorState();
+ }
+
+ ol.endIndent();
+
+ // enable LaTeX again
+ //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex);
+ ol.popGeneratorState();
+
+ //------------------------------------------------
+
+ if (!Config_getBool("EXTRACT_ALL") &&
+ Config_getBool("WARN_IF_UNDOCUMENTED") &&
+ Config_getBool("WARN_NO_PARAMDOC") &&
+ !Doxygen::suppressDocWarnings)
+ {
+ if (!hasDocumentedParams())
+ {
+ warn_doc_error(docFile(),docLine(),
+ "warning: parameters of member %s are not (all) documented",
+ qPrint(qualifiedName()));
+ }
+ if (!hasDocumentedReturnType() && isFunction() && hasDocumentation())
+ {
+ warn_doc_error(docFile(),docLine(),
+ "warning: return type of member %s is not documented",
+ qPrint(qualifiedName()));
+ }
+ }
+}
+
+// strip scope and field name from the type
+// example: "struct N::S.v.c" will become "struct v"
+static QCString simplifyTypeForTable(const QCString &s)
+{
+ QCString ts=removeAnonymousScopes(s);
+ if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
+ static QRegExp re("[A-Z_a-z0-9]+::");
+ int i,l;
+ while ((i=re.match(ts,0,&l))!=-1)
+ {
+ ts=ts.left(i)+ts.mid(i+l);
+ }
+ i=ts.findRev('.');
+ if (i!=-1) ts = ts.left(i);
+ i=ts.findRev('.');
+ if (i!=-1) ts = ts.right(ts.length()-i-1);
+ //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
+ return ts;
+}
+
+void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
+{
+ KEEP_RESIDENT_DURING_CALL;
+
+ Definition *scope = getOuterScope();
+ QCString doxyName = name();
+ QCString doxyArgs = argsString();
+ QCString memAnchor = anchor();
+ QCString cfname = getOutputFileBase();
+ QCString cname;
+ if (scope) cname = scope->name();
+ if (doxyName.at(0)=='@')
+ {
+ doxyName="__unnamed__";
+ }
+
+ ol.startInlineMemberType();
+ ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
+
+ QCString ts = simplifyTypeForTable(m_impl->type);
+
+ linkifyText(TextGeneratorOLImpl(ol), // out
+ scope, // scope
+ getBodyDef(), // fileScope
+ doxyName, //
+ ts, // text
+ TRUE // autoBreak
+ );
+ ol.endDoxyAnchor(cfname,memAnchor);
+ ol.endInlineMemberType();
+
+ ol.startInlineMemberName();
+ ol.docify(doxyName);
+ if (!m_impl->bitfields.isEmpty()) // add bitfields
+ {
+ linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),name(),m_impl->bitfields.simplifyWhiteSpace());
+ }
+ ol.endInlineMemberName();
+
+ ol.startInlineMemberDoc();
+
+ QCString brief = briefDescription();
+ QCString detailed = documentation();
+
+ /* write brief description */
+ if (!brief.isEmpty() &&
+ (Config_getBool("REPEAT_BRIEF") ||
+ !Config_getBool("BRIEF_MEMBER_DESC")
+ )
+ )
+ {
+ ol.parseDoc(briefFile(),briefLine(),
+ getOuterScope()?getOuterScope():container,this,
+ brief,FALSE,FALSE,0,TRUE,FALSE);
+ }
+
+ /* write detailed description */
+ if (!detailed.isEmpty())
+ {
+ ol.parseDoc(docFile(),docLine(),
+ getOuterScope()?getOuterScope():container,this,
+ detailed+"\n",FALSE,FALSE,0,TRUE,FALSE);
+
+ }
+
+ ol.endInlineMemberDoc();
+}
+
+QCString MemberDef::memberTypeName() const
+{
+ makeResident();
+ switch (m_impl->mtype)
+ {
+ case Define: return "define";
+ case Function: return "function";
+ case Variable: return "variable";
+ case Typedef: return "typedef";
+ case Enumeration: return "enumeration";
+ case EnumValue: return "enumvalue";
+ case Signal: return "signal";
+ case Slot: return "slot";
+ case Friend: return "friend";
+ case DCOP: return "dcop";
+ case Property: return "property";
+ case Event: return "event";
+ default: return "unknown";
+ }
+}
+
+void MemberDef::warnIfUndocumented()
+{
+ makeResident();
+ if (m_impl->memberGroup) return;
+ ClassDef *cd = getClassDef();
+ NamespaceDef *nd = getNamespaceDef();
+ FileDef *fd = getFileDef();
+ GroupDef *gd = getGroupDef();
+ Definition *d=0;
+ const char *t=0;
+ if (cd)
+ t="class", d=cd;
+ else if (nd)
+ t="namespace", d=nd;
+ else if (gd)
+ t="group", d=gd;
+ else
+ t="file", d=fd;
+ static bool extractAll = Config_getBool("EXTRACT_ALL");
+
+ //printf("warnIfUndoc: d->isLinkable()=%d isLinkable()=%d "
+ // "isDocumentedFriendClass()=%d name()=%s prot=%d\n",
+ // d->isLinkable(),isLinkable(),isDocumentedFriendClass(),
+ // name().data(),prot);
+ if ((!hasUserDocumentation() && !extractAll) &&
+ !isFriendClass() &&
+ name().find('@')==-1 && d->name().find('@')==-1 &&
+ protectionLevelVisible(m_impl->prot)
+ )
+ {
+ warn_undoc(getDefFileName(),getDefLine(),"warning: Member %s%s (%s) of %s %s is not documented.",
+ qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
+ }
+}
+
+
+
+bool MemberDef::isFriendClass() const
+{
+ makeResident();
+ return (isFriend() &&
+ (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
+ m_impl->type=="friend union"));
+}
+
+bool MemberDef::isDocumentedFriendClass() const
+{
+ makeResident();
+ ClassDef *fcd=0;
+ QCString baseName=name();
+ int i=baseName.find('<');
+ if (i!=-1) baseName=baseName.left(i);
+ return (isFriendClass() &&
+ (fcd=getClass(baseName)) && fcd->isLinkable());
+}
+
+bool MemberDef::hasDocumentation() const
+{
+ makeResident();
+ return Definition::hasDocumentation() ||
+ (m_impl->mtype==Enumeration && m_impl->docEnumValues) || // has enum values
+ (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
+}
+
+#if 0
+bool MemberDef::hasUserDocumentation() const
+{
+ bool hasDocs = Definition::hasUserDocumentation();
+ return hasDocs;
+}
+#endif
+
+
+void MemberDef::setMemberGroup(MemberGroup *grp)
+{
+ makeResident();
+ m_impl->memberGroup = grp;
+}
+
+bool MemberDef::visibleMemberGroup(bool hideNoHeader)
+{
+ makeResident();
+ return m_impl->memberGroup!=0 &&
+ (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
+}
+
+QCString MemberDef::getScopeString() const
+{
+ makeResident();
+ QCString result;
+ if (getClassDef()) result=getClassDef()->displayName();
+ else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
+ return result;
+}
+
+#if 0
+static QCString escapeAnchor(const QCString &anchor)
+{
+ QCString result;
+ int l = anchor.length(),i;
+ for (i=0;i<l;i++)
+ {
+ char c = anchor.at(i);
+ if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
+ {
+ result+=c;
+ }
+ else
+ {
+ static char hexStr[]="0123456789ABCDEF";
+ char escChar[]={ '_', 0, 0, 0 };
+ escChar[1]=hexStr[c>>4];
+ escChar[2]=hexStr[c&0xf];
+ result+=escChar;
+ }
+ }
+ return result;
+}
+#endif
+
+void MemberDef::setAnchor(const char *a)
+{
+ makeResident();
+ //anc=a;
+ a=a;
+ QCString memAnchor = name();
+ if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
+
+ memAnchor.prepend(definition()); // actually the method name is now included
+ // twice, which is silly, but we keep it this way for backward
+ // compatibility.
+
+ // include number of template arguments as well,
+ // to distinguish between two template
+ // specializations that only differ in the template parameters.
+ if (m_impl->tArgList)
+ {
+ char buf[20];
+ snprintf(buf,20,"%d:",m_impl->tArgList->count());
+ buf[19]='\0';
+ memAnchor.prepend(buf);
+ }
+
+ // convert to md5 hash
+ uchar md5_sig[16];
+ QCString sigStr(33);
+ MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
+ //printf("memAnchor=%s\n",memAnchor.data());
+ MD5SigToString(md5_sig,sigStr.data(),33);
+ m_impl->anc = "a"+sigStr;
+}
+
+void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
+ const QCString &fileName,int startLine,
+ bool hasDocs,MemberDef *member)
+{
+ //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
+ makeResident();
+ m_impl->group=gd;
+ m_impl->grouppri=pri;
+ m_impl->groupFileName=fileName;
+ m_impl->groupStartLine=startLine;
+ m_impl->groupHasDocs=hasDocs;
+ m_impl->groupMember=member;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setEnumScope(MemberDef *md)
+{
+ makeResident();
+ m_impl->enumScope=md;
+ if (md->getGroupDef())
+ {
+ m_impl->group=md->getGroupDef();
+ m_impl->grouppri=md->getGroupPri();
+ m_impl->groupFileName=md->getGroupFileName();
+ m_impl->groupStartLine=md->getGroupStartLine();
+ m_impl->groupHasDocs=md->getGroupHasDocs();
+ m_isLinkableCached = 0;
+ }
+}
+
+void MemberDef::setMemberClass(ClassDef *cd)
+{
+ makeResident();
+ m_impl->classDef=cd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ setOuterScope(cd);
+}
+
+void MemberDef::setNamespace(NamespaceDef *nd)
+{
+ makeResident();
+ m_impl->nspace=nd;
+ setOuterScope(nd);
+}
+
+MemberDef *MemberDef::createTemplateInstanceMember(
+ ArgumentList *formalArgs,ArgumentList *actualArgs)
+{
+ KEEP_RESIDENT_DURING_CALL;
+ //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
+ ArgumentList *actualArgList = 0;
+ if (m_impl->defArgList)
+ {
+ actualArgList = new ArgumentList;
+ ArgumentListIterator ali(*m_impl->defArgList);
+ Argument *arg;
+ for (;(arg=ali.current());++ali)
+ {
+ Argument *actArg = new Argument(*arg);
+ actArg->type = substituteTemplateArgumentsInString(actArg->type,formalArgs,actualArgs);
+ actualArgList->append(actArg);
+ }
+ actualArgList->constSpecifier = m_impl->defArgList->constSpecifier;
+ actualArgList->volatileSpecifier = m_impl->defArgList->volatileSpecifier;
+ actualArgList->pureSpecifier = m_impl->defArgList->pureSpecifier;
+ }
+
+ QCString methodName=name();
+ if (methodName.left(9)=="operator ") // conversion operator
+ {
+ methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
+ }
+
+ MemberDef *imd = new MemberDef(
+ getDefFileName(),getDefLine(),
+ substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
+ methodName,
+ substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
+ m_impl->exception, m_impl->prot,
+ m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
+ );
+ imd->setArgumentList(actualArgList);
+ imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
+ imd->setBodyDef(getBodyDef());
+ imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
+ //imd->setBodyMember(this);
+
+ // TODO: init other member variables (if needed).
+ // TODO: reimplemented info
+ return imd;
+}
+
+bool MemberDef::hasOneLineInitializer() const
+{
+ makeResident();
+ //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
+ // name().data(),m_impl->initializer.data(),m_impl->initLines,
+ // m_impl->maxInitLines,m_impl->userInitLines);
+ return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
+ ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
+}
+
+bool MemberDef::hasMultiLineInitializer() const
+{
+ makeResident();
+ //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
+ // initLines,userInitLines,maxInitLines);
+ return m_impl->initLines>0 &&
+ ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
+ || m_impl->initLines<m_impl->userInitLines // explicitly enabled
+ );
+}
+
+void MemberDef::setInitializer(const char *initializer)
+{
+ makeResident();
+ m_impl->initializer=initializer;
+ int p=m_impl->initializer.length()-1;
+ while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
+ m_impl->initializer=m_impl->initializer.left(p+1);
+ m_impl->initLines=m_impl->initializer.contains('\n');
+}
+
+void MemberDef::addListReference(Definition *)
+{
+ KEEP_RESIDENT_DURING_CALL;
+ static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ //static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ SrcLangExt lang = getLanguage();
+ visited=TRUE;
+ if (!isLinkableInProject()) return;
+ QCString memLabel;
+ if (optimizeOutputForC)
+ {
+ memLabel=theTranslator->trGlobal(TRUE,TRUE);
+ }
+ else if (lang==SrcLangExt_Fortran)
+ {
+ memLabel=theTranslator->trSubprogram(TRUE,TRUE);
+ }
+ else
+ {
+ memLabel=theTranslator->trMember(TRUE,TRUE);
+ }
+ QCString memName = name();
+ Definition *pd=getOuterScope();
+ QCString pdName = pd->definitionType()==Definition::TypeClass ?
+ ((ClassDef*)pd)->displayName() : pd->name();
+ QCString sep = getLanguageSpecificSeparator(lang,TRUE);
+ QCString memArgs;
+ if (!isRelated()
+ /* && commented out as a result of bug 597016
+ (
+ (!hideScopeNames && // there is a scope
+ pd && pd!=Doxygen::globalScope) // and we can show it
+ ||
+ (pd=getClassDef()) // it's a class so we
+ // show the scope anyway
+ )
+ */
+ )
+ {
+ if (isObjCMethod())
+ {
+ memName = "[" + pd->name() + " " + name() + "]";
+ }
+ else
+ {
+ if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
+ memArgs = argsString();
+ }
+ }
+ LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
+ if (xrefItems!=0)
+ {
+ addRefItem(xrefItems.pointer(),
+ qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
+ memLabel,
+ getOutputFileBase()+"#"+anchor(),memName,memArgs);
+ }
+}
+
+MemberList *MemberDef::getSectionList(Definition *d) const
+{
+ makeResident();
+ char key[20];
+ sprintf(key,"%p",d);
+ return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
+}
+
+void MemberDef::setSectionList(Definition *d, MemberList *sl)
+{
+ makeResident();
+ //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
+ char key[20];
+ sprintf(key,"%p",d);
+ if (m_impl->classSectionSDict==0)
+ {
+ m_impl->classSectionSDict = new SDict<MemberList>(7);
+ }
+ m_impl->classSectionSDict->append(key,sl);
+}
+
+Specifier MemberDef::virtualness(int count) const
+{
+ KEEP_RESIDENT_DURING_CALL;
+ if (count>25)
+ {
+ warn(getDefFileName(),getDefLine(),
+ "warning: Internal inconsistency: recursion detected in overload relation for member %s!"
+ ,qPrint(name())
+ );
+ return Normal;
+ }
+ makeResident();
+ Specifier v = m_impl->virt;
+ MemberDef *rmd = reimplements();
+ while (rmd && v==Normal)
+ {
+ v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
+ rmd = rmd->reimplements();
+ }
+ return v;
+}
+
+void MemberDef::_computeIsConstructor()
+{
+ KEEP_RESIDENT_DURING_CALL;
+ m_isConstructorCached=1; // FALSE
+ if (m_impl->classDef)
+ {
+ if (m_impl->isDMember) // for D
+ {
+ m_isConstructorCached = name()=="this" ? 2 : 1;
+ return;
+ }
+ else if (getLanguage()==SrcLangExt_PHP) // for PHP
+ {
+ m_isConstructorCached = name()=="__construct" ? 2 : 1;
+ return;
+ }
+ else if (name()=="__init__" &&
+ getLanguage()==SrcLangExt_Python) // for Python
+ {
+ m_isConstructorCached = 2; // TRUE
+ return;
+ }
+ else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
+ {
+ m_isConstructorCached = name()=="constructor" ? 2 : 1;
+ return;
+ }
+ else // for other languages
+ {
+ QCString locName = m_impl->classDef->localName();
+ int i=locName.find('<');
+ if (i==-1) // not a template class
+ {
+ m_isConstructorCached = name()==locName ? 2 : 1;
+ }
+ else
+ {
+ m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
+ }
+ return;
+ }
+ }
+}
+
+bool MemberDef::isConstructor() const
+{
+ if (m_isConstructorCached==0)
+ {
+ MemberDef *that = (MemberDef*)this;
+ that->_computeIsConstructor();
+ }
+ ASSERT(m_isConstructorCached>0);
+ return m_isConstructorCached==2;
+
+}
+
+void MemberDef::_computeIsDestructor()
+{
+ KEEP_RESIDENT_DURING_CALL;
+ bool isDestructor;
+ if (m_impl->isDMember) // for D
+ {
+ isDestructor = name()=="~this";
+ }
+ else if (getLanguage()==SrcLangExt_PHP) // for PHP
+ {
+ isDestructor = name()=="__destruct";
+ }
+ else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
+ {
+ isDestructor = name()=="destructor";
+ }
+ else if (name()=="__del__" &&
+ getLanguage()==SrcLangExt_Python) // for Python
+ {
+ isDestructor=TRUE;
+ }
+ else // other languages
+ {
+ isDestructor =
+ (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
+ && name().find("operator")==-1;
+ }
+ m_isDestructorCached = isDestructor ? 2 : 1;
+}
+
+bool MemberDef::isDestructor() const
+{
+ if (m_isDestructorCached==0)
+ {
+ MemberDef *that=(MemberDef*)this;
+ that->_computeIsDestructor();
+ }
+ ASSERT(m_isDestructorCached>0);
+ return m_isDestructorCached==2;
+}
+
+void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
+ ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
+{
+ KEEP_RESIDENT_DURING_CALL;
+
+ int enumMemCount=0;
+
+ QList<MemberDef> *fmdl=m_impl->enumFields;
+ uint numVisibleEnumValues=0;
+ if (fmdl)
+ {
+ MemberDef *fmd=fmdl->first();
+ while (fmd)
+ {
+ if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
+ fmd=fmdl->next();
+ }
+ }
+ if (numVisibleEnumValues==0 && !isBriefSectionVisible())
+ {
+ return;
+ }
+
+ QCString n = name();
+ int i=n.findRev("::");
+ if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
+ if (n[0]!='@') // not an anonymous enum
+ {
+ if (isLinkableInProject() || hasDocumentedEnumValues())
+ {
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
+ {
+ Doxygen::tagFile << " <member kind=\"enumeration\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
+ Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
+ Doxygen::tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
+ Doxygen::tagFile << " </member>" << endl;
+ }
+ writeLink(typeDecl,cd,nd,fd,gd);
+ }
+ else
+ {
+ typeDecl.startBold();
+ typeDecl.docify(n);
+ typeDecl.endBold();
+ }
+ typeDecl.writeChar(' ');
+ }
+
+ uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE");
+ if (numVisibleEnumValues>0 && enumValuesPerLine>0)
+ {
+ typeDecl.docify("{ ");
+ if (fmdl)
+ {
+ MemberDef *fmd=fmdl->first();
+ bool fmdVisible = fmd->isBriefSectionVisible();
+ while (fmd)
+ {
+ if (fmdVisible)
+ {
+ /* in html we start a new line after a number of items */
+ if (numVisibleEnumValues>enumValuesPerLine
+ && (enumMemCount%enumValuesPerLine)==0
+ )
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.enable(OutputGenerator::Latex);
+ typeDecl.lineBreak();
+ typeDecl.disable(OutputGenerator::Latex);
+ typeDecl.writeString("&#160;&#160;");
+ typeDecl.popGeneratorState();
+ }
+
+ if (fmd->hasDocumentation()) // enum value has docs
+ {
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fmd->isReference())
+ {
+ Doxygen::tagFile << " <member kind=\"enumvalue\">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(fmd->name()) << "</name>" << endl;
+ Doxygen::tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
+ Doxygen::tagFile << " <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl;
+ Doxygen::tagFile << " <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl;
+ Doxygen::tagFile << " </member>" << endl;
+ }
+ fmd->writeLink(typeDecl,cd,nd,fd,gd);
+ }
+ else // no docs for this enum value
+ {
+ typeDecl.startBold();
+ typeDecl.docify(fmd->name());
+ typeDecl.endBold();
+ }
+ if (fmd->hasOneLineInitializer()) // enum value has initializer
+ {
+ typeDecl.writeString(" = ");
+ typeDecl.parseText(fmd->initializer());
+ }
+ }
+
+ bool prevVisible = fmdVisible;
+ fmd=fmdl->next();
+ if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
+ {
+ typeDecl.writeString(", ");
+ }
+ if (prevVisible)
+ {
+ typeDecl.disable(OutputGenerator::Man);
+ typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
+ typeDecl.enable(OutputGenerator::Man);
+ enumMemCount++;
+ }
+ }
+ if (numVisibleEnumValues>enumValuesPerLine)
+ {
+ typeDecl.pushGeneratorState();
+ typeDecl.disableAllBut(OutputGenerator::Html);
+ typeDecl.lineBreak();
+ typeDecl.popGeneratorState();
+ }
+ }
+ typeDecl.docify(" }");
+ }
+}
+
+void MemberDef::setArgumentList(ArgumentList *al)
+{
+ makeResident();
+ if (m_impl->defArgList) delete m_impl->defArgList;
+ m_impl->defArgList = al;
+}
+
+void MemberDef::setDeclArgumentList(ArgumentList *al)
+{
+ makeResident();
+ if (m_impl->declArgList) delete m_impl->declArgList;
+ m_impl->declArgList = al;
+}
+
+void MemberDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ makeResident();
+ if (m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ m_impl->typeConstraints->setAutoDelete(TRUE);
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
+void MemberDef::setType(const char *t)
+{
+ makeResident();
+ m_impl->type = t;
+}
+
+void MemberDef::findSectionsInDocumentation()
+{
+ makeResident();
+ docFindSections(documentation(),this,0,docFile());
+}
+
+void MemberDef::enableCallGraph(bool e)
+{
+ makeResident();
+ m_impl->hasCallGraph=e;
+ if (e) Doxygen::parseSourcesNeeded = TRUE;
+}
+
+void MemberDef::enableCallerGraph(bool e)
+{
+ makeResident();
+ m_impl->hasCallerGraph=e;
+ if (e) Doxygen::parseSourcesNeeded = TRUE;
+}
+
+#if 0
+bool MemberDef::protectionVisible() const
+{
+ makeResident();
+ return m_impl->prot==Public ||
+ (m_impl->prot==Private && Config_getBool("EXTRACT_PRIVATE")) ||
+ (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) ||
+ (m_impl->prot==Package && Config_getBool("EXTRACT_PACKAGE"));
+}
+#endif
+
+#if 0
+void MemberDef::setInbodyDocumentation(const char *docs,
+ const char *docFile,int docLine)
+{
+ makeResident();
+ m_impl->inbodyDocs = docs;
+ m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
+ m_impl->inbodyLine = docLine;
+ m_impl->inbodyFile = docFile;
+}
+#endif
+
+bool MemberDef::isObjCMethod() const
+{
+ makeResident();
+ if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
+ return FALSE;
+}
+
+bool MemberDef::isObjCProperty() const
+{
+ makeResident();
+ if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
+ return FALSE;
+}
+
+QCString MemberDef::qualifiedName() const
+{
+ makeResident();
+ if (isObjCMethod())
+ {
+ QCString qm;
+ if (isStatic()) qm="+"; else qm="-";
+ qm+="[";
+ qm+=m_impl->classDef->name()+" ";
+ qm+=name();
+ qm+="]";
+ return qm;
+ }
+ else
+ {
+ return Definition::qualifiedName();
+ }
+}
+
+void MemberDef::setTagInfo(TagInfo *ti)
+{
+ if (ti)
+ {
+ makeResident();
+ //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
+ m_impl->anc=ti->anchor;
+ setReference(ti->tagName);
+ m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
+ }
+}
+
+QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
+{
+ makeResident();
+ QCString qm;
+ if (showStatic)
+ {
+ if (isStatic()) qm="+ "; else qm="- ";
+ }
+ qm+=name();
+ if (!localLink) // link to method of same class
+ {
+ qm+=" (";
+ qm+=m_impl->classDef->name();
+ qm+=")";
+ }
+ return qm;
+}
+
+const char *MemberDef::declaration() const
+{
+ makeResident();
+ return m_impl->decl;
+}
+
+const char *MemberDef::definition() const
+{
+ makeResident();
+ return m_impl->def;
+}
+
+const char *MemberDef::extraTypeChars() const
+{
+ makeResident();
+ return m_impl->extraTypeChars;
+}
+
+const char *MemberDef::typeString() const
+{
+ makeResident();
+ return m_impl->type;
+}
+
+const char *MemberDef::argsString() const
+{
+ makeResident();
+ return m_impl->args;
+}
+
+const char *MemberDef::excpString() const
+{
+ makeResident();
+ return m_impl->exception;
+}
+
+const char *MemberDef::bitfieldString() const
+{
+ makeResident();
+ return m_impl->bitfields;
+}
+
+const QCString &MemberDef::initializer() const
+{
+ makeResident();
+ return m_impl->initializer;
+}
+
+int MemberDef::initializerLines() const
+{
+ makeResident();
+ return m_impl->initLines;
+}
+
+int MemberDef::getMemberSpecifiers() const
+{
+ makeResident();
+ return m_impl->memSpec;
+}
+
+ClassDef *MemberDef::getClassDef() const
+{
+ makeResident();
+ return m_impl->classDef;
+}
+
+FileDef *MemberDef::getFileDef() const
+{
+ makeResident();
+ return m_impl->fileDef;
+}
+
+NamespaceDef* MemberDef::getNamespaceDef() const
+{
+ makeResident();
+ return m_impl->nspace;
+}
+
+const char *MemberDef::getReadAccessor() const
+{
+ makeResident();
+ return m_impl->read;
+}
+
+const char *MemberDef::getWriteAccessor() const
+{
+ makeResident();
+ return m_impl->write;
+}
+
+GroupDef *MemberDef::getGroupDef() const
+{
+ makeResident();
+ return m_impl->group;
+}
+
+Grouping::GroupPri_t MemberDef::getGroupPri() const
+{
+ makeResident();
+ return m_impl->grouppri;
+}
+
+const char *MemberDef::getGroupFileName() const
+{
+ makeResident();
+ return m_impl->groupFileName;
+}
+
+int MemberDef::getGroupStartLine() const
+{
+ makeResident();
+ return m_impl->groupStartLine;
+}
+
+bool MemberDef::getGroupHasDocs() const
+{
+ makeResident();
+ return m_impl->groupHasDocs;
+}
+
+Protection MemberDef::protection() const
+{
+ makeResident();
+ return m_impl->prot;
+}
+
+MemberDef::MemberType MemberDef::memberType() const
+{
+ makeResident();
+ return m_impl->mtype;
+}
+
+bool MemberDef::isSignal() const
+{
+ makeResident();
+ return m_impl->mtype==Signal;
+}
+
+bool MemberDef::isSlot() const
+{
+ makeResident();
+ return m_impl->mtype==Slot;
+}
+
+bool MemberDef::isVariable() const
+{
+ makeResident();
+ return m_impl->mtype==Variable;
+}
+
+bool MemberDef::isEnumerate() const
+{
+ makeResident();
+ return m_impl->mtype==Enumeration;
+}
+
+bool MemberDef::isEnumValue() const
+{
+ makeResident();
+ return m_impl->mtype==EnumValue;
+}
+
+bool MemberDef::isTypedef() const
+{
+ makeResident();
+ return m_impl->mtype==Typedef;
+}
+
+bool MemberDef::isFunction() const
+{
+ makeResident();
+ return m_impl->mtype==Function;
+}
+
+bool MemberDef::isFunctionPtr() const
+{
+ makeResident();
+ return m_impl->mtype==Variable && QCString(argsString()).find(")(")!=-1;
+}
+
+bool MemberDef::isDefine() const
+{
+ makeResident();
+ return m_impl->mtype==Define;
+}
+
+bool MemberDef::isFriend() const
+{
+ makeResident();
+ return m_impl->mtype==Friend;
+}
+
+bool MemberDef::isDCOP() const
+{
+ makeResident();
+ return m_impl->mtype==DCOP;
+}
+
+bool MemberDef::isProperty() const
+{
+ makeResident();
+ return m_impl->mtype==Property;
+}
+
+bool MemberDef::isEvent() const
+{
+ makeResident();
+ return m_impl->mtype==Event;
+}
+
+bool MemberDef::isRelated() const
+{
+ makeResident();
+ return m_impl->related == Related;
+}
+
+bool MemberDef::isForeign() const
+{
+ makeResident();
+ return m_impl->related == Foreign;
+}
+
+bool MemberDef::isStatic() const
+{
+ makeResident();
+ return m_impl->stat;
+}
+
+bool MemberDef::isInline() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Inline)!=0;
+}
+
+bool MemberDef::isExplicit() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Explicit)!=0;
+}
+
+bool MemberDef::isMutable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Mutable)!=0;
+}
+
+bool MemberDef::isGettable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Gettable)!=0;
+}
+
+bool MemberDef::isSettable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Settable)!=0;
+}
+
+bool MemberDef::isAddable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Addable)!=0;
+}
+
+bool MemberDef::isRemovable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Removable)!=0;
+}
+
+bool MemberDef::isRaisable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Raisable)!=0;
+}
+
+bool MemberDef::isReadable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Readable)!=0;
+}
+
+bool MemberDef::isWritable() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Writable)!=0;
+}
+
+bool MemberDef::isFinal() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Final)!=0;
+}
+
+bool MemberDef::isNew() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::New)!=0;
+}
+
+bool MemberDef::isSealed() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Sealed)!=0;
+}
+
+bool MemberDef::isOverride() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Override)!=0;
+}
+
+bool MemberDef::isInitonly() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Initonly)!=0;
+}
+
+bool MemberDef::isAbstract() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Abstract)!=0;
+}
+
+bool MemberDef::isOptional() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Optional)!=0;
+}
+
+bool MemberDef::isRequired() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Required)!=0;
+}
+
+bool MemberDef::isNonAtomic() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::NonAtomic)!=0;
+}
+
+bool MemberDef::isCopy() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Copy)!=0;
+}
+
+bool MemberDef::isAssign() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Assign)!=0;
+}
+
+bool MemberDef::isRetain() const
+{
+ makeResident();
+ return (m_impl->memSpec&Entry::Retain)!=0;
+}
+
+
+bool MemberDef::isImplementation() const
+{
+ makeResident();
+ return m_impl->implOnly;
+}
+
+bool MemberDef::isExternal() const
+{
+ makeResident();
+ return m_impl->explExt;
+}
+
+bool MemberDef::isTemplateSpecialization() const
+{
+ makeResident();
+ return m_impl->tspec;
+}
+
+bool MemberDef::hasDocumentedParams() const
+{
+ makeResident();
+ return m_impl->hasDocumentedParams;
+}
+
+bool MemberDef::hasDocumentedReturnType() const
+{
+ makeResident();
+ return m_impl->hasDocumentedReturnType;
+}
+
+ClassDef *MemberDef::relatedAlso() const
+{
+ makeResident();
+ return m_impl->relatedAlso;
+}
+
+bool MemberDef::hasDocumentedEnumValues() const
+{
+ makeResident();
+ return m_impl->docEnumValues;
+}
+
+MemberDef *MemberDef::getAnonymousEnumType() const
+{
+ makeResident();
+ return m_impl->annEnumType;
+}
+
+bool MemberDef::isDocsForDefinition() const
+{
+ makeResident();
+ return m_impl->docsForDefinition;
+}
+
+MemberDef *MemberDef::getEnumScope() const
+{
+ makeResident();
+ return m_impl->enumScope;
+}
+
+LockingPtr<MemberList> MemberDef::enumFieldList() const
+{
+ makeResident();
+ return LockingPtr<MemberList>(this,m_impl->enumFields);
+}
+
+LockingPtr<ExampleSDict> MemberDef::getExamples() const
+{
+ makeResident();
+ return LockingPtr<ExampleSDict>(this,m_impl->exampleSDict);
+}
+
+bool MemberDef::isPrototype() const
+{
+ makeResident();
+ return m_impl->proto;
+}
+
+LockingPtr<ArgumentList> MemberDef::argumentList() const
+{
+ makeResident();
+ return LockingPtr<ArgumentList>(this,m_impl->defArgList);
+}
+
+LockingPtr<ArgumentList> MemberDef::declArgumentList() const
+{
+ makeResident();
+ return LockingPtr<ArgumentList>(this,m_impl->declArgList);
+}
+
+LockingPtr<ArgumentList> MemberDef::templateArguments() const
+{
+ makeResident();
+ return LockingPtr<ArgumentList>(this,m_impl->tArgList);
+}
+
+LockingPtr< QList<ArgumentList> > MemberDef::definitionTemplateParameterLists() const
+{
+ makeResident();
+ return LockingPtr< QList<ArgumentList> >(this,m_impl->defTmpArgLists);
+}
+
+int MemberDef::getMemberGroupId() const
+{
+ makeResident();
+ return m_impl->grpId;
+}
+
+MemberGroup *MemberDef::getMemberGroup() const
+{
+ makeResident();
+ return m_impl->memberGroup;
+}
+
+bool MemberDef::fromAnonymousScope() const
+{
+ makeResident();
+ return m_impl->annScope;
+}
+
+bool MemberDef::anonymousDeclShown() const
+{
+ makeResident();
+ return m_impl->annUsed;
+}
+
+void MemberDef::setAnonymousUsed()
+{
+ makeResident();
+ m_impl->annUsed = TRUE;
+}
+
+bool MemberDef::hasCallGraph() const
+{
+ makeResident();
+ return m_impl->hasCallGraph;
+}
+
+bool MemberDef::hasCallerGraph() const
+{
+ makeResident();
+ return m_impl->hasCallerGraph;
+}
+
+MemberDef *MemberDef::templateMaster() const
+{
+ makeResident();
+ return m_impl->templateMaster;
+}
+
+bool MemberDef::isTypedefValCached() const
+{
+ makeResident();
+ return m_impl->isTypedefValCached;
+}
+
+ClassDef *MemberDef::getCachedTypedefVal() const
+{
+ makeResident();
+ return m_impl->cachedTypedefValue;
+}
+
+QCString MemberDef::getCachedTypedefTemplSpec() const
+{
+ makeResident();
+ return m_impl->cachedTypedefTemplSpec;
+}
+
+QCString MemberDef::getCachedResolvedTypedef() const
+{
+ makeResident();
+ //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
+ return m_impl->cachedResolvedType;
+}
+
+MemberDef *MemberDef::memberDefinition() const
+{
+ makeResident();
+ return m_impl->memDef;
+}
+
+MemberDef *MemberDef::memberDeclaration() const
+{
+ makeResident();
+ return m_impl->memDec;
+}
+
+MemberDef *MemberDef::inheritsDocsFrom() const
+{
+ makeResident();
+ return m_impl->docProvider;
+}
+
+MemberDef *MemberDef::getGroupAlias() const
+{
+ makeResident();
+ return m_impl->groupAlias;
+}
+
+void MemberDef::setMemberType(MemberType t)
+{
+ makeResident();
+ m_impl->mtype=t;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setDefinition(const char *d)
+{
+ makeResident();
+ m_impl->def=d;
+}
+
+void MemberDef::setFileDef(FileDef *fd)
+{
+ makeResident();
+ m_impl->fileDef=fd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+ m_isDestructorCached = 0;
+}
+
+void MemberDef::setProtection(Protection p)
+{
+ makeResident();
+ m_impl->prot=p;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setMemberSpecifiers(int s)
+{
+ makeResident();
+ m_impl->memSpec=s;
+}
+
+void MemberDef::mergeMemberSpecifiers(int s)
+{
+ makeResident();
+ m_impl->memSpec|=s;
+}
+
+void MemberDef::setBitfields(const char *s)
+{
+ makeResident();
+ m_impl->bitfields = s;
+}
+
+void MemberDef::setMaxInitLines(int lines)
+{
+ if (lines!=-1)
+ {
+ makeResident();
+ m_impl->userInitLines=lines;
+ }
+}
+
+void MemberDef::setExplicitExternal(bool b)
+{
+ makeResident();
+ m_impl->explExt=b;
+}
+
+void MemberDef::setReadAccessor(const char *r)
+{
+ makeResident();
+ m_impl->read=r;
+}
+
+void MemberDef::setWriteAccessor(const char *w)
+{
+ makeResident();
+ m_impl->write=w;
+}
+
+void MemberDef::setTemplateSpecialization(bool b)
+{
+ makeResident();
+ m_impl->tspec=b;
+}
+
+void MemberDef::makeRelated()
+{
+ makeResident();
+ m_impl->related = Related;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::makeForeign()
+{
+ makeResident();
+ m_impl->related = Foreign;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setHasDocumentedParams(bool b)
+{
+ makeResident();
+ m_impl->hasDocumentedParams = b;
+}
+
+void MemberDef::setHasDocumentedReturnType(bool b)
+{
+ makeResident();
+ m_impl->hasDocumentedReturnType = b;
+}
+
+void MemberDef::setInheritsDocsFrom(MemberDef *md)
+{
+ makeResident();
+ m_impl->docProvider = md;
+}
+
+void MemberDef::setArgsString(const char *as)
+{
+ makeResident();
+ m_impl->args = as;
+}
+
+void MemberDef::setRelatedAlso(ClassDef *cd)
+{
+ makeResident();
+ m_impl->relatedAlso=cd;
+}
+
+void MemberDef::setEnumClassScope(ClassDef *cd)
+{
+ makeResident();
+ m_impl->classDef = cd;
+ m_isLinkableCached = 0;
+ m_isConstructorCached = 0;
+}
+
+void MemberDef::setDocumentedEnumValues(bool value)
+{
+ makeResident();
+ m_impl->docEnumValues=value;
+}
+
+void MemberDef::setAnonymousEnumType(MemberDef *md)
+{
+ makeResident();
+ m_impl->annEnumType = md;
+}
+
+void MemberDef::setPrototype(bool p)
+{
+ makeResident();
+ m_impl->proto=p;
+}
+
+void MemberDef::setMemberGroupId(int id)
+{
+ makeResident();
+ m_impl->grpId=id;
+}
+
+void MemberDef::makeImplementationDetail()
+{
+ makeResident();
+ m_impl->implOnly=TRUE;
+}
+
+void MemberDef::setFromAnonymousScope(bool b)
+{
+ makeResident();
+ m_impl->annScope=b;
+}
+
+void MemberDef::setFromAnonymousMember(MemberDef *m)
+{
+ makeResident();
+ m_impl->annMemb=m;
+}
+
+void MemberDef::setTemplateMaster(MemberDef *mt)
+{
+ makeResident();
+ m_impl->templateMaster=mt;
+ m_isLinkableCached = 0;
+}
+
+void MemberDef::setDocsForDefinition(bool b)
+{
+ makeResident();
+ m_impl->docsForDefinition = b;
+}
+
+void MemberDef::setGroupAlias(MemberDef *md)
+{
+ makeResident();
+ m_impl->groupAlias = md;
+}
+
+void MemberDef::invalidateTypedefValCache()
+{
+ makeResident();
+ m_impl->isTypedefValCached=FALSE;
+}
+
+void MemberDef::setMemberDefinition(MemberDef *md)
+{
+ makeResident();
+ m_impl->memDef=md;
+}
+
+void MemberDef::setMemberDeclaration(MemberDef *md)
+{
+ makeResident();
+ m_impl->memDec=md;
+}
+
+ClassDef *MemberDef::category() const
+{
+ makeResident();
+ return m_impl->category;
+}
+
+void MemberDef::setCategory(ClassDef *def)
+{
+ makeResident();
+ m_impl->category = def;
+}
+
+
+void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
+{
+ makeResident();
+ m_impl->isTypedefValCached=TRUE;
+ m_impl->cachedTypedefValue=val;
+ m_impl->cachedTypedefTemplSpec=templSpec;
+ m_impl->cachedResolvedType=resolvedType;
+ //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
+}
+
+void MemberDef::copyArgumentNames(MemberDef *bmd)
+{
+ makeResident();
+ {
+ LockingPtr<ArgumentList> arguments = bmd->argumentList();
+ if (m_impl->defArgList && arguments!=0)
+ {
+ ArgumentListIterator aliDst(*m_impl->defArgList);
+ ArgumentListIterator aliSrc(*arguments);
+ Argument *argDst, *argSrc;
+ for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+ {
+ argDst->name = argSrc->name;
+ }
+ }
+ }
+ {
+ LockingPtr<ArgumentList> arguments = bmd->declArgumentList();
+ if (m_impl->declArgList && arguments!=0)
+ {
+ ArgumentListIterator aliDst(*m_impl->declArgList);
+ ArgumentListIterator aliSrc(*arguments);
+ Argument *argDst, *argSrc;
+ for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
+ {
+ argDst->name = argSrc->name;
+ }
+ }
+ }
+}
+
+static void invalidateCachedTypesInArgumentList(ArgumentList *al)
+{
+ if (al)
+ {
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (ali.toFirst();(a=ali.current());++ali)
+ {
+ a->canType.resize(0);
+ }
+ }
+}
+
+void MemberDef::invalidateCachedArgumentTypes()
+{
+ makeResident();
+ invalidateCachedTypesInArgumentList(m_impl->defArgList);
+ invalidateCachedTypesInArgumentList(m_impl->declArgList);
+}
+
+
+//-----------------------------------------------------------------
+
+void MemberDef::flushToDisk() const
+{
+ if (isLocked()) return;
+ MemberDef *that = (MemberDef*)this;
+ that->m_storagePos = Doxygen::symbolStorage->alloc();
+ //printf("%p: MemberDef::flushToDisk() m_impl=%p\n",this,m_impl);
+ // write the definition base class member variables to disk
+ Definition::flushToDisk();
+
+ //printf("%p: flushing specific part\n",this);
+
+ // write the memberdef member variables to disk
+ marshalUInt(Doxygen::symbolStorage,START_MARKER);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->classDef);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->fileDef);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->nspace);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->enumScope);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->annEnumType);
+ marshalMemberList (Doxygen::symbolStorage,m_impl->enumFields);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->redefines);
+ marshalMemberList (Doxygen::symbolStorage,m_impl->redefinedBy);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->memDef);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->memDec);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->relatedAlso);
+ marshalExampleSDict (Doxygen::symbolStorage,m_impl->exampleSDict);
+ marshalQCString (Doxygen::symbolStorage,m_impl->type);
+ marshalQCString (Doxygen::symbolStorage,m_impl->args);
+ marshalQCString (Doxygen::symbolStorage,m_impl->def);
+ marshalQCString (Doxygen::symbolStorage,m_impl->anc);
+ marshalInt (Doxygen::symbolStorage,(int)m_impl->virt);
+ marshalInt (Doxygen::symbolStorage,(int)m_impl->prot);
+ marshalQCString (Doxygen::symbolStorage,m_impl->decl);
+ marshalQCString (Doxygen::symbolStorage,m_impl->bitfields);
+ marshalQCString (Doxygen::symbolStorage,m_impl->read);
+ marshalQCString (Doxygen::symbolStorage,m_impl->write);
+ marshalQCString (Doxygen::symbolStorage,m_impl->exception);
+ marshalQCString (Doxygen::symbolStorage,m_impl->initializer);
+ marshalQCString (Doxygen::symbolStorage,m_impl->extraTypeChars);
+ marshalInt (Doxygen::symbolStorage,m_impl->initLines);
+ marshalInt (Doxygen::symbolStorage,m_impl->memSpec);
+ marshalInt (Doxygen::symbolStorage,(int)m_impl->mtype);
+ marshalInt (Doxygen::symbolStorage,m_impl->maxInitLines);
+ marshalInt (Doxygen::symbolStorage,m_impl->userInitLines);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->annMemb);
+ marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList);
+ marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList);
+ marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList);
+ marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->templateMaster);
+ marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedAnonymousType);
+ marshalMemberLists (Doxygen::symbolStorage,m_impl->classSectionSDict);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->groupAlias);
+ marshalInt (Doxygen::symbolStorage,m_impl->grpId);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->memberGroup);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->group);
+ marshalInt (Doxygen::symbolStorage,(int)m_impl->grouppri);
+ marshalQCString (Doxygen::symbolStorage,m_impl->groupFileName);
+ marshalInt (Doxygen::symbolStorage,m_impl->groupStartLine);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->groupMember);
+ marshalBool (Doxygen::symbolStorage,m_impl->isTypedefValCached);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->cachedTypedefValue);
+ marshalQCString (Doxygen::symbolStorage,m_impl->cachedTypedefTemplSpec);
+ marshalQCString (Doxygen::symbolStorage,m_impl->cachedResolvedType);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->docProvider);
+ marshalQCString (Doxygen::symbolStorage,m_impl->explicitOutputFileBase);
+ marshalBool (Doxygen::symbolStorage,m_impl->implOnly);
+ marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedParams);
+ marshalBool (Doxygen::symbolStorage,m_impl->hasDocumentedReturnType);
+ marshalBool (Doxygen::symbolStorage,m_impl->isDMember);
+ marshalInt (Doxygen::symbolStorage,(int)m_impl->related);
+ marshalBool (Doxygen::symbolStorage,m_impl->stat);
+ marshalBool (Doxygen::symbolStorage,m_impl->proto);
+ marshalBool (Doxygen::symbolStorage,m_impl->docEnumValues);
+ marshalBool (Doxygen::symbolStorage,m_impl->annScope);
+ marshalBool (Doxygen::symbolStorage,m_impl->annUsed);
+ marshalBool (Doxygen::symbolStorage,m_impl->hasCallGraph);
+ marshalBool (Doxygen::symbolStorage,m_impl->hasCallerGraph);
+ marshalBool (Doxygen::symbolStorage,m_impl->explExt);
+ marshalBool (Doxygen::symbolStorage,m_impl->tspec);
+ marshalBool (Doxygen::symbolStorage,m_impl->groupHasDocs);
+ marshalBool (Doxygen::symbolStorage,m_impl->docsForDefinition);
+ marshalObjPointer (Doxygen::symbolStorage,m_impl->category);
+ marshalUInt(Doxygen::symbolStorage,END_MARKER);
+
+ // function doesn't modify the object conceptually but compiler doesn't know this.
+ delete that->m_impl;
+ that->m_impl=0;
+ that->m_flushPending=FALSE;
+}
+
+void MemberDef::loadFromDisk() const
+{
+ MemberDef *that = (MemberDef *)this;
+ if (isLocked())
+ {
+ //printf("%p: loadFromDisk() locked: so still in memory\n",this);
+ assert(m_impl!=0);
+ return;
+ }
+ assert(m_impl==0);
+
+ Doxygen::symbolStorage->seek(m_storagePos);
+ Definition::loadFromDisk();
+
+ //printf("%p: loading specific part\n",this);
+
+ that->m_impl = new MemberDefImpl;
+ //printf("%p: MemberDef::loadFromDisk(): m_impl=%p\n",this,m_impl);
+
+ uint marker = unmarshalUInt(Doxygen::symbolStorage);
+ assert(marker==START_MARKER);
+ m_impl->classDef = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->fileDef = (FileDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->nspace = (NamespaceDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->enumScope = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->annEnumType = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->enumFields = unmarshalMemberList (Doxygen::symbolStorage);
+ m_impl->redefines = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->redefinedBy = unmarshalMemberList (Doxygen::symbolStorage);
+ m_impl->memDef = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->memDec = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->relatedAlso = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->exampleSDict = unmarshalExampleSDict (Doxygen::symbolStorage);
+ m_impl->type = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->args = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->def = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->anc = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->virt = (Specifier)unmarshalInt (Doxygen::symbolStorage);
+ m_impl->prot = (Protection)unmarshalInt(Doxygen::symbolStorage);
+ m_impl->decl = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->bitfields = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->read = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->write = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->exception = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->initializer = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->extraTypeChars = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->initLines = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->memSpec = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->mtype = (MemberDef::MemberType)unmarshalInt (Doxygen::symbolStorage);
+ m_impl->maxInitLines = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->userInitLines = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->annMemb = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->defArgList = unmarshalArgumentList (Doxygen::symbolStorage);
+ m_impl->declArgList = unmarshalArgumentList (Doxygen::symbolStorage);
+ m_impl->tArgList = unmarshalArgumentList (Doxygen::symbolStorage);
+ m_impl->typeConstraints = unmarshalArgumentList (Doxygen::symbolStorage);
+ m_impl->templateMaster = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->defTmpArgLists = unmarshalArgumentLists(Doxygen::symbolStorage);
+ m_impl->cachedAnonymousType = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->classSectionSDict = unmarshalMemberLists (Doxygen::symbolStorage);
+ m_impl->groupAlias = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->grpId = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->memberGroup = (MemberGroup*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->group = (GroupDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->grouppri = (Grouping::GroupPri_t)unmarshalInt (Doxygen::symbolStorage);
+ m_impl->groupFileName = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->groupStartLine = unmarshalInt (Doxygen::symbolStorage);
+ m_impl->groupMember = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->isTypedefValCached = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->cachedTypedefValue = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->cachedTypedefTemplSpec = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->cachedResolvedType = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->docProvider = (MemberDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ m_impl->explicitOutputFileBase = unmarshalQCString (Doxygen::symbolStorage);
+ m_impl->implOnly = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->hasDocumentedParams = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->hasDocumentedReturnType = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->isDMember = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->related = (Relationship)unmarshalInt(Doxygen::symbolStorage);
+ m_impl->stat = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->proto = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->docEnumValues = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->annScope = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->annUsed = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->hasCallGraph = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->hasCallerGraph = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->explExt = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->tspec = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->groupHasDocs = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->docsForDefinition = unmarshalBool (Doxygen::symbolStorage);
+ m_impl->category = (ClassDef*)unmarshalObjPointer (Doxygen::symbolStorage);
+ marker = unmarshalUInt(Doxygen::symbolStorage);
+ assert(marker==END_MARKER);
+
+ //printf("%p: MemberDef::loadFromDisk(): sorting\n",this);
+}
+
+void MemberDef::makeResident() const
+{
+ if (Doxygen::symbolCache==0) return;
+ if (m_cacheHandle==-1) // not yet in cache
+ {
+ MemberDef *victim = 0;
+ MemberDef *that = (MemberDef*)this; // fake method constness
+ that->m_cacheHandle = Doxygen::symbolCache->add(that,(void **)&victim);
+ //printf("adding %s to cache, handle=%d\n",m_impl->name.data(),that->m_cacheHandle);
+ if (victim) // cache was full, victim was the least recently used item and has to go
+ {
+ //printf("%p: makeResident(): cache full %p::saveToDisk(): m_impl=%p\n",this,victim,victim->m_impl);
+ victim->m_cacheHandle=-1; // invalidate cache handle
+ victim->saveToDisk(); // store the item on disk
+ }
+ else // cache not yet full
+ {
+ //printf("Adding %s to cache, handle=%d\n",m_impl->name.data(),m_cacheHandle);
+ }
+ if (m_storagePos!=-1) // already been written to disk
+ {
+ if (isLocked()) // locked in memory
+ {
+ assert(m_impl!=0);
+ that->m_flushPending=FALSE; // no need to flush anymore
+ }
+ else // not locked in memory
+ {
+ assert(m_impl==0);
+ loadFromDisk();
+ }
+ }
+ }
+ else // already cached, make this object the most recently used.
+ {
+ assert(m_impl!=0);
+ //printf("Touching symbol %s\n",m_impl->name.data());
+ Doxygen::symbolCache->use(m_cacheHandle);
+ }
+}
+
+void MemberDef::saveToDisk() const
+{
+ assert(m_impl!=0);
+ MemberDef *that = (MemberDef *)this;
+ //printf("%p: saveToDisk(): m_impl=%p\n",this,m_impl);
+ if (isLocked()) // cannot flush the item as it is locked
+ {
+ that->m_flushPending=TRUE; // flush when unlocked
+ }
+ else // ready to flush the item to disk
+ {
+ //printf("Adding %s to cache, handle=%d by replacing %s\n",
+ // m_impl->name.data(),m_cacheHandle,victim->m_impl->name.data());
+ if (m_storagePos!=-1)
+ // if victim was stored on disk already and is not locked
+ {
+ // free the storage space occupied by the old store item
+ Doxygen::symbolStorage->release(m_storagePos); // free up space for others
+ }
+ // write a the new (possibly modified) instance to disk
+ flushToDisk();
+ // end to write sequence (unless nothing was written due to the lock)
+ Doxygen::symbolStorage->end();
+ }
+}
+
+void MemberDef::lock() const
+{
+}
+
+void MemberDef::unlock() const
+{
+ if (m_flushPending && !isLocked())
+ {
+ //printf("%p: flush after unlock\n",this);
+ // write a the new (possibly modified) instance to disk
+ flushToDisk();
+ // end to write sequence (unless nothing was written due to the lock)
+ Doxygen::symbolStorage->end();
+ }
+}
+