memberdef.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * 
00004  *
00005  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and its
00008  * documentation under the terms of the GNU General Public License is hereby 
00009  * granted. No representations are made about the suitability of this software 
00010  * for any purpose. It is provided "as is" without express or implied warranty.
00011  * See the GNU General Public License for more details.
00012  *
00013  * Documents produced by Doxygen are derivative works derived from the
00014  * input used in their production; they are not affected by this license.
00015  *
00016  */
00017 
00018 #include <stdio.h>
00019 #include <qregexp.h>
00020 #include <assert.h>
00021 #include <md5.h>
00022 #include "memberdef.h"
00023 #include "membername.h"
00024 #include "doxygen.h"
00025 #include "util.h"
00026 #include "code.h"
00027 #include "message.h"
00028 #include "htmlhelp.h"
00029 #include "language.h"
00030 #include "outputlist.h"
00031 #include "example.h"
00032 #include "membergroup.h"
00033 #include "groupdef.h"
00034 #include "defargs.h"
00035 #include "docparser.h"
00036 #include "dot.h"
00037 #include "searchindex.h"
00038 #include "parserintf.h"
00039 #include "marshal.h"
00040 #include "objcache.h"
00041 #include "vhdlscanner.h"
00042 #include "vhdldocgen.h"
00043 
00044 #define START_MARKER 0x4D454D5B // MEM[
00045 #define END_MARKER   0x4D454D5D // MEM]
00046 
00047 //-----------------------------------------------------------------------------
00048 
00049 int MemberDef::s_indentLevel = 0;
00050 
00051 //-----------------------------------------------------------------------------
00052 
00053 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
00054 {
00055   QCString result;
00056   QCString clRealName=n;
00057   int p=0,i;
00058   if ((i=clRealName.find('<'))!=-1)
00059   {
00060     clRealName=clRealName.left(i); // strip template specialization
00061   }
00062   if ((i=clRealName.findRev("::"))!=-1)
00063   {
00064     clRealName=clRealName.right(clRealName.length()-i-2);
00065   }
00066   while ((i=s.find(clRealName,p))!=-1)
00067   {
00068     result+=s.mid(p,i-p);
00069     uint j=clRealName.length()+i;
00070     if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
00071     { // add template names
00072       //printf("Adding %s+%s\n",clRealName.data(),t.data());
00073       result+=clRealName+t; 
00074     }
00075     else 
00076     { // template names already present
00077       //printf("Adding %s\n",clRealName.data());
00078       result+=clRealName;
00079     }
00080     p=i+clRealName.length();
00081   }
00082   result+=s.right(s.length()-p);
00083   //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
00084   return result;
00085 }
00086 
00087 static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
00088                                  const QCString & /*scopeName*/,MemberDef *md)
00089 {
00090   LockingPtr<ArgumentList> defArgList=(md->isDocsForDefinition()) ? 
00091                              md->argumentList() : md->declArgumentList();
00092   //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
00093   if (defArgList==0 || md->isProperty()) 
00094   {
00095     return FALSE; // member has no function like argument list
00096   }
00097   if (!md->isDefine()) ol.docify(" ");
00098 
00099   //printf("writeDefArgList(%d)\n",defArgList->count());
00100   ol.pushGeneratorState();
00101   ol.disableAllBut(OutputGenerator::Html);
00102   {
00103     // html
00104     ol.endMemberDocName();
00105     ol.startParameterList(!md->isObjCMethod()); 
00106   }
00107   ol.enableAll();
00108   ol.disable(OutputGenerator::Html);
00109   {
00110     // other formats
00111     if (!md->isObjCMethod()) ol.docify("("); // start argument list
00112     ol.endMemberDocName();
00113   }
00114   ol.popGeneratorState();
00115   //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
00116 
00117   Argument *a=defArgList->first();
00118   QCString cName;
00119   if (cd)
00120   {
00121     cName=cd->name();
00122     int il=cName.find('<');
00123     int ir=cName.findRev('>');
00124     if (il!=-1 && ir!=-1 && ir>il)
00125     {
00126       cName=cName.mid(il,ir-il+1);
00127       //printf("1. cName=%s\n",cName.data());
00128     }
00129     else if (cd->templateArguments())
00130     {
00131       cName=tempArgListToString(cd->templateArguments()); 
00132       //printf("2. cName=%s\n",cName.data());
00133     }
00134     else // no template specifier
00135     {
00136       cName.resize(0);
00137     }
00138   }
00139   //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
00140 
00141   //if (!md->isDefine()) ol.startParameter(TRUE); else ol.docify(" ");
00142   bool first=TRUE;
00143   while (a)
00144   {
00145     if (md->isDefine() || first) ol.startParameterType(first,md->isObjCMethod()?"dummy":0);
00146     QRegExp re(")("),res("(.*\\*");
00147     int vp=a->type.find(re);
00148     int wp=a->type.find(res);
00149 
00150     // use the following to put the function pointer type before the name
00151     bool hasFuncPtrType=FALSE; 
00152 
00153     // or use the following to put the function pointer as it appears in
00154     // the prototype.
00155     //bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp; 
00156 
00157     if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
00158     {
00159       ol.docify(a->attrib+" ");
00160     }
00161     if (hasFuncPtrType) // argument type is a function pointer
00162     {
00163       //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
00164       QCString n=a->type.left(vp);
00165       if (hasFuncPtrType) n=a->type.left(wp);
00166       if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
00167       if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
00168       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
00169     }
00170     else // non-function pointer type
00171     {
00172       QCString n=a->type;
00173       if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
00174       if (a->type!="...")
00175       {
00176         if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
00177         linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
00178       }
00179     }
00180     if (!md->isDefine())
00181     {
00182       ol.endParameterType();
00183       ol.startParameterName(defArgList->count()<2);
00184     }
00185     if (hasFuncPtrType)
00186     {
00187       ol.docify(a->type.mid(wp,vp-wp)); 
00188     }
00189     if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name
00190     { 
00191       if (!hasFuncPtrType)
00192       {
00193         ol.docify(" ");
00194       }
00195       ol.disable(OutputGenerator::Man);
00196       ol.startEmphasis();
00197       ol.enable(OutputGenerator::Man);
00198       if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
00199       ol.disable(OutputGenerator::Man);
00200       ol.endEmphasis();
00201       ol.enable(OutputGenerator::Man);
00202     }
00203     if (!a->array.isEmpty())
00204     {
00205       ol.docify(a->array);
00206     }
00207     if (hasFuncPtrType) // write the part of the argument type 
00208                         // that comes after the name
00209     {
00210       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),
00211                   md->name(),a->type.right(a->type.length()-vp));
00212     }
00213     if (!a->defval.isEmpty()) // write the default value
00214     {
00215       QCString n=a->defval;
00216       if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
00217       ol.docify(" = ");
00218 
00219       ol.startTypewriter();
00220       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n,FALSE,TRUE,TRUE); 
00221       ol.endTypewriter();
00222 
00223     }
00224     a=defArgList->next();
00225     if (a) 
00226     {
00227       if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
00228       if (!md->isDefine()) 
00229       {
00230         QCString key;
00231         if (md->isObjCMethod() && a->attrib.length()>=2)
00232         {
00233           //printf("Found parameter keyword %s\n",a->attrib.data());
00234           // strip [ and ]
00235           key=a->attrib.mid(1,a->attrib.length()-2);
00236           if (key!=",") key+=":"; // for normal keywords add colon
00237         }
00238         ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
00239         ol.startParameterType(FALSE,key);
00240       }
00241     }
00242     first=FALSE;
00243   }
00244   ol.pushGeneratorState();
00245   bool htmlOn = ol.isEnabled(OutputGenerator::Html);
00246   ol.disable(OutputGenerator::Html);
00247   //if (!first) ol.writeString("&nbsp;");
00248   if (!md->isObjCMethod()) ol.docify(")"); // end argument list
00249   ol.enableAll();
00250   ol.disableAllBut(OutputGenerator::Html);
00251   if (!htmlOn) ol.disable(OutputGenerator::Html);
00252   if (!md->isDefine()) 
00253   {
00254     if (first) ol.startParameterName(defArgList->count()<2);
00255     ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
00256   }
00257   else 
00258   {
00259     ol.endParameterType();
00260     ol.startParameterName(TRUE);
00261     ol.endParameterName(TRUE,TRUE,!md->isObjCMethod());
00262   }
00263   ol.popGeneratorState();
00264   if (md->extraTypeChars())
00265   {
00266     ol.docify(md->extraTypeChars());
00267   }
00268   if (defArgList->constSpecifier)
00269   {
00270     ol.docify(" const");
00271   }
00272   if (defArgList->volatileSpecifier)
00273   {
00274     ol.docify(" volatile");
00275   }
00276   return TRUE;
00277 }
00278 
00279 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
00280 {
00281   ol.docify("template<");
00282   Argument *a=al->first();
00283   while (a)
00284   {
00285     ol.docify(a->type);
00286     ol.docify(" ");
00287     ol.docify(a->name);
00288     if (a->defval.length()!=0)
00289     {
00290       ol.docify(" = ");
00291       ol.docify(a->defval);
00292     } 
00293     a=al->next();
00294     if (a) ol.docify(", ");
00295   }
00296   ol.docify("> ");
00297 }
00298 
00299 //-----------------------------------------------------------------------------
00300 //-----------------------------------------------------------------------------
00301 //-----------------------------------------------------------------------------
00302 
00303 class MemberDefImpl
00304 {
00305   public:
00306     MemberDefImpl();
00307    ~MemberDefImpl();
00308     void init(Definition *def,const char *t,const char *a,const char *e,
00309               Protection p,Specifier v,bool s,bool r,MemberDef::MemberType mt,
00310               const ArgumentList *tal,const ArgumentList *al
00311              );
00312 
00313     ClassDef     *classDef;   // member of or related to 
00314     FileDef      *fileDef;    // member of file definition 
00315     NamespaceDef *nspace;     // the namespace this member is in.
00316 
00317     MemberDef  *enumScope;    // the enclosing scope, if this is an enum field
00318     MemberDef  *annEnumType;  // the annonymous enum that is the type of this member
00319     MemberList *enumFields;   // enumeration fields
00320 
00321     MemberDef  *redefines;    // the members that this member redefines 
00322     MemberList *redefinedBy;  // the list of members that redefine this one
00323 
00324     MemberDef  *memDef;       // member definition for this declaration
00325     MemberDef  *memDec;       // member declaration for this definition
00326     ClassDef   *relatedAlso;  // points to class marked by relatedAlso
00327 
00328     ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
00329 
00330     QCString type;            // return type
00331     QCString args;            // function arguments/variable array specifiers
00332     QCString def;             // member definition in code (fully qualified name)
00333     QCString anc;             // HTML anchor name
00334     Specifier virt;           // normal/virtual/pure virtual
00335     Protection prot;          // protection type [Public/Protected/Private]
00336     QCString decl;            // member declaration in class
00337 
00338     QCString bitfields;       // struct member bitfields
00339     QCString read;            // property read accessor
00340     QCString write;           // property write accessor
00341     QCString exception;       // exceptions that can be thrown
00342     QCString initializer;     // initializer
00343     QCString extraTypeChars;  // extra type info found after the argument list
00344     int initLines;            // number of lines in the initializer
00345 
00346     int  memSpec;             // The specifiers present for this member
00347     MemberDef::MemberType mtype;         // returns the kind of member
00348     int maxInitLines;         // when the initializer will be displayed 
00349     int userInitLines;        // result of explicit \hideinitializer or \showinitializer
00350     MemberDef  *annMemb;
00351 
00352     ArgumentList *defArgList;    // argument list of this member definition
00353     ArgumentList *declArgList;   // argument list of this member declaration
00354 
00355     ArgumentList *tArgList;      // template argument list of function template
00356     ArgumentList *typeConstraints; // type constraints for template parameters
00357     MemberDef *templateMaster;
00358     QList<ArgumentList> *defTmpArgLists; // lists of template argument lists 
00359                                          // (for template functions in nested template classes)
00360 
00361     ClassDef *cachedAnonymousType; // if the member has an anonymous compound
00362                                    // as its type then this is computed by
00363                                    // getClassDefOfAnonymousType() and 
00364                                    // cached here. 
00365     SDict<MemberList> *classSectionSDict; // not accessible
00366 
00367     MemberDef *groupAlias;    // Member containing the definition
00368     int grpId;                // group id
00369     MemberGroup *memberGroup; // group's member definition
00370     GroupDef *group;          // group in which this member is in
00371     Grouping::GroupPri_t grouppri; // priority of this definition
00372     QCString groupFileName;   // file where this grouping was defined
00373     int groupStartLine;       // line  "      "      "     "     "
00374     MemberDef *groupMember;
00375 
00376     bool isTypedefValCached;
00377     ClassDef *cachedTypedefValue;
00378     QCString cachedTypedefTemplSpec;
00379     QCString cachedResolvedType;
00380     
00381     // inbody documentation
00382     int inbodyLine;
00383     QCString inbodyFile;
00384     QCString inbodyDocs;
00385 
00386     // documentation inheritance
00387     MemberDef *docProvider;
00388 
00389     // to store the output file base from tag files
00390     QCString explicitOutputFileBase;
00391 
00392     // objective-c
00393     bool implOnly; // function found in implementation but not 
00394                      // in the interface
00395     bool hasDocumentedParams;
00396     bool hasDocumentedReturnType;
00397     bool isDMember;
00398     bool related;             // is this a member that is only related to a class
00399     bool stat;                // is it a static function?
00400     bool proto;               // is it a prototype;
00401     bool docEnumValues;       // is an enum with documented enum values.
00402     bool annScope;            // member is part of an annoymous scope
00403     bool annUsed;             
00404     bool hasCallGraph;
00405     bool hasCallerGraph;
00406     bool explExt;             // member was explicitly declared external
00407     bool tspec;               // member is a template specialization
00408     bool groupHasDocs;        // true if the entry that caused the grouping was documented
00409     bool docsForDefinition;   // TRUE => documentation block is put before
00410                               //         definition.
00411                               // FALSE => block is put before declaration.
00412 };
00413 
00414 MemberDefImpl::MemberDefImpl() :
00415     enumFields(0),
00416     redefinedBy(0),
00417     exampleSDict(0),
00418     defArgList(0),
00419     declArgList(0),
00420     tArgList(0),
00421     typeConstraints(0),
00422     defTmpArgLists(0),
00423     classSectionSDict(0)
00424 {
00425 }
00426 
00427 MemberDefImpl::~MemberDefImpl()
00428 {
00429   delete redefinedBy;
00430   delete exampleSDict;
00431   delete enumFields;
00432   delete defArgList;
00433   delete tArgList;
00434   delete typeConstraints;
00435   delete defTmpArgLists;
00436   delete classSectionSDict;
00437   delete declArgList;
00438 }
00439 
00440 void MemberDefImpl::init(Definition *def,
00441                      const char *t,const char *a,const char *e,
00442                      Protection p,Specifier v,bool s,bool r,MemberDef::MemberType mt,
00443                      const ArgumentList *tal,const ArgumentList *al
00444                     )
00445 {
00446   classDef=0;
00447   fileDef=0;
00448   redefines=0;
00449   relatedAlso=0;
00450   redefinedBy=0;
00451   nspace=0;
00452   memDef=0;
00453   memDec=0;
00454   group=0;
00455   grpId=-1;
00456   exampleSDict=0;
00457   enumFields=0;
00458   enumScope=0;
00459   defTmpArgLists=0;
00460   hasCallGraph = FALSE;
00461   hasCallerGraph = FALSE;
00462   initLines=0;
00463   type=t;
00464   if (mt==MemberDef::Typedef) type.stripPrefix("typedef ");
00465   //  type.stripPrefix("struct ");
00466   //  type.stripPrefix("class " );
00467   //  type.stripPrefix("union " );
00468   type=removeRedundantWhiteSpace(type);
00469   args=a;
00470   args=removeRedundantWhiteSpace(args);
00471   if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
00472 
00473   memberGroup=0;
00474   virt=v;
00475   prot=p;
00476   related=r;
00477   stat=s;
00478   mtype=mt;
00479   exception=e;
00480   proto=FALSE;
00481   annScope=FALSE;
00482   memSpec=0;
00483   annMemb=0;
00484   annUsed=FALSE;
00485   annEnumType=0;
00486   groupAlias=0;
00487   explExt=FALSE;
00488   tspec=FALSE;
00489   cachedAnonymousType=0;
00490   maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
00491   userInitLines=-1;
00492   docEnumValues=FALSE;
00493   // copy function template arguments (if any)
00494   if (tal)
00495   {
00496     tArgList = new ArgumentList;
00497     tArgList->setAutoDelete(TRUE);
00498     ArgumentListIterator ali(*tal);
00499     Argument *a;
00500     for (;(a=ali.current());++ali)
00501     {
00502       tArgList->append(new Argument(*a));
00503     }
00504   }
00505   else
00506   {
00507     tArgList=0;
00508   }
00509   //printf("new member al=%p\n",al);
00510   // copy function definition arguments (if any)
00511   if (al)
00512   {
00513     defArgList = new ArgumentList;
00514     defArgList->setAutoDelete(TRUE);
00515     ArgumentListIterator ali(*al);
00516     Argument *a;
00517     for (;(a=ali.current());++ali)
00518     {
00519       //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data());
00520       defArgList->append(new Argument(*a));
00521     }
00522     defArgList->constSpecifier    = al->constSpecifier;
00523     defArgList->volatileSpecifier = al->volatileSpecifier;
00524     defArgList->pureSpecifier     = al->pureSpecifier;
00525     //printf("defArgList(%p)->constSpecifier=%d\n",defArgList,defArgList->constSpecifier);
00526   }
00527   else
00528   {
00529     defArgList=0;
00530   }
00531   // convert function declaration arguments (if any)
00532   if (!args.isEmpty())
00533   {
00534     declArgList = new ArgumentList;
00535     stringToArgumentList(args,declArgList,&extraTypeChars);
00536     //printf("setDeclArgList %s to %p const=%d\n",args.data(),
00537     //    declArgList,declArgList->constSpecifier);
00538   }
00539   else
00540   {
00541     declArgList = 0;
00542   }
00543   templateMaster = 0;
00544   classSectionSDict = 0;
00545   docsForDefinition = TRUE;
00546   isTypedefValCached = FALSE;
00547   cachedTypedefValue = 0;
00548   inbodyLine = -1;
00549   implOnly=FALSE;
00550   groupMember = 0;
00551   hasDocumentedParams = FALSE;
00552   hasDocumentedReturnType = FALSE;
00553   docProvider = 0;
00554   isDMember = def->getDefFileName().right(2).lower()==".d";
00555 }
00556 
00557 
00558 //-----------------------------------------------------------------------------
00559 //-----------------------------------------------------------------------------
00560 //-----------------------------------------------------------------------------
00561 
00583 MemberDef::MemberDef(const char *df,int dl,
00584                      const char *t,const char *na,const char *a,const char *e,
00585                      Protection p,Specifier v,bool s,bool r,MemberType mt,
00586                      const ArgumentList *tal,const ArgumentList *al
00587                     ) : Definition(df,dl,removeRedundantWhiteSpace(na))
00588 {
00589   m_storagePos=-1;
00590   m_cacheHandle=-1;
00591   m_impl = new MemberDefImpl;
00592   m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
00593   m_flushPending = FALSE;
00594 }
00595 
00597 MemberDef::~MemberDef()
00598 {
00599   delete m_impl;
00600   if (m_cacheHandle!=-1)
00601   {
00602     Doxygen::symbolCache->del(m_cacheHandle);
00603     m_cacheHandle=-1;
00604   }
00605 }
00606 
00607 void MemberDef::setReimplements(MemberDef *md)   
00608 { 
00609   makeResident();
00610   //if (redefines==0) redefines = new MemberList;
00611   //if (redefines->find(md)==-1) redefines->inSort(md);
00612 
00613   m_impl->redefines = md;
00614 }
00615 
00616 void MemberDef::insertReimplementedBy(MemberDef *md)
00617 {
00618   makeResident();
00619   if (m_impl->templateMaster)
00620   {
00621     m_impl->templateMaster->insertReimplementedBy(md);
00622   }
00623   if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberList::redefinedBy);
00624   if (m_impl->redefinedBy->findRef(md)==-1) 
00625   {
00626     m_impl->redefinedBy->inSort(md);
00627   }
00628 }
00629 
00630 MemberDef *MemberDef::reimplements() const      
00631 { 
00632   makeResident();
00633   return m_impl->redefines; 
00634 }
00635 
00636 LockingPtr<MemberList> MemberDef::reimplementedBy() const   
00637 { 
00638   makeResident();
00639   return LockingPtr<MemberList>(this,m_impl->redefinedBy); 
00640 }
00641 
00642 void MemberDef::insertEnumField(MemberDef *md)
00643 {
00644   makeResident();
00645   if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberList::enumFields);
00646   m_impl->enumFields->append(md);
00647 }
00648 
00649 bool MemberDef::addExample(const char *anchor,const char *nameStr,
00650                            const char *file)
00651 {
00652   makeResident();
00653   //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
00654   if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
00655   if (m_impl->exampleSDict->find(nameStr)==0) 
00656   {
00657     //printf("Add reference to example %s to member %s\n",nameStr,name.data());
00658     Example *e=new Example;
00659     e->anchor=anchor;
00660     e->name=nameStr;
00661     e->file=file;
00662     m_impl->exampleSDict->inSort(nameStr,e);
00663     return TRUE;
00664   }
00665   return FALSE; 
00666 }
00667 
00668 bool MemberDef::hasExamples()
00669 {
00670   makeResident();
00671   if (m_impl->exampleSDict==0) 
00672     return FALSE;
00673   else
00674     return m_impl->exampleSDict->count()>0;
00675 }
00676 
00677 QCString MemberDef::getOutputFileBase() const
00678 {
00679   makeResident();
00680   static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
00681   QCString baseName;
00682   //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
00683   //    name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
00684   //    m_impl->nspace,m_impl->fileDef);
00685   if (!m_impl->explicitOutputFileBase.isEmpty())
00686   {
00687     return m_impl->explicitOutputFileBase;
00688   }
00689   else if (m_impl->templateMaster)
00690   {
00691     return m_impl->templateMaster->getOutputFileBase();
00692   }
00693   else if (m_impl->group)
00694   {
00695     baseName=m_impl->group->getOutputFileBase();
00696   }
00697   else if (m_impl->classDef)
00698   {
00699     baseName=m_impl->classDef->getOutputFileBase();
00700   }
00701   else if (m_impl->nspace)
00702   {
00703     baseName=m_impl->nspace->getOutputFileBase();
00704   }
00705   else if (m_impl->fileDef)
00706   {
00707     baseName=m_impl->fileDef->getOutputFileBase();
00708   }
00709   
00710   if (baseName.isEmpty())
00711   {
00712     warn(getDefFileName(),getDefLine(),
00713        "Warning: Internal inconsistency: member %s does not belong to any"
00714        " container!",name().data()
00715       );
00716     return "dummy";
00717   }
00718   else if (separateMemberPages)
00719   {
00720     if (getEnumScope()) // enum value, which is part of enum's documentation
00721     {
00722       baseName+="_"+getEnumScope()->anchor();
00723     }
00724     else
00725     {
00726       baseName+="_"+anchor();
00727     }
00728   }
00729   return baseName;
00730 }
00731 
00732 QCString MemberDef::getReference() const
00733 {
00734   makeResident();
00735   QCString ref = Definition::getReference();
00736   if (!ref.isEmpty())
00737   {
00738     return ref;
00739   }
00740   if (m_impl->templateMaster)
00741   {
00742     return m_impl->templateMaster->getReference();
00743   }
00744   else if (m_impl->group)
00745   {
00746     return m_impl->group->getReference();
00747   }
00748   else if (m_impl->classDef)
00749   {
00750     return m_impl->classDef->getReference();
00751   }
00752   else if (m_impl->nspace)
00753   {
00754     return m_impl->nspace->getReference();
00755   }
00756   else if (m_impl->fileDef)
00757   {
00758     return m_impl->fileDef->getReference();
00759   }
00760   return "";
00761 }
00762 
00763 QCString MemberDef::anchor() const
00764 {
00765   makeResident();
00766   QCString result=m_impl->anc;
00767   if (m_impl->groupAlias)     return m_impl->groupAlias->anchor();
00768   if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
00769   if (m_impl->enumScope) result.prepend(m_impl->enumScope->anchor());
00770   if (m_impl->group) 
00771   {
00772     if (m_impl->groupMember)
00773     {
00774       result=m_impl->groupMember->anchor();
00775     }
00776     else if (getReference().isEmpty())
00777     {
00778       result.prepend("g");
00779     }
00780   }
00781   return result;
00782 }
00783 
00784 bool MemberDef::isLinkableInProject() const
00785 {
00786   static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
00787   static bool extractStatic  = Config_getBool("EXTRACT_STATIC");
00788   makeResident();
00789 
00790   //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
00791   if (isHidden()) 
00792   {
00793     //printf("is hidden\n");
00794     return FALSE;
00795   }
00796   if (m_impl->templateMaster)
00797   {
00798     //printf("has template master\n");
00799     return m_impl->templateMaster->isLinkableInProject();
00800   }
00801   if (name().isEmpty() || name().at(0)=='@') 
00802   {
00803     //printf("name invalid\n");
00804     return FALSE; // not a valid or a dummy name
00805   }
00806   if (!hasDocumentation() && !isReference()) 
00807   {
00808     //printf("no docs or reference\n");
00809     return FALSE; // no documentation
00810   }
00811   if (m_impl->group && !m_impl->group->isLinkableInProject()) 
00812   {
00813     //printf("group but group not linkable!\n");
00814     return FALSE; // group but group not linkable
00815   }
00816   if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject()) 
00817   {
00818     //printf("in a class but class not linkable!\n");
00819     return FALSE; // in class but class not linkable
00820   }
00821   if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject()) 
00822   {
00823     //printf("in a namespace but namespace not linkable!\n");
00824     return FALSE; // in namespace but namespace not linkable
00825   }
00826   if (!m_impl->group && !m_impl->nspace && !m_impl->related && !m_impl->classDef && m_impl->fileDef && !m_impl->fileDef->isLinkableInProject()) 
00827   {
00828     //printf("in a file but file not linkable!\n");
00829     return FALSE; // in file (and not in namespace) but file not linkable
00830   }
00831   if (m_impl->prot==Private && !extractPrivate && m_impl->mtype!=Friend) 
00832   {
00833     //printf("private and invisible!\n");
00834     return FALSE; // hidden due to protection
00835   }
00836   if (isStatic() && m_impl->classDef==0 && !extractStatic) 
00837   {
00838     //printf("static and invisible!\n");
00839     return FALSE; // hidden due to staticness
00840   }
00841   //printf("linkable!\n");
00842   return TRUE; // linkable!
00843 }
00844 
00845 bool MemberDef::isLinkable() const
00846 {
00847   makeResident();
00848   if (m_impl->templateMaster)
00849   {
00850     return m_impl->templateMaster->isLinkable();
00851   }
00852   else
00853   {
00854     return isLinkableInProject() || isReference();
00855   }
00856 }
00857 
00858 
00859 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
00860 {
00861   if (lists)
00862   {
00863     makeResident();
00864     if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
00865     m_impl->defTmpArgLists = copyArgumentLists(lists);
00866   }
00867 }
00868 
00869 void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
00870                       FileDef *fd,GroupDef *gd,bool onlyText)
00871 {
00872   static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
00873   static bool hideScopeNames     = Config_getBool("HIDE_SCOPE_NAMES");
00874   makeResident();
00875   LockingPtr<MemberDef> lock(this,this);
00876   QCString sep = optimizeOutputJava ? "." : "::";
00877   QCString n = name();
00878   if (!hideScopeNames && m_impl->classDef && gd) n.prepend(m_impl->classDef->name()+sep);
00879   else if (!hideScopeNames && m_impl->nspace && (gd || fd)) n.prepend(m_impl->nspace->name()+sep);
00880   if (isObjCMethod())
00881   {
00882     if (isStatic()) ol.docify("+ "); else ol.docify("- ");
00883   }
00884   if (!onlyText) // write link
00885   {
00886     if (m_impl->mtype==EnumValue && getGroupDef()==0 &&          // enum value is not grouped
00887         getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
00888     {
00889       GroupDef *enumValGroup = getEnumScope()->getGroupDef();
00890       ol.writeObjectLink(enumValGroup->getReference(),
00891                          enumValGroup->getOutputFileBase(),
00892                          anchor(),n);
00893     }
00894     else
00895     {
00896       ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
00897     }
00898   }
00899   else // write only text
00900   {
00901     ol.startBold();
00902     ol.docify(n);
00903     ol.endBold();
00904   }
00905 }
00906 
00910 ClassDef *MemberDef::getClassDefOfAnonymousType() 
00911 {
00912   makeResident();
00913   if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
00914   LockingPtr<MemberDef> lock(this,this);
00915 
00916   QCString cname;
00917   if (getClassDef()!=0) 
00918   {
00919     cname=getClassDef()->name().copy();
00920   }
00921   else if (getNamespaceDef()!=0)
00922   {
00923     cname=getNamespaceDef()->name().copy();
00924   }
00925   QCString ltype(m_impl->type);
00926   // strip `static' keyword from ltype
00927   //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
00928   // strip `friend' keyword from ltype
00929   ltype.stripPrefix("friend ");
00930   static QRegExp r("@[0-9]+");
00931   int l,i=r.match(ltype,0,&l);
00932   //printf("ltype=`%s' i=%d\n",ltype.data(),i);
00933   // search for the last anonymous scope in the member type
00934   ClassDef *annoClassDef=0;
00935   if (i!=-1) // found anonymous scope in type
00936   {
00937     int il=i-1,ir=i+l;
00938     // extract anonymous scope
00939     while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
00940     if (il>0) il++; else if (il<0) il=0;
00941     while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
00942 
00943     QCString annName = ltype.mid(il,ir-il);
00944 
00945     // if inside a class or namespace try to prepend the scope name
00946     if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::") 
00947     {
00948       QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
00949       //printf("Member::writeDeclaration: Trying %s\n",ts.data());
00950       annoClassDef=getClass(ts);
00951     }
00952     // if not found yet, try without scope name
00953     if (annoClassDef==0)
00954     {
00955       QCString ts=stripAnonymousNamespaceScope(annName);
00956       //printf("Member::writeDeclaration: Trying %s\n",ts.data());
00957       annoClassDef=getClass(ts);
00958     }
00959   }
00960   m_impl->cachedAnonymousType = annoClassDef;
00961   return annoClassDef;
00962 }
00963     
00967 bool MemberDef::isBriefSectionVisible() const
00968 {
00969   static bool extractStatic       = Config_getBool("EXTRACT_STATIC");
00970   static bool hideUndocMembers    = Config_getBool("HIDE_UNDOC_MEMBERS");
00971   static bool briefMemberDesc     = Config_getBool("BRIEF_MEMBER_DESC");
00972   static bool repeatBrief         = Config_getBool("REPEAT_BRIEF");
00973   static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
00974   static bool extractPrivate      = Config_getBool("EXTRACT_PRIVATE");
00975 
00976   //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
00977   //    name().data(),
00978   //    0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
00979   //    "", //getFileDef()->name().data(),
00980   //    argsString());
00981 
00982   makeResident();
00983   LockingPtr<MemberDef> lock(this,this);
00984   MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
00985   //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
00986   //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
00987   bool hasDocs = hasDocumentation() || 
00988                   // part of a documented member group
00989                  (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
00990 
00991   // only include static members with file/namespace scope if 
00992   // explicitly enabled in the config file
00993   bool visibleIfStatic = !(getClassDef()==0 && 
00994                            isStatic() && 
00995                            !extractStatic
00996                           );
00997 
00998   // only include members is the are documented or 
00999   // HIDE_UNDOC_MEMBERS is NO in the config file
01000   bool visibleIfDocumented = (!hideUndocMembers || 
01001                               hasDocs || 
01002                               isDocumentedFriendClass()
01003                              );
01004 
01005   // hide members with no detailed description and brief descriptions 
01006   // explicitly disabled.
01007   bool visibleIfEnabled = !(hideUndocMembers && 
01008                             documentation().isEmpty() &&
01009                             !briefMemberDesc && 
01010                             !repeatBrief
01011                            );
01012 
01013   // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
01014   bool visibleIfFriendCompound = !(hideFriendCompounds &&
01015                                    isFriend() &&
01016                                    (m_impl->type=="friend class" || 
01017                                     m_impl->type=="friend struct" ||
01018                                     m_impl->type=="friend union"
01019                                    )
01020                                   );
01021   
01022   // only include members that are non-private unless EXTRACT_PRIVATE is
01023   // set to YES or the member is part of a group
01024   bool visibleIfPrivate = (protection()!=Private || 
01025                            extractPrivate ||
01026                            m_impl->mtype==Friend
01027                           );
01028   
01029   // hide member if it overrides a member in a superclass and has no
01030   // documentation of its own
01031   //bool visibleIfDocVirtual = !reimplements() || 
01032   //                           !Config_getBool("INHERIT_DOCS") ||  
01033   //                           hasDocs;
01034 
01035   // true if this member is a constructor or destructor
01036   bool cOrDTor = isConstructor() || isDestructor();
01037 
01038   // hide default constructors or destructors (no args) without
01039   // documentation
01040   bool visibleIfNotDefaultCDTor = !(cOrDTor &&
01041                                    m_impl->defArgList &&
01042                                    (m_impl->defArgList->isEmpty() ||
01043                                     m_impl->defArgList->first()->type == "void"
01044                                    ) &&
01045                                    !hasDocs
01046                                   );
01047 
01048   //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
01049   //       "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
01050   //       "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented,
01051   //       visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
01052   //       visibleIfFriendCompound);
01053   
01054   bool visible = visibleIfStatic     && visibleIfDocumented      && 
01055                  visibleIfEnabled    && visibleIfPrivate         &&
01056                  /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor && 
01057                  visibleIfFriendCompound &&
01058                  !m_impl->annScope;
01059   //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
01060   return visible;
01061 }
01062 
01063 
01064 void MemberDef::writeDeclaration(OutputList &ol,
01065                ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
01066                bool inGroup
01067                )
01068 {
01069   //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",name().data(),inGroup);
01070 
01071   // hide enum value, since they appear already as part of the enum, unless they
01072   // are explicitly grouped.
01073   makeResident();
01074   if (!inGroup && m_impl->mtype==EnumValue) return;
01075   LockingPtr<MemberDef> lock(this,this);
01076 
01077   // hide members whose brief section should not be visible
01078   //if (!isBriefSectionVisible()) return;
01079 
01080   Definition *d=0;
01081   ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
01082   if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
01083 
01084   // write tag file information of this member
01085   if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
01086   {
01087     Doxygen::tagFile << "    <member kind=\"";
01088     switch (m_impl->mtype)
01089     {
01090       case Define:      Doxygen::tagFile << "define";      break;
01091       case EnumValue:   Doxygen::tagFile << "enumvalue";   break;
01092       case Property:    Doxygen::tagFile << "property";    break;
01093       case Event:       Doxygen::tagFile << "event";       break;
01094       case Variable:    Doxygen::tagFile << "variable";    break;
01095       case Typedef:     Doxygen::tagFile << "typedef";     break;
01096       case Enumeration: Doxygen::tagFile << "enumeration"; break;
01097       case Function:    Doxygen::tagFile << "function";    break;
01098       case Signal:      Doxygen::tagFile << "signal";      break;
01099       case Prototype:   Doxygen::tagFile << "prototype";   break;
01100       case Friend:      Doxygen::tagFile << "friend";      break;
01101       case DCOP:        Doxygen::tagFile << "dcop";        break;
01102       case Slot:        Doxygen::tagFile << "slot";        break;
01103     }
01104     if (m_impl->prot!=Public)
01105     {
01106       Doxygen::tagFile << "\" protection=\"";
01107       if (m_impl->prot==Protected)    Doxygen::tagFile << "protected";
01108       else if (m_impl->prot==Package) Doxygen::tagFile << "package";
01109       else /* Private */              Doxygen::tagFile << "private"; 
01110     }
01111     if (m_impl->virt!=Normal)
01112     {
01113       Doxygen::tagFile << "\" virtualness=\"";
01114       if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual";
01115       else /* Pure */            Doxygen::tagFile << "pure"; 
01116     }
01117     if (isStatic())
01118     {
01119       Doxygen::tagFile << "\" static=\"yes";
01120     }
01121     Doxygen::tagFile << "\">" << endl;
01122     Doxygen::tagFile << "      <type>" << convertToXML(typeString()) << "</type>" << endl;
01123     Doxygen::tagFile << "      <name>" << convertToXML(name()) << "</name>" << endl;
01124     Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
01125     Doxygen::tagFile << "      <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
01126     Doxygen::tagFile << "      <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
01127     writeDocAnchorsToTagFile();
01128     Doxygen::tagFile << "    </member>" << endl;
01129   }
01130 
01131   // write search index info
01132   if (Config_getBool("SEARCHENGINE") && !isReference())
01133   {
01134     Doxygen::searchIndex->setCurrentDoc(qualifiedName(),getOutputFileBase(),anchor());
01135     Doxygen::searchIndex->addWord(localName(),TRUE);
01136     Doxygen::searchIndex->addWord(qualifiedName(),FALSE);
01137   }
01138 
01139   QCString cname  = d->name();
01140   QCString cfname = getOutputFileBase();
01141   //QCString osname = cname;
01142   // in case of class members that are put in a group the name of the outerscope
01143   // differs from the cname.
01144   //if (getOuterScope()) osname=getOuterScope()->name();
01145 
01146   //HtmlHelp *htmlHelp=0;
01147   //bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
01148   //if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
01149 
01150   // search for the last anonymous scope in the member type
01151   ClassDef *annoClassDef=getClassDefOfAnonymousType();
01152 
01153   // start a new member declaration
01154   bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
01156   ol.startMemberItem( isAnonymous ? 1 : m_impl->tArgList ? 3 : 0);
01157 
01158   // If there is no detailed description we need to write the anchor here.
01159   bool detailsVisible = isDetailedSectionLinkable();
01160   if (!detailsVisible && !m_impl->annMemb)
01161   {
01162     QCString doxyName=name().copy();
01163     if (!cname.isEmpty()) doxyName.prepend(cname+"::");
01164     QCString doxyArgs=argsString();
01165     ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
01166 
01167     ol.pushGeneratorState();
01168     ol.disable(OutputGenerator::Man);
01169     ol.disable(OutputGenerator::Latex);
01170     ol.docify("\n");
01171     ol.popGeneratorState();
01172   }
01173 
01174   if (annoClassDef || m_impl->annMemb)
01175   {
01176     int j;
01177     for (j=0;j<s_indentLevel;j++) 
01178     {
01179       ol.writeNonBreakableSpace(3);
01180     }
01181   }
01182 
01183   // *** write template lists
01184   if (m_impl->tArgList)
01185   {
01186     if (!isAnonymous) ol.startMemberTemplateParams();
01187     writeTemplatePrefix(ol,m_impl->tArgList);
01188     if (!isAnonymous) ol.endMemberTemplateParams();
01189   }
01190 
01191   // *** write type
01192   QCString ltype(m_impl->type);
01193   if (m_impl->mtype==Typedef) ltype.prepend("typedef ");
01194   // strip `friend' keyword from ltype
01195   ltype.stripPrefix("friend ");
01196   static QRegExp r("@[0-9]+");
01197 
01198   bool endAnonScopeNeeded=FALSE;
01199   int l,i=r.match(ltype,0,&l);
01200   if (i!=-1) // member has an anonymous type
01201   {
01202     //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
01203     //    annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
01204 
01205     if (annoClassDef) // type is an anonymous compound
01206     {
01207       int ir=i+l;
01208       //printf("<<<<<<<<<<<<<<\n");
01209       ol.startAnonTypeScope(s_indentLevel++);
01210       annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup);
01211       //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
01212       ol.startMemberItem(2);
01213       int j;
01214       for (j=0;j< s_indentLevel-1;j++) 
01215       {
01216         ol.writeNonBreakableSpace(3);
01217       }
01218       QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
01219       //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data());
01220       ol.docify("}");
01221       if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) 
01222       {
01223         ol.docify(";"); 
01224       }
01225       endAnonScopeNeeded=TRUE;
01226     }
01227     else
01228     {
01229       if (getAnonymousEnumType()) // type is an anonymous enum
01230       {
01231         linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype.left(i),TRUE); 
01232         getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
01233         //ol+=*getAnonymousEnumType()->enumDecl();
01234         linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); 
01235       }
01236       else
01237       {
01238         ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
01239         linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); 
01240       }
01241     }
01242   }
01243   else if (ltype=="@") // rename type from enum values
01244   {
01245     ltype="";
01246   }
01247   else
01248   {
01249     if (isObjCMethod())
01250     {
01251       ltype.prepend("(");
01252       ltype.append(")");
01253     }
01254     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); 
01255   }
01256   bool htmlOn = ol.isEnabled(OutputGenerator::Html);
01257   if (htmlOn && Config_getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty())
01258   {
01259     ol.disable(OutputGenerator::Html);
01260   }
01261   if (!ltype.isEmpty()) ol.docify(" ");
01262   if (htmlOn) 
01263   {
01264     ol.enable(OutputGenerator::Html);
01265   }
01266 
01267   if (m_impl->annMemb) 
01268   {
01269     ol.pushGeneratorState();
01270     ol.disableAllBut(OutputGenerator::Html);
01271     ol.writeNonBreakableSpace(3);
01272     ol.popGeneratorState();
01273   }
01274   else
01275   {
01276     ol.insertMemberAlign(m_impl->tArgList!=0);
01277   }
01278 
01279   // *** write name
01280   if (!name().isEmpty() && name().at(0)!='@') // hide annonymous stuff 
01281   {
01282     //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
01283     if (!(name().isEmpty() || name().at(0)=='@') && // name valid
01284         (hasDocumentation() || isReference()) && // has docs
01285         !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=Friend) && // hidden due to protection
01286         !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness
01287        )
01288     {
01289       if (m_impl->annMemb)
01290       {
01291         //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
01292         m_impl->annMemb->writeLink(ol,
01293             m_impl->annMemb->getClassDef(),
01294             m_impl->annMemb->getNamespaceDef(),
01295             m_impl->annMemb->getFileDef(),
01296             m_impl->annMemb->getGroupDef()
01297                           );
01298         m_impl->annMemb->setAnonymousUsed();
01299         setAnonymousUsed();
01300       }
01301       else
01302       {
01303         //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
01304         ClassDef *rcd = cd;
01305         if (isReference() && m_impl->classDef) rcd = m_impl->classDef; 
01306         writeLink(ol,rcd,nd,fd,gd);
01307       }
01308     }
01309     else if (isDocumentedFriendClass())
01310       // if the member is an undocumented friend declaration for some class, 
01311       // then maybe we can link to the class
01312     {
01313       writeLink(ol,getClass(name()),0,0,0);
01314     }
01315     else
01316       // there is a brief member description and brief member 
01317       // descriptions are enabled or there is no detailed description.
01318     {
01319       if (m_impl->annMemb)  
01320       {
01321         m_impl->annMemb->setAnonymousUsed();
01322         setAnonymousUsed();
01323       }
01324       ClassDef *rcd = cd;
01325       if (isReference() && m_impl->classDef) rcd = m_impl->classDef; 
01326       writeLink(ol,rcd,nd,fd,gd,TRUE);
01327     }
01328   }
01329 
01330   // add to index
01331   if (isEnumerate() && name().at(0)=='@')
01332   {
01333     // don't add to index
01334   }
01335   else // index member
01336   {
01337     static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
01338     QCString cfname = getOutputFileBase();
01339     QCString cfiname = d->getOutputFileBase();
01340     Doxygen::indexList.addIndexItem(
01341         cname,                                 // level1
01342         name(),                                // level2
01343         separateMemPages ? cfname : cfiname,   // contRef
01344         cfname,                                // memRef
01345         anchor(),                              // anchor
01346         this);                                 // memberdef
01347   }
01348 
01349   // *** write arguments
01350   if (argsString() && !isObjCMethod()) 
01351   {
01352     if (!isDefine()) ol.writeString(" ");
01353     //ol.docify(argsString());
01354     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),argsString()); 
01355   }
01356 
01357   // *** write exceptions
01358   if (excpString())
01359   {
01360     ol.writeString(" ");
01361     ol.docify(excpString());
01362   }
01363 
01364   // *** write bitfields
01365   if (!m_impl->bitfields.isEmpty()) // add bitfields
01366   {
01367     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->bitfields.simplifyWhiteSpace());
01368   }
01369   else if (hasOneLineInitializer()
01371       //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
01372           ) // add initializer
01373   {
01374     if (!isDefine()) 
01375     {
01376       ol.writeString(" = "); 
01377       linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
01378     }
01379     else 
01380     {
01381       ol.writeNonBreakableSpace(3);
01382       linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer);
01383     }
01384   }
01385 
01386   if (isObjCMethod() && isImplementation())
01387   {
01388     ol.startTypewriter();
01389     ol.docify(" [implementation]");
01390     ol.endTypewriter();
01391   }
01392 
01393   if (isProperty() && (isSettable() || isGettable()))
01394   {
01395       ol.writeLatexSpacing();
01396       ol.startTypewriter();
01397       ol.docify(" [");
01398       QStrList sl;
01399       if (isGettable())  sl.append("get");
01400       if (isSettable())  sl.append("set");
01401       const char *s=sl.first();
01402       while (s)
01403       {
01404          ol.docify(s);
01405          s=sl.next();
01406          if (s) ol.docify(", ");
01407       }
01408       ol.docify("]");
01409       ol.endTypewriter();
01410   }
01411 
01412   if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
01413   {
01414       ol.writeLatexSpacing();
01415       ol.startTypewriter();
01416       ol.docify(" [");
01417       QStrList sl;
01418       if (isAddable())   sl.append("add");
01419       if (isRemovable()) sl.append("remove");
01420       if (isRaisable())  sl.append("raise");
01421       const char *s=sl.first();
01422       while (s)
01423       {
01424          ol.docify(s);
01425          s=sl.next();
01426          if (s) ol.docify(", ");
01427       }
01428       ol.docify("]");
01429       ol.endTypewriter();
01430   }
01431 
01432   if (!detailsVisible && !m_impl->annMemb)
01433   {
01434     ol.endDoxyAnchor(cfname,anchor());
01435   }
01436 
01437   //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
01438   //    name().data(),annoClassDef,annEnumType);
01439   ol.endMemberItem();
01440   if (endAnonScopeNeeded) 
01441   {
01442     ol.endAnonTypeScope(--s_indentLevel);
01443   }
01444 
01445   // write brief description
01446   if (!briefDescription().isEmpty() && 
01447       Config_getBool("BRIEF_MEMBER_DESC") 
01448       /* && !annMemb */
01449      )
01450   {
01451     ol.startMemberDescription();
01452     ol.parseDoc(briefFile(),briefLine(),getOuterScope()?getOuterScope():d,this,briefDescription(),TRUE,FALSE);
01453     if (detailsVisible) 
01454     {
01455       ol.pushGeneratorState();
01456       ol.disableAllBut(OutputGenerator::Html);
01457       //ol.endEmphasis();
01458       ol.docify(" ");
01459       if (m_impl->group!=0 && gd==0) // forward link to the group
01460       {
01461         ol.startTextLink(getOutputFileBase(),anchor());
01462       }
01463       else // local link
01464       {
01465         ol.startTextLink(0,anchor());
01466       }
01467       ol.endTextLink();
01468       //ol.startEmphasis();
01469       ol.popGeneratorState();
01470     }
01471     //ol.newParagraph();
01472     ol.endMemberDescription();
01473   }
01474   warnIfUndocumented();
01475 }
01476 
01477 bool MemberDef::isDetailedSectionLinkable() const          
01478 { 
01479   static bool extractAll        = Config_getBool("EXTRACT_ALL");
01480   static bool alwaysDetailedSec = Config_getBool("ALWAYS_DETAILED_SEC");
01481   static bool repeatBrief       = Config_getBool("REPEAT_BRIEF");
01482   static bool briefMemberDesc   = Config_getBool("BRIEF_MEMBER_DESC");
01483   static bool hideUndocMembers  = Config_getBool("HIDE_UNDOC_MEMBERS");
01484   static bool extractStatic     = Config_getBool("EXTRACT_STATIC");
01485   static bool extractPrivate    = Config_getBool("EXTRACT_PRIVATE");
01486 
01487   makeResident();
01488   // the member has details documentation for any of the following reasons
01489   bool docFilter = 
01490          // treat everything as documented
01491          extractAll ||          
01492          // has detailed docs
01493          !documentation().isEmpty() ||             
01494          // has inbody docs
01495          !inbodyDocumentation().isEmpty() ||
01496          // is an enum with values that are documented
01497          (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||  
01498          // is documented enum value
01499          (m_impl->mtype==EnumValue && !briefDescription().isEmpty()) || 
01500          // has brief description that is part of the detailed description
01501          (!briefDescription().isEmpty() &&           // has brief docs
01502           (alwaysDetailedSec &&  // they or visible in
01503            repeatBrief ||        // detailed section or
01504            !briefMemberDesc      // they are explicitly not
01505           )                                          // shown in brief section
01506          ) ||
01507          // has a multi-line initialization block
01508          //(initLines>0 && initLines<maxInitLines) || 
01509          (hasMultiLineInitializer() && !hideUndocMembers) ||
01510          // has one or more documented arguments
01511          (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
01512          // has user comments
01513          Doxygen::userComments
01514          ; 
01515          
01516   // this is not a global static or global statics should be extracted
01517   bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic; 
01518          
01519   // only include members that are non-private unless EXTRACT_PRIVATE is
01520   // set to YES or the member is part of a group
01521   bool privateFilter = (protection()!=Private || extractPrivate ||
01522                            m_impl->mtype==Friend
01523                           );
01524 
01525   // member is part of an anonymous scope that is the type of
01526   // another member in the list.
01527   //
01528   //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
01529 
01530   // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
01531   // is true
01532   bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
01533                                 isFriend() &&
01534                                 (m_impl->type=="friend class" || 
01535                                  m_impl->type=="friend struct" ||
01536                                  m_impl->type=="friend union"
01537                                 )
01538                                );
01539   
01540   return ((docFilter && staticFilter && privateFilter && friendCompoundFilter) /*|| inAnonymousScope*/);
01541 }
01542 
01543 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const          
01544 { 
01545   bool groupFilter = getGroupDef()==0 || inGroup; 
01546   bool fileFilter  = getNamespaceDef()==0 || !inFile;
01547 
01548   bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter && 
01549                  !isReference();
01550   //printf("MemberDef::isDetailedSectionVisible() %d\n",visible);
01551   return visible;
01552 }
01553 
01557 void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
01558                                    const char *scName,
01559                                    Definition *container,
01560                                    bool inGroup,
01561                                    bool showEnumValues
01562                                   )
01563 {
01564   // if this member is in a group find the real scope name.
01565   bool hasParameterList = FALSE;
01566   bool inFile = container->definitionType()==Definition::TypeFile;
01567   bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
01568   static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
01569   static bool optVhdl          = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
01570   //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
01571   //    name().data(),hasDocs,container->definitionType(),inGroup);
01572   if ( !hasDocs ) return;
01573   if (isEnumValue() && !showEnumValues) return;
01574 
01575   makeResident();
01576   LockingPtr<MemberDef> lock(this,this);
01577 
01578   QCString scopeName = scName;
01579   QCString memAnchor = anchor();
01580   QCString ciname = container->name();
01581   if (container->definitionType()==TypeGroup)
01582   {
01583     if (getClassDef())          scopeName=getClassDef()->name();
01584     else if (getNamespaceDef()) scopeName=getNamespaceDef()->name();
01585     else if (getFileDef())      scopeName=getFileDef()->name();
01586     ciname = ((GroupDef *)container)->groupTitle();
01587   }
01588   else if (container->definitionType()==TypeFile && getNamespaceDef())
01589   { // member is in a namespace, but is written as part of the file documentation
01590     // as well, so we need to make sure its label is unique.
01591     memAnchor.prepend("file_");
01592   }
01593 
01594   QCString cname  = container->name();
01595   QCString cfname = getOutputFileBase();
01596   QCString cfiname = container->getOutputFileBase();
01597 
01598   // the next part is moved to declaration
01599   //if (isEnumerate() && name().at(0)=='@')
01600   //{
01601   //  // don't add to index
01602   //}
01603   //else
01604   //{
01605   //  Doxygen::indexList.addIndexItem(
01606   //      ciname,                                // level1
01607   //      name(),                                // level2
01608   //      separateMemPages ? cfname : cfiname,   // contRef
01609   //      cfname,                                // memRef
01610   //      memAnchor,                             // anchor
01611   //      this);                                 // memberdef
01612   //}
01613 
01614   // get member name
01615   QCString doxyName=name();
01616   // prepend scope if there is any. TODO: make this optional for C only docs
01617   if (scopeName) doxyName.prepend((QCString)scopeName+"::");
01618   QCString doxyArgs=argsString();
01619 
01620   QCString ldef = definition();
01621   //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
01622   if (isEnumerate()) 
01623   {
01624     if (name().at(0)=='@')
01625     {
01626       ldef = "anonymous enum";
01627     }
01628     else
01629     {
01630       ldef.prepend("enum ");
01631     }
01632   }
01633   else if (isEnumValue())
01634   {
01635     if (ldef.at(0)=='@')
01636     {
01637       ldef=ldef.mid(2);
01638     }
01639   }
01640   int i=0,l;
01641   static QRegExp r("@[0-9]+");
01642 
01643   //----------------------------------------
01644 
01645   ol.pushGeneratorState();
01646 
01647 
01648   if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
01649   {
01650     // find enum type and insert it in the definition
01651     MemberListIterator vmli(*ml);
01652     MemberDef *vmd;
01653     bool found=FALSE;
01654     for ( ; (vmd=vmli.current()) && !found ; ++vmli)
01655     {
01656       if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
01657       {
01658         ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
01659         ol.startMemberDoc(cname,name(),memAnchor,name());
01660         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.left(i));
01661         vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
01662         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-i-l));
01663 
01664         found=TRUE;
01665       }
01666     }
01667     if (!found) // anonymous compound
01668     {
01669       //printf("Anonymous compound `%s'\n",cname.data());
01670       ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
01671       ol.startMemberDoc(cname,name(),memAnchor,name());
01672       // strip anonymous compound names from definition
01673       int si=ldef.find(' '),pi,ei=i+l;
01674       if (si==-1) si=0;
01675       while ((pi=r.match(ldef,i+l,&l))!=-1) ei=i=pi+l;
01676       // first si characters of ldef contain compound type name
01677       ol.startMemberDocName(isObjCMethod());
01678       ol.docify(ldef.left(si));
01679       ol.docify(" { ... } ");
01680       // last ei characters of ldef contain pointer/reference specifiers
01681       int ni=ldef.find("::",si);
01682       if (ni>=ei) ei=ni+2;
01683       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-ei));
01684     }
01685   }
01686   else // not an enum value
01687   {
01688     ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
01689     ol.startMemberDoc(cname,name(),memAnchor,name());
01690 
01691     ClassDef *cd=getClassDef();
01692     if (!Config_getBool("HIDE_SCOPE_NAMES"))
01693     {
01694       bool first=TRUE;
01695       if (m_impl->defTmpArgLists) 
01696         // definition has explicit template parameter declarations
01697       {
01698         QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
01699         ArgumentList *tal;
01700         for (ali.toFirst();(tal=ali.current());++ali)
01701         {
01702           if (tal->count()>0)
01703           {
01704             if (!first) ol.docify(" ");
01705             ol.startMemberDocPrefixItem();
01706             writeTemplatePrefix(ol,tal);
01707             ol.endMemberDocPrefixItem();
01708           }
01709         }
01710       }
01711       else // definition gets it template parameters from its class
01712         // (since no definition was found)
01713       {
01714         if (cd && !isTemplateSpecialization())
01715         {
01716           QList<ArgumentList> tempParamLists;
01717           cd->getTemplateParameterLists(tempParamLists);
01718           //printf("#tempParamLists=%d\n",tempParamLists.count());
01719           QListIterator<ArgumentList> ali(tempParamLists);
01720           ArgumentList *tal;
01721           for (ali.toFirst();(tal=ali.current());++ali)
01722           {
01723             if (tal->count()>0)
01724             {
01725               if (!first) ol.docify(" ");
01726               ol.startMemberDocPrefixItem();
01727               writeTemplatePrefix(ol,tal);
01728               ol.endMemberDocPrefixItem();
01729             }
01730           }
01731         }
01732         if (m_impl->tArgList) // function template prefix
01733         {
01734           ol.startMemberDocPrefixItem();
01735           writeTemplatePrefix(ol,m_impl->tArgList);
01736           ol.endMemberDocPrefixItem();
01737         }
01738       }
01739     }
01740 
01741     ol.startMemberDocName(isObjCMethod());
01742     if (cd && cd->isObjectiveC())
01743     {
01744       // strip scope name
01745       int ep = ldef.find("::");
01746       if (ep!=-1) 
01747       {
01748         int sp=ldef.findRev(' ',ep);
01749         if (sp!=-1)
01750         {
01751           ldef=ldef.left(sp+1)+ldef.mid(ep+2);
01752         }
01753       }
01754       // strip keywords
01755       int dp = ldef.find(':');
01756       if (dp!=-1)
01757       {
01758         ldef=ldef.left(dp+1);
01759       }
01760       int l=ldef.length();
01761       //printf("start >%s<\n",ldef.data());
01762       int i=l-1;
01763       while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
01764       while (i>=0 && isspace((uchar)ldef.at(i))) i--;
01765       if (i>0)
01766       {
01767         // insert braches around the type
01768         QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
01769         ldef=tmp;
01770       }
01771       //printf("end   >%s< i=%d\n",ldef.data(),i);
01772       if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
01773     }
01774 
01775     if (optVhdl)
01776     {
01777       VhdlDocGen::writeVHDLTypeDocumentation(this,container,ol);
01778     }
01779     else
01780     {
01781       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef);
01782       hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
01783     }
01784 
01785     if (hasOneLineInitializer()) // add initializer
01786     {
01787       if (!isDefine()) 
01788       {
01789         ol.docify(" = "); 
01790         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
01791       }
01792       else 
01793       {
01794         ol.writeNonBreakableSpace(3);
01795         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer);
01796       }
01797     }
01798     if (excpString()) // add exception list
01799     {
01800       ol.docify(" ");
01801       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),excpString());
01802     }
01803   }
01804 
01805   Specifier lvirt=virtualness();
01806 
01807   if (!isObjCMethod() &&
01808       (protection()!=Public || lvirt!=Normal ||
01809        isFriend() || isRelated() || 
01810        (isInline() && Config_getBool("INLINE_INFO")) ||
01811        isSignal() || isSlot() ||
01812        isStatic() || (m_impl->classDef && m_impl->classDef!=container) ||
01813        (m_impl->memSpec & ~Entry::Inline)!=0 
01814       )
01815      )
01816   {
01817     // write the member specifier list
01818     ol.writeLatexSpacing();
01819     ol.startTypewriter();
01820     ol.docify(" [");
01821     QStrList sl;
01822     if (optVhdl)
01823     {
01824       sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
01825     }
01826     else
01827     {
01828       if (isFriend()) sl.append("friend");
01829       else if (isRelated()) sl.append("related");
01830       else
01831       {
01832         if      (Config_getBool("INLINE_INFO") && isInline()) sl.append("inline");
01833         if      (isExplicit())            sl.append("explicit");
01834         if      (isMutable())             sl.append("mutable");
01835         if      (isStatic())              sl.append("static");
01836         if      (isGettable())            sl.append("get");
01837         if      (isSettable())            sl.append("set");
01838         if      (isAddable())             sl.append("add");
01839         if      (isRemovable())           sl.append("remove");
01840         if      (isRaisable())            sl.append("raise");
01841         if      (isReadable())            sl.append("read");
01842         if      (isWritable())            sl.append("write");
01843         if      (isFinal())               sl.append("final");
01844         if      (isAbstract())            sl.append("abstract");
01845         if      (isOverride())            sl.append("override");
01846         if      (isInitonly())            sl.append("initonly");
01847         if      (isSealed())              sl.append("sealed");
01848         if      (isNew())                 sl.append("new");
01849         if      (isOptional())            sl.append("optional");
01850         if      (isRequired())            sl.append("required");
01851         if      (isAssign())              sl.append("assign");
01852         else if (isCopy())                sl.append("copy");
01853         else if (isRetain())              sl.append("retain");
01854         if      (protection()==Protected) sl.append("protected");
01855         else if (protection()==Private)   sl.append("private");
01856         else if (protection()==Package)   sl.append("package");
01857         if      (lvirt==Virtual)          sl.append("virtual");
01858         else if (lvirt==Pure)             sl.append("pure virtual");
01859         if      (isSignal())              sl.append("signal");
01860         if      (isSlot())                sl.append("slot");
01861       }
01862       if (m_impl->classDef && m_impl->classDef!=container) sl.append("inherited");
01863     }
01864     const char *s=sl.first();
01865     while (s)
01866     {
01867       ol.docify(s);
01868       s=sl.next();
01869       if (s) ol.docify(", ");
01870     }
01871     ol.docify("]");
01872     ol.endTypewriter();
01873   }
01874   else if (isObjCMethod() && isImplementation())
01875   {
01876     ol.writeLatexSpacing();
01877     ol.startTypewriter();
01878     ol.docify(" [implementation]");
01879     ol.endTypewriter();
01880   }
01881   if (hasParameterList) 
01882   {
01883     ol.endParameterList();
01884     ol.endMemberDoc(TRUE);
01885   }
01886   else
01887   {
01888     ol.endMemberDocName();
01889     ol.endMemberDoc(FALSE);
01890   }
01891   ol.endDoxyAnchor(cfname,memAnchor);
01892   ol.startIndent();
01893 
01894   ol.pushGeneratorState();
01895   ol.disable(OutputGenerator::RTF);
01896   ol.newParagraph();
01897   ol.popGeneratorState();
01898 
01899   /* write multi-line initializer (if any) */
01900   if (hasMultiLineInitializer()
01901       //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
01902       //                || initLines<userInitLines // explicitly enabled
01903       //               )
01904      )
01905   {
01906     //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
01907     ol.startBold();
01908     if (m_impl->mtype==Define)
01909       ol.parseText(theTranslator->trDefineValue());
01910     else
01911       ol.parseText(theTranslator->trInitialValue());
01912     ol.endBold();
01913     ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
01914     pIntf->resetCodeParserState();
01915     ol.startCodeFragment();
01916     pIntf->parseCode(ol,scopeName,m_impl->initializer,FALSE,0);
01917     ol.endCodeFragment();
01918   }
01919 
01920   QCString brief           = briefDescription();
01921   QCString detailed        = documentation();
01922   LockingPtr<ArgumentList> docArgList = LockingPtr<ArgumentList>(this,m_impl->defArgList);
01923   if (m_impl->templateMaster)
01924   {
01925     brief      = m_impl->templateMaster->briefDescription();
01926     detailed   = m_impl->templateMaster->documentation();
01927     docArgList = m_impl->templateMaster->argumentList();
01928   }
01929 
01930   /* write brief description */
01931   if (!brief.isEmpty() && 
01932       (Config_getBool("REPEAT_BRIEF") || 
01933        !Config_getBool("BRIEF_MEMBER_DESC")
01934       ) 
01935      )  
01936   { 
01937     ol.parseDoc(briefFile(),briefLine(),getOuterScope()?getOuterScope():container,this,brief,FALSE,FALSE);
01938     ol.newParagraph();
01939   }
01940 
01941   /* write detailed description */
01942   if (!detailed.isEmpty() || !m_impl->inbodyDocs.isEmpty())
01943   { 
01944     ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
01945     if (!m_impl->inbodyDocs.isEmpty())
01946     {
01947       ol.newParagraph();
01948       ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_impl->inbodyDocs+"\n",TRUE,FALSE);
01949     }
01950   }
01951   else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
01952         !Config_getBool("BRIEF_MEMBER_DESC")))
01953   {
01954     if (!m_impl->inbodyDocs.isEmpty())
01955     {
01956       ol.newParagraph();
01957       ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,m_impl->inbodyDocs+"\n",TRUE,FALSE);
01958     }
01959   }
01960 
01961 
01962   //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
01963   //     defArgList, 
01964   //     defArgList?defArgList->hasDocumentation():-1);
01965   if (docArgList!=0 && docArgList->hasDocumentation())
01966   {
01967     //printf("***** argumentList is documented\n");
01968     ol.startParamList(BaseOutputDocInterface::Param,theTranslator->trParameters()+": ");
01969     ol.writeDescItem();
01970     ol.startDescTable();
01971     ArgumentListIterator ali(*docArgList);
01972     Argument *a;
01973     for (ali.toFirst();(a=ali.current());++ali)
01974     {
01975       if (a->hasDocumentation())
01976       {
01977         ol.startDescTableTitle();
01978         ol.docify(a->name);
01979         ol.endDescTableTitle();
01980         ol.startDescTableData();
01981         ol.parseDoc(docFile(),docLine(),
01982                     getOuterScope()?getOuterScope():container,
01983                     this,         // memberDef
01984                     a->docs+"\n", // docStr
01985                     TRUE,         // indexWords
01986                     FALSE         // isExample
01987                    );
01988         ol.endDescTableData();
01989       }
01990     }
01991     ol.endDescTable();
01992     ol.endParamList();
01993   }
01994 
01995   // For enum, we also write the documented enum values
01996   if (isEnumerate())
01997   {
01998     bool first=TRUE;
01999     LockingPtr<MemberList> fmdl=enumFieldList();
02000     if (fmdl!=0)
02001     {
02002       MemberDef *fmd=fmdl->first();
02003       while (fmd)
02004       {
02005         if (fmd->isLinkable())
02006         {
02007           if (first)
02008           {
02009             //ol.newParagraph();
02010             ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
02011             ol.writeDescItem();
02012             ol.startDescTable();
02013           }
02014 
02015           ol.addIndexItem(fmd->name(),cname);
02016           ol.addIndexItem(cname,fmd->name());
02017 
02018           //if (hasHtmlHelp)
02019           //{
02020           //   htmlHelp->addIndexItem(ciname,                                // level1
02021           //                          fmd->name(),                           // level2
02022           //                          separateMemPages ? cfname : cfiname,   // contRef
02023           //                          cfname,                                // memRef
02024           //                          fmd->anchor());                        // anchor
02025           //}
02026           Doxygen::indexList.addIndexItem(
02027                                  ciname,                                // level1
02028                                  fmd->name(),                           // level2
02029                                  separateMemPages ? cfname : cfiname,   // contRef
02030                                  cfname,                                // memRef
02031                                  fmd->anchor(),                         // anchor
02032                                  fmd);                                  // memberdef
02033           //ol.writeListItem();
02034           ol.startDescTableTitle(); // this enables emphasis!
02035           ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
02036           first=FALSE;
02037           //ol.startEmphasis();
02038           ol.docify(fmd->name());
02039           //ol.endEmphasis();
02040           ol.disableAllBut(OutputGenerator::Man);
02041           ol.writeString(" ");
02042           ol.enableAll();
02043           ol.endDoxyAnchor(cfname,fmd->anchor());
02044           ol.endDescTableTitle();
02045           //ol.newParagraph();
02046           ol.startDescTableData();
02047 
02048           if (!fmd->briefDescription().isEmpty())
02049           { 
02050             ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
02051             //ol.newParagraph();
02052           }
02053           if (!fmd->briefDescription().isEmpty() && 
02054               !fmd->documentation().isEmpty())
02055           {
02056             ol.newParagraph();
02057           }
02058           if (!fmd->documentation().isEmpty())
02059           { 
02060             ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
02061           }
02062           ol.endDescTableData();
02063         }
02064         fmd=fmdl->next();
02065       }
02066     }
02067     if (!first) 
02068     { 
02069       //ol.endItemList(); 
02070       ol.endDescTable();
02071       ol.endSimpleSect();
02072       ol.writeChar('\n'); 
02073     }
02074   }
02075 
02076   MemberDef *bmd=reimplements();
02077   ClassDef *bcd=0;
02078   if (bmd && (bcd=bmd->getClassDef()))
02079   {
02080     // write class that contains a member that is reimplemented by this one
02081     if (bcd->isLinkable())
02082     {
02083       ol.startParagraph();
02084       QCString reimplFromLine; 
02085       if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
02086       {
02087         reimplFromLine = theTranslator->trReimplementedFromList(1);
02088       }
02089       else
02090       {
02091         reimplFromLine = theTranslator->trImplementedFromList(1);
02092       }
02093       int markerPos = reimplFromLine.find("@0");
02094       if (markerPos!=-1) // should always pass this.
02095       {
02096         ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
02097         if (bmd->isLinkable()) // replace marker with link
02098         {
02099           //Definition *bd=bmd->group;
02100           //if (bd==0) bd=bcd;
02101           ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
02102               bmd->anchor(),bcd->displayName());
02103 
02104           //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
02105           //    bmd->anchor(),bcd->name());
02106           if ( bmd->isLinkableInProject() ) 
02107           {
02108             writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
02109           }
02110         }
02111         else
02112         {
02113           ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
02114               0,bcd->displayName());
02115           if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
02116           {
02117             writePageRef(ol,bcd->getOutputFileBase(),0);
02118           }
02119         }
02120         ol.parseText(reimplFromLine.right(
02121               reimplFromLine.length()-markerPos-2)); // text right from marker
02122 
02123       }
02124       else
02125       {
02126         err("Error: translation error: no marker in trReimplementsFromList()\n");
02127       }
02128       ol.endParagraph();
02129     }
02130 
02131     //ol.writeString(".");
02132   }
02133 
02134   LockingPtr<MemberList> bml=reimplementedBy();
02135   if (bml!=0)
02136   {
02137     MemberListIterator mli(*bml);
02138     MemberDef *bmd=0;
02139     uint count=0;
02140     ClassDef *bcd=0;
02141     for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
02142     {
02143       // count the members that directly inherit from md and for
02144       // which the member and class are visible in the docs.
02145       if ( bmd->isLinkable() && bcd->isLinkable() ) 
02146       {
02147         count++;
02148       }
02149     }
02150     if (count>0)
02151     {
02152       mli.toFirst();
02153       // write the list of classes that overwrite this member
02154       ol.startParagraph();
02155 
02156       QCString reimplInLine;
02157       if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
02158       {
02159         reimplInLine = theTranslator->trImplementedInList(count);
02160       }
02161       else
02162       {
02163         reimplInLine = theTranslator->trReimplementedInList(count);
02164       }
02165       static QRegExp marker("@[0-9]+");
02166       int index=0,newIndex,matchLen;
02167       // now replace all markers in reimplInLine with links to the classes
02168       while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
02169       {
02170         ol.parseText(reimplInLine.mid(index,newIndex-index));
02171         bool ok;
02172         uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
02173         //bmd=bml->at(entryIndex);
02174 
02175         count=0;
02176         // find the entryIndex-th documented entry in the inheritance list.
02177         for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
02178         {
02179           if ( bmd->isLinkable() && bcd->isLinkable()) 
02180           {
02181             if (count==entryIndex) break;
02182             count++;
02183           }
02184         }
02185 
02186         if (ok && bcd && bmd) // write link for marker
02187         {
02188           //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
02189           //    bmd->anchor(),bcd->name());
02190           ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
02191               bmd->anchor(),bcd->displayName());
02192 
02193           if (bmd->isLinkableInProject() ) 
02194           {
02195             writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
02196           }
02197         }
02198         ++mli;
02199         index=newIndex+matchLen;
02200       } 
02201       ol.parseText(reimplInLine.right(reimplInLine.length()-index));
02202       ol.endParagraph();
02203     }
02204   }
02205 
02206   // write the list of examples that use this member
02207   if (hasExamples())
02208   {
02209     ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
02210     ol.writeDescItem();
02211     writeExample(ol,m_impl->exampleSDict);
02212     //ol.endDescItem();
02213     ol.endSimpleSect();
02214   }
02215 
02216   if (m_impl->typeConstraints)
02217   {
02218     writeTypeConstraints(ol,this,m_impl->typeConstraints);
02219   }
02220 
02221   // write reference to the source
02222   writeSourceDef(ol,cname);
02223   writeSourceRefs(ol,cname);
02224   writeSourceReffedBy(ol,cname);
02225   writeInlineCode(ol,cname);
02226 
02227   // write call graph
02228   if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH")) 
02229       && isFunction() && Config_getBool("HAVE_DOT")
02230      )
02231   {
02232     DotCallGraph callGraph(this,FALSE);
02233     if (!callGraph.isTrivial() && !callGraph.isTooBig())
02234     {
02235       msg("Generating call graph for function %s\n",qualifiedName().data());
02236       ol.disable(OutputGenerator::Man);
02237       ol.newParagraph();
02238       ol.startCallGraph();
02239       ol.parseText(theTranslator->trCallGraph());
02240       ol.endCallGraph(callGraph);
02241       ol.enableAll();
02242     }
02243   }
02244   if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH")) 
02245       && isFunction() && Config_getBool("HAVE_DOT")
02246      )
02247   {
02248     DotCallGraph callerGraph(this, TRUE);
02249     if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
02250     {
02251       msg("Generating caller graph for function %s\n",qualifiedName().data());
02252       ol.disable(OutputGenerator::Man);
02253       ol.newParagraph();
02254       ol.startCallGraph();
02255       ol.parseText(theTranslator->trCallerGraph());
02256       ol.endCallGraph(callerGraph);
02257       ol.enableAll();
02258     }
02259   }
02260 
02261   if (Doxygen::userComments)
02262   {
02263     ol.pushGeneratorState();
02264     ol.disableAllBut(OutputGenerator::Html);
02265     QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
02266                    "passthru(\"$root/doxynotes --lookup "+
02267                    getOutputFileBase()+":"+anchor()+"\") ?>";
02268     ol.writeString(cmd);
02269     ol.popGeneratorState();
02270   }
02271 
02272   ol.endIndent();
02273 
02274   // enable LaTeX again
02275   //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); 
02276   ol.popGeneratorState();
02277 
02278   //------------------------------------------------
02279 
02280   if (!Config_getBool("EXTRACT_ALL") &&
02281       Config_getBool("WARN_IF_UNDOCUMENTED") &&
02282       Config_getBool("WARN_NO_PARAMDOC") &&
02283       !Doxygen::suppressDocWarnings)
02284   {
02285     if (!hasDocumentedParams())
02286     {
02287       warn_doc_error(docFile(),docLine(),
02288           "Warning: parameters of member %s are not (all) documented",
02289           qualifiedName().data());
02290     }
02291     if (!hasDocumentedReturnType())
02292     {
02293       warn_doc_error(docFile(),docLine(),
02294           "Warning: return type of member %s is not documented",
02295           qualifiedName().data());
02296     }
02297   }
02298 
02299 }
02300 
02301 QCString MemberDef::memberTypeName() const
02302 {
02303   makeResident();
02304   switch (m_impl->mtype)
02305   {
02306     case Define:      return "define";
02307     case Function:    return "function";
02308     case Variable:    return "variable";
02309     case Typedef:     return "typedef";
02310     case Enumeration: return "enumeration"; 
02311     case EnumValue:   return "enumvalue";
02312     case Prototype:   return "prototype";   
02313     case Signal:      return "signal";
02314     case Slot:        return "slot";
02315     case Friend:      return "friend";
02316     case DCOP:        return "dcop";
02317     case Property:    return "property";
02318     case Event:       return "event";
02319     default:          return "unknown";
02320   }
02321 }
02322 
02323 void MemberDef::warnIfUndocumented()
02324 {
02325   makeResident();
02326   if (m_impl->memberGroup) return;
02327   ClassDef     *cd = getClassDef();
02328   NamespaceDef *nd = getNamespaceDef();
02329   FileDef      *fd = getFileDef();
02330   GroupDef     *gd = getGroupDef();
02331   Definition *d=0;
02332   const char *t=0;
02333   if (cd) 
02334     t="class", d=cd; 
02335   else if (nd) 
02336     t="namespace", d=nd; 
02337   else if (gd)
02338     t="group", d=gd;
02339   else
02340     t="file", d=fd;
02341   static bool extractAll = Config_getBool("EXTRACT_ALL");
02342 
02343   //printf("warnIfUndoc: d->isLinkable()=%d isLinkable()=%d "
02344   //       "isDocumentedFriendClass()=%d name()=%s prot=%d\n",
02345   //       d->isLinkable(),isLinkable(),isDocumentedFriendClass(),
02346   //       name().data(),prot);
02347   if ((!hasUserDocumentation() && !extractAll) &&
02348       !isFriendClass() && 
02349       name().find('@')==-1 && d->name().find('@')==-1 &&
02350       (m_impl->prot!=Private || Config_getBool("EXTRACT_PRIVATE"))
02351      )
02352   {
02353     warn_undoc(getDefFileName(),getDefLine(),"Warning: Member %s%s (%s) of %s %s is not documented.",
02354          name().data(),argsString()?argsString():"",memberTypeName().data(),t,d->name().data());
02355   }
02356 }
02357 
02358 
02359 
02360 bool MemberDef::isFriendClass() const
02361 {
02362   makeResident();
02363   return (isFriend() && 
02364          (m_impl->type=="friend class" || m_impl->type=="friend struct" || 
02365           m_impl->type=="friend union"));
02366 }
02367 
02368 bool MemberDef::isDocumentedFriendClass() const
02369 {
02370   makeResident();
02371   ClassDef *fcd=0;
02372   QCString baseName=name();
02373   int i=baseName.find('<');
02374   if (i!=-1) baseName=baseName.left(i);
02375   return (isFriendClass() &&
02376          (fcd=getClass(baseName)) && fcd->isLinkable()); 
02377 }
02378 
02379 bool MemberDef::hasDocumentation() const
02380 { 
02381   makeResident();
02382   return Definition::hasDocumentation() || 
02383          !m_impl->inbodyDocs.isEmpty() ||
02384          (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||  // has enum values
02385          (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
02386 }
02387 
02388 bool MemberDef::hasUserDocumentation() const
02389 {
02390   bool hasDocs = Definition::hasUserDocumentation() ||
02391          (m_impl->inbodyDocs  && !m_impl->inbodyDocs.isEmpty());
02392   return hasDocs;
02393 }
02394 
02395 
02396 void MemberDef::setMemberGroup(MemberGroup *grp)
02397 {
02398   makeResident();
02399   m_impl->memberGroup = grp;
02400 }
02401 
02402 bool MemberDef::visibleMemberGroup(bool hideNoHeader) 
02403 { 
02404   makeResident();
02405   return m_impl->memberGroup!=0 && 
02406           (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]"); 
02407 }
02408 
02409 QCString MemberDef::getScopeString() const
02410 {
02411   makeResident();
02412   QCString result;
02413   if (getClassDef()) result=getClassDef()->displayName();
02414   else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
02415   return result;
02416 }
02417 
02418 #if 0
02419 static QCString escapeAnchor(const QCString &anchor)
02420 {
02421   QCString result;
02422   int l = anchor.length(),i;
02423   for (i=0;i<l;i++)
02424   {
02425     char c = anchor.at(i);
02426     if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
02427     {
02428       result+=c;
02429     }
02430     else
02431     {
02432       static char hexStr[]="0123456789ABCDEF";
02433       char escChar[]={ '_', 0, 0, 0 };
02434       escChar[1]=hexStr[c>>4];
02435       escChar[2]=hexStr[c&0xf];
02436       result+=escChar;
02437     }
02438   }
02439   return result;
02440 }
02441 #endif
02442 
02443 void MemberDef::setAnchor(const char *a)
02444 {
02445   makeResident();
02446   //anc=a;
02447   a=a;
02448   QCString memAnchor = name();
02449   if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
02450 
02451   // include definition as well, to distinguish between two template
02452   // specializations that only differ in the template parameters.
02453   memAnchor.prepend(definition());
02454   
02455   // convert to md5 hash
02456   uchar md5_sig[16];
02457   QCString sigStr(33);
02458   MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
02459   MD5SigToString(md5_sig,sigStr.data(),33);
02460   m_impl->anc = sigStr;
02461 }
02462 
02463 void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
02464                             const QCString &fileName,int startLine,
02465                             bool hasDocs,MemberDef *member)
02466 {
02467   //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
02468   makeResident();
02469   m_impl->group=gd;
02470   m_impl->grouppri=pri;
02471   m_impl->groupFileName=fileName;
02472   m_impl->groupStartLine=startLine;
02473   m_impl->groupHasDocs=hasDocs;
02474   m_impl->groupMember=member;
02475 }
02476 
02477 void MemberDef::setEnumScope(MemberDef *md) 
02478 { 
02479   makeResident();
02480   m_impl->enumScope=md; 
02481   if (md->getGroupDef())
02482   {
02483     m_impl->group=md->getGroupDef();
02484     m_impl->grouppri=md->getGroupPri();
02485     m_impl->groupFileName=md->getGroupFileName();
02486     m_impl->groupStartLine=md->getGroupStartLine();
02487     m_impl->groupHasDocs=md->getGroupHasDocs();
02488   }
02489 }
02490 
02491 void MemberDef::setMemberClass(ClassDef *cd)     
02492 { 
02493   makeResident();
02494   m_impl->classDef=cd; 
02495   setOuterScope(cd); 
02496 }
02497 
02498 void MemberDef::setNamespace(NamespaceDef *nd) 
02499 { 
02500   makeResident();
02501   m_impl->nspace=nd; 
02502   setOuterScope(nd); 
02503 }
02504 
02505 MemberDef *MemberDef::createTemplateInstanceMember(
02506         ArgumentList *formalArgs,ArgumentList *actualArgs)
02507 {
02508   makeResident();
02509   LockingPtr<MemberDef> lock(this,this);
02510   //printf("  Member %s %s %s\n",typeString(),name().data(),argsString());
02511   ArgumentList *actualArgList = 0;
02512   if (m_impl->defArgList)
02513   {
02514     actualArgList = new ArgumentList;
02515     ArgumentListIterator ali(*m_impl->defArgList);
02516     Argument *arg;
02517     for (;(arg=ali.current());++ali)
02518     {
02519       Argument *actArg = new Argument(*arg);
02520       actArg->type = substituteTemplateArgumentsInString(actArg->type,formalArgs,actualArgs);
02521       actualArgList->append(actArg);
02522     }
02523     actualArgList->constSpecifier    = m_impl->defArgList->constSpecifier;
02524     actualArgList->volatileSpecifier = m_impl->defArgList->volatileSpecifier;
02525     actualArgList->pureSpecifier     = m_impl->defArgList->pureSpecifier;
02526   }
02527 
02528   QCString methodName=name();
02529   if (methodName.left(9)=="operator ") // conversion operator
02530   {
02531     methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
02532   }
02533 
02534   MemberDef *imd = new MemberDef(
02535                        getDefFileName(),getDefLine(),
02536                        substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs), 
02537                        methodName, 
02538                        substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs), 
02539                        m_impl->exception, m_impl->prot,
02540                        m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
02541                    );
02542   imd->setArgumentList(actualArgList);
02543   imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
02544   imd->setBodyDef(getBodyDef());
02545   imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
02546   //imd->setBodyMember(this);
02547 
02548   // TODO: init other member variables (if needed).
02549   // TODO: reimplemented info
02550   return imd; 
02551 }
02552 
02553 bool MemberDef::hasOneLineInitializer() const
02554 {
02555   makeResident();
02556   //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
02557   //    name().data(),m_impl->initializer.data(),m_impl->initLines,
02558   //    m_impl->maxInitLines,m_impl->userInitLines);
02559   return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
02560          ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
02561 }
02562 
02563 bool MemberDef::hasMultiLineInitializer() const
02564 {
02565   makeResident();
02566   //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
02567   //    initLines,userInitLines,maxInitLines);
02568   return m_impl->initLines>0 && 
02569          ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
02570           || m_impl->initLines<m_impl->userInitLines // explicitly enabled
02571          );
02572 }
02573 
02574 void MemberDef::setInitializer(const char *initializer)    
02575 { 
02576   makeResident();
02577   m_impl->initializer=initializer; 
02578   int p=m_impl->initializer.length()-1;
02579   while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
02580   m_impl->initializer=m_impl->initializer.left(p+1);
02581   m_impl->initLines=m_impl->initializer.contains('\n');
02582 }
02583 
02584 void MemberDef::addListReference(Definition *)
02585 {
02586   makeResident();
02587   static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
02588   static bool hideScopeNames     = Config_getBool("HIDE_SCOPE_NAMES");
02589   static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
02590   static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");  
02591   visited=TRUE;
02592   if (!isLinkableInProject()) return;
02593   QCString memLabel;
02594   if (optimizeOutputForC) 
02595   {
02596     memLabel=theTranslator->trGlobal(TRUE,TRUE);
02597   }
02598   else if (fortranOpt)
02599   {
02600     memLabel=theTranslator->trSubprogram(TRUE,TRUE);
02601   }
02602   else
02603   {
02604     memLabel=theTranslator->trMember(TRUE,TRUE);
02605   }
02606   QCString memName = name();
02607   Definition *pd=getOuterScope();
02608   QCString memArgs;
02609   if (!isRelated() &&
02610       (
02611        (!hideScopeNames && // there is a scope
02612         pd && pd!=Doxygen::globalScope)       // and we can show it
02613        ||
02614        (pd=getClassDef())                     // it's a class so we
02615                                               // show the scope anyway
02616       )
02617      )
02618   {
02619     if (isObjCMethod())
02620     {
02621       memName = "[" + pd->name() + " " + name() + "]";
02622     }
02623     else if (optimizeOutputJava)
02624     {
02625       memName.prepend(pd->name()+".");
02626       memArgs = argsString();
02627     }
02628     else
02629     {
02630       memName.prepend(pd->name()+"::");
02631       memArgs = argsString();
02632     }
02633   }
02634   LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
02635   if (xrefItems!=0)
02636   {
02637     addRefItem(xrefItems.pointer(),memLabel,
02638         getOutputFileBase()+"#"+anchor(),memName,memArgs);
02639   }
02640 }
02641 
02642 MemberList *MemberDef::getSectionList(Definition *d) const 
02643 { 
02644   makeResident();
02645   char key[20];
02646   sprintf(key,"%p",d);
02647   return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
02648 }
02649 
02650 void MemberDef::setSectionList(Definition *d, MemberList *sl)   
02651 { 
02652   makeResident();
02653   //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
02654   char key[20];
02655   sprintf(key,"%p",d);
02656   if (m_impl->classSectionSDict==0) 
02657   {
02658     m_impl->classSectionSDict = new SDict<MemberList>(7);
02659   }
02660   m_impl->classSectionSDict->append(key,sl);
02661 }
02662 
02663 Specifier MemberDef::virtualness(int count) const
02664 {
02665   if (count>25) 
02666   {
02667      warn(getDefFileName(),getDefLine(),
02668        "Warning: Internal inconsistency: recursion detected in overload relation for member %s!"
02669        ,name().data()
02670       );
02671      return Normal;
02672   }
02673   makeResident();
02674   Specifier v = m_impl->virt;
02675   MemberDef *rmd = reimplements();
02676   while (rmd && v==Normal)
02677   {
02678     v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
02679     rmd = rmd->reimplements();
02680   }
02681   return v;
02682 }
02683 
02684 bool MemberDef::isConstructor() const            
02685 { 
02686   makeResident();
02687   if (m_impl->classDef) 
02688   {
02689     if (m_impl->isDMember) // for D
02690     {
02691       return name()=="this";
02692     }
02693     else if (m_impl->fileDef && 
02694              getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP)
02695     {                // for PHP
02696       return name()=="__construct";
02697     }
02698     else // for other languages
02699     {
02700       QCString locName = m_impl->classDef->localName();
02701       int i=locName.find('<');
02702       if (i==-1) // not a template class
02703       {
02704         return name()==locName;
02705       }
02706       else
02707       {
02708         return name()==locName.left(i);
02709       }
02710     }
02711   }
02712   else
02713      return FALSE; 
02714 }
02715 
02716 bool MemberDef::isDestructor() const
02717 { 
02718   makeResident();
02719   if (m_impl->isDMember) // for D
02720   {
02721     return name()=="~this";
02722   }
02723   else if (m_impl->fileDef && 
02724       getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP)
02725   {                // for PHP
02726     return name()=="__destruct";
02727   }
02728   else // other languages
02729   {
02730     return (name().find('~')!=-1 || name().find('!')!=-1)  // The ! is for C++/CLI
02731            && name().find("operator")==-1; 
02732   }
02733 }
02734 
02735 void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
02736      ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
02737 {
02738   makeResident();
02739   LockingPtr<MemberDef> lock(this,this);
02740   int enumMemCount=0;
02741 
02742   QList<MemberDef> *fmdl=m_impl->enumFields;
02743   uint numVisibleEnumValues=0;
02744   if (fmdl)
02745   {
02746     MemberDef *fmd=fmdl->first();
02747     while (fmd)
02748     {
02749       if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
02750       fmd=fmdl->next();
02751     }
02752   }
02753   if (numVisibleEnumValues==0 && !isBriefSectionVisible()) 
02754   {
02755     return;
02756   }
02757 
02758   QCString n = name();
02759   int i=n.findRev("::");
02760   if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
02761   if (n[0]!='@') // not an anonymous enum
02762   {
02763     if (isLinkableInProject() || hasDocumentedEnumValues())
02764     {
02765       if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
02766       {
02767         Doxygen::tagFile << "    <member kind=\"enumeration\">" << endl;
02768         Doxygen::tagFile << "      <name>" << convertToXML(name()) << "</name>" << endl; 
02769         Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
02770         Doxygen::tagFile << "      <anchor>" << convertToXML(anchor()) << "</anchor>" << endl; 
02771         Doxygen::tagFile << "      <arglist>" << convertToXML(argsString()) << "</arglist>" << endl; 
02772         Doxygen::tagFile << "    </member>" << endl;
02773       }
02774       writeLink(typeDecl,cd,nd,fd,gd);
02775     }
02776     else
02777     {
02778       typeDecl.startBold();
02779       typeDecl.docify(n);
02780       typeDecl.endBold();
02781     }
02782     typeDecl.writeChar(' ');
02783   }
02784 
02785   if (numVisibleEnumValues>0)
02786   {
02787     uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE");
02788     if (enumValuesPerLine==0) enumValuesPerLine=1;
02789     typeDecl.docify("{ ");
02790     if (fmdl)
02791     {
02792       MemberDef *fmd=fmdl->first();
02793       bool fmdVisible = fmd->isBriefSectionVisible();
02794       while (fmd)
02795       {
02796         if (fmdVisible)
02797         {
02798           /* in html we start a new line after a number of items */
02799           if (numVisibleEnumValues>enumValuesPerLine
02800               && (enumMemCount%enumValuesPerLine)==0
02801              )
02802           {
02803             typeDecl.pushGeneratorState();
02804             typeDecl.disableAllBut(OutputGenerator::Html);
02805             typeDecl.enable(OutputGenerator::Latex);
02806             typeDecl.lineBreak(); 
02807             typeDecl.disable(OutputGenerator::Latex);
02808             typeDecl.writeString("&nbsp;&nbsp;");
02809             typeDecl.popGeneratorState();
02810           }
02811 
02812           if (fmd->hasDocumentation()) // enum value has docs
02813           {
02814             if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fmd->isReference())
02815             {
02816               Doxygen::tagFile << "    <member kind=\"enumvalue\">" << endl;
02817               Doxygen::tagFile << "      <name>" << convertToXML(fmd->name()) << "</name>" << endl; 
02818               Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;              
02819               Doxygen::tagFile << "      <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl; 
02820               Doxygen::tagFile << "      <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl; 
02821               Doxygen::tagFile << "    </member>" << endl;
02822             }
02823             fmd->writeLink(typeDecl,cd,nd,fd,gd);
02824           }
02825           else // no docs for this enum value
02826           {
02827             typeDecl.startBold();
02828             typeDecl.docify(fmd->name());
02829             typeDecl.endBold();
02830           }
02831           if (fmd->hasOneLineInitializer()) // enum value has initializer
02832           {
02833             typeDecl.writeString(" = ");
02834             typeDecl.parseText(fmd->initializer());
02835           }
02836         }
02837 
02838         bool prevVisible = fmdVisible;
02839         fmd=fmdl->next();
02840         if (fmd && (fmdVisible=fmd->isBriefSectionVisible())) 
02841         {
02842           typeDecl.writeString(", ");
02843         }
02844         if (prevVisible)
02845         {
02846           typeDecl.disable(OutputGenerator::Man);
02847           typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
02848           typeDecl.enable(OutputGenerator::Man);
02849           enumMemCount++;
02850         }
02851       }
02852       if (numVisibleEnumValues>enumValuesPerLine)
02853       {
02854         typeDecl.pushGeneratorState();
02855         typeDecl.disableAllBut(OutputGenerator::Html);
02856         typeDecl.lineBreak(); 
02857         typeDecl.popGeneratorState();
02858       }
02859     }
02860     typeDecl.docify(" }");
02861   }
02862 }
02863 
02864 void MemberDef::setArgumentList(ArgumentList *al) 
02865 { 
02866   makeResident();
02867   if (m_impl->defArgList) delete m_impl->defArgList;
02868   m_impl->defArgList = al;
02869 }
02870 
02871 void MemberDef::setDeclArgumentList(ArgumentList *al)
02872 {
02873   makeResident();
02874   if (m_impl->declArgList) delete m_impl->declArgList;
02875   m_impl->declArgList = al;
02876 }
02877 
02878 void MemberDef::setTypeConstraints(ArgumentList *al)
02879 {
02880   if (al==0) return;
02881   makeResident();
02882   if (m_impl->typeConstraints) delete m_impl->typeConstraints;
02883   m_impl->typeConstraints = new ArgumentList;
02884   m_impl->typeConstraints->setAutoDelete(TRUE);
02885   ArgumentListIterator ali(*al);
02886   Argument *a;
02887   for (;(a=ali.current());++ali)
02888   {
02889     m_impl->typeConstraints->append(new Argument(*a));
02890   }
02891 }
02892 
02893 void MemberDef::findSectionsInDocumentation()
02894 {
02895   makeResident();
02896   docFindSections(documentation(),this,0,docFile());  
02897 }
02898 
02899 void MemberDef::enableCallGraph(bool e) 
02900 { 
02901   makeResident();
02902   m_impl->hasCallGraph=e; 
02903   if (e) Doxygen::parseSourcesNeeded = TRUE;
02904 }
02905 
02906 void MemberDef::enableCallerGraph(bool e) 
02907 { 
02908   makeResident();
02909   m_impl->hasCallerGraph=e; 
02910   if (e) Doxygen::parseSourcesNeeded = TRUE;
02911 }
02912 
02913 bool MemberDef::protectionVisible() const
02914 {
02915   makeResident();
02916   return m_impl->prot==Public || 
02917          (m_impl->prot==Private   && Config_getBool("EXTRACT_PRIVATE"))   ||
02918          (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) ||
02919          (m_impl->prot==Package   && Config_getBool("EXTRACT_PACKAGE"));
02920 }
02921 
02922 void MemberDef::setInbodyDocumentation(const char *docs,
02923                   const char *docFile,int docLine)
02924 {
02925   makeResident();
02926   m_impl->inbodyDocs = docs;
02927   m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
02928   m_impl->inbodyLine = docLine;
02929   m_impl->inbodyFile = docFile;
02930 }
02931 
02932 bool MemberDef::isObjCMethod() const
02933 {
02934   makeResident();
02935   if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
02936   return FALSE; 
02937 }
02938 
02939 QCString MemberDef::qualifiedName() const
02940 {
02941   makeResident();
02942   if (isObjCMethod())
02943   {
02944     QCString qm;
02945     if (isStatic()) qm="+"; else qm="-";
02946     qm+="[";
02947     qm+=m_impl->classDef->name()+" ";
02948     qm+=name();
02949     qm+="]";
02950     return qm;
02951   }
02952   else
02953   {
02954     return Definition::qualifiedName();
02955   }  
02956 }
02957 
02958 void MemberDef::setTagInfo(TagInfo *ti)
02959 {
02960   if (ti)
02961   {
02962     makeResident();
02963     //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
02964     m_impl->anc=ti->anchor;
02965     setReference(ti->tagName);
02966     m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
02967   }
02968 }
02969 
02970 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
02971 {
02972   makeResident();
02973   QCString qm;
02974   if (showStatic)
02975   {
02976     if (isStatic()) qm="+ "; else qm="- ";
02977   }
02978   qm+=name();
02979   if (!localLink) // link to method of same class
02980   {
02981     qm+=" (";
02982     qm+=m_impl->classDef->name();
02983     qm+=")";
02984   }
02985   return qm;
02986 }
02987 
02988 const char *MemberDef::declaration() const
02989 { 
02990   makeResident();
02991   return m_impl->decl; 
02992 }
02993 
02994 const char *MemberDef::definition() const
02995 { 
02996   makeResident();
02997   return m_impl->def;
02998 }
02999 
03000 const char *MemberDef::extraTypeChars() const
03001 {
03002   makeResident();
03003   return m_impl->extraTypeChars;
03004 }
03005 
03006 const char *MemberDef::typeString() const
03007 { 
03008   makeResident();
03009   return m_impl->type; 
03010 }
03011 
03012 const char *MemberDef::argsString() const
03013 { 
03014   makeResident();
03015   return m_impl->args; 
03016 }
03017 
03018 const char *MemberDef::excpString() const
03019 { 
03020   makeResident();
03021   return m_impl->exception; 
03022 }
03023 
03024 const char *MemberDef::bitfieldString() const
03025 { 
03026   makeResident();
03027   return m_impl->bitfields; 
03028 }
03029 
03030 const QCString &MemberDef::initializer() const
03031 { 
03032   makeResident();
03033   return m_impl->initializer; 
03034 }
03035 
03036 int MemberDef::initializerLines() const
03037 { 
03038   makeResident();
03039   return m_impl->initLines; 
03040 }
03041 
03042 int  MemberDef::getMemberSpecifiers() const
03043 { 
03044   makeResident();
03045   return m_impl->memSpec; 
03046 }
03047 
03048 ClassDef *MemberDef::getClassDef() const
03049 { 
03050   makeResident();
03051   return m_impl->classDef; 
03052 }
03053 
03054 FileDef  *MemberDef::getFileDef() const
03055 { 
03056   makeResident();
03057   return m_impl->fileDef; 
03058 }
03059 
03060 NamespaceDef* MemberDef::getNamespaceDef() const
03061 { 
03062   makeResident();
03063   return m_impl->nspace; 
03064 }
03065 
03066 const char *MemberDef::getReadAccessor() const
03067 { 
03068   makeResident();
03069   return m_impl->read; 
03070 }
03071 
03072 const char *MemberDef::getWriteAccessor() const
03073 { 
03074   makeResident();
03075   return m_impl->write; 
03076 }
03077 
03078 GroupDef *MemberDef::getGroupDef() const
03079 { 
03080   makeResident();
03081   return m_impl->group; 
03082 }
03083 
03084 Grouping::GroupPri_t MemberDef::getGroupPri() const
03085 { 
03086   makeResident();
03087   return m_impl->grouppri; 
03088 }
03089 
03090 const char *MemberDef::getGroupFileName() const
03091 { 
03092   makeResident();
03093   return m_impl->groupFileName; 
03094 }
03095 
03096 int MemberDef::getGroupStartLine() const
03097 { 
03098   makeResident();
03099   return m_impl->groupStartLine; 
03100 }
03101 
03102 bool MemberDef::getGroupHasDocs() const
03103 { 
03104   makeResident();
03105   return m_impl->groupHasDocs; 
03106 }
03107 
03108 Protection MemberDef::protection() const
03109 { 
03110   makeResident();
03111   return m_impl->prot; 
03112 }
03113 
03114 MemberDef::MemberType MemberDef::memberType() const
03115 { 
03116   makeResident();
03117   return m_impl->mtype; 
03118 }
03119 
03120 bool MemberDef::isSignal() const
03121 { 
03122   makeResident();
03123   return m_impl->mtype==Signal;      
03124 }
03125 
03126 bool MemberDef::isSlot() const
03127 { 
03128   makeResident();
03129   return m_impl->mtype==Slot;        
03130 }
03131 
03132 bool MemberDef::isVariable() const
03133 { 
03134   makeResident();
03135   return m_impl->mtype==Variable;    
03136 }
03137 
03138 bool MemberDef::isEnumerate() const
03139 { 
03140   makeResident();
03141   return m_impl->mtype==Enumeration; 
03142 }
03143 
03144 bool MemberDef::isEnumValue() const
03145 { 
03146   makeResident();
03147   return m_impl->mtype==EnumValue;   
03148 }
03149 
03150 bool MemberDef::isTypedef() const
03151 { 
03152   makeResident();
03153   return m_impl->mtype==Typedef;     
03154 }
03155 
03156 bool MemberDef::isFunction() const
03157 { 
03158   makeResident();
03159   return m_impl->mtype==Function;    
03160 }
03161 
03162 bool MemberDef::isDefine() const
03163 { 
03164   makeResident();
03165   return m_impl->mtype==Define;      
03166 }
03167 
03168 bool MemberDef::isFriend() const
03169 { 
03170   makeResident();
03171   return m_impl->mtype==Friend;      
03172 }
03173 
03174 bool MemberDef::isDCOP() const
03175 { 
03176   makeResident();
03177   return m_impl->mtype==DCOP;        
03178 }
03179 
03180 bool MemberDef::isProperty() const
03181 { 
03182   makeResident();
03183   return m_impl->mtype==Property;    
03184 }
03185 
03186 bool MemberDef::isEvent() const
03187 { 
03188   makeResident();
03189   return m_impl->mtype==Event;       
03190 }
03191 
03192 bool MemberDef::isRelated() const
03193 { 
03194   makeResident();
03195   return m_impl->related; 
03196 }
03197 
03198 bool MemberDef::isStatic() const
03199 { 
03200   makeResident();
03201   return m_impl->stat; 
03202 }
03203 
03204 bool MemberDef::isInline() const
03205 { 
03206   makeResident();
03207   return (m_impl->memSpec&Entry::Inline)!=0; 
03208 }
03209 
03210 bool MemberDef::isExplicit() const
03211 { 
03212   makeResident();
03213   return (m_impl->memSpec&Entry::Explicit)!=0; 
03214 }
03215 
03216 bool MemberDef::isMutable() const
03217 { 
03218   makeResident();
03219   return (m_impl->memSpec&Entry::Mutable)!=0; 
03220 }
03221 
03222 bool MemberDef::isGettable() const
03223 { 
03224   makeResident();
03225   return (m_impl->memSpec&Entry::Gettable)!=0; 
03226 }
03227 
03228 bool MemberDef::isSettable() const
03229 { 
03230   makeResident();
03231   return (m_impl->memSpec&Entry::Settable)!=0; 
03232 }
03233 
03234 bool MemberDef::isAddable() const
03235 { 
03236   makeResident();
03237   return (m_impl->memSpec&Entry::Addable)!=0; 
03238 }
03239 
03240 bool MemberDef::isRemovable() const
03241 { 
03242   makeResident();
03243   return (m_impl->memSpec&Entry::Removable)!=0; 
03244 }
03245 
03246 bool MemberDef::isRaisable() const
03247 { 
03248   makeResident();
03249   return (m_impl->memSpec&Entry::Raisable)!=0; 
03250 }
03251 
03252 bool MemberDef::isReadable() const
03253 { 
03254   makeResident();
03255   return (m_impl->memSpec&Entry::Readable)!=0; 
03256 }
03257 
03258 bool MemberDef::isWritable() const
03259 { 
03260   makeResident();
03261   return (m_impl->memSpec&Entry::Writable)!=0; 
03262 }
03263 
03264 bool MemberDef::isFinal() const
03265 { 
03266   makeResident();
03267   return (m_impl->memSpec&Entry::Final)!=0; 
03268 }
03269 
03270 bool MemberDef::isNew() const
03271 { 
03272   makeResident();
03273   return (m_impl->memSpec&Entry::New)!=0; 
03274 }
03275 
03276 bool MemberDef::isSealed() const
03277 { 
03278   makeResident();
03279   return (m_impl->memSpec&Entry::Sealed)!=0; 
03280 }
03281 
03282 bool MemberDef::isOverride() const
03283 { 
03284   makeResident();
03285   return (m_impl->memSpec&Entry::Override)!=0; 
03286 }
03287 
03288 bool MemberDef::isInitonly() const
03289 { 
03290   makeResident();
03291   return (m_impl->memSpec&Entry::Initonly)!=0; 
03292 }
03293 
03294 bool MemberDef::isAbstract() const
03295 { 
03296   makeResident();
03297   return (m_impl->memSpec&Entry::Abstract)!=0; 
03298 }
03299 
03300 bool MemberDef::isOptional() const
03301 { 
03302   makeResident();
03303   return (m_impl->memSpec&Entry::Optional)!=0; 
03304 }
03305 
03306 bool MemberDef::isRequired() const
03307 { 
03308   makeResident();
03309   return (m_impl->memSpec&Entry::Required)!=0; 
03310 }
03311 
03312 bool MemberDef::isNonAtomic() const
03313 { 
03314   makeResident();
03315   return (m_impl->memSpec&Entry::NonAtomic)!=0; 
03316 }
03317 
03318 bool MemberDef::isCopy() const
03319 { 
03320   makeResident();
03321   return (m_impl->memSpec&Entry::Copy)!=0; 
03322 }
03323 
03324 bool MemberDef::isAssign() const
03325 { 
03326   makeResident();
03327   return (m_impl->memSpec&Entry::Assign)!=0; 
03328 }
03329 
03330 bool MemberDef::isRetain() const
03331 { 
03332   makeResident();
03333   return (m_impl->memSpec&Entry::Retain)!=0; 
03334 }
03335 
03336 
03337 bool MemberDef::isImplementation() const
03338 { 
03339   makeResident();
03340   return m_impl->implOnly; 
03341 }
03342 
03343 bool MemberDef::isExternal() const
03344 { 
03345   makeResident();
03346   return m_impl->explExt; 
03347 }
03348 
03349 bool MemberDef::isTemplateSpecialization() const
03350 { 
03351   makeResident();
03352   return m_impl->tspec; 
03353 }
03354 
03355 bool MemberDef::hasDocumentedParams() const
03356 { 
03357   makeResident();
03358   return m_impl->hasDocumentedParams; 
03359 }
03360 
03361 bool MemberDef::hasDocumentedReturnType() const
03362 { 
03363   makeResident();
03364   return m_impl->hasDocumentedReturnType; 
03365 }
03366 
03367 int MemberDef::inbodyLine() const
03368 { 
03369   makeResident();
03370   return m_impl->inbodyLine; 
03371 }
03372 
03373 QCString MemberDef::inbodyFile() const
03374 { 
03375   makeResident();
03376   return m_impl->inbodyFile; 
03377 }
03378 
03379 const QCString &MemberDef::inbodyDocumentation() const
03380 { 
03381   makeResident();
03382   return m_impl->inbodyDocs; 
03383 }
03384 
03385 ClassDef *MemberDef::relatedAlso() const
03386 { 
03387   makeResident();
03388   return m_impl->relatedAlso; 
03389 }
03390 
03391 bool MemberDef::hasDocumentedEnumValues() const
03392 { 
03393   makeResident();
03394   return m_impl->docEnumValues; 
03395 }
03396 
03397 MemberDef *MemberDef::getAnonymousEnumType() const
03398 { 
03399   makeResident();
03400   return m_impl->annEnumType; 
03401 }
03402 
03403 bool MemberDef::isDocsForDefinition() const
03404 { 
03405   makeResident();
03406   return m_impl->docsForDefinition; 
03407 }
03408 
03409 MemberDef *MemberDef::getEnumScope() const
03410 { 
03411   makeResident();
03412   return m_impl->enumScope; 
03413 }
03414 
03415 LockingPtr<MemberList> MemberDef::enumFieldList() const
03416 { 
03417   makeResident();
03418   return LockingPtr<MemberList>(this,m_impl->enumFields); 
03419 }
03420 
03421 LockingPtr<ExampleSDict> MemberDef::getExamples() const
03422 { 
03423   makeResident();
03424   return LockingPtr<ExampleSDict>(this,m_impl->exampleSDict); 
03425 }
03426 
03427 bool MemberDef::isPrototype() const
03428 { 
03429   makeResident();
03430   return m_impl->proto; 
03431 }
03432 
03433 LockingPtr<ArgumentList> MemberDef::argumentList() const
03434 { 
03435   makeResident();
03436   return LockingPtr<ArgumentList>(this,m_impl->defArgList); 
03437 }
03438 
03439 LockingPtr<ArgumentList> MemberDef::declArgumentList() const
03440 { 
03441   makeResident();
03442   return LockingPtr<ArgumentList>(this,m_impl->declArgList); 
03443 }
03444 
03445 LockingPtr<ArgumentList> MemberDef::templateArguments() const
03446 { 
03447   makeResident();
03448   return LockingPtr<ArgumentList>(this,m_impl->tArgList); 
03449 }
03450 
03451 LockingPtr< QList<ArgumentList> > MemberDef::definitionTemplateParameterLists() const
03452 { 
03453   makeResident();
03454   return LockingPtr< QList<ArgumentList> >(this,m_impl->defTmpArgLists); 
03455 }
03456 
03457 int MemberDef::getMemberGroupId() const
03458 { 
03459   makeResident();
03460   return m_impl->grpId; 
03461 }
03462 
03463 MemberGroup *MemberDef::getMemberGroup() const
03464 { 
03465   makeResident();
03466   return m_impl->memberGroup; 
03467 }
03468 
03469 bool MemberDef::fromAnonymousScope() const
03470 { 
03471   makeResident();
03472   return m_impl->annScope; 
03473 }
03474 
03475 bool MemberDef::anonymousDeclShown() const
03476 { 
03477   makeResident();
03478   return m_impl->annUsed; 
03479 }
03480 
03481 void MemberDef::setAnonymousUsed() 
03482 {
03483   makeResident();
03484   m_impl->annUsed = TRUE;
03485 }
03486 
03487 bool MemberDef::hasCallGraph() const
03488 { 
03489   makeResident();
03490   return m_impl->hasCallGraph; 
03491 }
03492 
03493 bool MemberDef::hasCallerGraph() const
03494 { 
03495   makeResident();
03496   return m_impl->hasCallerGraph; 
03497 }
03498 
03499 MemberDef *MemberDef::templateMaster() const
03500 { 
03501   makeResident();
03502   return m_impl->templateMaster; 
03503 }
03504 
03505 bool MemberDef::isTypedefValCached() const
03506 { 
03507   makeResident();
03508   return m_impl->isTypedefValCached; 
03509 }
03510 
03511 ClassDef *MemberDef::getCachedTypedefVal() const
03512 { 
03513   makeResident();
03514   return m_impl->cachedTypedefValue; 
03515 }
03516 
03517 QCString MemberDef::getCachedTypedefTemplSpec() const
03518 { 
03519   makeResident();
03520   return m_impl->cachedTypedefTemplSpec; 
03521 }
03522 
03523 QCString MemberDef::getCachedResolvedTypedef() const
03524 { 
03525   makeResident();
03526   //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
03527   return m_impl->cachedResolvedType; 
03528 }
03529 
03530 MemberDef *MemberDef::memberDefinition() const
03531 { 
03532   makeResident();
03533   return m_impl->memDef; 
03534 }
03535 
03536 MemberDef *MemberDef::memberDeclaration() const
03537 { 
03538   makeResident();
03539   return m_impl->memDec; 
03540 }
03541 
03542 MemberDef *MemberDef::inheritsDocsFrom() const
03543 { 
03544   makeResident();
03545   return m_impl->docProvider; 
03546 }
03547 
03548 MemberDef *MemberDef::getGroupAlias() const
03549 { 
03550   makeResident();
03551   return m_impl->groupAlias; 
03552 }
03553 
03554 void MemberDef::setMemberType(MemberType t)
03555 { 
03556   makeResident();
03557   m_impl->mtype=t; 
03558 }
03559 
03560 void MemberDef::setDefinition(const char *d)
03561 { 
03562   makeResident();
03563   m_impl->def=d; 
03564 }
03565 
03566 void MemberDef::setFileDef(FileDef *fd)
03567 { 
03568   makeResident();
03569   m_impl->fileDef=fd; 
03570 }
03571 
03572 void MemberDef::setProtection(Protection p)
03573 { 
03574   makeResident();
03575   m_impl->prot=p; 
03576 }
03577 
03578 void MemberDef::setMemberSpecifiers(int s)
03579 { 
03580   makeResident();
03581   m_impl->memSpec=s; 
03582 }
03583 
03584 void MemberDef::mergeMemberSpecifiers(int s)
03585 { 
03586   makeResident();
03587   m_impl->memSpec|=s; 
03588 }
03589 
03590 void MemberDef::setBitfields(const char *s)
03591 { 
03592   makeResident();
03593   m_impl->bitfields = s; 
03594 }
03595 
03596 void MemberDef::setMaxInitLines(int lines)
03597 { 
03598   if (lines!=-1)
03599   {
03600     makeResident();
03601     m_impl->userInitLines=lines; 
03602   }
03603 }
03604 
03605 void MemberDef::setExplicitExternal(bool b)
03606 { 
03607   makeResident();
03608   m_impl->explExt=b; 
03609 }
03610 
03611 void MemberDef::setReadAccessor(const char *r)
03612 { 
03613   makeResident();
03614   m_impl->read=r; 
03615 }
03616 
03617 void MemberDef::setWriteAccessor(const char *w)
03618 { 
03619   makeResident();
03620   m_impl->write=w; 
03621 }
03622 
03623 void MemberDef::setTemplateSpecialization(bool b)
03624 { 
03625   makeResident();
03626   m_impl->tspec=b; 
03627 }
03628 
03629 void MemberDef::makeRelated()
03630 { 
03631   makeResident();
03632   m_impl->related=TRUE; 
03633 }
03634 
03635 void MemberDef::setHasDocumentedParams(bool b)
03636 { 
03637   makeResident();
03638   m_impl->hasDocumentedParams = b; 
03639 }
03640 
03641 void MemberDef::setHasDocumentedReturnType(bool b)
03642 { 
03643   makeResident();
03644   m_impl->hasDocumentedReturnType = b; 
03645 }
03646 
03647 void MemberDef::setInheritsDocsFrom(MemberDef *md)
03648 { 
03649   makeResident();
03650   m_impl->docProvider = md; 
03651 }
03652 
03653 void MemberDef::setArgsString(const char *as)
03654 { 
03655   makeResident();
03656   m_impl->args = as; 
03657 }
03658 
03659 void MemberDef::setRelatedAlso(ClassDef *cd)
03660 { 
03661   makeResident();
03662   m_impl->relatedAlso=cd; 
03663 }
03664 
03665 void MemberDef::setEnumClassScope(ClassDef *cd)
03666 { 
03667   makeResident();
03668   m_impl->classDef = cd; 
03669 }
03670 
03671 void MemberDef::setDocumentedEnumValues(bool value)
03672 { 
03673   makeResident();
03674   m_impl->docEnumValues=value; 
03675 }
03676 
03677 void MemberDef::setAnonymousEnumType(MemberDef *md)
03678 { 
03679   makeResident();
03680   m_impl->annEnumType = md; 
03681 }
03682 
03683 void MemberDef::setPrototype(bool p)
03684 { 
03685   makeResident();
03686   m_impl->proto=p; 
03687 }
03688 
03689 void MemberDef::setMemberGroupId(int id)
03690 { 
03691   makeResident();
03692   m_impl->grpId=id; 
03693 }
03694 
03695 void MemberDef::makeImplementationDetail()
03696 { 
03697   makeResident();
03698   m_impl->implOnly=TRUE; 
03699 }
03700 
03701 void MemberDef::setFromAnonymousScope(bool b)
03702 { 
03703   makeResident();
03704   m_impl->annScope=b; 
03705 }
03706 
03707 void MemberDef::setFromAnonymousMember(MemberDef *m)
03708 { 
03709   makeResident();
03710   m_impl->annMemb=m; 
03711 }
03712 
03713 void MemberDef::setTemplateMaster(MemberDef *mt)
03714 { 
03715   makeResident();
03716   m_impl->templateMaster=mt; 
03717 }
03718 
03719 void MemberDef::setDocsForDefinition(bool b)
03720 { 
03721   makeResident();
03722   m_impl->docsForDefinition = b; 
03723 }
03724 
03725 void MemberDef::setGroupAlias(MemberDef *md)
03726 { 
03727   makeResident();
03728   m_impl->groupAlias = md; 
03729 }
03730 
03731 void MemberDef::invalidateTypedefValCache()
03732 { 
03733   makeResident();
03734   m_impl->isTypedefValCached=FALSE; 
03735 }
03736 
03737 void MemberDef::setMemberDefinition(MemberDef *md)
03738 { 
03739   makeResident();
03740   m_impl->memDef=md; 
03741 }
03742 
03743 void MemberDef::setMemberDeclaration(MemberDef *md)
03744 { 
03745   makeResident();
03746   m_impl->memDec=md; 
03747 }
03748 
03749 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
03750 {
03751   makeResident();
03752   m_impl->isTypedefValCached=TRUE; 
03753   m_impl->cachedTypedefValue=val; 
03754   m_impl->cachedTypedefTemplSpec=templSpec; 
03755   m_impl->cachedResolvedType=resolvedType;
03756   //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
03757 }
03758 
03759 void MemberDef::flushToDisk() const
03760 {
03761   if (isLocked()) return;
03762   MemberDef *that = (MemberDef*)this;
03763   that->m_storagePos = Doxygen::symbolStorage->alloc();
03764   //printf("%p: MemberDef::flushToDisk()\n",this);
03765   // write the definition base class member variables to disk
03766   Definition::flushToDisk();
03767 
03768   //printf("%p:   flushing specific part\n",this);
03769 
03770   // write the memberdef member variables to disk
03771   marshalUInt(Doxygen::symbolStorage,START_MARKER);
03772   marshalObjPointer   (Doxygen::symbolStorage,m_impl->classDef);
03773   marshalObjPointer   (Doxygen::symbolStorage,m_impl->fileDef);
03774   marshalObjPointer   (Doxygen::symbolStorage,m_impl->nspace);
03775   marshalObjPointer   (Doxygen::symbolStorage,m_impl->enumScope);
03776   marshalObjPointer   (Doxygen::symbolStorage,m_impl->annEnumType);
03777   marshalMemberList   (Doxygen::symbolStorage,m_impl->enumFields);
03778   marshalObjPointer   (Doxygen::symbolStorage,m_impl->redefines);
03779   marshalMemberList   (Doxygen::symbolStorage,m_impl->redefinedBy);
03780   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memDef);
03781   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memDec);
03782   marshalObjPointer   (Doxygen::symbolStorage,m_impl->relatedAlso);
03783   marshalExampleSDict (Doxygen::symbolStorage,m_impl->exampleSDict);
03784   marshalQCString     (Doxygen::symbolStorage,m_impl->type);
03785   marshalQCString     (Doxygen::symbolStorage,m_impl->args);
03786   marshalQCString     (Doxygen::symbolStorage,m_impl->def);
03787   marshalQCString     (Doxygen::symbolStorage,m_impl->anc);
03788   marshalInt          (Doxygen::symbolStorage,(int)m_impl->virt);
03789   marshalInt          (Doxygen::symbolStorage,(int)m_impl->prot);
03790   marshalQCString     (Doxygen::symbolStorage,m_impl->decl);
03791   marshalQCString     (Doxygen::symbolStorage,m_impl->bitfields);
03792   marshalQCString     (Doxygen::symbolStorage,m_impl->read);
03793   marshalQCString     (Doxygen::symbolStorage,m_impl->write);
03794   marshalQCString     (Doxygen::symbolStorage,m_impl->exception);
03795   marshalQCString     (Doxygen::symbolStorage,m_impl->initializer);
03796   marshalQCString     (Doxygen::symbolStorage,m_impl->extraTypeChars);
03797   marshalInt          (Doxygen::symbolStorage,m_impl->initLines);
03798   marshalInt          (Doxygen::symbolStorage,m_impl->memSpec);
03799   marshalInt          (Doxygen::symbolStorage,(int)m_impl->mtype);
03800   marshalInt          (Doxygen::symbolStorage,m_impl->maxInitLines);
03801   marshalInt          (Doxygen::symbolStorage,m_impl->userInitLines);
03802   marshalObjPointer   (Doxygen::symbolStorage,m_impl->annMemb);
03803   marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList);
03804   marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList);
03805   marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList);
03806   marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints);
03807   marshalObjPointer   (Doxygen::symbolStorage,m_impl->templateMaster);
03808   marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists);
03809   marshalObjPointer   (Doxygen::symbolStorage,m_impl->cachedAnonymousType);
03810   marshalMemberLists  (Doxygen::symbolStorage,m_impl->classSectionSDict);
03811   marshalObjPointer   (Doxygen::symbolStorage,m_impl->groupAlias);
03812   marshalInt          (Doxygen::symbolStorage,m_impl->grpId);
03813   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memberGroup);
03814   marshalObjPointer   (Doxygen::symbolStorage,m_impl->group);
03815   marshalInt          (Doxygen::symbolStorage,(int)m_impl->grouppri);
03816   marshalQCString     (Doxygen::symbolStorage,m_impl->groupFileName);
03817   marshalInt          (Doxygen::symbolStorage,m_impl->groupStartLine);
03818   marshalObjPointer   (Doxygen::symbolStorage,m_impl->groupMember);
03819   marshalBool         (Doxygen::symbolStorage,m_impl->isTypedefValCached);
03820   marshalObjPointer   (Doxygen::symbolStorage,m_impl->cachedTypedefValue);
03821   marshalQCString     (Doxygen::symbolStorage,m_impl->cachedTypedefTemplSpec);
03822   marshalQCString     (Doxygen::symbolStorage,m_impl->cachedResolvedType);
03823   marshalInt          (Doxygen::symbolStorage,m_impl->inbodyLine);
03824   marshalQCString     (Doxygen::symbolStorage,m_impl->inbodyFile);
03825   marshalQCString     (Doxygen::symbolStorage,m_impl->inbodyDocs);
03826   marshalObjPointer   (Doxygen::symbolStorage,m_impl->docProvider);
03827   marshalQCString     (Doxygen::symbolStorage,m_impl->explicitOutputFileBase);
03828   marshalBool         (Doxygen::symbolStorage,m_impl->implOnly); 
03829   marshalBool         (Doxygen::symbolStorage,m_impl->hasDocumentedParams);
03830   marshalBool         (Doxygen::symbolStorage,m_impl->hasDocumentedReturnType);
03831   marshalBool         (Doxygen::symbolStorage,m_impl->isDMember);
03832   marshalBool         (Doxygen::symbolStorage,m_impl->related);
03833   marshalBool         (Doxygen::symbolStorage,m_impl->stat);
03834   marshalBool         (Doxygen::symbolStorage,m_impl->proto);
03835   marshalBool         (Doxygen::symbolStorage,m_impl->docEnumValues);
03836   marshalBool         (Doxygen::symbolStorage,m_impl->annScope);
03837   marshalBool         (Doxygen::symbolStorage,m_impl->annUsed);
03838   marshalBool         (Doxygen::symbolStorage,m_impl->hasCallGraph);
03839   marshalBool         (Doxygen::symbolStorage,m_impl->hasCallerGraph);
03840   marshalBool         (Doxygen::symbolStorage,m_impl->explExt);
03841   marshalBool         (Doxygen::symbolStorage,m_impl->tspec);
03842   marshalBool         (Doxygen::symbolStorage,m_impl->groupHasDocs);
03843   marshalBool         (Doxygen::symbolStorage,m_impl->docsForDefinition);
03844   marshalUInt(Doxygen::symbolStorage,END_MARKER);
03845 
03846   // function doesn't modify the object conceptually but compiler doesn't know this.
03847   delete that->m_impl;
03848   that->m_impl=0;
03849   that->m_flushPending=FALSE;
03850 }
03851 
03852 void MemberDef::loadFromDisk() const
03853 {
03854   //printf("%p: MemberDef::loadFromDisk()\n",this);
03855   MemberDef *that = (MemberDef *)this;
03856   if (isLocked()) 
03857   {
03858     assert(m_impl!=0);
03859     return;
03860   }
03861   assert(m_impl==0);
03862 
03863   Doxygen::symbolStorage->seek(m_storagePos);
03864   Definition::loadFromDisk();
03865 
03866   //printf("%p:   loading specific part\n",this);
03867 
03868   that->m_impl = new MemberDefImpl;
03869 
03870   uint marker = unmarshalUInt(Doxygen::symbolStorage);
03871   assert(marker==START_MARKER);
03872   m_impl->classDef                = (ClassDef*)unmarshalObjPointer     (Doxygen::symbolStorage);
03873   m_impl->fileDef                 = (FileDef*)unmarshalObjPointer      (Doxygen::symbolStorage);
03874   m_impl->nspace                  = (NamespaceDef*)unmarshalObjPointer (Doxygen::symbolStorage);
03875   m_impl->enumScope               = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
03876   m_impl->annEnumType             = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
03877   m_impl->enumFields              = unmarshalMemberList                (Doxygen::symbolStorage);
03878   m_impl->redefines               = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
03879   m_impl->redefinedBy             = unmarshalMemberList                (Doxygen::symbolStorage);
03880   m_impl->memDef                  = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
03881   m_impl->memDec                  = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
03882   m_impl->relatedAlso             = (ClassDef*)unmarshalObjPointer     (Doxygen::symbolStorage);
03883   m_impl->exampleSDict            = unmarshalExampleSDict (Doxygen::symbolStorage);
03884   m_impl->type                    = unmarshalQCString     (Doxygen::symbolStorage);
03885   m_impl->args                    = unmarshalQCString     (Doxygen::symbolStorage);
03886   m_impl->def                     = unmarshalQCString     (Doxygen::symbolStorage);
03887   m_impl->anc                     = unmarshalQCString     (Doxygen::symbolStorage);
03888   m_impl->virt                    = (Specifier)unmarshalInt (Doxygen::symbolStorage);
03889   m_impl->prot                    = (Protection)unmarshalInt(Doxygen::symbolStorage);
03890   m_impl->decl                    = unmarshalQCString     (Doxygen::symbolStorage);
03891   m_impl->bitfields               = unmarshalQCString     (Doxygen::symbolStorage);
03892   m_impl->read                    = unmarshalQCString     (Doxygen::symbolStorage);
03893   m_impl->write                   = unmarshalQCString     (Doxygen::symbolStorage);
03894   m_impl->exception               = unmarshalQCString     (Doxygen::symbolStorage);
03895   m_impl->initializer             = unmarshalQCString     (Doxygen::symbolStorage);
03896   m_impl->extraTypeChars          = unmarshalQCString     (Doxygen::symbolStorage);
03897   m_impl->initLines               = unmarshalInt          (Doxygen::symbolStorage);
03898   m_impl->memSpec                 = unmarshalInt          (Doxygen::symbolStorage);
03899   m_impl->mtype                   = (MemberDef::MemberType)unmarshalInt          (Doxygen::symbolStorage);
03900   m_impl->maxInitLines            = unmarshalInt          (Doxygen::symbolStorage);
03901   m_impl->userInitLines           = unmarshalInt          (Doxygen::symbolStorage);
03902   m_impl->annMemb                 = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03903   m_impl->defArgList              = unmarshalArgumentList (Doxygen::symbolStorage);
03904   m_impl->declArgList             = unmarshalArgumentList (Doxygen::symbolStorage);
03905   m_impl->tArgList                = unmarshalArgumentList (Doxygen::symbolStorage);
03906   m_impl->typeConstraints         = unmarshalArgumentList (Doxygen::symbolStorage);
03907   m_impl->templateMaster          = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03908   m_impl->defTmpArgLists          = unmarshalArgumentLists(Doxygen::symbolStorage);
03909   m_impl->cachedAnonymousType     = (ClassDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03910   m_impl->classSectionSDict       = unmarshalMemberLists  (Doxygen::symbolStorage);
03911   m_impl->groupAlias              = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03912   m_impl->grpId                   = unmarshalInt          (Doxygen::symbolStorage);
03913   m_impl->memberGroup             = (MemberGroup*)unmarshalObjPointer   (Doxygen::symbolStorage);
03914   m_impl->group                   = (GroupDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03915   m_impl->grouppri                = (Grouping::GroupPri_t)unmarshalInt          (Doxygen::symbolStorage);
03916   m_impl->groupFileName           = unmarshalQCString     (Doxygen::symbolStorage);
03917   m_impl->groupStartLine          = unmarshalInt          (Doxygen::symbolStorage);
03918   m_impl->groupMember             = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03919   m_impl->isTypedefValCached      = unmarshalBool         (Doxygen::symbolStorage);
03920   m_impl->cachedTypedefValue      = (ClassDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03921   m_impl->cachedTypedefTemplSpec  = unmarshalQCString     (Doxygen::symbolStorage);
03922   m_impl->cachedResolvedType      = unmarshalQCString     (Doxygen::symbolStorage);
03923   m_impl->inbodyLine              = unmarshalInt          (Doxygen::symbolStorage);
03924   m_impl->inbodyFile              = unmarshalQCString     (Doxygen::symbolStorage);
03925   m_impl->inbodyDocs              = unmarshalQCString     (Doxygen::symbolStorage);
03926   m_impl->docProvider             = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
03927   m_impl->explicitOutputFileBase  = unmarshalQCString     (Doxygen::symbolStorage);
03928   m_impl->implOnly                = unmarshalBool         (Doxygen::symbolStorage); 
03929   m_impl->hasDocumentedParams     = unmarshalBool         (Doxygen::symbolStorage);
03930   m_impl->hasDocumentedReturnType = unmarshalBool         (Doxygen::symbolStorage);
03931   m_impl->isDMember               = unmarshalBool         (Doxygen::symbolStorage);
03932   m_impl->related                 = unmarshalBool         (Doxygen::symbolStorage);
03933   m_impl->stat                    = unmarshalBool         (Doxygen::symbolStorage);
03934   m_impl->proto                   = unmarshalBool         (Doxygen::symbolStorage);
03935   m_impl->docEnumValues           = unmarshalBool         (Doxygen::symbolStorage);
03936   m_impl->annScope                = unmarshalBool         (Doxygen::symbolStorage);
03937   m_impl->annUsed                 = unmarshalBool         (Doxygen::symbolStorage);
03938   m_impl->hasCallGraph            = unmarshalBool         (Doxygen::symbolStorage);
03939   m_impl->hasCallerGraph          = unmarshalBool         (Doxygen::symbolStorage);
03940   m_impl->explExt                 = unmarshalBool         (Doxygen::symbolStorage);
03941   m_impl->tspec                   = unmarshalBool         (Doxygen::symbolStorage);
03942   m_impl->groupHasDocs            = unmarshalBool         (Doxygen::symbolStorage);
03943   m_impl->docsForDefinition       = unmarshalBool         (Doxygen::symbolStorage);
03944   marker = unmarshalUInt(Doxygen::symbolStorage);
03945   assert(marker==END_MARKER);
03946 }
03947 
03948 void MemberDef::makeResident() const
03949 { 
03950   if (m_cacheHandle==-1) // not yet in cache
03951   { 
03952     MemberDef *victim = 0;
03953     MemberDef *that = (MemberDef*)this; // fake method constness
03954     that->m_cacheHandle = Doxygen::symbolCache->add(that,(void **)&victim);
03955     //printf("adding %s to cache, handle=%d\n",m_impl->name.data(),that->m_cacheHandle);
03956     if (victim)  // cache was full, victim was the least recently used item and has to go
03957     {
03958       victim->m_cacheHandle=-1; // invalidate cache handle
03959       victim->saveToDisk();     // store the item on disk
03960     }
03961     else // cache not yet full
03962     {
03963       //printf("Adding %s to cache, handle=%d\n",m_impl->name.data(),m_cacheHandle);
03964     }
03965     if (m_storagePos!=-1) // already been written to disk
03966     {
03967       if (isLocked()) // locked in memory
03968       {
03969         assert(m_impl!=0);
03970         that->m_flushPending=FALSE; // no need to flush anymore
03971       }
03972       else // not locked in memory
03973       {
03974         assert(m_impl==0);
03975         loadFromDisk();
03976       }
03977     }
03978   }
03979   else // already cached, make this object the most recently used.
03980   {
03981     assert(m_impl!=0);
03982     //printf("Touching symbol %s\n",m_impl->name.data());
03983     Doxygen::symbolCache->use(m_cacheHandle);
03984   }
03985 }
03986 
03987 void MemberDef::saveToDisk() const
03988 {
03989   assert(m_impl!=0);
03990   MemberDef *that = (MemberDef *)this;
03991   if (isLocked()) // cannot flush the item as it is locked
03992   {
03993     that->m_flushPending=TRUE; // flush when unlocked
03994   }
03995   else // ready to flush the item to disk
03996   {
03997     //printf("Adding %s to cache, handle=%d by replacing %s\n",
03998     //    m_impl->name.data(),m_cacheHandle,victim->m_impl->name.data());
03999     if (m_storagePos!=-1) 
04000       // if victim was stored on disk already and is not locked
04001     {
04002       // free the storage space occupied by the old store item
04003       Doxygen::symbolStorage->release(m_storagePos); // free up space for others
04004     }
04005     // write a the new (possibly modified) instance to disk
04006     flushToDisk();
04007     // end to write sequence (unless nothing was written due to the lock)
04008     Doxygen::symbolStorage->end();
04009   }
04010 }
04011 
04012 void MemberDef::lock() const
04013 {
04014 }
04015 
04016 void MemberDef::unlock() const
04017 {
04018   if (m_flushPending && !isLocked())
04019   {
04020     // write a the new (possibly modified) instance to disk
04021     flushToDisk();
04022     // end to write sequence (unless nothing was written due to the lock)
04023     Doxygen::symbolStorage->end();
04024   }
04025 }
04026 
04027 void MemberDef::copyArgumentNames(MemberDef *bmd)
04028 {
04029   makeResident();
04030   {
04031     LockingPtr<ArgumentList> arguments = bmd->argumentList();
04032     if (m_impl->defArgList && arguments!=0)
04033     {
04034       ArgumentListIterator aliDst(*m_impl->defArgList);
04035       ArgumentListIterator aliSrc(*arguments);
04036       Argument *argDst, *argSrc;
04037       for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
04038       {
04039         argDst->name = argSrc->name;
04040       }
04041     }
04042   }
04043   {
04044     LockingPtr<ArgumentList> arguments = bmd->declArgumentList();
04045     if (m_impl->declArgList && arguments!=0)
04046     {
04047       ArgumentListIterator aliDst(*m_impl->declArgList);
04048       ArgumentListIterator aliSrc(*arguments);
04049       Argument *argDst, *argSrc;
04050       for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
04051       {
04052         argDst->name = argSrc->name;
04053       }
04054     }
04055   }
04056 }
04057 
04058 



Generated on Mon Mar 31 10:58:40 2008 by  doxygen 1.5.1