Orb/Doxygen/src/memberdef.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 #include <stdio.h>
       
    19 #include <qregexp.h>
       
    20 #include <assert.h>
       
    21 #include <md5.h>
       
    22 #include "memberdef.h"
       
    23 #include "membername.h"
       
    24 #include "doxygen.h"
       
    25 #include "util.h"
       
    26 #include "code.h"
       
    27 #include "message.h"
       
    28 #include "htmlhelp.h"
       
    29 #include "language.h"
       
    30 #include "outputlist.h"
       
    31 #include "example.h"
       
    32 #include "membergroup.h"
       
    33 #include "groupdef.h"
       
    34 #include "defargs.h"
       
    35 #include "docparser.h"
       
    36 #include "dot.h"
       
    37 #include "searchindex.h"
       
    38 #include "parserintf.h"
       
    39 #include "marshal.h"
       
    40 #include "objcache.h"
       
    41 #include "vhdlscanner.h"
       
    42 #include "vhdldocgen.h"
       
    43 
       
    44 #define START_MARKER 0x4D454D5B // MEM[
       
    45 #define END_MARKER   0x4D454D5D // MEM]
       
    46 
       
    47 //-----------------------------------------------------------------------------
       
    48 
       
    49 int MemberDef::s_indentLevel = 0;
       
    50 
       
    51 //-----------------------------------------------------------------------------
       
    52 
       
    53 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
       
    54 {
       
    55   QCString result;
       
    56   QCString clRealName=n;
       
    57   int p=0,i;
       
    58   if ((i=clRealName.find('<'))!=-1)
       
    59   {
       
    60     clRealName=clRealName.left(i); // strip template specialization
       
    61   }
       
    62   if ((i=clRealName.findRev("::"))!=-1)
       
    63   {
       
    64     clRealName=clRealName.right(clRealName.length()-i-2);
       
    65   }
       
    66   while ((i=s.find(clRealName,p))!=-1)
       
    67   {
       
    68     result+=s.mid(p,i-p);
       
    69     uint j=clRealName.length()+i;
       
    70     if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
       
    71     { // add template names
       
    72       //printf("Adding %s+%s\n",clRealName.data(),t.data());
       
    73       result+=clRealName+t; 
       
    74     }
       
    75     else 
       
    76     { // template names already present
       
    77       //printf("Adding %s\n",clRealName.data());
       
    78       result+=clRealName;
       
    79     }
       
    80     p=i+clRealName.length();
       
    81   }
       
    82   result+=s.right(s.length()-p);
       
    83   //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
       
    84   return result;
       
    85 }
       
    86 
       
    87 static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
       
    88                                  const QCString & /*scopeName*/,MemberDef *md)
       
    89 {
       
    90   LockingPtr<ArgumentList> defArgList=(md->isDocsForDefinition()) ? 
       
    91                              md->argumentList() : md->declArgumentList();
       
    92   //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
       
    93   if (defArgList==0 || md->isProperty()) 
       
    94   {
       
    95     return FALSE; // member has no function like argument list
       
    96   }
       
    97   if (!md->isDefine()) ol.docify(" ");
       
    98 
       
    99   //printf("writeDefArgList(%d)\n",defArgList->count());
       
   100   ol.pushGeneratorState();
       
   101   ol.disableAllBut(OutputGenerator::Html);
       
   102   {
       
   103     // html
       
   104     ol.endMemberDocName();
       
   105     ol.startParameterList(!md->isObjCMethod()); 
       
   106   }
       
   107   ol.enableAll();
       
   108   ol.disable(OutputGenerator::Html);
       
   109   {
       
   110     // other formats
       
   111     if (!md->isObjCMethod()) ol.docify("("); // start argument list
       
   112     ol.endMemberDocName();
       
   113   }
       
   114   ol.popGeneratorState();
       
   115   //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
       
   116 
       
   117   Argument *a=defArgList->first();
       
   118   QCString cName;
       
   119   if (cd)
       
   120   {
       
   121     cName=cd->name();
       
   122     int il=cName.find('<');
       
   123     int ir=cName.findRev('>');
       
   124     if (il!=-1 && ir!=-1 && ir>il)
       
   125     {
       
   126       cName=cName.mid(il,ir-il+1);
       
   127       //printf("1. cName=%s\n",cName.data());
       
   128     }
       
   129     else if (cd->templateArguments())
       
   130     {
       
   131       cName=tempArgListToString(cd->templateArguments()); 
       
   132       //printf("2. cName=%s\n",cName.data());
       
   133     }
       
   134     else // no template specifier
       
   135     {
       
   136       cName.resize(0);
       
   137     }
       
   138   }
       
   139   //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
       
   140 
       
   141   //if (!md->isDefine()) ol.startParameter(TRUE); else ol.docify(" ");
       
   142   bool first=TRUE;
       
   143   bool paramTypeStarted=FALSE;
       
   144   while (a)
       
   145   {
       
   146     if (md->isDefine() || first) 
       
   147     {
       
   148       ol.startParameterType(first,md->isObjCMethod()?"dummy":0);
       
   149       paramTypeStarted=TRUE;
       
   150     }
       
   151     QRegExp re(")("),res("(.*\\*");
       
   152     int vp=a->type.find(re);
       
   153     int wp=a->type.find(res);
       
   154 
       
   155     // use the following to put the function pointer type before the name
       
   156     bool hasFuncPtrType=FALSE; 
       
   157 
       
   158     // or use the following to put the function pointer as it appears in
       
   159     // the prototype.
       
   160     //bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp; 
       
   161 
       
   162     if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
       
   163     {
       
   164       ol.docify(a->attrib+" ");
       
   165     }
       
   166     if (hasFuncPtrType) // argument type is a function pointer
       
   167     {
       
   168       //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
       
   169       QCString n=a->type.left(vp);
       
   170       if (hasFuncPtrType) n=a->type.left(wp);
       
   171       if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
       
   172       if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
       
   173       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
       
   174     }
       
   175     else // non-function pointer type
       
   176     {
       
   177       QCString n=a->type;
       
   178       if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
       
   179       if (a->type!="...")
       
   180       {
       
   181         if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
       
   182         linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n);
       
   183       }
       
   184     }
       
   185     if (!md->isDefine())
       
   186     {
       
   187       if (paramTypeStarted) 
       
   188       {
       
   189         ol.endParameterType();
       
   190         paramTypeStarted=FALSE;
       
   191       }
       
   192       ol.startParameterName(defArgList->count()<2);
       
   193     }
       
   194     if (hasFuncPtrType)
       
   195     {
       
   196       ol.docify(a->type.mid(wp,vp-wp)); 
       
   197     }
       
   198     if (!a->name.isEmpty() || (a->name.isEmpty() && a->type=="...")) // argument has a name
       
   199     { 
       
   200       if (!hasFuncPtrType)
       
   201       {
       
   202         ol.docify(" ");
       
   203       }
       
   204       ol.disable(OutputGenerator::Man);
       
   205       ol.startEmphasis();
       
   206       ol.enable(OutputGenerator::Man);
       
   207       if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
       
   208       ol.disable(OutputGenerator::Man);
       
   209       ol.endEmphasis();
       
   210       ol.enable(OutputGenerator::Man);
       
   211     }
       
   212     if (!a->array.isEmpty())
       
   213     {
       
   214       ol.docify(a->array);
       
   215     }
       
   216     if (hasFuncPtrType) // write the part of the argument type 
       
   217                         // that comes after the name
       
   218     {
       
   219       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),
       
   220                   md->name(),a->type.right(a->type.length()-vp));
       
   221     }
       
   222     if (!a->defval.isEmpty()) // write the default value
       
   223     {
       
   224       QCString n=a->defval;
       
   225       if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
       
   226       ol.docify(" = ");
       
   227 
       
   228       ol.startTypewriter();
       
   229       linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md->name(),n,FALSE,TRUE,TRUE); 
       
   230       ol.endTypewriter();
       
   231 
       
   232     }
       
   233     a=defArgList->next();
       
   234     if (a) 
       
   235     {
       
   236       if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
       
   237       if (!md->isDefine()) 
       
   238       {
       
   239         QCString key;
       
   240         if (md->isObjCMethod() && a->attrib.length()>=2)
       
   241         {
       
   242           //printf("Found parameter keyword %s\n",a->attrib.data());
       
   243           // strip [ and ]
       
   244           key=a->attrib.mid(1,a->attrib.length()-2);
       
   245           if (key!=",") key+=":"; // for normal keywords add colon
       
   246         }
       
   247         ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
       
   248         if (paramTypeStarted) 
       
   249         {
       
   250           ol.endParameterType();
       
   251         }
       
   252         ol.startParameterType(FALSE,key);
       
   253         paramTypeStarted=TRUE;
       
   254       }
       
   255       else
       
   256       {
       
   257         ol.endParameterName(FALSE,FALSE,TRUE);
       
   258       }
       
   259     }
       
   260     first=FALSE;
       
   261   }
       
   262   ol.pushGeneratorState();
       
   263   bool htmlOn = ol.isEnabled(OutputGenerator::Html);
       
   264   ol.disable(OutputGenerator::Html);
       
   265   //if (!first) ol.writeString("&nbsp;");
       
   266   if (!md->isObjCMethod()) ol.docify(")"); // end argument list
       
   267   ol.enableAll();
       
   268   ol.disableAllBut(OutputGenerator::Html);
       
   269   if (!htmlOn) ol.disable(OutputGenerator::Html);
       
   270   if (!md->isDefine()) 
       
   271   {
       
   272     if (first) ol.startParameterName(defArgList->count()<2);
       
   273     ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
       
   274   }
       
   275   else 
       
   276   {
       
   277     ol.endParameterType();
       
   278     ol.startParameterName(TRUE);
       
   279     ol.endParameterName(TRUE,TRUE,!md->isObjCMethod());
       
   280   }
       
   281   ol.popGeneratorState();
       
   282   if (md->extraTypeChars())
       
   283   {
       
   284     ol.docify(md->extraTypeChars());
       
   285   }
       
   286   if (defArgList->constSpecifier)
       
   287   {
       
   288     ol.docify(" const");
       
   289   }
       
   290   if (defArgList->volatileSpecifier)
       
   291   {
       
   292     ol.docify(" volatile");
       
   293   }
       
   294   return TRUE;
       
   295 }
       
   296 
       
   297 static void writeTemplatePrefix(OutputList &ol,ArgumentList *al)
       
   298 {
       
   299   ol.docify("template<");
       
   300   Argument *a=al->first();
       
   301   while (a)
       
   302   {
       
   303     ol.docify(a->type);
       
   304     ol.docify(" ");
       
   305     ol.docify(a->name);
       
   306     if (a->defval.length()!=0)
       
   307     {
       
   308       ol.docify(" = ");
       
   309       ol.docify(a->defval);
       
   310     } 
       
   311     a=al->next();
       
   312     if (a) ol.docify(", ");
       
   313   }
       
   314   ol.docify("> ");
       
   315 }
       
   316 
       
   317 QCString extractDirection(QCString &docs)
       
   318 {
       
   319   QRegExp re("\\[[^\\]]+\\]"); // [...]
       
   320   int l=0;
       
   321   if (re.match(docs,0,&l)==0)
       
   322   {
       
   323     int  inPos  = docs.find("in", 1,FALSE);
       
   324     int outPos  = docs.find("out",1,FALSE);
       
   325     bool input  =  inPos!=-1 &&  inPos<l;
       
   326     bool output = outPos!=-1 && outPos<l;
       
   327     if (input || output) // in,out attributes
       
   328     {
       
   329       docs = docs.mid(l); // strip attributes
       
   330       if (input && output) return "[in,out]";
       
   331       else if (input)      return "[in]";
       
   332       else if (output)     return "[out]";
       
   333     }
       
   334   }
       
   335   return QCString();
       
   336 }
       
   337 
       
   338 //-----------------------------------------------------------------------------
       
   339 //-----------------------------------------------------------------------------
       
   340 //-----------------------------------------------------------------------------
       
   341 
       
   342 class MemberDefImpl
       
   343 {
       
   344   public:
       
   345     MemberDefImpl();
       
   346    ~MemberDefImpl();
       
   347     void init(Definition *def,const char *t,const char *a,const char *e,
       
   348               Protection p,Specifier v,bool s,Relationship r,
       
   349               MemberDef::MemberType mt,const ArgumentList *tal,
       
   350               const ArgumentList *al
       
   351              );
       
   352 
       
   353     ClassDef     *classDef;   // member of or related to 
       
   354     FileDef      *fileDef;    // member of file definition 
       
   355     NamespaceDef *nspace;     // the namespace this member is in.
       
   356 
       
   357     MemberDef  *enumScope;    // the enclosing scope, if this is an enum field
       
   358     MemberDef  *annEnumType;  // the annonymous enum that is the type of this member
       
   359     MemberList *enumFields;   // enumeration fields
       
   360 
       
   361     MemberDef  *redefines;    // the members that this member redefines 
       
   362     MemberList *redefinedBy;  // the list of members that redefine this one
       
   363 
       
   364     MemberDef  *memDef;       // member definition for this declaration
       
   365     MemberDef  *memDec;       // member declaration for this definition
       
   366     ClassDef   *relatedAlso;  // points to class marked by relatedAlso
       
   367 
       
   368     ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
       
   369 
       
   370     QCString type;            // return type
       
   371     QCString args;            // function arguments/variable array specifiers
       
   372     QCString def;             // member definition in code (fully qualified name)
       
   373     QCString anc;             // HTML anchor name
       
   374     Specifier virt;           // normal/virtual/pure virtual
       
   375     Protection prot;          // protection type [Public/Protected/Private]
       
   376     QCString decl;            // member declaration in class
       
   377 
       
   378     QCString bitfields;       // struct member bitfields
       
   379     QCString read;            // property read accessor
       
   380     QCString write;           // property write accessor
       
   381     QCString exception;       // exceptions that can be thrown
       
   382     QCString initializer;     // initializer
       
   383     QCString extraTypeChars;  // extra type info found after the argument list
       
   384     int initLines;            // number of lines in the initializer
       
   385 
       
   386     int  memSpec;             // The specifiers present for this member
       
   387     MemberDef::MemberType mtype;         // returns the kind of member
       
   388     int maxInitLines;         // when the initializer will be displayed 
       
   389     int userInitLines;        // result of explicit \hideinitializer or \showinitializer
       
   390     MemberDef  *annMemb;
       
   391 
       
   392     ArgumentList *defArgList;    // argument list of this member definition
       
   393     ArgumentList *declArgList;   // argument list of this member declaration
       
   394 
       
   395     ArgumentList *tArgList;      // template argument list of function template
       
   396     ArgumentList *typeConstraints; // type constraints for template parameters
       
   397     MemberDef *templateMaster;
       
   398     QList<ArgumentList> *defTmpArgLists; // lists of template argument lists 
       
   399                                          // (for template functions in nested template classes)
       
   400 
       
   401     ClassDef *cachedAnonymousType; // if the member has an anonymous compound
       
   402                                    // as its type then this is computed by
       
   403                                    // getClassDefOfAnonymousType() and 
       
   404                                    // cached here. 
       
   405     SDict<MemberList> *classSectionSDict; // not accessible
       
   406 
       
   407     MemberDef *groupAlias;    // Member containing the definition
       
   408     int grpId;                // group id
       
   409     MemberGroup *memberGroup; // group's member definition
       
   410     GroupDef *group;          // group in which this member is in
       
   411     Grouping::GroupPri_t grouppri; // priority of this definition
       
   412     QCString groupFileName;   // file where this grouping was defined
       
   413     int groupStartLine;       // line  "      "      "     "     "
       
   414     MemberDef *groupMember;
       
   415 
       
   416     bool isTypedefValCached;
       
   417     ClassDef *cachedTypedefValue;
       
   418     QCString cachedTypedefTemplSpec;
       
   419     QCString cachedResolvedType;
       
   420     
       
   421     // inbody documentation
       
   422     //int inbodyLine;
       
   423     //QCString inbodyFile;
       
   424     //QCString inbodyDocs;
       
   425 
       
   426     // documentation inheritance
       
   427     MemberDef *docProvider;
       
   428 
       
   429     // to store the output file base from tag files
       
   430     QCString explicitOutputFileBase;
       
   431 
       
   432     // objective-c
       
   433     bool implOnly; // function found in implementation but not 
       
   434                      // in the interface
       
   435     bool hasDocumentedParams;
       
   436     bool hasDocumentedReturnType;
       
   437     bool isDMember;
       
   438     Relationship related;     // relationship of this to the class
       
   439     bool stat;                // is it a static function?
       
   440     bool proto;               // is it a prototype;
       
   441     bool docEnumValues;       // is an enum with documented enum values.
       
   442     bool annScope;            // member is part of an annoymous scope
       
   443     bool annUsed;             
       
   444     bool hasCallGraph;
       
   445     bool hasCallerGraph;
       
   446     bool explExt;             // member was explicitly declared external
       
   447     bool tspec;               // member is a template specialization
       
   448     bool groupHasDocs;        // true if the entry that caused the grouping was documented
       
   449     bool docsForDefinition;   // TRUE => documentation block is put before
       
   450                               //         definition.
       
   451                               // FALSE => block is put before declaration.
       
   452 
       
   453     ClassDef *category;
       
   454 };
       
   455 
       
   456 MemberDefImpl::MemberDefImpl() :
       
   457     enumFields(0),
       
   458     redefinedBy(0),
       
   459     exampleSDict(0),
       
   460     defArgList(0),
       
   461     declArgList(0),
       
   462     tArgList(0),
       
   463     typeConstraints(0),
       
   464     defTmpArgLists(0),
       
   465     classSectionSDict(0),
       
   466     category(0)
       
   467 {
       
   468 }
       
   469 
       
   470 MemberDefImpl::~MemberDefImpl()
       
   471 {
       
   472   delete redefinedBy;
       
   473   delete exampleSDict;
       
   474   delete enumFields;
       
   475   delete defArgList;
       
   476   delete tArgList;
       
   477   delete typeConstraints;
       
   478   delete defTmpArgLists;
       
   479   delete classSectionSDict;
       
   480   delete declArgList;
       
   481 }
       
   482 
       
   483 void MemberDefImpl::init(Definition *def,
       
   484                      const char *t,const char *a,const char *e,
       
   485                      Protection p,Specifier v,bool s,Relationship r,
       
   486                      MemberDef::MemberType mt,const ArgumentList *tal,
       
   487                      const ArgumentList *al
       
   488                     )
       
   489 {
       
   490   classDef=0;
       
   491   fileDef=0;
       
   492   redefines=0;
       
   493   relatedAlso=0;
       
   494   redefinedBy=0;
       
   495   nspace=0;
       
   496   memDef=0;
       
   497   memDec=0;
       
   498   group=0;
       
   499   grpId=-1;
       
   500   exampleSDict=0;
       
   501   enumFields=0;
       
   502   enumScope=0;
       
   503   defTmpArgLists=0;
       
   504   hasCallGraph = FALSE;
       
   505   hasCallerGraph = FALSE;
       
   506   initLines=0;
       
   507   type=t;
       
   508   if (mt==MemberDef::Typedef) type.stripPrefix("typedef ");
       
   509   //  type.stripPrefix("struct ");
       
   510   //  type.stripPrefix("class " );
       
   511   //  type.stripPrefix("union " );
       
   512   type=removeRedundantWhiteSpace(type);
       
   513   args=a;
       
   514   args=removeRedundantWhiteSpace(args);
       
   515   if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
       
   516 
       
   517   memberGroup=0;
       
   518   virt=v;
       
   519   prot=p;
       
   520   related=r;
       
   521   stat=s;
       
   522   mtype=mt;
       
   523   exception=e;
       
   524   proto=FALSE;
       
   525   annScope=FALSE;
       
   526   memSpec=0;
       
   527   annMemb=0;
       
   528   annUsed=FALSE;
       
   529   annEnumType=0;
       
   530   groupAlias=0;
       
   531   explExt=FALSE;
       
   532   tspec=FALSE;
       
   533   cachedAnonymousType=0;
       
   534   maxInitLines=Config_getInt("MAX_INITIALIZER_LINES");
       
   535   userInitLines=-1;
       
   536   docEnumValues=FALSE;
       
   537   // copy function template arguments (if any)
       
   538   if (tal)
       
   539   {
       
   540     tArgList = new ArgumentList;
       
   541     tArgList->setAutoDelete(TRUE);
       
   542     ArgumentListIterator ali(*tal);
       
   543     Argument *a;
       
   544     for (;(a=ali.current());++ali)
       
   545     {
       
   546       tArgList->append(new Argument(*a));
       
   547     }
       
   548   }
       
   549   else
       
   550   {
       
   551     tArgList=0;
       
   552   }
       
   553   //printf("new member al=%p\n",al);
       
   554   // copy function definition arguments (if any)
       
   555   if (al)
       
   556   {
       
   557     defArgList = new ArgumentList;
       
   558     defArgList->setAutoDelete(TRUE);
       
   559     ArgumentListIterator ali(*al);
       
   560     Argument *a;
       
   561     for (;(a=ali.current());++ali)
       
   562     {
       
   563       //printf("copy argument %s (doc=%s)\n",a->name.data(),a->docs.data());
       
   564       defArgList->append(new Argument(*a));
       
   565     }
       
   566     defArgList->constSpecifier    = al->constSpecifier;
       
   567     defArgList->volatileSpecifier = al->volatileSpecifier;
       
   568     defArgList->pureSpecifier     = al->pureSpecifier;
       
   569     //printf("defArgList(%p)->constSpecifier=%d\n",defArgList,defArgList->constSpecifier);
       
   570   }
       
   571   else
       
   572   {
       
   573     defArgList=0;
       
   574   }
       
   575   // convert function declaration arguments (if any)
       
   576   if (!args.isEmpty())
       
   577   {
       
   578     declArgList = new ArgumentList;
       
   579     stringToArgumentList(args,declArgList,&extraTypeChars);
       
   580     //printf("setDeclArgList %s to %s const=%d\n",args.data(),
       
   581     //    argListToString(declArgList).data(),declArgList->constSpecifier);
       
   582   }
       
   583   else
       
   584   {
       
   585     declArgList = 0;
       
   586   }
       
   587   templateMaster = 0;
       
   588   classSectionSDict = 0;
       
   589   docsForDefinition = TRUE;
       
   590   isTypedefValCached = FALSE;
       
   591   cachedTypedefValue = 0;
       
   592   //inbodyLine = -1;
       
   593   implOnly=FALSE;
       
   594   groupMember = 0;
       
   595   hasDocumentedParams = FALSE;
       
   596   hasDocumentedReturnType = FALSE;
       
   597   docProvider = 0;
       
   598   isDMember = def->getDefFileName().right(2).lower()==".d";
       
   599 }
       
   600 
       
   601 
       
   602 //-----------------------------------------------------------------------------
       
   603 //-----------------------------------------------------------------------------
       
   604 //-----------------------------------------------------------------------------
       
   605 
       
   606 /*! Creates a new member definition.
       
   607  *
       
   608  * \param df File containing the definition of this member.
       
   609  * \param dl Line at which the member definition was found.
       
   610  * \param t  A string representing the type of the member.
       
   611  * \param na A string representing the name of the member.
       
   612  * \param a  A string representing the arguments of the member.
       
   613  * \param e  A string representing the throw clause of the members.
       
   614  * \param p  The protection context of the member, possible values are:
       
   615  *           \c Public, \c Protected, \c Private.
       
   616  * \param v  The degree of `virtualness' of the member, possible values are:
       
   617  *           \c Normal, \c Virtual, \c Pure.
       
   618  * \param s  A boolean that is true iff the member is static.
       
   619  * \param r  The relationship between the class and the member.
       
   620  * \param mt The kind of member. See #MemberDef::MemberType for a list of 
       
   621  *           all types.
       
   622  * \param tal The template arguments of this member.
       
   623  * \param al  The arguments of this member. This is a structured form of 
       
   624  *            the string past as argument \a a.
       
   625  */
       
   626 
       
   627 MemberDef::MemberDef(const char *df,int dl,
       
   628                      const char *t,const char *na,const char *a,const char *e,
       
   629                      Protection p,Specifier v,bool s,Relationship r,MemberType mt,
       
   630                      const ArgumentList *tal,const ArgumentList *al
       
   631                     ) : Definition(df,dl,removeRedundantWhiteSpace(na))
       
   632 {
       
   633   m_storagePos=-1;
       
   634   m_cacheHandle=-1;
       
   635   m_impl = new MemberDefImpl;
       
   636   m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
       
   637   m_flushPending = FALSE;
       
   638 }
       
   639 
       
   640 void MemberDef::moveTo(Definition *scope)
       
   641 {
       
   642    setOuterScope(scope);
       
   643    if (scope->definitionType()==Definition::TypeClass)
       
   644    {
       
   645      m_impl->classDef = (ClassDef*)scope;
       
   646    }
       
   647    else if (scope->definitionType()==Definition::TypeFile)
       
   648    {
       
   649      m_impl->fileDef = (FileDef*)scope;
       
   650    }
       
   651    else if (scope->definitionType()==Definition::TypeNamespace)
       
   652    {
       
   653      m_impl->nspace = (NamespaceDef*)scope;
       
   654    }
       
   655 }
       
   656 
       
   657 
       
   658 /*! Destroys the member definition. */
       
   659 MemberDef::~MemberDef()
       
   660 {
       
   661   delete m_impl;
       
   662   if (m_cacheHandle!=-1)
       
   663   {
       
   664     Doxygen::symbolCache->del(m_cacheHandle);
       
   665     m_cacheHandle=-1;
       
   666   }
       
   667 }
       
   668 
       
   669 void MemberDef::setReimplements(MemberDef *md)   
       
   670 { 
       
   671   makeResident();
       
   672   //if (redefines==0) redefines = new MemberList;
       
   673   //if (redefines->find(md)==-1) redefines->inSort(md);
       
   674 
       
   675   m_impl->redefines = md;
       
   676 }
       
   677 
       
   678 void MemberDef::insertReimplementedBy(MemberDef *md)
       
   679 {
       
   680   makeResident();
       
   681   if (m_impl->templateMaster)
       
   682   {
       
   683     m_impl->templateMaster->insertReimplementedBy(md);
       
   684   }
       
   685   if (m_impl->redefinedBy==0) m_impl->redefinedBy = new MemberList(MemberList::redefinedBy);
       
   686   if (m_impl->redefinedBy->findRef(md)==-1) 
       
   687   {
       
   688     m_impl->redefinedBy->inSort(md);
       
   689   }
       
   690 }
       
   691 
       
   692 MemberDef *MemberDef::reimplements() const      
       
   693 { 
       
   694   makeResident();
       
   695   return m_impl->redefines; 
       
   696 }
       
   697 
       
   698 LockingPtr<MemberList> MemberDef::reimplementedBy() const   
       
   699 { 
       
   700   makeResident();
       
   701   return LockingPtr<MemberList>(this,m_impl->redefinedBy); 
       
   702 }
       
   703 
       
   704 void MemberDef::insertEnumField(MemberDef *md)
       
   705 {
       
   706   makeResident();
       
   707   if (m_impl->enumFields==0) m_impl->enumFields=new MemberList(MemberList::enumFields);
       
   708   m_impl->enumFields->append(md);
       
   709 }
       
   710 
       
   711 bool MemberDef::addExample(const char *anchor,const char *nameStr,
       
   712                            const char *file)
       
   713 {
       
   714   makeResident();
       
   715   //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
       
   716   if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
       
   717   if (m_impl->exampleSDict->find(nameStr)==0) 
       
   718   {
       
   719     //printf("Add reference to example %s to member %s\n",nameStr,name.data());
       
   720     Example *e=new Example;
       
   721     e->anchor=anchor;
       
   722     e->name=nameStr;
       
   723     e->file=file;
       
   724     m_impl->exampleSDict->inSort(nameStr,e);
       
   725     return TRUE;
       
   726   }
       
   727   return FALSE; 
       
   728 }
       
   729 
       
   730 bool MemberDef::hasExamples()
       
   731 {
       
   732   makeResident();
       
   733   if (m_impl->exampleSDict==0) 
       
   734     return FALSE;
       
   735   else
       
   736     return m_impl->exampleSDict->count()>0;
       
   737 }
       
   738 
       
   739 QCString MemberDef::getOutputFileBase() const
       
   740 {
       
   741   makeResident();
       
   742   static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
       
   743   QCString baseName;
       
   744   //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
       
   745   //    name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
       
   746   //    m_impl->nspace,m_impl->fileDef);
       
   747   if (!m_impl->explicitOutputFileBase.isEmpty())
       
   748   {
       
   749     return m_impl->explicitOutputFileBase;
       
   750   }
       
   751   else if (m_impl->templateMaster)
       
   752   {
       
   753     return m_impl->templateMaster->getOutputFileBase();
       
   754   }
       
   755   else if (m_impl->group)
       
   756   {
       
   757     baseName=m_impl->group->getOutputFileBase();
       
   758   }
       
   759   else if (m_impl->classDef)
       
   760   {
       
   761     baseName=m_impl->classDef->getOutputFileBase();
       
   762   }
       
   763   else if (m_impl->nspace)
       
   764   {
       
   765     baseName=m_impl->nspace->getOutputFileBase();
       
   766   }
       
   767   else if (m_impl->fileDef)
       
   768   {
       
   769     baseName=m_impl->fileDef->getOutputFileBase();
       
   770   }
       
   771   
       
   772   if (baseName.isEmpty())
       
   773   {
       
   774     warn(getDefFileName(),getDefLine(),
       
   775        "Warning: Internal inconsistency: member %s does not belong to any"
       
   776        " container!",name().data()
       
   777       );
       
   778     return "dummy";
       
   779   }
       
   780   else if (separateMemberPages)
       
   781   {
       
   782     if (getEnumScope()) // enum value, which is part of enum's documentation
       
   783     {
       
   784       baseName+="_"+getEnumScope()->anchor();
       
   785     }
       
   786     else
       
   787     {
       
   788       baseName+="_"+anchor();
       
   789     }
       
   790   }
       
   791   return baseName;
       
   792 }
       
   793 
       
   794 QCString MemberDef::getReference() const
       
   795 {
       
   796   makeResident();
       
   797   QCString ref = Definition::getReference();
       
   798   if (!ref.isEmpty())
       
   799   {
       
   800     return ref;
       
   801   }
       
   802   if (m_impl->templateMaster)
       
   803   {
       
   804     return m_impl->templateMaster->getReference();
       
   805   }
       
   806   else if (m_impl->group)
       
   807   {
       
   808     return m_impl->group->getReference();
       
   809   }
       
   810   else if (m_impl->classDef)
       
   811   {
       
   812     return m_impl->classDef->getReference();
       
   813   }
       
   814   else if (m_impl->nspace)
       
   815   {
       
   816     return m_impl->nspace->getReference();
       
   817   }
       
   818   else if (m_impl->fileDef)
       
   819   {
       
   820     return m_impl->fileDef->getReference();
       
   821   }
       
   822   return "";
       
   823 }
       
   824 
       
   825 QCString MemberDef::anchor() const
       
   826 {
       
   827   makeResident();
       
   828   QCString result=m_impl->anc;
       
   829   if (m_impl->groupAlias)     return m_impl->groupAlias->anchor();
       
   830   if (m_impl->templateMaster) return m_impl->templateMaster->anchor();
       
   831   if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
       
   832   {
       
   833     result.prepend(m_impl->enumScope->anchor());
       
   834   }
       
   835   if (m_impl->group) 
       
   836   {
       
   837     if (m_impl->groupMember)
       
   838     {
       
   839       result=m_impl->groupMember->anchor();
       
   840     }
       
   841     else if (getReference().isEmpty())
       
   842     {
       
   843       result.prepend("g");
       
   844     }
       
   845   }
       
   846   return result;
       
   847 }
       
   848 
       
   849 bool MemberDef::isLinkableInProject() const
       
   850 {
       
   851   static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
       
   852   static bool extractStatic  = Config_getBool("EXTRACT_STATIC");
       
   853   makeResident();
       
   854 
       
   855   //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
       
   856   if (isHidden()) 
       
   857   {
       
   858     //printf("is hidden\n");
       
   859     return FALSE;
       
   860   }
       
   861   if (m_impl->templateMaster)
       
   862   {
       
   863     //printf("has template master\n");
       
   864     return m_impl->templateMaster->isLinkableInProject();
       
   865   }
       
   866   if (name().isEmpty() || name().at(0)=='@') 
       
   867   {
       
   868     //printf("name invalid\n");
       
   869     return FALSE; // not a valid or a dummy name
       
   870   }
       
   871   if (!hasDocumentation() && !isReference()) 
       
   872   {
       
   873     //printf("no docs or reference\n");
       
   874     return FALSE; // no documentation
       
   875   }
       
   876   if (m_impl->group && !m_impl->group->isLinkableInProject()) 
       
   877   {
       
   878     //printf("group but group not linkable!\n");
       
   879     return FALSE; // group but group not linkable
       
   880   }
       
   881   if (!m_impl->group && m_impl->classDef && !m_impl->classDef->isLinkableInProject()) 
       
   882   {
       
   883     //printf("in a class but class not linkable!\n");
       
   884     return FALSE; // in class but class not linkable
       
   885   }
       
   886   if (!m_impl->group && m_impl->nspace && !m_impl->related && !m_impl->nspace->isLinkableInProject()) 
       
   887   {
       
   888     //printf("in a namespace but namespace not linkable!\n");
       
   889     return FALSE; // in namespace but namespace not linkable
       
   890   }
       
   891   if (!m_impl->group && !m_impl->nspace && 
       
   892       !m_impl->related && !m_impl->classDef && 
       
   893       m_impl->fileDef && !m_impl->fileDef->isLinkableInProject()) 
       
   894   {
       
   895     //printf("in a file but file not linkable!\n");
       
   896     return FALSE; // in file (and not in namespace) but file not linkable
       
   897   }
       
   898   if (m_impl->prot==Private && !extractPrivate && m_impl->mtype!=Friend) 
       
   899   {
       
   900     //printf("private and invisible!\n");
       
   901     return FALSE; // hidden due to protection
       
   902   }
       
   903   if (m_impl->stat && m_impl->classDef==0 && !extractStatic) 
       
   904   {
       
   905     //printf("static and invisible!\n");
       
   906     return FALSE; // hidden due to staticness
       
   907   }
       
   908   //printf("linkable!\n");
       
   909   return TRUE; // linkable!
       
   910 }
       
   911 
       
   912 bool MemberDef::isLinkable() const
       
   913 {
       
   914   makeResident();
       
   915   if (m_impl->templateMaster)
       
   916   {
       
   917     return m_impl->templateMaster->isLinkable();
       
   918   }
       
   919   else
       
   920   {
       
   921     return isLinkableInProject() || isReference();
       
   922   }
       
   923 }
       
   924 
       
   925 
       
   926 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
       
   927 {
       
   928   if (lists)
       
   929   {
       
   930     makeResident();
       
   931     if (m_impl->defTmpArgLists) delete m_impl->defTmpArgLists;
       
   932     m_impl->defTmpArgLists = copyArgumentLists(lists);
       
   933   }
       
   934 }
       
   935 
       
   936 void MemberDef::writeLink(OutputList &ol,ClassDef *,NamespaceDef *,
       
   937                       FileDef *fd,GroupDef *gd,bool onlyText)
       
   938 {
       
   939   static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
       
   940   static bool hideScopeNames     = Config_getBool("HIDE_SCOPE_NAMES");
       
   941   makeResident();
       
   942   LockingPtr<MemberDef> lock(this,this);
       
   943   QCString sep = optimizeOutputJava ? "." : "::";
       
   944   QCString n = name();
       
   945   if (!hideScopeNames && m_impl->classDef && gd) n.prepend(m_impl->classDef->name()+sep);
       
   946   else if (!hideScopeNames && m_impl->nspace && (gd || fd)) n.prepend(m_impl->nspace->name()+sep);
       
   947   if (isObjCMethod())
       
   948   {
       
   949     if (isStatic()) ol.docify("+ "); else ol.docify("- ");
       
   950   }
       
   951   if (!onlyText) // write link
       
   952   {
       
   953     if (m_impl->mtype==EnumValue && getGroupDef()==0 &&          // enum value is not grouped
       
   954         getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
       
   955     {
       
   956       GroupDef *enumValGroup = getEnumScope()->getGroupDef();
       
   957       ol.writeObjectLink(enumValGroup->getReference(),
       
   958                          enumValGroup->getOutputFileBase(),
       
   959                          anchor(),n);
       
   960     }
       
   961     else
       
   962     {
       
   963       ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),n);
       
   964     }
       
   965   }
       
   966   else // write only text
       
   967   {
       
   968     ol.startBold();
       
   969     ol.docify(n);
       
   970     ol.endBold();
       
   971   }
       
   972 }
       
   973 
       
   974 /*! If this member has an anonymous class/struct/union as its type, then
       
   975  *  this method will return the ClassDef that describes this return type.
       
   976  */
       
   977 ClassDef *MemberDef::getClassDefOfAnonymousType() 
       
   978 {
       
   979   makeResident();
       
   980   if (m_impl->cachedAnonymousType) return m_impl->cachedAnonymousType;
       
   981   LockingPtr<MemberDef> lock(this,this);
       
   982 
       
   983   QCString cname;
       
   984   if (getClassDef()!=0) 
       
   985   {
       
   986     cname=getClassDef()->name().copy();
       
   987   }
       
   988   else if (getNamespaceDef()!=0)
       
   989   {
       
   990     cname=getNamespaceDef()->name().copy();
       
   991   }
       
   992   QCString ltype(m_impl->type);
       
   993   // strip `static' keyword from ltype
       
   994   //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
       
   995   // strip `friend' keyword from ltype
       
   996   ltype.stripPrefix("friend ");
       
   997   static QRegExp r("@[0-9]+");
       
   998   int l,i=r.match(ltype,0,&l);
       
   999   //printf("ltype=`%s' i=%d\n",ltype.data(),i);
       
  1000   // search for the last anonymous scope in the member type
       
  1001   ClassDef *annoClassDef=0;
       
  1002   if (i!=-1) // found anonymous scope in type
       
  1003   {
       
  1004     int il=i-1,ir=i+l;
       
  1005     // extract anonymous scope
       
  1006     while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
       
  1007     if (il>0) il++; else if (il<0) il=0;
       
  1008     while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
       
  1009 
       
  1010     QCString annName = ltype.mid(il,ir-il);
       
  1011 
       
  1012     // if inside a class or namespace try to prepend the scope name
       
  1013     if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::") 
       
  1014     {
       
  1015       QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
       
  1016       //printf("Member::writeDeclaration: Trying %s\n",ts.data());
       
  1017       annoClassDef=getClass(ts);
       
  1018     }
       
  1019     // if not found yet, try without scope name
       
  1020     if (annoClassDef==0)
       
  1021     {
       
  1022       QCString ts=stripAnonymousNamespaceScope(annName);
       
  1023       //printf("Member::writeDeclaration: Trying %s\n",ts.data());
       
  1024       annoClassDef=getClass(ts);
       
  1025     }
       
  1026   }
       
  1027   m_impl->cachedAnonymousType = annoClassDef;
       
  1028   return annoClassDef;
       
  1029 }
       
  1030     
       
  1031 /*! This methods returns TRUE iff the brief section (also known as
       
  1032  *  declaration section) is visible in the documentation.
       
  1033  */
       
  1034 bool MemberDef::isBriefSectionVisible() const
       
  1035 {
       
  1036   static bool extractStatic       = Config_getBool("EXTRACT_STATIC");
       
  1037   static bool hideUndocMembers    = Config_getBool("HIDE_UNDOC_MEMBERS");
       
  1038   static bool briefMemberDesc     = Config_getBool("BRIEF_MEMBER_DESC");
       
  1039   static bool repeatBrief         = Config_getBool("REPEAT_BRIEF");
       
  1040   static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
       
  1041   static bool extractPrivate      = Config_getBool("EXTRACT_PRIVATE");
       
  1042 
       
  1043   //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
       
  1044   //    name().data(),
       
  1045   //    0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
       
  1046   //    "", //getFileDef()->name().data(),
       
  1047   //    argsString());
       
  1048 
       
  1049   makeResident();
       
  1050   LockingPtr<MemberDef> lock(this,this);
       
  1051   MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
       
  1052   //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
       
  1053   //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
       
  1054   bool hasDocs = hasDocumentation() || 
       
  1055                   // part of a documented member group
       
  1056                  (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
       
  1057 
       
  1058   // only include static members with file/namespace scope if 
       
  1059   // explicitly enabled in the config file
       
  1060   bool visibleIfStatic = !(getClassDef()==0 && 
       
  1061                            isStatic() && 
       
  1062                            !extractStatic
       
  1063                           );
       
  1064 
       
  1065   // only include members is the are documented or 
       
  1066   // HIDE_UNDOC_MEMBERS is NO in the config file
       
  1067   bool visibleIfDocumented = (!hideUndocMembers || 
       
  1068                               hasDocs || 
       
  1069                               isDocumentedFriendClass()
       
  1070                              );
       
  1071 
       
  1072   // hide members with no detailed description and brief descriptions 
       
  1073   // explicitly disabled.
       
  1074   bool visibleIfEnabled = !(hideUndocMembers && 
       
  1075                             documentation().isEmpty() &&
       
  1076                             !briefMemberDesc && 
       
  1077                             !repeatBrief
       
  1078                            );
       
  1079 
       
  1080   // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
       
  1081   bool visibleIfFriendCompound = !(hideFriendCompounds &&
       
  1082                                    isFriend() &&
       
  1083                                    (m_impl->type=="friend class" || 
       
  1084                                     m_impl->type=="friend struct" ||
       
  1085                                     m_impl->type=="friend union"
       
  1086                                    )
       
  1087                                   );
       
  1088   
       
  1089   // only include members that are non-private unless EXTRACT_PRIVATE is
       
  1090   // set to YES or the member is part of a group
       
  1091   bool visibleIfPrivate = (protection()!=Private || 
       
  1092                            extractPrivate ||
       
  1093                            m_impl->mtype==Friend
       
  1094                           );
       
  1095   
       
  1096   // hide member if it overrides a member in a superclass and has no
       
  1097   // documentation of its own
       
  1098   //bool visibleIfDocVirtual = !reimplements() || 
       
  1099   //                           !Config_getBool("INHERIT_DOCS") ||  
       
  1100   //                           hasDocs;
       
  1101 
       
  1102   // true if this member is a constructor or destructor
       
  1103   bool cOrDTor = isConstructor() || isDestructor();
       
  1104 
       
  1105   // hide default constructors or destructors (no args) without
       
  1106   // documentation
       
  1107   bool visibleIfNotDefaultCDTor = !(cOrDTor &&
       
  1108                                    m_impl->defArgList &&
       
  1109                                    (m_impl->defArgList->isEmpty() ||
       
  1110                                     m_impl->defArgList->first()->type == "void"
       
  1111                                    ) &&
       
  1112                                    !hasDocs
       
  1113                                   );
       
  1114 
       
  1115   //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
       
  1116   //       "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
       
  1117   //       "visibleIfFriendCompound=%d !annScope=%d\n",
       
  1118   //       visibleIfStatic,visibleIfDocumented,
       
  1119   //       visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
       
  1120   //       visibleIfFriendCompound,!m_impl->annScope);
       
  1121   
       
  1122   bool visible = visibleIfStatic     && visibleIfDocumented      && 
       
  1123                  visibleIfEnabled    && visibleIfPrivate         &&
       
  1124                  /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor && 
       
  1125                  visibleIfFriendCompound &&
       
  1126                  !m_impl->annScope;
       
  1127   //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
       
  1128   return visible;
       
  1129 }
       
  1130 
       
  1131 
       
  1132 void MemberDef::writeDeclaration(OutputList &ol,
       
  1133                ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
       
  1134                bool inGroup
       
  1135                )
       
  1136 {
       
  1137   //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",name().data(),inGroup);
       
  1138 
       
  1139   // hide enum value, since they appear already as part of the enum, unless they
       
  1140   // are explicitly grouped.
       
  1141   makeResident();
       
  1142   if (!inGroup && m_impl->mtype==EnumValue) return;
       
  1143   LockingPtr<MemberDef> lock(this,this);
       
  1144 
       
  1145   // hide members whose brief section should not be visible
       
  1146   //if (!isBriefSectionVisible()) return;
       
  1147 
       
  1148   Definition *d=0;
       
  1149   ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
       
  1150   if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
       
  1151 
       
  1152   // write tag file information of this member
       
  1153   if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
       
  1154   {
       
  1155     Doxygen::tagFile << "    <member kind=\"";
       
  1156     switch (m_impl->mtype)
       
  1157     {
       
  1158       case Define:      Doxygen::tagFile << "define";      break;
       
  1159       case EnumValue:   Doxygen::tagFile << "enumvalue";   break;
       
  1160       case Property:    Doxygen::tagFile << "property";    break;
       
  1161       case Event:       Doxygen::tagFile << "event";       break;
       
  1162       case Variable:    Doxygen::tagFile << "variable";    break;
       
  1163       case Typedef:     Doxygen::tagFile << "typedef";     break;
       
  1164       case Enumeration: Doxygen::tagFile << "enumeration"; break;
       
  1165       case Function:    Doxygen::tagFile << "function";    break;
       
  1166       case Signal:      Doxygen::tagFile << "signal";      break;
       
  1167       //case Prototype:   Doxygen::tagFile << "prototype";   break;
       
  1168       case Friend:      Doxygen::tagFile << "friend";      break;
       
  1169       case DCOP:        Doxygen::tagFile << "dcop";        break;
       
  1170       case Slot:        Doxygen::tagFile << "slot";        break;
       
  1171     }
       
  1172     if (m_impl->prot!=Public)
       
  1173     {
       
  1174       Doxygen::tagFile << "\" protection=\"";
       
  1175       if (m_impl->prot==Protected)    Doxygen::tagFile << "protected";
       
  1176       else if (m_impl->prot==Package) Doxygen::tagFile << "package";
       
  1177       else /* Private */              Doxygen::tagFile << "private"; 
       
  1178     }
       
  1179     if (m_impl->virt!=Normal)
       
  1180     {
       
  1181       Doxygen::tagFile << "\" virtualness=\"";
       
  1182       if (m_impl->virt==Virtual) Doxygen::tagFile << "virtual";
       
  1183       else /* Pure */            Doxygen::tagFile << "pure"; 
       
  1184     }
       
  1185     if (isStatic())
       
  1186     {
       
  1187       Doxygen::tagFile << "\" static=\"yes";
       
  1188     }
       
  1189     Doxygen::tagFile << "\">" << endl;
       
  1190     Doxygen::tagFile << "      <type>" << convertToXML(typeString()) << "</type>" << endl;
       
  1191     Doxygen::tagFile << "      <name>" << convertToXML(name()) << "</name>" << endl;
       
  1192     Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
       
  1193     Doxygen::tagFile << "      <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
       
  1194     Doxygen::tagFile << "      <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
       
  1195     writeDocAnchorsToTagFile();
       
  1196     Doxygen::tagFile << "    </member>" << endl;
       
  1197   }
       
  1198 
       
  1199   // write search index info
       
  1200   if (Doxygen::searchIndex && isLinkableInProject())
       
  1201   {
       
  1202     Doxygen::searchIndex->setCurrentDoc(qualifiedName(),getOutputFileBase(),anchor());
       
  1203     Doxygen::searchIndex->addWord(localName(),TRUE);
       
  1204     Doxygen::searchIndex->addWord(qualifiedName(),FALSE);
       
  1205   }
       
  1206 
       
  1207   QCString cname  = d->name();
       
  1208   QCString cfname = getOutputFileBase();
       
  1209   //QCString osname = cname;
       
  1210   // in case of class members that are put in a group the name of the outerscope
       
  1211   // differs from the cname.
       
  1212   //if (getOuterScope()) osname=getOuterScope()->name();
       
  1213 
       
  1214   //HtmlHelp *htmlHelp=0;
       
  1215   //bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
       
  1216   //if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
       
  1217 
       
  1218   // search for the last anonymous scope in the member type
       
  1219   ClassDef *annoClassDef=getClassDefOfAnonymousType();
       
  1220 
       
  1221   // start a new member declaration
       
  1222   bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
       
  1223   ///printf("startMemberItem for %s\n",name().data());
       
  1224   ol.startMemberItem( isAnonymous ? 1 : m_impl->tArgList ? 3 : 0);
       
  1225 
       
  1226   // If there is no detailed description we need to write the anchor here.
       
  1227   bool detailsVisible = isDetailedSectionLinkable();
       
  1228   if (!detailsVisible && !m_impl->annMemb)
       
  1229   {
       
  1230     QCString doxyName=name().copy();
       
  1231     if (!cname.isEmpty()) doxyName.prepend(cname+"::");
       
  1232     QCString doxyArgs=argsString();
       
  1233     ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
       
  1234 
       
  1235     ol.pushGeneratorState();
       
  1236     ol.disable(OutputGenerator::Man);
       
  1237     ol.disable(OutputGenerator::Latex);
       
  1238     ol.docify("\n");
       
  1239     ol.popGeneratorState();
       
  1240   }
       
  1241 
       
  1242   if (annoClassDef || m_impl->annMemb)
       
  1243   {
       
  1244     int j;
       
  1245     for (j=0;j<s_indentLevel;j++) 
       
  1246     {
       
  1247       ol.writeNonBreakableSpace(3);
       
  1248     }
       
  1249   }
       
  1250 
       
  1251   // *** write template lists
       
  1252   if (m_impl->tArgList)
       
  1253   {
       
  1254     if (!isAnonymous) ol.startMemberTemplateParams();
       
  1255     writeTemplatePrefix(ol,m_impl->tArgList);
       
  1256     if (!isAnonymous) ol.endMemberTemplateParams();
       
  1257   }
       
  1258 
       
  1259   // *** write type
       
  1260   QCString ltype(m_impl->type);
       
  1261   if (m_impl->mtype==Typedef) ltype.prepend("typedef ");
       
  1262   // strip `friend' keyword from ltype
       
  1263   ltype.stripPrefix("friend ");
       
  1264   static QRegExp r("@[0-9]+");
       
  1265 
       
  1266   bool endAnonScopeNeeded=FALSE;
       
  1267   int l,i=r.match(ltype,0,&l);
       
  1268   if (i!=-1) // member has an anonymous type
       
  1269   {
       
  1270     //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
       
  1271     //    annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
       
  1272 
       
  1273     if (annoClassDef) // type is an anonymous compound
       
  1274     {
       
  1275       int ir=i+l;
       
  1276       //printf("<<<<<<<<<<<<<<\n");
       
  1277       ol.startAnonTypeScope(s_indentLevel++);
       
  1278       annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup);
       
  1279       //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
       
  1280       ol.startMemberItem(2);
       
  1281       int j;
       
  1282       for (j=0;j< s_indentLevel-1;j++) 
       
  1283       {
       
  1284         ol.writeNonBreakableSpace(3);
       
  1285       }
       
  1286       QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
       
  1287       //printf(">>>>>> indDepth=%d ltype=`%s' varName=`%s'\n",indDepth,ltype.data(),varName.data());
       
  1288       ol.docify("}");
       
  1289       if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) 
       
  1290       {
       
  1291         ol.docify(";"); 
       
  1292       }
       
  1293       endAnonScopeNeeded=TRUE;
       
  1294     }
       
  1295     else
       
  1296     {
       
  1297       if (getAnonymousEnumType()) // type is an anonymous enum
       
  1298       {
       
  1299         linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype.left(i),TRUE); 
       
  1300         getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
       
  1301         //ol+=*getAnonymousEnumType()->enumDecl();
       
  1302         linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,name(),ltype.right(ltype.length()-i-l),TRUE); 
       
  1303       }
       
  1304       else
       
  1305       {
       
  1306         ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
       
  1307         linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); 
       
  1308       }
       
  1309     }
       
  1310   }
       
  1311   else if (ltype=="@") // rename type from enum values
       
  1312   {
       
  1313     ltype="";
       
  1314   }
       
  1315   else
       
  1316   {
       
  1317     if (isObjCMethod())
       
  1318     {
       
  1319       ltype.prepend("(");
       
  1320       ltype.append(")");
       
  1321     }
       
  1322     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); 
       
  1323   }
       
  1324   bool htmlOn = ol.isEnabled(OutputGenerator::Html);
       
  1325   if (htmlOn && Config_getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty())
       
  1326   {
       
  1327     ol.disable(OutputGenerator::Html);
       
  1328   }
       
  1329   if (!ltype.isEmpty()) ol.docify(" ");
       
  1330   if (htmlOn) 
       
  1331   {
       
  1332     ol.enable(OutputGenerator::Html);
       
  1333   }
       
  1334 
       
  1335   if (m_impl->annMemb) 
       
  1336   {
       
  1337     ol.pushGeneratorState();
       
  1338     ol.disableAllBut(OutputGenerator::Html);
       
  1339     ol.writeNonBreakableSpace(3);
       
  1340     ol.popGeneratorState();
       
  1341   }
       
  1342   else
       
  1343   {
       
  1344     ol.insertMemberAlign(m_impl->tArgList!=0);
       
  1345   }
       
  1346 
       
  1347   // *** write name
       
  1348   if (!name().isEmpty() && name().at(0)!='@') // hide annonymous stuff 
       
  1349   {
       
  1350     //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable());
       
  1351     if (!(name().isEmpty() || name().at(0)=='@') && // name valid
       
  1352         (hasDocumentation() || isReference()) && // has docs
       
  1353         !(m_impl->prot==Private && !Config_getBool("EXTRACT_PRIVATE") && m_impl->mtype!=Friend) && // hidden due to protection
       
  1354         !(isStatic() && m_impl->classDef==0 && !Config_getBool("EXTRACT_STATIC")) // hidden due to static-ness
       
  1355        )
       
  1356     {
       
  1357       if (m_impl->annMemb)
       
  1358       {
       
  1359         //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
       
  1360         m_impl->annMemb->writeLink(ol,
       
  1361             m_impl->annMemb->getClassDef(),
       
  1362             m_impl->annMemb->getNamespaceDef(),
       
  1363             m_impl->annMemb->getFileDef(),
       
  1364             m_impl->annMemb->getGroupDef()
       
  1365                           );
       
  1366         m_impl->annMemb->setAnonymousUsed();
       
  1367         setAnonymousUsed();
       
  1368       }
       
  1369       else
       
  1370       {
       
  1371         //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
       
  1372         ClassDef *rcd = cd;
       
  1373         if (isReference() && m_impl->classDef) rcd = m_impl->classDef; 
       
  1374         writeLink(ol,rcd,nd,fd,gd);
       
  1375       }
       
  1376     }
       
  1377     else if (isDocumentedFriendClass())
       
  1378       // if the member is an undocumented friend declaration for some class, 
       
  1379       // then maybe we can link to the class
       
  1380     {
       
  1381       writeLink(ol,getClass(name()),0,0,0);
       
  1382     }
       
  1383     else
       
  1384       // there is a brief member description and brief member 
       
  1385       // descriptions are enabled or there is no detailed description.
       
  1386     {
       
  1387       if (m_impl->annMemb)  
       
  1388       {
       
  1389         m_impl->annMemb->setAnonymousUsed();
       
  1390         setAnonymousUsed();
       
  1391       }
       
  1392       ClassDef *rcd = cd;
       
  1393       if (isReference() && m_impl->classDef) rcd = m_impl->classDef; 
       
  1394       writeLink(ol,rcd,nd,fd,gd,TRUE);
       
  1395     }
       
  1396   }
       
  1397 
       
  1398   // add to index
       
  1399   if (isEnumerate() && name().at(0)=='@')
       
  1400   {
       
  1401     // don't add to index
       
  1402   }
       
  1403   else // index member
       
  1404   {
       
  1405     //static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
       
  1406     //QCString cfname = getOutputFileBase();
       
  1407     //QCString cfiname = d->getOutputFileBase();
       
  1408     //Doxygen::indexList.addIndexItem(
       
  1409     //    cname,                                 // level1
       
  1410     //    name(),                                // level2
       
  1411     //    separateMemPages ? cfname : cfiname,   // contRef
       
  1412     //    cfname,                                // memRef
       
  1413     //    anchor(),                              // anchor
       
  1414     //    this);                                 // memberdef
       
  1415     Doxygen::indexList.addIndexItem(d,this);
       
  1416   }
       
  1417 
       
  1418   // *** write arguments
       
  1419   if (argsString() && !isObjCMethod()) 
       
  1420   {
       
  1421     if (!isDefine()) ol.writeString(" ");
       
  1422     //ol.docify(argsString());
       
  1423     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),argsString()); 
       
  1424   }
       
  1425 
       
  1426   // *** write exceptions
       
  1427   if (excpString())
       
  1428   {
       
  1429     ol.writeString(" ");
       
  1430     ol.docify(excpString());
       
  1431   }
       
  1432 
       
  1433   // *** write bitfields
       
  1434   if (!m_impl->bitfields.isEmpty()) // add bitfields
       
  1435   {
       
  1436     linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->bitfields.simplifyWhiteSpace());
       
  1437   }
       
  1438   else if (hasOneLineInitializer()
       
  1439       //!init.isEmpty() && initLines==0 && // one line initializer
       
  1440       //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
       
  1441           ) // add initializer
       
  1442   {
       
  1443     if (!isDefine()) 
       
  1444     {
       
  1445       ol.writeString(" = "); 
       
  1446       linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
       
  1447     }
       
  1448     else 
       
  1449     {
       
  1450       ol.writeNonBreakableSpace(3);
       
  1451       linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),m_impl->initializer);
       
  1452     }
       
  1453   }
       
  1454 
       
  1455   if (isObjCMethod() && isImplementation())
       
  1456   {
       
  1457     ol.startTypewriter();
       
  1458     ol.docify(" [implementation]");
       
  1459     ol.endTypewriter();
       
  1460   }
       
  1461 
       
  1462   if (isProperty() && (isSettable() || isGettable()))
       
  1463   {
       
  1464       ol.writeLatexSpacing();
       
  1465       ol.startTypewriter();
       
  1466       ol.docify(" [");
       
  1467       QStrList sl;
       
  1468       if (isGettable())  sl.append("get");
       
  1469       if (isSettable())  sl.append("set");
       
  1470       const char *s=sl.first();
       
  1471       while (s)
       
  1472       {
       
  1473          ol.docify(s);
       
  1474          s=sl.next();
       
  1475          if (s) ol.docify(", ");
       
  1476       }
       
  1477       ol.docify("]");
       
  1478       ol.endTypewriter();
       
  1479   }
       
  1480 
       
  1481   if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
       
  1482   {
       
  1483       ol.writeLatexSpacing();
       
  1484       ol.startTypewriter();
       
  1485       ol.docify(" [");
       
  1486       QStrList sl;
       
  1487       if (isAddable())   sl.append("add");
       
  1488       if (isRemovable()) sl.append("remove");
       
  1489       if (isRaisable())  sl.append("raise");
       
  1490       const char *s=sl.first();
       
  1491       while (s)
       
  1492       {
       
  1493          ol.docify(s);
       
  1494          s=sl.next();
       
  1495          if (s) ol.docify(", ");
       
  1496       }
       
  1497       ol.docify("]");
       
  1498       ol.endTypewriter();
       
  1499   }
       
  1500 
       
  1501   if (!detailsVisible && !m_impl->annMemb)
       
  1502   {
       
  1503     ol.endDoxyAnchor(cfname,anchor());
       
  1504   }
       
  1505 
       
  1506   //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
       
  1507   //    name().data(),annoClassDef,annEnumType);
       
  1508   ol.endMemberItem();
       
  1509   if (endAnonScopeNeeded) 
       
  1510   {
       
  1511     ol.endAnonTypeScope(--s_indentLevel);
       
  1512   }
       
  1513 
       
  1514   // write brief description
       
  1515   if (!briefDescription().isEmpty() && 
       
  1516       Config_getBool("BRIEF_MEMBER_DESC") 
       
  1517       /* && !annMemb */
       
  1518      )
       
  1519   {
       
  1520     ol.startMemberDescription();
       
  1521     ol.parseDoc(briefFile(),briefLine(),
       
  1522                 getOuterScope()?getOuterScope():d,this,briefDescription(),
       
  1523                 TRUE,FALSE,0,TRUE,FALSE);
       
  1524     if (detailsVisible) 
       
  1525     {
       
  1526       ol.pushGeneratorState();
       
  1527       ol.disableAllBut(OutputGenerator::Html);
       
  1528       //ol.endEmphasis();
       
  1529       ol.docify(" ");
       
  1530       if (m_impl->group!=0 && gd==0) // forward link to the group
       
  1531       {
       
  1532         ol.startTextLink(getOutputFileBase(),anchor());
       
  1533       }
       
  1534       else // local link
       
  1535       {
       
  1536         ol.startTextLink(0,anchor());
       
  1537       }
       
  1538       ol.endTextLink();
       
  1539       //ol.startEmphasis();
       
  1540       ol.popGeneratorState();
       
  1541     }
       
  1542     // for RTF we need to add an extra empty paragraph
       
  1543     ol.pushGeneratorState();
       
  1544     ol.disableAllBut(OutputGenerator::RTF);
       
  1545       ol.startParagraph();
       
  1546       ol.endParagraph();
       
  1547     ol.popGeneratorState();
       
  1548     ol.endMemberDescription();
       
  1549   }
       
  1550   warnIfUndocumented();
       
  1551 }
       
  1552 
       
  1553 bool MemberDef::isDetailedSectionLinkable() const          
       
  1554 { 
       
  1555   static bool extractAll        = Config_getBool("EXTRACT_ALL");
       
  1556   static bool alwaysDetailedSec = Config_getBool("ALWAYS_DETAILED_SEC");
       
  1557   static bool repeatBrief       = Config_getBool("REPEAT_BRIEF");
       
  1558   static bool briefMemberDesc   = Config_getBool("BRIEF_MEMBER_DESC");
       
  1559   static bool hideUndocMembers  = Config_getBool("HIDE_UNDOC_MEMBERS");
       
  1560   static bool extractStatic     = Config_getBool("EXTRACT_STATIC");
       
  1561   static bool extractPrivate    = Config_getBool("EXTRACT_PRIVATE");
       
  1562 
       
  1563   makeResident();
       
  1564   // the member has details documentation for any of the following reasons
       
  1565   bool docFilter = 
       
  1566          // treat everything as documented
       
  1567          extractAll ||          
       
  1568          // has detailed docs
       
  1569          !documentation().isEmpty() ||             
       
  1570          // has inbody docs
       
  1571          !inbodyDocumentation().isEmpty() ||
       
  1572          // is an enum with values that are documented
       
  1573          (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||  
       
  1574          // is documented enum value
       
  1575          (m_impl->mtype==EnumValue && !briefDescription().isEmpty()) || 
       
  1576          // has brief description that is part of the detailed description
       
  1577          (!briefDescription().isEmpty() &&           // has brief docs
       
  1578           (alwaysDetailedSec &&                      // they are visible in
       
  1579            (repeatBrief ||                           // detailed section or
       
  1580             !briefMemberDesc                         // they are explicitly not
       
  1581            )                                         // shown in brief section
       
  1582           )                                       
       
  1583          ) ||
       
  1584          // has a multi-line initialization block
       
  1585          //(initLines>0 && initLines<maxInitLines) || 
       
  1586          (hasMultiLineInitializer() && !hideUndocMembers) ||
       
  1587          // has one or more documented arguments
       
  1588          (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()) ||
       
  1589          // has user comments
       
  1590          Doxygen::userComments
       
  1591          ; 
       
  1592          
       
  1593   // this is not a global static or global statics should be extracted
       
  1594   bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic; 
       
  1595          
       
  1596   // only include members that are non-private unless EXTRACT_PRIVATE is
       
  1597   // set to YES or the member is part of a group
       
  1598   bool privateFilter = (protection()!=Private || extractPrivate ||
       
  1599                            m_impl->mtype==Friend
       
  1600                           );
       
  1601 
       
  1602   // member is part of an anonymous scope that is the type of
       
  1603   // another member in the list.
       
  1604   //
       
  1605   //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
       
  1606 
       
  1607   // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
       
  1608   // is true
       
  1609   bool friendCompoundFilter = !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
       
  1610                                 isFriend() &&
       
  1611                                 (m_impl->type=="friend class" || 
       
  1612                                  m_impl->type=="friend struct" ||
       
  1613                                  m_impl->type=="friend union"
       
  1614                                 )
       
  1615                                );
       
  1616   
       
  1617   return ((docFilter && staticFilter && privateFilter && friendCompoundFilter) /*|| inAnonymousScope*/);
       
  1618 }
       
  1619 
       
  1620 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const          
       
  1621 { 
       
  1622   static bool separateMemPages = Config_getBool("SEPARATE_MEMBER_PAGES");
       
  1623   bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages; 
       
  1624   bool fileFilter  = getNamespaceDef()==0 || !inFile;
       
  1625 
       
  1626   bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter && 
       
  1627                  !isReference();
       
  1628   //printf("MemberDef::isDetailedSectionVisible() %d\n",visible);
       
  1629   return visible;
       
  1630 }
       
  1631 
       
  1632 /*! Writes the "detailed documentation" section of this member to
       
  1633  *  all active output formats.
       
  1634  */
       
  1635 void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
       
  1636                                    const char *scName,
       
  1637                                    Definition *container,
       
  1638                                    bool inGroup,
       
  1639                                    bool showEnumValues
       
  1640                                   )
       
  1641 {
       
  1642   // if this member is in a group find the real scope name.
       
  1643   bool hasParameterList = FALSE;
       
  1644   bool inFile = container->definitionType()==Definition::TypeFile;
       
  1645   bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
       
  1646   static bool optVhdl          = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  1647   //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d\n",
       
  1648   //    name().data(),hasDocs,container->definitionType(),inGroup);
       
  1649   if ( !hasDocs ) return;
       
  1650   if (isEnumValue() && !showEnumValues) return;
       
  1651 
       
  1652   makeResident();
       
  1653   LockingPtr<MemberDef> lock(this,this);
       
  1654 
       
  1655   QCString scopeName = scName;
       
  1656   QCString memAnchor = anchor();
       
  1657   QCString ciname = container->name();
       
  1658   if (container->definitionType()==TypeGroup)
       
  1659   {
       
  1660     if (getClassDef())          scopeName=getClassDef()->name();
       
  1661     else if (getNamespaceDef()) scopeName=getNamespaceDef()->name();
       
  1662     else if (getFileDef())      scopeName=getFileDef()->name();
       
  1663     ciname = ((GroupDef *)container)->groupTitle();
       
  1664   }
       
  1665   else if (container->definitionType()==TypeFile && getNamespaceDef())
       
  1666   { // member is in a namespace, but is written as part of the file documentation
       
  1667     // as well, so we need to make sure its label is unique.
       
  1668     memAnchor.prepend("file_");
       
  1669   }
       
  1670 
       
  1671   QCString cname  = container->name();
       
  1672   QCString cfname = getOutputFileBase();
       
  1673   QCString cfiname = container->getOutputFileBase();
       
  1674 
       
  1675   // get member name
       
  1676   QCString doxyName=name();
       
  1677   // prepend scope if there is any. TODO: make this optional for C only docs
       
  1678   if (scopeName) doxyName.prepend((QCString)scopeName+"::");
       
  1679   QCString doxyArgs=argsString();
       
  1680 
       
  1681   QCString ldef = definition();
       
  1682   //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
       
  1683   if (isEnumerate()) 
       
  1684   {
       
  1685     if (name().at(0)=='@')
       
  1686     {
       
  1687       ldef = "anonymous enum";
       
  1688     }
       
  1689     else
       
  1690     {
       
  1691       ldef.prepend("enum ");
       
  1692     }
       
  1693   }
       
  1694   else if (isEnumValue())
       
  1695   {
       
  1696     if (ldef.at(0)=='@')
       
  1697     {
       
  1698       ldef=ldef.mid(2);
       
  1699     }
       
  1700   }
       
  1701   int i=0,l;
       
  1702   static QRegExp r("@[0-9]+");
       
  1703 
       
  1704   //----------------------------------------
       
  1705 
       
  1706   ol.pushGeneratorState();
       
  1707 
       
  1708 
       
  1709   if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
       
  1710   {
       
  1711     // find enum type and insert it in the definition
       
  1712     MemberListIterator vmli(*ml);
       
  1713     MemberDef *vmd;
       
  1714     bool found=FALSE;
       
  1715     for ( ; (vmd=vmli.current()) && !found ; ++vmli)
       
  1716     {
       
  1717       if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
       
  1718       {
       
  1719         ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
       
  1720         ol.startMemberDoc(cname,name(),memAnchor,name());
       
  1721         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.left(i));
       
  1722         vmd->writeEnumDeclaration(ol,getClassDef(),getNamespaceDef(),getFileDef(),getGroupDef());
       
  1723         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-i-l));
       
  1724 
       
  1725         found=TRUE;
       
  1726       }
       
  1727     }
       
  1728     if (!found) // anonymous compound
       
  1729     {
       
  1730       //printf("Anonymous compound `%s'\n",cname.data());
       
  1731       ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
       
  1732       ol.startMemberDoc(cname,name(),memAnchor,name());
       
  1733       // strip anonymous compound names from definition
       
  1734       int si=ldef.find(' '),pi,ei=i+l;
       
  1735       if (si==-1) si=0;
       
  1736       while ((pi=r.match(ldef,i+l,&l))!=-1) ei=i=pi+l;
       
  1737       // first si characters of ldef contain compound type name
       
  1738       ol.startMemberDocName(isObjCMethod());
       
  1739       ol.docify(ldef.left(si));
       
  1740       ol.docify(" { ... } ");
       
  1741       // last ei characters of ldef contain pointer/reference specifiers
       
  1742       int ni=ldef.find("::",si);
       
  1743       if (ni>=ei) ei=ni+2;
       
  1744       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef.right(ldef.length()-ei));
       
  1745     }
       
  1746   }
       
  1747   else // not an enum value
       
  1748   {
       
  1749     ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
       
  1750     ol.startMemberDoc(cname,name(),memAnchor,name());
       
  1751 
       
  1752     ClassDef *cd=getClassDef();
       
  1753     if (!Config_getBool("HIDE_SCOPE_NAMES"))
       
  1754     {
       
  1755       bool first=TRUE;
       
  1756       if (m_impl->defTmpArgLists) 
       
  1757         // definition has explicit template parameter declarations
       
  1758       {
       
  1759         QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
       
  1760         ArgumentList *tal;
       
  1761         for (ali.toFirst();(tal=ali.current());++ali)
       
  1762         {
       
  1763           if (tal->count()>0)
       
  1764           {
       
  1765             if (!first) ol.docify(" ");
       
  1766             ol.startMemberDocPrefixItem();
       
  1767             writeTemplatePrefix(ol,tal);
       
  1768             ol.endMemberDocPrefixItem();
       
  1769           }
       
  1770         }
       
  1771       }
       
  1772       else // definition gets it template parameters from its class
       
  1773         // (since no definition was found)
       
  1774       {
       
  1775         if (cd && !isTemplateSpecialization())
       
  1776         {
       
  1777           QList<ArgumentList> tempParamLists;
       
  1778           cd->getTemplateParameterLists(tempParamLists);
       
  1779           //printf("#tempParamLists=%d\n",tempParamLists.count());
       
  1780           QListIterator<ArgumentList> ali(tempParamLists);
       
  1781           ArgumentList *tal;
       
  1782           for (ali.toFirst();(tal=ali.current());++ali)
       
  1783           {
       
  1784             if (tal->count()>0)
       
  1785             {
       
  1786               if (!first) ol.docify(" ");
       
  1787               ol.startMemberDocPrefixItem();
       
  1788               writeTemplatePrefix(ol,tal);
       
  1789               ol.endMemberDocPrefixItem();
       
  1790             }
       
  1791           }
       
  1792         }
       
  1793         if (m_impl->tArgList) // function template prefix
       
  1794         {
       
  1795           ol.startMemberDocPrefixItem();
       
  1796           writeTemplatePrefix(ol,m_impl->tArgList);
       
  1797           ol.endMemberDocPrefixItem();
       
  1798         }
       
  1799       }
       
  1800     }
       
  1801 
       
  1802     ol.startMemberDocName(isObjCMethod());
       
  1803     if (cd && cd->isObjectiveC())
       
  1804     {
       
  1805       // strip scope name
       
  1806       int ep = ldef.find("::");
       
  1807       if (ep!=-1) 
       
  1808       {
       
  1809         int sp=ldef.findRev(' ',ep);
       
  1810         if (sp!=-1)
       
  1811         {
       
  1812           ldef=ldef.left(sp+1)+ldef.mid(ep+2);
       
  1813         }
       
  1814       }
       
  1815       // strip keywords
       
  1816       int dp = ldef.find(':');
       
  1817       if (dp!=-1)
       
  1818       {
       
  1819         ldef=ldef.left(dp+1);
       
  1820       }
       
  1821       int l=ldef.length();
       
  1822       //printf("start >%s<\n",ldef.data());
       
  1823       int i=l-1;
       
  1824       while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
       
  1825       while (i>=0 && isspace((uchar)ldef.at(i))) i--;
       
  1826       if (i>0)
       
  1827       {
       
  1828         // insert braches around the type
       
  1829         QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
       
  1830         ldef=tmp;
       
  1831       }
       
  1832       //printf("end   >%s< i=%d\n",ldef.data(),i);
       
  1833       if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
       
  1834     }
       
  1835 
       
  1836     if (optVhdl)
       
  1837     {
       
  1838       VhdlDocGen::writeVHDLTypeDocumentation(this,container,ol);
       
  1839     }
       
  1840     else
       
  1841     {
       
  1842       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),ldef);
       
  1843       hasParameterList=writeDefArgumentList(ol,cd,scopeName,this);
       
  1844     }
       
  1845 
       
  1846     if (hasOneLineInitializer()) // add initializer
       
  1847     {
       
  1848       if (!isDefine()) 
       
  1849       {
       
  1850         ol.docify(" = "); 
       
  1851         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer.simplifyWhiteSpace());
       
  1852       }
       
  1853       else 
       
  1854       {
       
  1855         ol.writeNonBreakableSpace(3);
       
  1856         linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),m_impl->initializer);
       
  1857       }
       
  1858     }
       
  1859     if (excpString()) // add exception list
       
  1860     {
       
  1861       ol.docify(" ");
       
  1862       linkifyText(TextGeneratorOLImpl(ol),container,getBodyDef(),name(),excpString());
       
  1863     }
       
  1864   }
       
  1865 
       
  1866   Specifier lvirt=virtualness();
       
  1867 
       
  1868   if ((!isObjCMethod() || isOptional() || isRequired()) &&
       
  1869       (protection()!=Public || lvirt!=Normal ||
       
  1870        isFriend() || isRelated() || 
       
  1871        (isInline() && Config_getBool("INLINE_INFO")) ||
       
  1872        isSignal() || isSlot() ||
       
  1873        isStatic() || (m_impl->classDef && m_impl->classDef!=container) ||
       
  1874        (m_impl->memSpec & ~Entry::Inline)!=0 
       
  1875       )
       
  1876      )
       
  1877   {
       
  1878     // write the member specifier list
       
  1879     ol.writeLatexSpacing();
       
  1880     ol.startTypewriter();
       
  1881     ol.docify(" [");
       
  1882     QStrList sl;
       
  1883     if (optVhdl)
       
  1884     {
       
  1885       sl.append(VhdlDocGen::trTypeString(getMemberSpecifiers()));
       
  1886     }
       
  1887     else
       
  1888     {
       
  1889       if (isFriend()) sl.append("friend");
       
  1890       else if (isRelated()) sl.append("related");
       
  1891       else
       
  1892       {
       
  1893         if      (Config_getBool("INLINE_INFO") && isInline()) sl.append("inline");
       
  1894         if      (isExplicit())            sl.append("explicit");
       
  1895         if      (isMutable())             sl.append("mutable");
       
  1896         if      (isStatic())              sl.append("static");
       
  1897         if      (isGettable())            sl.append("get");
       
  1898         if      (isSettable())            sl.append("set");
       
  1899         if      (isAddable())             sl.append("add");
       
  1900         if      (isRemovable())           sl.append("remove");
       
  1901         if      (isRaisable())            sl.append("raise");
       
  1902         if      (isReadable())            sl.append("read");
       
  1903         if      (isWritable())            sl.append("write");
       
  1904         if      (isFinal())               sl.append("final");
       
  1905         if      (isAbstract())            sl.append("abstract");
       
  1906         if      (isOverride())            sl.append("override");
       
  1907         if      (isInitonly())            sl.append("initonly");
       
  1908         if      (isSealed())              sl.append("sealed");
       
  1909         if      (isNew())                 sl.append("new");
       
  1910         if      (isOptional())            sl.append("optional");
       
  1911         if      (isRequired())            sl.append("required");
       
  1912         if      (isAssign())              sl.append("assign");
       
  1913         else if (isCopy())                sl.append("copy");
       
  1914         else if (isRetain())              sl.append("retain");
       
  1915 
       
  1916         if (!isObjCMethod())
       
  1917         {
       
  1918           if      (protection()==Protected) sl.append("protected");
       
  1919           else if (protection()==Private)   sl.append("private");
       
  1920           else if (protection()==Package)   sl.append("package");
       
  1921 
       
  1922           if      (lvirt==Virtual)          sl.append("virtual");
       
  1923           else if (lvirt==Pure)             sl.append("pure virtual");
       
  1924           if      (isSignal())              sl.append("signal");
       
  1925           if      (isSlot())                sl.append("slot");
       
  1926         }
       
  1927       }
       
  1928       if (m_impl->classDef && m_impl->classDef!=container) sl.append("inherited");
       
  1929     }
       
  1930     const char *s=sl.first();
       
  1931     while (s)
       
  1932     {
       
  1933       ol.docify(s);
       
  1934       s=sl.next();
       
  1935       if (s) ol.docify(", ");
       
  1936     }
       
  1937     ol.docify("]");
       
  1938     ol.endTypewriter();
       
  1939   }
       
  1940   else if (isObjCMethod() && isImplementation())
       
  1941   {
       
  1942     ol.writeLatexSpacing();
       
  1943     ol.startTypewriter();
       
  1944     ol.docify(" [implementation]");
       
  1945     ol.endTypewriter();
       
  1946   }
       
  1947   if (hasParameterList) 
       
  1948   {
       
  1949     ol.endParameterList();
       
  1950     ol.endMemberDoc(TRUE);
       
  1951   }
       
  1952   else
       
  1953   {
       
  1954     ol.endMemberDocName();
       
  1955     ol.endMemberDoc(FALSE);
       
  1956   }
       
  1957   ol.endDoxyAnchor(cfname,memAnchor);
       
  1958   ol.startIndent();
       
  1959 
       
  1960   // FIXME:PARA
       
  1961   //ol.pushGeneratorState();
       
  1962   //ol.disable(OutputGenerator::RTF);
       
  1963   //ol.newParagraph();
       
  1964   //ol.popGeneratorState();
       
  1965 
       
  1966   /* write multi-line initializer (if any) */
       
  1967   if (hasMultiLineInitializer()
       
  1968       //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
       
  1969       //                || initLines<userInitLines // explicitly enabled
       
  1970       //               )
       
  1971      )
       
  1972   {
       
  1973     //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
       
  1974     ol.startBold();
       
  1975     if (m_impl->mtype==Define)
       
  1976       ol.parseText(theTranslator->trDefineValue());
       
  1977     else
       
  1978       ol.parseText(theTranslator->trInitialValue());
       
  1979     ol.endBold();
       
  1980     ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension());
       
  1981     pIntf->resetCodeParserState();
       
  1982     ol.startCodeFragment();
       
  1983     pIntf->parseCode(ol,scopeName,m_impl->initializer,FALSE,0);
       
  1984     ol.endCodeFragment();
       
  1985   }
       
  1986 
       
  1987   QCString brief           = briefDescription();
       
  1988   QCString detailed        = documentation();
       
  1989   LockingPtr<ArgumentList> docArgList = LockingPtr<ArgumentList>(this,m_impl->defArgList);
       
  1990   if (m_impl->templateMaster)
       
  1991   {
       
  1992     brief      = m_impl->templateMaster->briefDescription();
       
  1993     detailed   = m_impl->templateMaster->documentation();
       
  1994     docArgList = m_impl->templateMaster->argumentList();
       
  1995   }
       
  1996 
       
  1997   /* write brief description */
       
  1998   if (!brief.isEmpty() && 
       
  1999       (Config_getBool("REPEAT_BRIEF") || 
       
  2000        !Config_getBool("BRIEF_MEMBER_DESC")
       
  2001       ) 
       
  2002      )  
       
  2003   { 
       
  2004     ol.startParagraph();
       
  2005     ol.parseDoc(briefFile(),briefLine(),
       
  2006                 getOuterScope()?getOuterScope():container,this,
       
  2007                 brief,FALSE,FALSE,0,TRUE,FALSE);
       
  2008     ol.endParagraph();
       
  2009   }
       
  2010 
       
  2011   /* write detailed description */
       
  2012   if (!detailed.isEmpty() || 
       
  2013       !inbodyDocumentation().isEmpty())
       
  2014   { 
       
  2015     ol.parseDoc(docFile(),docLine(),getOuterScope()?getOuterScope():container,this,detailed+"\n",TRUE,FALSE);
       
  2016     if (!inbodyDocumentation().isEmpty())
       
  2017     {
       
  2018       ol.startParagraph();
       
  2019       ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,inbodyDocumentation()+"\n",TRUE,FALSE);
       
  2020       ol.endParagraph();
       
  2021     }
       
  2022   }
       
  2023   else if (!brief.isEmpty() && (Config_getBool("REPEAT_BRIEF") ||
       
  2024         !Config_getBool("BRIEF_MEMBER_DESC")))
       
  2025   {
       
  2026     if (!inbodyDocumentation().isEmpty())
       
  2027     {
       
  2028       ol.parseDoc(inbodyFile(),inbodyLine(),getOuterScope()?getOuterScope():container,this,inbodyDocumentation()+"\n",TRUE,FALSE);
       
  2029     }
       
  2030   }
       
  2031 
       
  2032 
       
  2033   //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
       
  2034   //     defArgList, 
       
  2035   //     defArgList?defArgList->hasDocumentation():-1);
       
  2036   if (docArgList!=0 && docArgList->hasDocumentation())
       
  2037   {
       
  2038     QCString paramDocs;
       
  2039     ArgumentListIterator ali(*docArgList);
       
  2040     Argument *a;
       
  2041     // convert the parameter documentation into a list of @param commands
       
  2042     for (ali.toFirst();(a=ali.current());++ali)
       
  2043     {
       
  2044       if (a->hasDocumentation())
       
  2045       {
       
  2046         QCString direction = extractDirection(a->docs);
       
  2047         paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
       
  2048       }
       
  2049     }
       
  2050     // feed the result to the documentation parser
       
  2051     ol.parseDoc(
       
  2052         docFile(),docLine(),
       
  2053         getOuterScope()?getOuterScope():container,
       
  2054         this,         // memberDef
       
  2055         paramDocs,    // docStr
       
  2056         TRUE,         // indexWords
       
  2057         FALSE         // isExample
       
  2058         );
       
  2059 
       
  2060   }
       
  2061 
       
  2062   // For enum, we also write the documented enum values
       
  2063   if (isEnumerate())
       
  2064   {
       
  2065     bool first=TRUE;
       
  2066     LockingPtr<MemberList> fmdl=enumFieldList();
       
  2067     if (fmdl!=0)
       
  2068     {
       
  2069       MemberDef *fmd=fmdl->first();
       
  2070       while (fmd)
       
  2071       {
       
  2072         //printf("Enum: isLinkable()=%d\n",fmd->isLinkable());
       
  2073         if (fmd->isLinkable())
       
  2074         {
       
  2075           if (first)
       
  2076           {
       
  2077             ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
       
  2078             ol.startDescForItem();
       
  2079             ol.startDescTable();
       
  2080           }
       
  2081 
       
  2082           ol.addIndexItem(fmd->name(),cname);
       
  2083           ol.addIndexItem(cname,fmd->name());
       
  2084 
       
  2085           //Doxygen::indexList.addIndexItem(
       
  2086           //                       ciname,                                // level1
       
  2087           //                       fmd->name(),                           // level2
       
  2088           //                       separateMemPages ? cfname : cfiname,   // contRef
       
  2089           //                       cfname,                                // memRef
       
  2090           //                       fmd->anchor(),                         // anchor
       
  2091           //                       fmd);                                  // memberdef
       
  2092           Doxygen::indexList.addIndexItem(container,fmd);
       
  2093 
       
  2094           //ol.writeListItem();
       
  2095           ol.startDescTableTitle(); // this enables emphasis!
       
  2096           ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
       
  2097           first=FALSE;
       
  2098           //ol.startEmphasis();
       
  2099           ol.docify(fmd->name());
       
  2100           //ol.endEmphasis();
       
  2101           ol.disableAllBut(OutputGenerator::Man);
       
  2102           ol.writeString(" ");
       
  2103           ol.enableAll();
       
  2104           ol.endDoxyAnchor(cfname,fmd->anchor());
       
  2105           ol.endDescTableTitle();
       
  2106           //ol.newParagraph();
       
  2107           ol.startDescTableData();
       
  2108 
       
  2109           if (!fmd->briefDescription().isEmpty())
       
  2110           { 
       
  2111             ol.parseDoc(fmd->briefFile(),fmd->briefLine(),getOuterScope()?getOuterScope():container,fmd,fmd->briefDescription(),TRUE,FALSE);
       
  2112           }
       
  2113           // FIXME:PARA
       
  2114           //if (!fmd->briefDescription().isEmpty() && 
       
  2115           //    !fmd->documentation().isEmpty())
       
  2116           //{
       
  2117           //  ol.newParagraph();
       
  2118           //}
       
  2119           if (!fmd->documentation().isEmpty())
       
  2120           { 
       
  2121             ol.parseDoc(fmd->docFile(),fmd->docLine(),getOuterScope()?getOuterScope():container,fmd,fmd->documentation()+"\n",TRUE,FALSE);
       
  2122           }
       
  2123           ol.endDescTableData();
       
  2124         }
       
  2125         fmd=fmdl->next();
       
  2126       }
       
  2127     }
       
  2128     if (!first) 
       
  2129     { 
       
  2130       //ol.endItemList(); 
       
  2131       ol.endDescTable();
       
  2132       ol.endDescForItem();
       
  2133       ol.endSimpleSect();
       
  2134       ol.writeChar('\n'); 
       
  2135     }
       
  2136   }
       
  2137 
       
  2138   MemberDef *bmd=reimplements();
       
  2139   ClassDef *bcd=0;
       
  2140   if (bmd && (bcd=bmd->getClassDef()))
       
  2141   {
       
  2142     // write class that contains a member that is reimplemented by this one
       
  2143     if (bcd->isLinkable())
       
  2144     {
       
  2145       ol.startParagraph();
       
  2146       QCString reimplFromLine; 
       
  2147       if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
       
  2148       {
       
  2149         reimplFromLine = theTranslator->trReimplementedFromList(1);
       
  2150       }
       
  2151       else
       
  2152       {
       
  2153         reimplFromLine = theTranslator->trImplementedFromList(1);
       
  2154       }
       
  2155       int markerPos = reimplFromLine.find("@0");
       
  2156       if (markerPos!=-1) // should always pass this.
       
  2157       {
       
  2158         ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
       
  2159         if (bmd->isLinkable()) // replace marker with link
       
  2160         {
       
  2161           //Definition *bd=bmd->group;
       
  2162           //if (bd==0) bd=bcd;
       
  2163           ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
       
  2164               bmd->anchor(),bcd->displayName());
       
  2165 
       
  2166           //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
       
  2167           //    bmd->anchor(),bcd->name());
       
  2168           if ( bmd->isLinkableInProject() ) 
       
  2169           {
       
  2170             writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
       
  2171           }
       
  2172         }
       
  2173         else
       
  2174         {
       
  2175           ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
       
  2176               0,bcd->displayName());
       
  2177           if (bcd->isLinkableInProject()/* && !Config_getBool("PDF_HYPERLINKS")*/ )
       
  2178           {
       
  2179             writePageRef(ol,bcd->getOutputFileBase(),0);
       
  2180           }
       
  2181         }
       
  2182         ol.parseText(reimplFromLine.right(
       
  2183               reimplFromLine.length()-markerPos-2)); // text right from marker
       
  2184 
       
  2185       }
       
  2186       else
       
  2187       {
       
  2188         err("Error: translation error: no marker in trReimplementsFromList()\n");
       
  2189       }
       
  2190       ol.endParagraph();
       
  2191     }
       
  2192 
       
  2193     //ol.writeString(".");
       
  2194   }
       
  2195 
       
  2196   LockingPtr<MemberList> bml=reimplementedBy();
       
  2197   if (bml!=0)
       
  2198   {
       
  2199     MemberListIterator mli(*bml);
       
  2200     MemberDef *bmd=0;
       
  2201     uint count=0;
       
  2202     ClassDef *bcd=0;
       
  2203     for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
       
  2204     {
       
  2205       // count the members that directly inherit from md and for
       
  2206       // which the member and class are visible in the docs.
       
  2207       if ( bmd->isLinkable() && bcd->isLinkable() ) 
       
  2208       {
       
  2209         count++;
       
  2210       }
       
  2211     }
       
  2212     if (count>0)
       
  2213     {
       
  2214       mli.toFirst();
       
  2215       // write the list of classes that overwrite this member
       
  2216       ol.startParagraph();
       
  2217 
       
  2218       QCString reimplInLine;
       
  2219       if (m_impl->virt==Pure || (m_impl->classDef && m_impl->classDef->compoundType()==ClassDef::Interface))
       
  2220       {
       
  2221         reimplInLine = theTranslator->trImplementedInList(count);
       
  2222       }
       
  2223       else
       
  2224       {
       
  2225         reimplInLine = theTranslator->trReimplementedInList(count);
       
  2226       }
       
  2227       static QRegExp marker("@[0-9]+");
       
  2228       int index=0,newIndex,matchLen;
       
  2229       // now replace all markers in reimplInLine with links to the classes
       
  2230       while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
       
  2231       {
       
  2232         ol.parseText(reimplInLine.mid(index,newIndex-index));
       
  2233         bool ok;
       
  2234         uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
       
  2235         //bmd=bml->at(entryIndex);
       
  2236 
       
  2237         count=0;
       
  2238         // find the entryIndex-th documented entry in the inheritance list.
       
  2239         for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
       
  2240         {
       
  2241           if ( bmd->isLinkable() && bcd->isLinkable()) 
       
  2242           {
       
  2243             if (count==entryIndex) break;
       
  2244             count++;
       
  2245           }
       
  2246         }
       
  2247 
       
  2248         if (ok && bcd && bmd) // write link for marker
       
  2249         {
       
  2250           //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
       
  2251           //    bmd->anchor(),bcd->name());
       
  2252           ol.writeObjectLink(bmd->getReference(),bmd->getOutputFileBase(),
       
  2253               bmd->anchor(),bcd->displayName());
       
  2254 
       
  2255           if (bmd->isLinkableInProject() ) 
       
  2256           {
       
  2257             writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
       
  2258           }
       
  2259         }
       
  2260         ++mli;
       
  2261         index=newIndex+matchLen;
       
  2262       } 
       
  2263       ol.parseText(reimplInLine.right(reimplInLine.length()-index));
       
  2264       ol.endParagraph();
       
  2265     }
       
  2266   }
       
  2267 
       
  2268   // write the list of examples that use this member
       
  2269   if (hasExamples())
       
  2270   {
       
  2271     ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
       
  2272     ol.startDescForItem();
       
  2273     writeExample(ol,m_impl->exampleSDict);
       
  2274     ol.endDescForItem();
       
  2275     ol.endSimpleSect();
       
  2276   }
       
  2277 
       
  2278   if (m_impl->typeConstraints)
       
  2279   {
       
  2280     writeTypeConstraints(ol,this,m_impl->typeConstraints);
       
  2281   }
       
  2282 
       
  2283   // write reference to the source
       
  2284   writeSourceDef(ol,cname);
       
  2285   writeSourceRefs(ol,cname);
       
  2286   writeSourceReffedBy(ol,cname);
       
  2287   writeInlineCode(ol,cname);
       
  2288 
       
  2289   // write call graph
       
  2290   if ((m_impl->hasCallGraph || Config_getBool("CALL_GRAPH")) 
       
  2291       && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
       
  2292      )
       
  2293   {
       
  2294     DotCallGraph callGraph(this,FALSE);
       
  2295     if (!callGraph.isTrivial() && !callGraph.isTooBig())
       
  2296     {
       
  2297       msg("Generating call graph for function %s\n",qualifiedName().data());
       
  2298       ol.disable(OutputGenerator::Man);
       
  2299       ol.startParagraph();
       
  2300       ol.startCallGraph();
       
  2301       ol.parseText(theTranslator->trCallGraph());
       
  2302       ol.endCallGraph(callGraph);
       
  2303       ol.endParagraph(); 
       
  2304       ol.enableAll();
       
  2305     }
       
  2306   }
       
  2307   if ((m_impl->hasCallerGraph || Config_getBool("CALLER_GRAPH")) 
       
  2308       && (isFunction() || isSlot() || isSignal()) && Config_getBool("HAVE_DOT")
       
  2309      )
       
  2310   {
       
  2311     DotCallGraph callerGraph(this, TRUE);
       
  2312     if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
       
  2313     {
       
  2314       msg("Generating caller graph for function %s\n",qualifiedName().data());
       
  2315       ol.disable(OutputGenerator::Man);
       
  2316       ol.startParagraph();
       
  2317       ol.startCallGraph();
       
  2318       ol.parseText(theTranslator->trCallerGraph());
       
  2319       ol.endCallGraph(callerGraph);
       
  2320       ol.endParagraph();
       
  2321       ol.enableAll();
       
  2322     }
       
  2323   }
       
  2324 
       
  2325   if (Doxygen::userComments)
       
  2326   {
       
  2327     ol.pushGeneratorState();
       
  2328     ol.disableAllBut(OutputGenerator::Html);
       
  2329     QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
       
  2330                    "passthru(\"$root/doxynotes --lookup "+
       
  2331                    getOutputFileBase()+":"+anchor()+"\") ?>";
       
  2332     ol.writeString(cmd);
       
  2333     ol.popGeneratorState();
       
  2334   }
       
  2335 
       
  2336   ol.endIndent();
       
  2337 
       
  2338   // enable LaTeX again
       
  2339   //if (Config_getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); 
       
  2340   ol.popGeneratorState();
       
  2341 
       
  2342   //------------------------------------------------
       
  2343 
       
  2344   if (!Config_getBool("EXTRACT_ALL") &&
       
  2345       Config_getBool("WARN_IF_UNDOCUMENTED") &&
       
  2346       Config_getBool("WARN_NO_PARAMDOC") &&
       
  2347       !Doxygen::suppressDocWarnings)
       
  2348   {
       
  2349     if (!hasDocumentedParams())
       
  2350     {
       
  2351       warn_doc_error(docFile(),docLine(),
       
  2352           "Warning: parameters of member %s are not (all) documented",
       
  2353           qualifiedName().data());
       
  2354     }
       
  2355     if (!hasDocumentedReturnType())
       
  2356     {
       
  2357       warn_doc_error(docFile(),docLine(),
       
  2358           "Warning: return type of member %s is not documented",
       
  2359           qualifiedName().data());
       
  2360     }
       
  2361   }
       
  2362 
       
  2363 }
       
  2364 
       
  2365 QCString MemberDef::memberTypeName() const
       
  2366 {
       
  2367   makeResident();
       
  2368   switch (m_impl->mtype)
       
  2369   {
       
  2370     case Define:      return "define";
       
  2371     case Function:    return "function";
       
  2372     case Variable:    return "variable";
       
  2373     case Typedef:     return "typedef";
       
  2374     case Enumeration: return "enumeration"; 
       
  2375     case EnumValue:   return "enumvalue";
       
  2376     case Signal:      return "signal";
       
  2377     case Slot:        return "slot";
       
  2378     case Friend:      return "friend";
       
  2379     case DCOP:        return "dcop";
       
  2380     case Property:    return "property";
       
  2381     case Event:       return "event";
       
  2382     default:          return "unknown";
       
  2383   }
       
  2384 }
       
  2385 
       
  2386 void MemberDef::warnIfUndocumented()
       
  2387 {
       
  2388   makeResident();
       
  2389   if (m_impl->memberGroup) return;
       
  2390   ClassDef     *cd = getClassDef();
       
  2391   NamespaceDef *nd = getNamespaceDef();
       
  2392   FileDef      *fd = getFileDef();
       
  2393   GroupDef     *gd = getGroupDef();
       
  2394   Definition *d=0;
       
  2395   const char *t=0;
       
  2396   if (cd) 
       
  2397     t="class", d=cd; 
       
  2398   else if (nd) 
       
  2399     t="namespace", d=nd; 
       
  2400   else if (gd)
       
  2401     t="group", d=gd;
       
  2402   else
       
  2403     t="file", d=fd;
       
  2404   static bool extractAll = Config_getBool("EXTRACT_ALL");
       
  2405 
       
  2406   //printf("warnIfUndoc: d->isLinkable()=%d isLinkable()=%d "
       
  2407   //       "isDocumentedFriendClass()=%d name()=%s prot=%d\n",
       
  2408   //       d->isLinkable(),isLinkable(),isDocumentedFriendClass(),
       
  2409   //       name().data(),prot);
       
  2410   if ((!hasUserDocumentation() && !extractAll) &&
       
  2411       !isFriendClass() && 
       
  2412       name().find('@')==-1 && d->name().find('@')==-1 &&
       
  2413       (m_impl->prot!=Private || Config_getBool("EXTRACT_PRIVATE"))
       
  2414      )
       
  2415   {
       
  2416     warn_undoc(getDefFileName(),getDefLine(),"Warning: Member %s%s (%s) of %s %s is not documented.",
       
  2417          name().data(),argsString()?argsString():"",memberTypeName().data(),t,d->name().data());
       
  2418   }
       
  2419 }
       
  2420 
       
  2421 
       
  2422 
       
  2423 bool MemberDef::isFriendClass() const
       
  2424 {
       
  2425   makeResident();
       
  2426   return (isFriend() && 
       
  2427          (m_impl->type=="friend class" || m_impl->type=="friend struct" || 
       
  2428           m_impl->type=="friend union"));
       
  2429 }
       
  2430 
       
  2431 bool MemberDef::isDocumentedFriendClass() const
       
  2432 {
       
  2433   makeResident();
       
  2434   ClassDef *fcd=0;
       
  2435   QCString baseName=name();
       
  2436   int i=baseName.find('<');
       
  2437   if (i!=-1) baseName=baseName.left(i);
       
  2438   return (isFriendClass() &&
       
  2439          (fcd=getClass(baseName)) && fcd->isLinkable()); 
       
  2440 }
       
  2441 
       
  2442 bool MemberDef::hasDocumentation() const
       
  2443 { 
       
  2444   makeResident();
       
  2445   return Definition::hasDocumentation() || 
       
  2446          (m_impl->mtype==Enumeration && m_impl->docEnumValues) ||  // has enum values
       
  2447          (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
       
  2448 }
       
  2449 
       
  2450 #if 0
       
  2451 bool MemberDef::hasUserDocumentation() const
       
  2452 {
       
  2453   bool hasDocs = Definition::hasUserDocumentation();
       
  2454   return hasDocs;
       
  2455 }
       
  2456 #endif
       
  2457 
       
  2458 
       
  2459 void MemberDef::setMemberGroup(MemberGroup *grp)
       
  2460 {
       
  2461   makeResident();
       
  2462   m_impl->memberGroup = grp;
       
  2463 }
       
  2464 
       
  2465 bool MemberDef::visibleMemberGroup(bool hideNoHeader) 
       
  2466 { 
       
  2467   makeResident();
       
  2468   return m_impl->memberGroup!=0 && 
       
  2469           (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]"); 
       
  2470 }
       
  2471 
       
  2472 QCString MemberDef::getScopeString() const
       
  2473 {
       
  2474   makeResident();
       
  2475   QCString result;
       
  2476   if (getClassDef()) result=getClassDef()->displayName();
       
  2477   else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
       
  2478   return result;
       
  2479 }
       
  2480 
       
  2481 #if 0
       
  2482 static QCString escapeAnchor(const QCString &anchor)
       
  2483 {
       
  2484   QCString result;
       
  2485   int l = anchor.length(),i;
       
  2486   for (i=0;i<l;i++)
       
  2487   {
       
  2488     char c = anchor.at(i);
       
  2489     if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
       
  2490     {
       
  2491       result+=c;
       
  2492     }
       
  2493     else
       
  2494     {
       
  2495       static char hexStr[]="0123456789ABCDEF";
       
  2496       char escChar[]={ '_', 0, 0, 0 };
       
  2497       escChar[1]=hexStr[c>>4];
       
  2498       escChar[2]=hexStr[c&0xf];
       
  2499       result+=escChar;
       
  2500     }
       
  2501   }
       
  2502   return result;
       
  2503 }
       
  2504 #endif
       
  2505 
       
  2506 void MemberDef::setAnchor(const char *a)
       
  2507 {
       
  2508   makeResident();
       
  2509   //anc=a;
       
  2510   a=a;
       
  2511   QCString memAnchor = name();
       
  2512   if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
       
  2513 
       
  2514   // include definition as well, to distinguish between two template
       
  2515   // specializations that only differ in the template parameters.
       
  2516   memAnchor.prepend(definition());
       
  2517   
       
  2518   // convert to md5 hash
       
  2519   uchar md5_sig[16];
       
  2520   QCString sigStr(33);
       
  2521   MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
       
  2522   MD5SigToString(md5_sig,sigStr.data(),33);
       
  2523   m_impl->anc = "a"+sigStr;
       
  2524 }
       
  2525 
       
  2526 void MemberDef::setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
       
  2527                             const QCString &fileName,int startLine,
       
  2528                             bool hasDocs,MemberDef *member)
       
  2529 {
       
  2530   //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
       
  2531   makeResident();
       
  2532   m_impl->group=gd;
       
  2533   m_impl->grouppri=pri;
       
  2534   m_impl->groupFileName=fileName;
       
  2535   m_impl->groupStartLine=startLine;
       
  2536   m_impl->groupHasDocs=hasDocs;
       
  2537   m_impl->groupMember=member;
       
  2538 }
       
  2539 
       
  2540 void MemberDef::setEnumScope(MemberDef *md) 
       
  2541 { 
       
  2542   makeResident();
       
  2543   m_impl->enumScope=md; 
       
  2544   if (md->getGroupDef())
       
  2545   {
       
  2546     m_impl->group=md->getGroupDef();
       
  2547     m_impl->grouppri=md->getGroupPri();
       
  2548     m_impl->groupFileName=md->getGroupFileName();
       
  2549     m_impl->groupStartLine=md->getGroupStartLine();
       
  2550     m_impl->groupHasDocs=md->getGroupHasDocs();
       
  2551   }
       
  2552 }
       
  2553 
       
  2554 void MemberDef::setMemberClass(ClassDef *cd)     
       
  2555 { 
       
  2556   makeResident();
       
  2557   m_impl->classDef=cd; 
       
  2558   setOuterScope(cd); 
       
  2559 }
       
  2560 
       
  2561 void MemberDef::setNamespace(NamespaceDef *nd) 
       
  2562 { 
       
  2563   makeResident();
       
  2564   m_impl->nspace=nd; 
       
  2565   setOuterScope(nd); 
       
  2566 }
       
  2567 
       
  2568 MemberDef *MemberDef::createTemplateInstanceMember(
       
  2569         ArgumentList *formalArgs,ArgumentList *actualArgs)
       
  2570 {
       
  2571   makeResident();
       
  2572   LockingPtr<MemberDef> lock(this,this);
       
  2573   //printf("  Member %s %s %s\n",typeString(),name().data(),argsString());
       
  2574   ArgumentList *actualArgList = 0;
       
  2575   if (m_impl->defArgList)
       
  2576   {
       
  2577     actualArgList = new ArgumentList;
       
  2578     ArgumentListIterator ali(*m_impl->defArgList);
       
  2579     Argument *arg;
       
  2580     for (;(arg=ali.current());++ali)
       
  2581     {
       
  2582       Argument *actArg = new Argument(*arg);
       
  2583       actArg->type = substituteTemplateArgumentsInString(actArg->type,formalArgs,actualArgs);
       
  2584       actualArgList->append(actArg);
       
  2585     }
       
  2586     actualArgList->constSpecifier    = m_impl->defArgList->constSpecifier;
       
  2587     actualArgList->volatileSpecifier = m_impl->defArgList->volatileSpecifier;
       
  2588     actualArgList->pureSpecifier     = m_impl->defArgList->pureSpecifier;
       
  2589   }
       
  2590 
       
  2591   QCString methodName=name();
       
  2592   if (methodName.left(9)=="operator ") // conversion operator
       
  2593   {
       
  2594     methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
       
  2595   }
       
  2596 
       
  2597   MemberDef *imd = new MemberDef(
       
  2598                        getDefFileName(),getDefLine(),
       
  2599                        substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs), 
       
  2600                        methodName, 
       
  2601                        substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs), 
       
  2602                        m_impl->exception, m_impl->prot,
       
  2603                        m_impl->virt, m_impl->stat, m_impl->related, m_impl->mtype, 0, 0
       
  2604                    );
       
  2605   imd->setArgumentList(actualArgList);
       
  2606   imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
       
  2607   imd->setBodyDef(getBodyDef());
       
  2608   imd->setBodySegment(getStartBodyLine(),getEndBodyLine());
       
  2609   //imd->setBodyMember(this);
       
  2610 
       
  2611   // TODO: init other member variables (if needed).
       
  2612   // TODO: reimplemented info
       
  2613   return imd; 
       
  2614 }
       
  2615 
       
  2616 bool MemberDef::hasOneLineInitializer() const
       
  2617 {
       
  2618   makeResident();
       
  2619   //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
       
  2620   //    name().data(),m_impl->initializer.data(),m_impl->initLines,
       
  2621   //    m_impl->maxInitLines,m_impl->userInitLines);
       
  2622   return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
       
  2623          ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
       
  2624 }
       
  2625 
       
  2626 bool MemberDef::hasMultiLineInitializer() const
       
  2627 {
       
  2628   makeResident();
       
  2629   //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
       
  2630   //    initLines,userInitLines,maxInitLines);
       
  2631   return m_impl->initLines>0 && 
       
  2632          ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
       
  2633           || m_impl->initLines<m_impl->userInitLines // explicitly enabled
       
  2634          );
       
  2635 }
       
  2636 
       
  2637 void MemberDef::setInitializer(const char *initializer)    
       
  2638 { 
       
  2639   makeResident();
       
  2640   m_impl->initializer=initializer; 
       
  2641   int p=m_impl->initializer.length()-1;
       
  2642   while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
       
  2643   m_impl->initializer=m_impl->initializer.left(p+1);
       
  2644   m_impl->initLines=m_impl->initializer.contains('\n');
       
  2645 }
       
  2646 
       
  2647 void MemberDef::addListReference(Definition *)
       
  2648 {
       
  2649   makeResident();
       
  2650   static bool optimizeOutputForC = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
       
  2651   static bool hideScopeNames     = Config_getBool("HIDE_SCOPE_NAMES");
       
  2652   static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
       
  2653   static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");  
       
  2654   visited=TRUE;
       
  2655   if (!isLinkableInProject()) return;
       
  2656   QCString memLabel;
       
  2657   if (optimizeOutputForC) 
       
  2658   {
       
  2659     memLabel=theTranslator->trGlobal(TRUE,TRUE);
       
  2660   }
       
  2661   else if (fortranOpt)
       
  2662   {
       
  2663     memLabel=theTranslator->trSubprogram(TRUE,TRUE);
       
  2664   }
       
  2665   else
       
  2666   {
       
  2667     memLabel=theTranslator->trMember(TRUE,TRUE);
       
  2668   }
       
  2669   QCString memName = name();
       
  2670   Definition *pd=getOuterScope();
       
  2671   QCString memArgs;
       
  2672   if (!isRelated() 
       
  2673       /* && commented out as a result of bug 597016
       
  2674       (
       
  2675        (!hideScopeNames &&                    // there is a scope
       
  2676         pd && pd!=Doxygen::globalScope)       // and we can show it
       
  2677        ||
       
  2678        (pd=getClassDef())                     // it's a class so we
       
  2679                                               // show the scope anyway
       
  2680       )
       
  2681       */
       
  2682      )
       
  2683   {
       
  2684     if (isObjCMethod())
       
  2685     {
       
  2686       memName = "[" + pd->name() + " " + name() + "]";
       
  2687     }
       
  2688     else if (optimizeOutputJava)
       
  2689     {
       
  2690       if (!hideScopeNames) memName.prepend(pd->name()+".");
       
  2691       memArgs = argsString();
       
  2692     }
       
  2693     else
       
  2694     {
       
  2695       if (!hideScopeNames) memName.prepend(pd->name()+"::");
       
  2696       memArgs = argsString();
       
  2697     }
       
  2698   }
       
  2699   LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
       
  2700   if (xrefItems!=0)
       
  2701   {
       
  2702     addRefItem(xrefItems.pointer(),
       
  2703         qualifiedName(),
       
  2704         memLabel,
       
  2705         getOutputFileBase()+"#"+anchor(),memName,memArgs);
       
  2706   }
       
  2707 }
       
  2708 
       
  2709 MemberList *MemberDef::getSectionList(Definition *d) const 
       
  2710 { 
       
  2711   makeResident();
       
  2712   char key[20];
       
  2713   sprintf(key,"%p",d);
       
  2714   return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
       
  2715 }
       
  2716 
       
  2717 void MemberDef::setSectionList(Definition *d, MemberList *sl)   
       
  2718 { 
       
  2719   makeResident();
       
  2720   //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
       
  2721   char key[20];
       
  2722   sprintf(key,"%p",d);
       
  2723   if (m_impl->classSectionSDict==0) 
       
  2724   {
       
  2725     m_impl->classSectionSDict = new SDict<MemberList>(7);
       
  2726   }
       
  2727   m_impl->classSectionSDict->append(key,sl);
       
  2728 }
       
  2729 
       
  2730 Specifier MemberDef::virtualness(int count) const
       
  2731 {
       
  2732   if (count>25) 
       
  2733   {
       
  2734      warn(getDefFileName(),getDefLine(),
       
  2735        "Warning: Internal inconsistency: recursion detected in overload relation for member %s!"
       
  2736        ,name().data()
       
  2737       );
       
  2738      return Normal;
       
  2739   }
       
  2740   makeResident();
       
  2741   Specifier v = m_impl->virt;
       
  2742   MemberDef *rmd = reimplements();
       
  2743   while (rmd && v==Normal)
       
  2744   {
       
  2745     v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
       
  2746     rmd = rmd->reimplements();
       
  2747   }
       
  2748   return v;
       
  2749 }
       
  2750 
       
  2751 bool MemberDef::isConstructor() const            
       
  2752 { 
       
  2753   makeResident();
       
  2754   if (m_impl->classDef) 
       
  2755   {
       
  2756     if (m_impl->isDMember) // for D
       
  2757     {
       
  2758       return name()=="this";
       
  2759     }
       
  2760     else if (m_impl->fileDef && 
       
  2761              getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP)
       
  2762     {                // for PHP
       
  2763       return name()=="__construct";
       
  2764     }
       
  2765     else // for other languages
       
  2766     {
       
  2767       QCString locName = m_impl->classDef->localName();
       
  2768       int i=locName.find('<');
       
  2769       if (i==-1) // not a template class
       
  2770       {
       
  2771         return name()==locName;
       
  2772       }
       
  2773       else
       
  2774       {
       
  2775         return name()==locName.left(i);
       
  2776       }
       
  2777     }
       
  2778   }
       
  2779   else
       
  2780      return FALSE; 
       
  2781 }
       
  2782 
       
  2783 bool MemberDef::isDestructor() const
       
  2784 { 
       
  2785   makeResident();
       
  2786   if (m_impl->isDMember) // for D
       
  2787   {
       
  2788     return name()=="~this";
       
  2789   }
       
  2790   else if (m_impl->fileDef && 
       
  2791       getLanguageFromFileName(m_impl->fileDef->name())==SrcLangExt_PHP)
       
  2792   {                // for PHP
       
  2793     return name()=="__destruct";
       
  2794   }
       
  2795   else // other languages
       
  2796   {
       
  2797     return (name().find('~')!=-1 || name().find('!')!=-1)  // The ! is for C++/CLI
       
  2798            && name().find("operator")==-1; 
       
  2799   }
       
  2800 }
       
  2801 
       
  2802 void MemberDef::writeEnumDeclaration(OutputList &typeDecl,
       
  2803      ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
       
  2804 {
       
  2805   makeResident();
       
  2806   LockingPtr<MemberDef> lock(this,this);
       
  2807   int enumMemCount=0;
       
  2808 
       
  2809   QList<MemberDef> *fmdl=m_impl->enumFields;
       
  2810   uint numVisibleEnumValues=0;
       
  2811   if (fmdl)
       
  2812   {
       
  2813     MemberDef *fmd=fmdl->first();
       
  2814     while (fmd)
       
  2815     {
       
  2816       if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
       
  2817       fmd=fmdl->next();
       
  2818     }
       
  2819   }
       
  2820   if (numVisibleEnumValues==0 && !isBriefSectionVisible()) 
       
  2821   {
       
  2822     return;
       
  2823   }
       
  2824 
       
  2825   QCString n = name();
       
  2826   int i=n.findRev("::");
       
  2827   if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
       
  2828   if (n[0]!='@') // not an anonymous enum
       
  2829   {
       
  2830     if (isLinkableInProject() || hasDocumentedEnumValues())
       
  2831     {
       
  2832       if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !isReference())
       
  2833       {
       
  2834         Doxygen::tagFile << "    <member kind=\"enumeration\">" << endl;
       
  2835         Doxygen::tagFile << "      <name>" << convertToXML(name()) << "</name>" << endl; 
       
  2836         Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
       
  2837         Doxygen::tagFile << "      <anchor>" << convertToXML(anchor()) << "</anchor>" << endl; 
       
  2838         Doxygen::tagFile << "      <arglist>" << convertToXML(argsString()) << "</arglist>" << endl; 
       
  2839         Doxygen::tagFile << "    </member>" << endl;
       
  2840       }
       
  2841       writeLink(typeDecl,cd,nd,fd,gd);
       
  2842     }
       
  2843     else
       
  2844     {
       
  2845       typeDecl.startBold();
       
  2846       typeDecl.docify(n);
       
  2847       typeDecl.endBold();
       
  2848     }
       
  2849     typeDecl.writeChar(' ');
       
  2850   }
       
  2851 
       
  2852   if (numVisibleEnumValues>0)
       
  2853   {
       
  2854     uint enumValuesPerLine = (uint)Config_getInt("ENUM_VALUES_PER_LINE");
       
  2855     if (enumValuesPerLine==0) enumValuesPerLine=1;
       
  2856     typeDecl.docify("{ ");
       
  2857     if (fmdl)
       
  2858     {
       
  2859       MemberDef *fmd=fmdl->first();
       
  2860       bool fmdVisible = fmd->isBriefSectionVisible();
       
  2861       while (fmd)
       
  2862       {
       
  2863         if (fmdVisible)
       
  2864         {
       
  2865           /* in html we start a new line after a number of items */
       
  2866           if (numVisibleEnumValues>enumValuesPerLine
       
  2867               && (enumMemCount%enumValuesPerLine)==0
       
  2868              )
       
  2869           {
       
  2870             typeDecl.pushGeneratorState();
       
  2871             typeDecl.disableAllBut(OutputGenerator::Html);
       
  2872             typeDecl.enable(OutputGenerator::Latex);
       
  2873             typeDecl.lineBreak(); 
       
  2874             typeDecl.disable(OutputGenerator::Latex);
       
  2875             typeDecl.writeString("&nbsp;&nbsp;");
       
  2876             typeDecl.popGeneratorState();
       
  2877           }
       
  2878 
       
  2879           if (fmd->hasDocumentation()) // enum value has docs
       
  2880           {
       
  2881             if (!Config_getString("GENERATE_TAGFILE").isEmpty() && !fmd->isReference())
       
  2882             {
       
  2883               Doxygen::tagFile << "    <member kind=\"enumvalue\">" << endl;
       
  2884               Doxygen::tagFile << "      <name>" << convertToXML(fmd->name()) << "</name>" << endl; 
       
  2885               Doxygen::tagFile << "      <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;              
       
  2886               Doxygen::tagFile << "      <anchor>" << convertToXML(fmd->anchor()) << "</anchor>" << endl; 
       
  2887               Doxygen::tagFile << "      <arglist>" << convertToXML(fmd->argsString()) << "</arglist>" << endl; 
       
  2888               Doxygen::tagFile << "    </member>" << endl;
       
  2889             }
       
  2890             fmd->writeLink(typeDecl,cd,nd,fd,gd);
       
  2891           }
       
  2892           else // no docs for this enum value
       
  2893           {
       
  2894             typeDecl.startBold();
       
  2895             typeDecl.docify(fmd->name());
       
  2896             typeDecl.endBold();
       
  2897           }
       
  2898           if (fmd->hasOneLineInitializer()) // enum value has initializer
       
  2899           {
       
  2900             typeDecl.writeString(" = ");
       
  2901             typeDecl.parseText(fmd->initializer());
       
  2902           }
       
  2903         }
       
  2904 
       
  2905         bool prevVisible = fmdVisible;
       
  2906         fmd=fmdl->next();
       
  2907         if (fmd && (fmdVisible=fmd->isBriefSectionVisible())) 
       
  2908         {
       
  2909           typeDecl.writeString(", ");
       
  2910         }
       
  2911         if (prevVisible)
       
  2912         {
       
  2913           typeDecl.disable(OutputGenerator::Man);
       
  2914           typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
       
  2915           typeDecl.enable(OutputGenerator::Man);
       
  2916           enumMemCount++;
       
  2917         }
       
  2918       }
       
  2919       if (numVisibleEnumValues>enumValuesPerLine)
       
  2920       {
       
  2921         typeDecl.pushGeneratorState();
       
  2922         typeDecl.disableAllBut(OutputGenerator::Html);
       
  2923         typeDecl.lineBreak(); 
       
  2924         typeDecl.popGeneratorState();
       
  2925       }
       
  2926     }
       
  2927     typeDecl.docify(" }");
       
  2928   }
       
  2929 }
       
  2930 
       
  2931 void MemberDef::setArgumentList(ArgumentList *al) 
       
  2932 { 
       
  2933   makeResident();
       
  2934   if (m_impl->defArgList) delete m_impl->defArgList;
       
  2935   m_impl->defArgList = al;
       
  2936 }
       
  2937 
       
  2938 void MemberDef::setDeclArgumentList(ArgumentList *al)
       
  2939 {
       
  2940   makeResident();
       
  2941   if (m_impl->declArgList) delete m_impl->declArgList;
       
  2942   m_impl->declArgList = al;
       
  2943 }
       
  2944 
       
  2945 void MemberDef::setTypeConstraints(ArgumentList *al)
       
  2946 {
       
  2947   if (al==0) return;
       
  2948   makeResident();
       
  2949   if (m_impl->typeConstraints) delete m_impl->typeConstraints;
       
  2950   m_impl->typeConstraints = new ArgumentList;
       
  2951   m_impl->typeConstraints->setAutoDelete(TRUE);
       
  2952   ArgumentListIterator ali(*al);
       
  2953   Argument *a;
       
  2954   for (;(a=ali.current());++ali)
       
  2955   {
       
  2956     m_impl->typeConstraints->append(new Argument(*a));
       
  2957   }
       
  2958 }
       
  2959 
       
  2960 void MemberDef::findSectionsInDocumentation()
       
  2961 {
       
  2962   makeResident();
       
  2963   docFindSections(documentation(),this,0,docFile());  
       
  2964 }
       
  2965 
       
  2966 void MemberDef::enableCallGraph(bool e) 
       
  2967 { 
       
  2968   makeResident();
       
  2969   m_impl->hasCallGraph=e; 
       
  2970   if (e) Doxygen::parseSourcesNeeded = TRUE;
       
  2971 }
       
  2972 
       
  2973 void MemberDef::enableCallerGraph(bool e) 
       
  2974 { 
       
  2975   makeResident();
       
  2976   m_impl->hasCallerGraph=e; 
       
  2977   if (e) Doxygen::parseSourcesNeeded = TRUE;
       
  2978 }
       
  2979 
       
  2980 bool MemberDef::protectionVisible() const
       
  2981 {
       
  2982   makeResident();
       
  2983   return m_impl->prot==Public || 
       
  2984          (m_impl->prot==Private   && Config_getBool("EXTRACT_PRIVATE"))   ||
       
  2985          (m_impl->prot==Protected && Config_getBool("EXTRACT_PROTECTED")) ||
       
  2986          (m_impl->prot==Package   && Config_getBool("EXTRACT_PACKAGE"));
       
  2987 }
       
  2988 
       
  2989 #if 0
       
  2990 void MemberDef::setInbodyDocumentation(const char *docs,
       
  2991                   const char *docFile,int docLine)
       
  2992 {
       
  2993   makeResident();
       
  2994   m_impl->inbodyDocs = docs;
       
  2995   m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
       
  2996   m_impl->inbodyLine = docLine;
       
  2997   m_impl->inbodyFile = docFile;
       
  2998 }
       
  2999 #endif
       
  3000 
       
  3001 bool MemberDef::isObjCMethod() const
       
  3002 {
       
  3003   makeResident();
       
  3004   if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
       
  3005   return FALSE; 
       
  3006 }
       
  3007 
       
  3008 bool MemberDef::isObjCProperty() const
       
  3009 {
       
  3010   makeResident();
       
  3011   if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
       
  3012   return FALSE; 
       
  3013 }
       
  3014 
       
  3015 QCString MemberDef::qualifiedName() const
       
  3016 {
       
  3017   makeResident();
       
  3018   if (isObjCMethod())
       
  3019   {
       
  3020     QCString qm;
       
  3021     if (isStatic()) qm="+"; else qm="-";
       
  3022     qm+="[";
       
  3023     qm+=m_impl->classDef->name()+" ";
       
  3024     qm+=name();
       
  3025     qm+="]";
       
  3026     return qm;
       
  3027   }
       
  3028   else
       
  3029   {
       
  3030     return Definition::qualifiedName();
       
  3031   }  
       
  3032 }
       
  3033 
       
  3034 void MemberDef::setTagInfo(TagInfo *ti)
       
  3035 {
       
  3036   if (ti)
       
  3037   {
       
  3038     makeResident();
       
  3039     //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
       
  3040     m_impl->anc=ti->anchor;
       
  3041     setReference(ti->tagName);
       
  3042     m_impl->explicitOutputFileBase = stripExtension(ti->fileName);
       
  3043   }
       
  3044 }
       
  3045 
       
  3046 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
       
  3047 {
       
  3048   makeResident();
       
  3049   QCString qm;
       
  3050   if (showStatic)
       
  3051   {
       
  3052     if (isStatic()) qm="+ "; else qm="- ";
       
  3053   }
       
  3054   qm+=name();
       
  3055   if (!localLink) // link to method of same class
       
  3056   {
       
  3057     qm+=" (";
       
  3058     qm+=m_impl->classDef->name();
       
  3059     qm+=")";
       
  3060   }
       
  3061   return qm;
       
  3062 }
       
  3063 
       
  3064 const char *MemberDef::declaration() const
       
  3065 { 
       
  3066   makeResident();
       
  3067   return m_impl->decl; 
       
  3068 }
       
  3069 
       
  3070 const char *MemberDef::definition() const
       
  3071 { 
       
  3072   makeResident();
       
  3073   return m_impl->def;
       
  3074 }
       
  3075 
       
  3076 const char *MemberDef::extraTypeChars() const
       
  3077 {
       
  3078   makeResident();
       
  3079   return m_impl->extraTypeChars;
       
  3080 }
       
  3081 
       
  3082 const char *MemberDef::typeString() const
       
  3083 { 
       
  3084   makeResident();
       
  3085   return m_impl->type; 
       
  3086 }
       
  3087 
       
  3088 const char *MemberDef::argsString() const
       
  3089 { 
       
  3090   makeResident();
       
  3091   return m_impl->args; 
       
  3092 }
       
  3093 
       
  3094 const char *MemberDef::excpString() const
       
  3095 { 
       
  3096   makeResident();
       
  3097   return m_impl->exception; 
       
  3098 }
       
  3099 
       
  3100 const char *MemberDef::bitfieldString() const
       
  3101 { 
       
  3102   makeResident();
       
  3103   return m_impl->bitfields; 
       
  3104 }
       
  3105 
       
  3106 const QCString &MemberDef::initializer() const
       
  3107 { 
       
  3108   makeResident();
       
  3109   return m_impl->initializer; 
       
  3110 }
       
  3111 
       
  3112 int MemberDef::initializerLines() const
       
  3113 { 
       
  3114   makeResident();
       
  3115   return m_impl->initLines; 
       
  3116 }
       
  3117 
       
  3118 int  MemberDef::getMemberSpecifiers() const
       
  3119 { 
       
  3120   makeResident();
       
  3121   return m_impl->memSpec; 
       
  3122 }
       
  3123 
       
  3124 ClassDef *MemberDef::getClassDef() const
       
  3125 { 
       
  3126   makeResident();
       
  3127   return m_impl->classDef; 
       
  3128 }
       
  3129 
       
  3130 FileDef  *MemberDef::getFileDef() const
       
  3131 { 
       
  3132   makeResident();
       
  3133   return m_impl->fileDef; 
       
  3134 }
       
  3135 
       
  3136 NamespaceDef* MemberDef::getNamespaceDef() const
       
  3137 { 
       
  3138   makeResident();
       
  3139   return m_impl->nspace; 
       
  3140 }
       
  3141 
       
  3142 const char *MemberDef::getReadAccessor() const
       
  3143 { 
       
  3144   makeResident();
       
  3145   return m_impl->read; 
       
  3146 }
       
  3147 
       
  3148 const char *MemberDef::getWriteAccessor() const
       
  3149 { 
       
  3150   makeResident();
       
  3151   return m_impl->write; 
       
  3152 }
       
  3153 
       
  3154 GroupDef *MemberDef::getGroupDef() const
       
  3155 { 
       
  3156   makeResident();
       
  3157   return m_impl->group; 
       
  3158 }
       
  3159 
       
  3160 Grouping::GroupPri_t MemberDef::getGroupPri() const
       
  3161 { 
       
  3162   makeResident();
       
  3163   return m_impl->grouppri; 
       
  3164 }
       
  3165 
       
  3166 const char *MemberDef::getGroupFileName() const
       
  3167 { 
       
  3168   makeResident();
       
  3169   return m_impl->groupFileName; 
       
  3170 }
       
  3171 
       
  3172 int MemberDef::getGroupStartLine() const
       
  3173 { 
       
  3174   makeResident();
       
  3175   return m_impl->groupStartLine; 
       
  3176 }
       
  3177 
       
  3178 bool MemberDef::getGroupHasDocs() const
       
  3179 { 
       
  3180   makeResident();
       
  3181   return m_impl->groupHasDocs; 
       
  3182 }
       
  3183 
       
  3184 Protection MemberDef::protection() const
       
  3185 { 
       
  3186   makeResident();
       
  3187   return m_impl->prot; 
       
  3188 }
       
  3189 
       
  3190 MemberDef::MemberType MemberDef::memberType() const
       
  3191 { 
       
  3192   makeResident();
       
  3193   return m_impl->mtype; 
       
  3194 }
       
  3195 
       
  3196 bool MemberDef::isSignal() const
       
  3197 { 
       
  3198   makeResident();
       
  3199   return m_impl->mtype==Signal;      
       
  3200 }
       
  3201 
       
  3202 bool MemberDef::isSlot() const
       
  3203 { 
       
  3204   makeResident();
       
  3205   return m_impl->mtype==Slot;        
       
  3206 }
       
  3207 
       
  3208 bool MemberDef::isVariable() const
       
  3209 { 
       
  3210   makeResident();
       
  3211   return m_impl->mtype==Variable;    
       
  3212 }
       
  3213 
       
  3214 bool MemberDef::isEnumerate() const
       
  3215 { 
       
  3216   makeResident();
       
  3217   return m_impl->mtype==Enumeration; 
       
  3218 }
       
  3219 
       
  3220 bool MemberDef::isEnumValue() const
       
  3221 { 
       
  3222   makeResident();
       
  3223   return m_impl->mtype==EnumValue;   
       
  3224 }
       
  3225 
       
  3226 bool MemberDef::isTypedef() const
       
  3227 { 
       
  3228   makeResident();
       
  3229   return m_impl->mtype==Typedef;     
       
  3230 }
       
  3231 
       
  3232 bool MemberDef::isFunction() const
       
  3233 { 
       
  3234   makeResident();
       
  3235   return m_impl->mtype==Function;    
       
  3236 }
       
  3237 
       
  3238 bool MemberDef::isDefine() const
       
  3239 { 
       
  3240   makeResident();
       
  3241   return m_impl->mtype==Define;      
       
  3242 }
       
  3243 
       
  3244 bool MemberDef::isFriend() const
       
  3245 { 
       
  3246   makeResident();
       
  3247   return m_impl->mtype==Friend;      
       
  3248 }
       
  3249 
       
  3250 bool MemberDef::isDCOP() const
       
  3251 { 
       
  3252   makeResident();
       
  3253   return m_impl->mtype==DCOP;        
       
  3254 }
       
  3255 
       
  3256 bool MemberDef::isProperty() const
       
  3257 { 
       
  3258   makeResident();
       
  3259   return m_impl->mtype==Property;    
       
  3260 }
       
  3261 
       
  3262 bool MemberDef::isEvent() const
       
  3263 { 
       
  3264   makeResident();
       
  3265   return m_impl->mtype==Event;       
       
  3266 }
       
  3267 
       
  3268 bool MemberDef::isRelated() const
       
  3269 { 
       
  3270   makeResident();
       
  3271   return m_impl->related == Related;
       
  3272 }
       
  3273 
       
  3274 bool MemberDef::isForeign() const
       
  3275 { 
       
  3276   makeResident();
       
  3277   return m_impl->related == Foreign; 
       
  3278 }
       
  3279 
       
  3280 bool MemberDef::isStatic() const
       
  3281 { 
       
  3282   makeResident();
       
  3283   return m_impl->stat; 
       
  3284 }
       
  3285 
       
  3286 bool MemberDef::isInline() const
       
  3287 { 
       
  3288   makeResident();
       
  3289   return (m_impl->memSpec&Entry::Inline)!=0; 
       
  3290 }
       
  3291 
       
  3292 bool MemberDef::isExplicit() const
       
  3293 { 
       
  3294   makeResident();
       
  3295   return (m_impl->memSpec&Entry::Explicit)!=0; 
       
  3296 }
       
  3297 
       
  3298 bool MemberDef::isMutable() const
       
  3299 { 
       
  3300   makeResident();
       
  3301   return (m_impl->memSpec&Entry::Mutable)!=0; 
       
  3302 }
       
  3303 
       
  3304 bool MemberDef::isGettable() const
       
  3305 { 
       
  3306   makeResident();
       
  3307   return (m_impl->memSpec&Entry::Gettable)!=0; 
       
  3308 }
       
  3309 
       
  3310 bool MemberDef::isSettable() const
       
  3311 { 
       
  3312   makeResident();
       
  3313   return (m_impl->memSpec&Entry::Settable)!=0; 
       
  3314 }
       
  3315 
       
  3316 bool MemberDef::isAddable() const
       
  3317 { 
       
  3318   makeResident();
       
  3319   return (m_impl->memSpec&Entry::Addable)!=0; 
       
  3320 }
       
  3321 
       
  3322 bool MemberDef::isRemovable() const
       
  3323 { 
       
  3324   makeResident();
       
  3325   return (m_impl->memSpec&Entry::Removable)!=0; 
       
  3326 }
       
  3327 
       
  3328 bool MemberDef::isRaisable() const
       
  3329 { 
       
  3330   makeResident();
       
  3331   return (m_impl->memSpec&Entry::Raisable)!=0; 
       
  3332 }
       
  3333 
       
  3334 bool MemberDef::isReadable() const
       
  3335 { 
       
  3336   makeResident();
       
  3337   return (m_impl->memSpec&Entry::Readable)!=0; 
       
  3338 }
       
  3339 
       
  3340 bool MemberDef::isWritable() const
       
  3341 { 
       
  3342   makeResident();
       
  3343   return (m_impl->memSpec&Entry::Writable)!=0; 
       
  3344 }
       
  3345 
       
  3346 bool MemberDef::isFinal() const
       
  3347 { 
       
  3348   makeResident();
       
  3349   return (m_impl->memSpec&Entry::Final)!=0; 
       
  3350 }
       
  3351 
       
  3352 bool MemberDef::isNew() const
       
  3353 { 
       
  3354   makeResident();
       
  3355   return (m_impl->memSpec&Entry::New)!=0; 
       
  3356 }
       
  3357 
       
  3358 bool MemberDef::isSealed() const
       
  3359 { 
       
  3360   makeResident();
       
  3361   return (m_impl->memSpec&Entry::Sealed)!=0; 
       
  3362 }
       
  3363 
       
  3364 bool MemberDef::isOverride() const
       
  3365 { 
       
  3366   makeResident();
       
  3367   return (m_impl->memSpec&Entry::Override)!=0; 
       
  3368 }
       
  3369 
       
  3370 bool MemberDef::isInitonly() const
       
  3371 { 
       
  3372   makeResident();
       
  3373   return (m_impl->memSpec&Entry::Initonly)!=0; 
       
  3374 }
       
  3375 
       
  3376 bool MemberDef::isAbstract() const
       
  3377 { 
       
  3378   makeResident();
       
  3379   return (m_impl->memSpec&Entry::Abstract)!=0; 
       
  3380 }
       
  3381 
       
  3382 bool MemberDef::isOptional() const
       
  3383 { 
       
  3384   makeResident();
       
  3385   return (m_impl->memSpec&Entry::Optional)!=0; 
       
  3386 }
       
  3387 
       
  3388 bool MemberDef::isRequired() const
       
  3389 { 
       
  3390   makeResident();
       
  3391   return (m_impl->memSpec&Entry::Required)!=0; 
       
  3392 }
       
  3393 
       
  3394 bool MemberDef::isNonAtomic() const
       
  3395 { 
       
  3396   makeResident();
       
  3397   return (m_impl->memSpec&Entry::NonAtomic)!=0; 
       
  3398 }
       
  3399 
       
  3400 bool MemberDef::isCopy() const
       
  3401 { 
       
  3402   makeResident();
       
  3403   return (m_impl->memSpec&Entry::Copy)!=0; 
       
  3404 }
       
  3405 
       
  3406 bool MemberDef::isAssign() const
       
  3407 { 
       
  3408   makeResident();
       
  3409   return (m_impl->memSpec&Entry::Assign)!=0; 
       
  3410 }
       
  3411 
       
  3412 bool MemberDef::isRetain() const
       
  3413 { 
       
  3414   makeResident();
       
  3415   return (m_impl->memSpec&Entry::Retain)!=0; 
       
  3416 }
       
  3417 
       
  3418 
       
  3419 bool MemberDef::isImplementation() const
       
  3420 { 
       
  3421   makeResident();
       
  3422   return m_impl->implOnly; 
       
  3423 }
       
  3424 
       
  3425 bool MemberDef::isExternal() const
       
  3426 { 
       
  3427   makeResident();
       
  3428   return m_impl->explExt; 
       
  3429 }
       
  3430 
       
  3431 bool MemberDef::isTemplateSpecialization() const
       
  3432 { 
       
  3433   makeResident();
       
  3434   return m_impl->tspec; 
       
  3435 }
       
  3436 
       
  3437 bool MemberDef::hasDocumentedParams() const
       
  3438 { 
       
  3439   makeResident();
       
  3440   return m_impl->hasDocumentedParams; 
       
  3441 }
       
  3442 
       
  3443 bool MemberDef::hasDocumentedReturnType() const
       
  3444 { 
       
  3445   makeResident();
       
  3446   return m_impl->hasDocumentedReturnType; 
       
  3447 }
       
  3448 
       
  3449 #if 0
       
  3450 int MemberDef::inbodyLine() const
       
  3451 { 
       
  3452   makeResident();
       
  3453   return m_impl->inbodyLine; 
       
  3454 }
       
  3455 
       
  3456 QCString MemberDef::inbodyFile() const
       
  3457 { 
       
  3458   makeResident();
       
  3459   return m_impl->inbodyFile; 
       
  3460 }
       
  3461 
       
  3462 const QCString &MemberDef::inbodyDocumentation() const
       
  3463 { 
       
  3464   makeResident();
       
  3465   return m_impl->inbodyDocs; 
       
  3466 }
       
  3467 #endif
       
  3468 
       
  3469 ClassDef *MemberDef::relatedAlso() const
       
  3470 { 
       
  3471   makeResident();
       
  3472   return m_impl->relatedAlso; 
       
  3473 }
       
  3474 
       
  3475 bool MemberDef::hasDocumentedEnumValues() const
       
  3476 { 
       
  3477   makeResident();
       
  3478   return m_impl->docEnumValues; 
       
  3479 }
       
  3480 
       
  3481 MemberDef *MemberDef::getAnonymousEnumType() const
       
  3482 { 
       
  3483   makeResident();
       
  3484   return m_impl->annEnumType; 
       
  3485 }
       
  3486 
       
  3487 bool MemberDef::isDocsForDefinition() const
       
  3488 { 
       
  3489   makeResident();
       
  3490   return m_impl->docsForDefinition; 
       
  3491 }
       
  3492 
       
  3493 MemberDef *MemberDef::getEnumScope() const
       
  3494 { 
       
  3495   makeResident();
       
  3496   return m_impl->enumScope; 
       
  3497 }
       
  3498 
       
  3499 LockingPtr<MemberList> MemberDef::enumFieldList() const
       
  3500 { 
       
  3501   makeResident();
       
  3502   return LockingPtr<MemberList>(this,m_impl->enumFields); 
       
  3503 }
       
  3504 
       
  3505 LockingPtr<ExampleSDict> MemberDef::getExamples() const
       
  3506 { 
       
  3507   makeResident();
       
  3508   return LockingPtr<ExampleSDict>(this,m_impl->exampleSDict); 
       
  3509 }
       
  3510 
       
  3511 bool MemberDef::isPrototype() const
       
  3512 { 
       
  3513   makeResident();
       
  3514   return m_impl->proto; 
       
  3515 }
       
  3516 
       
  3517 LockingPtr<ArgumentList> MemberDef::argumentList() const
       
  3518 { 
       
  3519   makeResident();
       
  3520   return LockingPtr<ArgumentList>(this,m_impl->defArgList); 
       
  3521 }
       
  3522 
       
  3523 LockingPtr<ArgumentList> MemberDef::declArgumentList() const
       
  3524 { 
       
  3525   makeResident();
       
  3526   return LockingPtr<ArgumentList>(this,m_impl->declArgList); 
       
  3527 }
       
  3528 
       
  3529 LockingPtr<ArgumentList> MemberDef::templateArguments() const
       
  3530 { 
       
  3531   makeResident();
       
  3532   return LockingPtr<ArgumentList>(this,m_impl->tArgList); 
       
  3533 }
       
  3534 
       
  3535 LockingPtr< QList<ArgumentList> > MemberDef::definitionTemplateParameterLists() const
       
  3536 { 
       
  3537   makeResident();
       
  3538   return LockingPtr< QList<ArgumentList> >(this,m_impl->defTmpArgLists); 
       
  3539 }
       
  3540 
       
  3541 int MemberDef::getMemberGroupId() const
       
  3542 { 
       
  3543   makeResident();
       
  3544   return m_impl->grpId; 
       
  3545 }
       
  3546 
       
  3547 MemberGroup *MemberDef::getMemberGroup() const
       
  3548 { 
       
  3549   makeResident();
       
  3550   return m_impl->memberGroup; 
       
  3551 }
       
  3552 
       
  3553 bool MemberDef::fromAnonymousScope() const
       
  3554 { 
       
  3555   makeResident();
       
  3556   return m_impl->annScope; 
       
  3557 }
       
  3558 
       
  3559 bool MemberDef::anonymousDeclShown() const
       
  3560 { 
       
  3561   makeResident();
       
  3562   return m_impl->annUsed; 
       
  3563 }
       
  3564 
       
  3565 void MemberDef::setAnonymousUsed() 
       
  3566 {
       
  3567   makeResident();
       
  3568   m_impl->annUsed = TRUE;
       
  3569 }
       
  3570 
       
  3571 bool MemberDef::hasCallGraph() const
       
  3572 { 
       
  3573   makeResident();
       
  3574   return m_impl->hasCallGraph; 
       
  3575 }
       
  3576 
       
  3577 bool MemberDef::hasCallerGraph() const
       
  3578 { 
       
  3579   makeResident();
       
  3580   return m_impl->hasCallerGraph; 
       
  3581 }
       
  3582 
       
  3583 MemberDef *MemberDef::templateMaster() const
       
  3584 { 
       
  3585   makeResident();
       
  3586   return m_impl->templateMaster; 
       
  3587 }
       
  3588 
       
  3589 bool MemberDef::isTypedefValCached() const
       
  3590 { 
       
  3591   makeResident();
       
  3592   return m_impl->isTypedefValCached; 
       
  3593 }
       
  3594 
       
  3595 ClassDef *MemberDef::getCachedTypedefVal() const
       
  3596 { 
       
  3597   makeResident();
       
  3598   return m_impl->cachedTypedefValue; 
       
  3599 }
       
  3600 
       
  3601 QCString MemberDef::getCachedTypedefTemplSpec() const
       
  3602 { 
       
  3603   makeResident();
       
  3604   return m_impl->cachedTypedefTemplSpec; 
       
  3605 }
       
  3606 
       
  3607 QCString MemberDef::getCachedResolvedTypedef() const
       
  3608 { 
       
  3609   makeResident();
       
  3610   //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
       
  3611   return m_impl->cachedResolvedType; 
       
  3612 }
       
  3613 
       
  3614 MemberDef *MemberDef::memberDefinition() const
       
  3615 { 
       
  3616   makeResident();
       
  3617   return m_impl->memDef; 
       
  3618 }
       
  3619 
       
  3620 MemberDef *MemberDef::memberDeclaration() const
       
  3621 { 
       
  3622   makeResident();
       
  3623   return m_impl->memDec; 
       
  3624 }
       
  3625 
       
  3626 MemberDef *MemberDef::inheritsDocsFrom() const
       
  3627 { 
       
  3628   makeResident();
       
  3629   return m_impl->docProvider; 
       
  3630 }
       
  3631 
       
  3632 MemberDef *MemberDef::getGroupAlias() const
       
  3633 { 
       
  3634   makeResident();
       
  3635   return m_impl->groupAlias; 
       
  3636 }
       
  3637 
       
  3638 void MemberDef::setMemberType(MemberType t)
       
  3639 { 
       
  3640   makeResident();
       
  3641   m_impl->mtype=t; 
       
  3642 }
       
  3643 
       
  3644 void MemberDef::setDefinition(const char *d)
       
  3645 { 
       
  3646   makeResident();
       
  3647   m_impl->def=d; 
       
  3648 }
       
  3649 
       
  3650 void MemberDef::setFileDef(FileDef *fd)
       
  3651 { 
       
  3652   makeResident();
       
  3653   m_impl->fileDef=fd; 
       
  3654 }
       
  3655 
       
  3656 void MemberDef::setProtection(Protection p)
       
  3657 { 
       
  3658   makeResident();
       
  3659   m_impl->prot=p; 
       
  3660 }
       
  3661 
       
  3662 void MemberDef::setMemberSpecifiers(int s)
       
  3663 { 
       
  3664   makeResident();
       
  3665   m_impl->memSpec=s; 
       
  3666 }
       
  3667 
       
  3668 void MemberDef::mergeMemberSpecifiers(int s)
       
  3669 { 
       
  3670   makeResident();
       
  3671   m_impl->memSpec|=s; 
       
  3672 }
       
  3673 
       
  3674 void MemberDef::setBitfields(const char *s)
       
  3675 { 
       
  3676   makeResident();
       
  3677   m_impl->bitfields = s; 
       
  3678 }
       
  3679 
       
  3680 void MemberDef::setMaxInitLines(int lines)
       
  3681 { 
       
  3682   if (lines!=-1)
       
  3683   {
       
  3684     makeResident();
       
  3685     m_impl->userInitLines=lines; 
       
  3686   }
       
  3687 }
       
  3688 
       
  3689 void MemberDef::setExplicitExternal(bool b)
       
  3690 { 
       
  3691   makeResident();
       
  3692   m_impl->explExt=b; 
       
  3693 }
       
  3694 
       
  3695 void MemberDef::setReadAccessor(const char *r)
       
  3696 { 
       
  3697   makeResident();
       
  3698   m_impl->read=r; 
       
  3699 }
       
  3700 
       
  3701 void MemberDef::setWriteAccessor(const char *w)
       
  3702 { 
       
  3703   makeResident();
       
  3704   m_impl->write=w; 
       
  3705 }
       
  3706 
       
  3707 void MemberDef::setTemplateSpecialization(bool b)
       
  3708 { 
       
  3709   makeResident();
       
  3710   m_impl->tspec=b; 
       
  3711 }
       
  3712 
       
  3713 void MemberDef::makeRelated()
       
  3714 { 
       
  3715   makeResident();
       
  3716   m_impl->related = Related; 
       
  3717 }
       
  3718 
       
  3719 void MemberDef::makeForeign()
       
  3720 { 
       
  3721   makeResident();
       
  3722   m_impl->related = Foreign; 
       
  3723 }
       
  3724 
       
  3725 void MemberDef::setHasDocumentedParams(bool b)
       
  3726 { 
       
  3727   makeResident();
       
  3728   m_impl->hasDocumentedParams = b; 
       
  3729 }
       
  3730 
       
  3731 void MemberDef::setHasDocumentedReturnType(bool b)
       
  3732 { 
       
  3733   makeResident();
       
  3734   m_impl->hasDocumentedReturnType = b; 
       
  3735 }
       
  3736 
       
  3737 void MemberDef::setInheritsDocsFrom(MemberDef *md)
       
  3738 { 
       
  3739   makeResident();
       
  3740   m_impl->docProvider = md; 
       
  3741 }
       
  3742 
       
  3743 void MemberDef::setArgsString(const char *as)
       
  3744 { 
       
  3745   makeResident();
       
  3746   m_impl->args = as; 
       
  3747 }
       
  3748 
       
  3749 void MemberDef::setRelatedAlso(ClassDef *cd)
       
  3750 { 
       
  3751   makeResident();
       
  3752   m_impl->relatedAlso=cd; 
       
  3753 }
       
  3754 
       
  3755 void MemberDef::setEnumClassScope(ClassDef *cd)
       
  3756 { 
       
  3757   makeResident();
       
  3758   m_impl->classDef = cd; 
       
  3759 }
       
  3760 
       
  3761 void MemberDef::setDocumentedEnumValues(bool value)
       
  3762 { 
       
  3763   makeResident();
       
  3764   m_impl->docEnumValues=value; 
       
  3765 }
       
  3766 
       
  3767 void MemberDef::setAnonymousEnumType(MemberDef *md)
       
  3768 { 
       
  3769   makeResident();
       
  3770   m_impl->annEnumType = md; 
       
  3771 }
       
  3772 
       
  3773 void MemberDef::setPrototype(bool p)
       
  3774 { 
       
  3775   makeResident();
       
  3776   m_impl->proto=p; 
       
  3777 }
       
  3778 
       
  3779 void MemberDef::setMemberGroupId(int id)
       
  3780 { 
       
  3781   makeResident();
       
  3782   m_impl->grpId=id; 
       
  3783 }
       
  3784 
       
  3785 void MemberDef::makeImplementationDetail()
       
  3786 { 
       
  3787   makeResident();
       
  3788   m_impl->implOnly=TRUE; 
       
  3789 }
       
  3790 
       
  3791 void MemberDef::setFromAnonymousScope(bool b)
       
  3792 { 
       
  3793   makeResident();
       
  3794   m_impl->annScope=b; 
       
  3795 }
       
  3796 
       
  3797 void MemberDef::setFromAnonymousMember(MemberDef *m)
       
  3798 { 
       
  3799   makeResident();
       
  3800   m_impl->annMemb=m; 
       
  3801 }
       
  3802 
       
  3803 void MemberDef::setTemplateMaster(MemberDef *mt)
       
  3804 { 
       
  3805   makeResident();
       
  3806   m_impl->templateMaster=mt; 
       
  3807 }
       
  3808 
       
  3809 void MemberDef::setDocsForDefinition(bool b)
       
  3810 { 
       
  3811   makeResident();
       
  3812   m_impl->docsForDefinition = b; 
       
  3813 }
       
  3814 
       
  3815 void MemberDef::setGroupAlias(MemberDef *md)
       
  3816 { 
       
  3817   makeResident();
       
  3818   m_impl->groupAlias = md; 
       
  3819 }
       
  3820 
       
  3821 void MemberDef::invalidateTypedefValCache()
       
  3822 { 
       
  3823   makeResident();
       
  3824   m_impl->isTypedefValCached=FALSE; 
       
  3825 }
       
  3826 
       
  3827 void MemberDef::setMemberDefinition(MemberDef *md)
       
  3828 { 
       
  3829   makeResident();
       
  3830   m_impl->memDef=md; 
       
  3831 }
       
  3832 
       
  3833 void MemberDef::setMemberDeclaration(MemberDef *md)
       
  3834 { 
       
  3835   makeResident();
       
  3836   m_impl->memDec=md; 
       
  3837 }
       
  3838 
       
  3839 ClassDef *MemberDef::category() const
       
  3840 {
       
  3841   makeResident();
       
  3842   return m_impl->category;
       
  3843 }
       
  3844 
       
  3845 void MemberDef::setCategory(ClassDef *def)
       
  3846 {
       
  3847   makeResident();
       
  3848   m_impl->category = def;
       
  3849 }
       
  3850 
       
  3851 
       
  3852 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
       
  3853 {
       
  3854   makeResident();
       
  3855   m_impl->isTypedefValCached=TRUE; 
       
  3856   m_impl->cachedTypedefValue=val; 
       
  3857   m_impl->cachedTypedefTemplSpec=templSpec; 
       
  3858   m_impl->cachedResolvedType=resolvedType;
       
  3859   //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
       
  3860 }
       
  3861 
       
  3862 void MemberDef::flushToDisk() const
       
  3863 {
       
  3864   if (isLocked()) return;
       
  3865   MemberDef *that = (MemberDef*)this;
       
  3866   that->m_storagePos = Doxygen::symbolStorage->alloc();
       
  3867   //printf("%p: MemberDef::flushToDisk()\n",this);
       
  3868   // write the definition base class member variables to disk
       
  3869   Definition::flushToDisk();
       
  3870 
       
  3871   //printf("%p:   flushing specific part\n",this);
       
  3872 
       
  3873   // write the memberdef member variables to disk
       
  3874   marshalUInt(Doxygen::symbolStorage,START_MARKER);
       
  3875   marshalObjPointer   (Doxygen::symbolStorage,m_impl->classDef);
       
  3876   marshalObjPointer   (Doxygen::symbolStorage,m_impl->fileDef);
       
  3877   marshalObjPointer   (Doxygen::symbolStorage,m_impl->nspace);
       
  3878   marshalObjPointer   (Doxygen::symbolStorage,m_impl->enumScope);
       
  3879   marshalObjPointer   (Doxygen::symbolStorage,m_impl->annEnumType);
       
  3880   marshalMemberList   (Doxygen::symbolStorage,m_impl->enumFields);
       
  3881   marshalObjPointer   (Doxygen::symbolStorage,m_impl->redefines);
       
  3882   marshalMemberList   (Doxygen::symbolStorage,m_impl->redefinedBy);
       
  3883   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memDef);
       
  3884   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memDec);
       
  3885   marshalObjPointer   (Doxygen::symbolStorage,m_impl->relatedAlso);
       
  3886   marshalExampleSDict (Doxygen::symbolStorage,m_impl->exampleSDict);
       
  3887   marshalQCString     (Doxygen::symbolStorage,m_impl->type);
       
  3888   marshalQCString     (Doxygen::symbolStorage,m_impl->args);
       
  3889   marshalQCString     (Doxygen::symbolStorage,m_impl->def);
       
  3890   marshalQCString     (Doxygen::symbolStorage,m_impl->anc);
       
  3891   marshalInt          (Doxygen::symbolStorage,(int)m_impl->virt);
       
  3892   marshalInt          (Doxygen::symbolStorage,(int)m_impl->prot);
       
  3893   marshalQCString     (Doxygen::symbolStorage,m_impl->decl);
       
  3894   marshalQCString     (Doxygen::symbolStorage,m_impl->bitfields);
       
  3895   marshalQCString     (Doxygen::symbolStorage,m_impl->read);
       
  3896   marshalQCString     (Doxygen::symbolStorage,m_impl->write);
       
  3897   marshalQCString     (Doxygen::symbolStorage,m_impl->exception);
       
  3898   marshalQCString     (Doxygen::symbolStorage,m_impl->initializer);
       
  3899   marshalQCString     (Doxygen::symbolStorage,m_impl->extraTypeChars);
       
  3900   marshalInt          (Doxygen::symbolStorage,m_impl->initLines);
       
  3901   marshalInt          (Doxygen::symbolStorage,m_impl->memSpec);
       
  3902   marshalInt          (Doxygen::symbolStorage,(int)m_impl->mtype);
       
  3903   marshalInt          (Doxygen::symbolStorage,m_impl->maxInitLines);
       
  3904   marshalInt          (Doxygen::symbolStorage,m_impl->userInitLines);
       
  3905   marshalObjPointer   (Doxygen::symbolStorage,m_impl->annMemb);
       
  3906   marshalArgumentList (Doxygen::symbolStorage,m_impl->defArgList);
       
  3907   marshalArgumentList (Doxygen::symbolStorage,m_impl->declArgList);
       
  3908   marshalArgumentList (Doxygen::symbolStorage,m_impl->tArgList);
       
  3909   marshalArgumentList (Doxygen::symbolStorage,m_impl->typeConstraints);
       
  3910   marshalObjPointer   (Doxygen::symbolStorage,m_impl->templateMaster);
       
  3911   marshalArgumentLists(Doxygen::symbolStorage,m_impl->defTmpArgLists);
       
  3912   marshalObjPointer   (Doxygen::symbolStorage,m_impl->cachedAnonymousType);
       
  3913   marshalMemberLists  (Doxygen::symbolStorage,m_impl->classSectionSDict);
       
  3914   marshalObjPointer   (Doxygen::symbolStorage,m_impl->groupAlias);
       
  3915   marshalInt          (Doxygen::symbolStorage,m_impl->grpId);
       
  3916   marshalObjPointer   (Doxygen::symbolStorage,m_impl->memberGroup);
       
  3917   marshalObjPointer   (Doxygen::symbolStorage,m_impl->group);
       
  3918   marshalInt          (Doxygen::symbolStorage,(int)m_impl->grouppri);
       
  3919   marshalQCString     (Doxygen::symbolStorage,m_impl->groupFileName);
       
  3920   marshalInt          (Doxygen::symbolStorage,m_impl->groupStartLine);
       
  3921   marshalObjPointer   (Doxygen::symbolStorage,m_impl->groupMember);
       
  3922   marshalBool         (Doxygen::symbolStorage,m_impl->isTypedefValCached);
       
  3923   marshalObjPointer   (Doxygen::symbolStorage,m_impl->cachedTypedefValue);
       
  3924   marshalQCString     (Doxygen::symbolStorage,m_impl->cachedTypedefTemplSpec);
       
  3925   marshalQCString     (Doxygen::symbolStorage,m_impl->cachedResolvedType);
       
  3926   marshalObjPointer   (Doxygen::symbolStorage,m_impl->docProvider);
       
  3927   marshalQCString     (Doxygen::symbolStorage,m_impl->explicitOutputFileBase);
       
  3928   marshalBool         (Doxygen::symbolStorage,m_impl->implOnly); 
       
  3929   marshalBool         (Doxygen::symbolStorage,m_impl->hasDocumentedParams);
       
  3930   marshalBool         (Doxygen::symbolStorage,m_impl->hasDocumentedReturnType);
       
  3931   marshalBool         (Doxygen::symbolStorage,m_impl->isDMember);
       
  3932   marshalInt          (Doxygen::symbolStorage,(int)m_impl->related);
       
  3933   marshalBool         (Doxygen::symbolStorage,m_impl->stat);
       
  3934   marshalBool         (Doxygen::symbolStorage,m_impl->proto);
       
  3935   marshalBool         (Doxygen::symbolStorage,m_impl->docEnumValues);
       
  3936   marshalBool         (Doxygen::symbolStorage,m_impl->annScope);
       
  3937   marshalBool         (Doxygen::symbolStorage,m_impl->annUsed);
       
  3938   marshalBool         (Doxygen::symbolStorage,m_impl->hasCallGraph);
       
  3939   marshalBool         (Doxygen::symbolStorage,m_impl->hasCallerGraph);
       
  3940   marshalBool         (Doxygen::symbolStorage,m_impl->explExt);
       
  3941   marshalBool         (Doxygen::symbolStorage,m_impl->tspec);
       
  3942   marshalBool         (Doxygen::symbolStorage,m_impl->groupHasDocs);
       
  3943   marshalBool         (Doxygen::symbolStorage,m_impl->docsForDefinition);
       
  3944   marshalObjPointer   (Doxygen::symbolStorage,m_impl->category);
       
  3945   marshalUInt(Doxygen::symbolStorage,END_MARKER);
       
  3946 
       
  3947   // function doesn't modify the object conceptually but compiler doesn't know this.
       
  3948   delete that->m_impl;
       
  3949   that->m_impl=0;
       
  3950   that->m_flushPending=FALSE;
       
  3951 }
       
  3952 
       
  3953 void MemberDef::loadFromDisk() const
       
  3954 {
       
  3955   //printf("%p: MemberDef::loadFromDisk()\n",this);
       
  3956   MemberDef *that = (MemberDef *)this;
       
  3957   if (isLocked()) 
       
  3958   {
       
  3959     assert(m_impl!=0);
       
  3960     return;
       
  3961   }
       
  3962   assert(m_impl==0);
       
  3963 
       
  3964   Doxygen::symbolStorage->seek(m_storagePos);
       
  3965   Definition::loadFromDisk();
       
  3966 
       
  3967   //printf("%p:   loading specific part\n",this);
       
  3968 
       
  3969   that->m_impl = new MemberDefImpl;
       
  3970 
       
  3971   uint marker = unmarshalUInt(Doxygen::symbolStorage);
       
  3972   assert(marker==START_MARKER);
       
  3973   m_impl->classDef                = (ClassDef*)unmarshalObjPointer     (Doxygen::symbolStorage);
       
  3974   m_impl->fileDef                 = (FileDef*)unmarshalObjPointer      (Doxygen::symbolStorage);
       
  3975   m_impl->nspace                  = (NamespaceDef*)unmarshalObjPointer (Doxygen::symbolStorage);
       
  3976   m_impl->enumScope               = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
       
  3977   m_impl->annEnumType             = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
       
  3978   m_impl->enumFields              = unmarshalMemberList                (Doxygen::symbolStorage);
       
  3979   m_impl->redefines               = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
       
  3980   m_impl->redefinedBy             = unmarshalMemberList                (Doxygen::symbolStorage);
       
  3981   m_impl->memDef                  = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
       
  3982   m_impl->memDec                  = (MemberDef*)unmarshalObjPointer    (Doxygen::symbolStorage);
       
  3983   m_impl->relatedAlso             = (ClassDef*)unmarshalObjPointer     (Doxygen::symbolStorage);
       
  3984   m_impl->exampleSDict            = unmarshalExampleSDict (Doxygen::symbolStorage);
       
  3985   m_impl->type                    = unmarshalQCString     (Doxygen::symbolStorage);
       
  3986   m_impl->args                    = unmarshalQCString     (Doxygen::symbolStorage);
       
  3987   m_impl->def                     = unmarshalQCString     (Doxygen::symbolStorage);
       
  3988   m_impl->anc                     = unmarshalQCString     (Doxygen::symbolStorage);
       
  3989   m_impl->virt                    = (Specifier)unmarshalInt (Doxygen::symbolStorage);
       
  3990   m_impl->prot                    = (Protection)unmarshalInt(Doxygen::symbolStorage);
       
  3991   m_impl->decl                    = unmarshalQCString     (Doxygen::symbolStorage);
       
  3992   m_impl->bitfields               = unmarshalQCString     (Doxygen::symbolStorage);
       
  3993   m_impl->read                    = unmarshalQCString     (Doxygen::symbolStorage);
       
  3994   m_impl->write                   = unmarshalQCString     (Doxygen::symbolStorage);
       
  3995   m_impl->exception               = unmarshalQCString     (Doxygen::symbolStorage);
       
  3996   m_impl->initializer             = unmarshalQCString     (Doxygen::symbolStorage);
       
  3997   m_impl->extraTypeChars          = unmarshalQCString     (Doxygen::symbolStorage);
       
  3998   m_impl->initLines               = unmarshalInt          (Doxygen::symbolStorage);
       
  3999   m_impl->memSpec                 = unmarshalInt          (Doxygen::symbolStorage);
       
  4000   m_impl->mtype                   = (MemberDef::MemberType)unmarshalInt          (Doxygen::symbolStorage);
       
  4001   m_impl->maxInitLines            = unmarshalInt          (Doxygen::symbolStorage);
       
  4002   m_impl->userInitLines           = unmarshalInt          (Doxygen::symbolStorage);
       
  4003   m_impl->annMemb                 = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4004   m_impl->defArgList              = unmarshalArgumentList (Doxygen::symbolStorage);
       
  4005   m_impl->declArgList             = unmarshalArgumentList (Doxygen::symbolStorage);
       
  4006   m_impl->tArgList                = unmarshalArgumentList (Doxygen::symbolStorage);
       
  4007   m_impl->typeConstraints         = unmarshalArgumentList (Doxygen::symbolStorage);
       
  4008   m_impl->templateMaster          = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4009   m_impl->defTmpArgLists          = unmarshalArgumentLists(Doxygen::symbolStorage);
       
  4010   m_impl->cachedAnonymousType     = (ClassDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4011   m_impl->classSectionSDict       = unmarshalMemberLists  (Doxygen::symbolStorage);
       
  4012   m_impl->groupAlias              = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4013   m_impl->grpId                   = unmarshalInt          (Doxygen::symbolStorage);
       
  4014   m_impl->memberGroup             = (MemberGroup*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4015   m_impl->group                   = (GroupDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4016   m_impl->grouppri                = (Grouping::GroupPri_t)unmarshalInt          (Doxygen::symbolStorage);
       
  4017   m_impl->groupFileName           = unmarshalQCString     (Doxygen::symbolStorage);
       
  4018   m_impl->groupStartLine          = unmarshalInt          (Doxygen::symbolStorage);
       
  4019   m_impl->groupMember             = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4020   m_impl->isTypedefValCached      = unmarshalBool         (Doxygen::symbolStorage);
       
  4021   m_impl->cachedTypedefValue      = (ClassDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4022   m_impl->cachedTypedefTemplSpec  = unmarshalQCString     (Doxygen::symbolStorage);
       
  4023   m_impl->cachedResolvedType      = unmarshalQCString     (Doxygen::symbolStorage);
       
  4024   m_impl->docProvider             = (MemberDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4025   m_impl->explicitOutputFileBase  = unmarshalQCString     (Doxygen::symbolStorage);
       
  4026   m_impl->implOnly                = unmarshalBool         (Doxygen::symbolStorage); 
       
  4027   m_impl->hasDocumentedParams     = unmarshalBool         (Doxygen::symbolStorage);
       
  4028   m_impl->hasDocumentedReturnType = unmarshalBool         (Doxygen::symbolStorage);
       
  4029   m_impl->isDMember               = unmarshalBool         (Doxygen::symbolStorage);
       
  4030   m_impl->related                 = (Relationship)unmarshalInt(Doxygen::symbolStorage);
       
  4031   m_impl->stat                    = unmarshalBool         (Doxygen::symbolStorage);
       
  4032   m_impl->proto                   = unmarshalBool         (Doxygen::symbolStorage);
       
  4033   m_impl->docEnumValues           = unmarshalBool         (Doxygen::symbolStorage);
       
  4034   m_impl->annScope                = unmarshalBool         (Doxygen::symbolStorage);
       
  4035   m_impl->annUsed                 = unmarshalBool         (Doxygen::symbolStorage);
       
  4036   m_impl->hasCallGraph            = unmarshalBool         (Doxygen::symbolStorage);
       
  4037   m_impl->hasCallerGraph          = unmarshalBool         (Doxygen::symbolStorage);
       
  4038   m_impl->explExt                 = unmarshalBool         (Doxygen::symbolStorage);
       
  4039   m_impl->tspec                   = unmarshalBool         (Doxygen::symbolStorage);
       
  4040   m_impl->groupHasDocs            = unmarshalBool         (Doxygen::symbolStorage);
       
  4041   m_impl->docsForDefinition       = unmarshalBool         (Doxygen::symbolStorage);
       
  4042   m_impl->category                = (ClassDef*)unmarshalObjPointer   (Doxygen::symbolStorage);
       
  4043   marker = unmarshalUInt(Doxygen::symbolStorage);
       
  4044   assert(marker==END_MARKER);
       
  4045 }
       
  4046 
       
  4047 void MemberDef::makeResident() const
       
  4048 { 
       
  4049   if (Doxygen::symbolCache==0) return;
       
  4050   if (m_cacheHandle==-1) // not yet in cache
       
  4051   { 
       
  4052     MemberDef *victim = 0;
       
  4053     MemberDef *that = (MemberDef*)this; // fake method constness
       
  4054     that->m_cacheHandle = Doxygen::symbolCache->add(that,(void **)&victim);
       
  4055     //printf("adding %s to cache, handle=%d\n",m_impl->name.data(),that->m_cacheHandle);
       
  4056     if (victim)  // cache was full, victim was the least recently used item and has to go
       
  4057     {
       
  4058       victim->m_cacheHandle=-1; // invalidate cache handle
       
  4059       victim->saveToDisk();     // store the item on disk
       
  4060     }
       
  4061     else // cache not yet full
       
  4062     {
       
  4063       //printf("Adding %s to cache, handle=%d\n",m_impl->name.data(),m_cacheHandle);
       
  4064     }
       
  4065     if (m_storagePos!=-1) // already been written to disk
       
  4066     {
       
  4067       if (isLocked()) // locked in memory
       
  4068       {
       
  4069         assert(m_impl!=0);
       
  4070         that->m_flushPending=FALSE; // no need to flush anymore
       
  4071       }
       
  4072       else // not locked in memory
       
  4073       {
       
  4074         assert(m_impl==0);
       
  4075         loadFromDisk();
       
  4076       }
       
  4077     }
       
  4078   }
       
  4079   else // already cached, make this object the most recently used.
       
  4080   {
       
  4081     assert(m_impl!=0);
       
  4082     //printf("Touching symbol %s\n",m_impl->name.data());
       
  4083     Doxygen::symbolCache->use(m_cacheHandle);
       
  4084   }
       
  4085 }
       
  4086 
       
  4087 void MemberDef::saveToDisk() const
       
  4088 {
       
  4089   assert(m_impl!=0);
       
  4090   MemberDef *that = (MemberDef *)this;
       
  4091   if (isLocked()) // cannot flush the item as it is locked
       
  4092   {
       
  4093     that->m_flushPending=TRUE; // flush when unlocked
       
  4094   }
       
  4095   else // ready to flush the item to disk
       
  4096   {
       
  4097     //printf("Adding %s to cache, handle=%d by replacing %s\n",
       
  4098     //    m_impl->name.data(),m_cacheHandle,victim->m_impl->name.data());
       
  4099     if (m_storagePos!=-1) 
       
  4100       // if victim was stored on disk already and is not locked
       
  4101     {
       
  4102       // free the storage space occupied by the old store item
       
  4103       Doxygen::symbolStorage->release(m_storagePos); // free up space for others
       
  4104     }
       
  4105     // write a the new (possibly modified) instance to disk
       
  4106     flushToDisk();
       
  4107     // end to write sequence (unless nothing was written due to the lock)
       
  4108     Doxygen::symbolStorage->end();
       
  4109   }
       
  4110 }
       
  4111 
       
  4112 void MemberDef::lock() const
       
  4113 {
       
  4114 }
       
  4115 
       
  4116 void MemberDef::unlock() const
       
  4117 {
       
  4118   if (m_flushPending && !isLocked())
       
  4119   {
       
  4120     // write a the new (possibly modified) instance to disk
       
  4121     flushToDisk();
       
  4122     // end to write sequence (unless nothing was written due to the lock)
       
  4123     Doxygen::symbolStorage->end();
       
  4124   }
       
  4125 }
       
  4126 
       
  4127 void MemberDef::copyArgumentNames(MemberDef *bmd)
       
  4128 {
       
  4129   makeResident();
       
  4130   {
       
  4131     LockingPtr<ArgumentList> arguments = bmd->argumentList();
       
  4132     if (m_impl->defArgList && arguments!=0)
       
  4133     {
       
  4134       ArgumentListIterator aliDst(*m_impl->defArgList);
       
  4135       ArgumentListIterator aliSrc(*arguments);
       
  4136       Argument *argDst, *argSrc;
       
  4137       for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
       
  4138       {
       
  4139         argDst->name = argSrc->name;
       
  4140       }
       
  4141     }
       
  4142   }
       
  4143   {
       
  4144     LockingPtr<ArgumentList> arguments = bmd->declArgumentList();
       
  4145     if (m_impl->declArgList && arguments!=0)
       
  4146     {
       
  4147       ArgumentListIterator aliDst(*m_impl->declArgList);
       
  4148       ArgumentListIterator aliSrc(*arguments);
       
  4149       Argument *argDst, *argSrc;
       
  4150       for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
       
  4151       {
       
  4152         argDst->name = argSrc->name;
       
  4153       }
       
  4154     }
       
  4155   }
       
  4156 }
       
  4157 
       
  4158 static void invalidateCachedTypesInArgumentList(ArgumentList *al)
       
  4159 {
       
  4160   if (al)
       
  4161   {
       
  4162     ArgumentListIterator ali(*al);
       
  4163     Argument *a;
       
  4164     for (ali.toFirst();(a=ali.current());++ali)
       
  4165     {
       
  4166       a->canType.resize(0);
       
  4167     }
       
  4168   }
       
  4169 }
       
  4170 
       
  4171 void MemberDef::invalidateCachedArgumentTypes()
       
  4172 {
       
  4173   makeResident();
       
  4174   invalidateCachedTypesInArgumentList(m_impl->defArgList);
       
  4175   invalidateCachedTypesInArgumentList(m_impl->declArgList);
       
  4176 }
       
  4177