Orb/Doxygen/src/classdef.cpp
changeset 3 d8fccb2cd802
child 4 468f4c8d3d5b
equal deleted inserted replaced
2:932c358ece3e 3:d8fccb2cd802
       
     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 <qfile.h>
       
    20 #include <qregexp.h>
       
    21 #include "classdef.h"
       
    22 #include "classlist.h"
       
    23 #include "entry.h"
       
    24 #include "doxygen.h"
       
    25 #include "membername.h"
       
    26 #include "message.h"
       
    27 #include "config.h"
       
    28 #include "util.h"
       
    29 #include "diagram.h"
       
    30 #include "language.h"
       
    31 #include "htmlhelp.h"
       
    32 #include "example.h"
       
    33 #include "outputlist.h"
       
    34 #include "dot.h"
       
    35 #include "defargs.h"
       
    36 #include "debug.h"
       
    37 #include "docparser.h"
       
    38 #include "searchindex.h"
       
    39 #include "vhdldocgen.h"
       
    40 #include "layout.h"
       
    41 
       
    42 //-----------------------------------------------------------------------------
       
    43 
       
    44 //static inline MemberList *createNewMemberList(MemberList::ListType lt)
       
    45 //{
       
    46 //  MemberList *result = new MemberList(lt);
       
    47 //  return result;
       
    48 //}
       
    49 
       
    50 class ClassDefImpl
       
    51 {
       
    52   public:
       
    53     ClassDefImpl();
       
    54    ~ClassDefImpl();
       
    55     void init(const char *defFileName, const char *name,
       
    56               const QCString &ctStr, const char *fName);
       
    57 
       
    58     /*! file name that forms the base for the output file containing the
       
    59      *  class documentation. For compatibility with Qt (e.g. links via tag 
       
    60      *  files) this name cannot be derived from the class name directly.
       
    61      */
       
    62     QCString fileName;                   
       
    63 
       
    64     /*! Include information about the header file should be included
       
    65      *  in the documentation. 0 by default, set by setIncludeFile().
       
    66      */
       
    67     IncludeInfo *incInfo;                
       
    68 
       
    69     /*! List of base class (or super-classes) from which this class derives
       
    70      *  directly. 
       
    71      */
       
    72     BaseClassList *inherits;
       
    73 
       
    74     /*! List of sub-classes that directly derive from this class 
       
    75      */
       
    76     BaseClassList *inheritedBy;
       
    77 
       
    78     /*! Namespace this class is part of 
       
    79      *  (this is the inner most namespace in case of nested namespaces)
       
    80      */
       
    81     NamespaceDef  *nspace;              
       
    82 
       
    83     /*! File this class is defined in */
       
    84     FileDef *fileDef;
       
    85 
       
    86     /*! List of all members (including inherited members) */
       
    87     MemberNameInfoSDict *allMemberNameInfoSDict;
       
    88 
       
    89     /*! Template arguments of this class */
       
    90     ArgumentList *tempArgs;
       
    91 
       
    92     /*! Type constraints for template parameters */
       
    93     ArgumentList *typeConstraints;
       
    94 
       
    95     /*! Files that were used for generating the class documentation. */
       
    96     QStrList files;
       
    97 
       
    98     /*! Examples that use this class */
       
    99     ExampleSDict *exampleSDict;
       
   100 
       
   101     /*! Holds the kind of "class" this is. */
       
   102     ClassDef::CompoundType compType;
       
   103 
       
   104     /*! The protection level in which this class was found. 
       
   105      *  Typically Public, but for nested classes this can also be Protected
       
   106      *  or Private.
       
   107      */ 
       
   108     Protection prot;
       
   109 
       
   110     /*! The inner classes contained in this class. Will be 0 if there are
       
   111      *  no inner classes.
       
   112      */
       
   113     ClassSDict *innerClasses;
       
   114 
       
   115     /* classes for the collaboration diagram */
       
   116     UsesClassDict *usesImplClassDict;
       
   117     UsesClassDict *usedByImplClassDict;
       
   118     UsesClassDict *usesIntfClassDict;
       
   119 
       
   120     /*! Template instances that exists of this class, the key in the
       
   121      *  dictionary is the template argument list.
       
   122      */ 
       
   123     QDict<ClassDef> *templateInstances;
       
   124 
       
   125     /*! Template instances that exists of this class, as defined by variables.
       
   126      *  We do NOT want to document these individually. The key in the
       
   127      *  dictionary is the template argument list.
       
   128      */ 
       
   129     QDict<ClassDef> *variableInstances;
       
   130 
       
   131     QDict<int> *templBaseClassNames;
       
   132 
       
   133     /*! The class this class is an instance of. */
       
   134     ClassDef *templateMaster;
       
   135 
       
   136     /*! local class name which could be a typedef'ed alias name. */
       
   137     QCString className;
       
   138 
       
   139     /*! If this class is a Objective-C category, then this points to the
       
   140      *  class which is extended.
       
   141      */
       
   142     ClassDef *categoryOf;
       
   143 
       
   144     QList<MemberList> memberLists;
       
   145 
       
   146     /* user defined member groups */
       
   147     MemberGroupSDict *memberGroupSDict;
       
   148 
       
   149     /*! Is this an abstact class? */
       
   150     bool isAbstract;
       
   151 
       
   152     /*! Is the class part of an unnamed namespace? */
       
   153     bool isStatic;
       
   154 
       
   155     /*! Is the class part implemented in Objective C? */
       
   156     bool isObjC;
       
   157 
       
   158     /*! TRUE if classes members are merged with those of the base classes. */
       
   159     bool membersMerged;
       
   160 
       
   161     /*! TRUE if the class is defined in a source file rather than a header file. */
       
   162     bool isLocal;
       
   163 
       
   164     bool isTemplArg;
       
   165 
       
   166     /*! Does this class group its user-grouped members
       
   167      *  as a sub-section of the normal (public/protected/..) 
       
   168      *  groups?
       
   169      */
       
   170     bool subGrouping; 
       
   171 
       
   172     bool usedOnly;
       
   173 };
       
   174 
       
   175 void ClassDefImpl::init(const char *defFileName, const char *name,
       
   176                         const QCString &ctStr, const char *fName)
       
   177 {
       
   178   if (fName)
       
   179   {
       
   180     fileName=stripExtension(fName);
       
   181   }
       
   182   else
       
   183   {
       
   184     fileName=ctStr+name;
       
   185   }
       
   186   exampleSDict = 0;
       
   187   inherits    = 0;
       
   188   inheritedBy = 0;
       
   189   allMemberNameInfoSDict = 0;
       
   190   incInfo=0;
       
   191   tempArgs=0;
       
   192   typeConstraints=0;
       
   193   prot=Public;
       
   194   nspace=0;
       
   195   fileDef=0;
       
   196   usesImplClassDict=0;
       
   197   usedByImplClassDict=0;
       
   198   usesIntfClassDict=0;
       
   199   memberGroupSDict = 0;
       
   200   innerClasses = 0;
       
   201   subGrouping=Config_getBool("SUBGROUPING");
       
   202   templateInstances = 0;
       
   203   variableInstances = 0;
       
   204   templateMaster =0;
       
   205   templBaseClassNames = 0;
       
   206   isAbstract = FALSE;
       
   207   isStatic = FALSE;
       
   208   isTemplArg = FALSE;
       
   209   membersMerged = FALSE;
       
   210   categoryOf = 0;
       
   211   usedOnly = FALSE;
       
   212   //QCString ns;
       
   213   //extractNamespaceName(name,className,ns);
       
   214   //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
       
   215 
       
   216   if (((QCString)defFileName).right(5)!=".java" && 
       
   217       guessSection(defFileName)==Entry::SOURCE_SEC)
       
   218   {
       
   219     isLocal=TRUE;
       
   220   }
       
   221   else
       
   222   {
       
   223     isLocal=FALSE;
       
   224   }
       
   225 }
       
   226 
       
   227 ClassDefImpl::ClassDefImpl()
       
   228 {
       
   229 }
       
   230 
       
   231 ClassDefImpl::~ClassDefImpl()
       
   232 {
       
   233   delete inherits;
       
   234   delete inheritedBy;
       
   235   delete allMemberNameInfoSDict;
       
   236   delete exampleSDict;
       
   237   delete usesImplClassDict;
       
   238   delete usedByImplClassDict;
       
   239   delete usesIntfClassDict;
       
   240   delete incInfo;
       
   241   delete memberGroupSDict;
       
   242   delete innerClasses;
       
   243   delete templateInstances;
       
   244   delete variableInstances;
       
   245   delete templBaseClassNames;
       
   246   delete tempArgs;
       
   247   delete typeConstraints;
       
   248 }
       
   249 
       
   250 // constructs a new class definition
       
   251 ClassDef::ClassDef(
       
   252     const char *defFileName,int defLine,
       
   253     const char *nm,CompoundType ct,
       
   254     const char *lref,const char *fName,
       
   255     bool isSymbol) 
       
   256  : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm),0,0,isSymbol) 
       
   257 {
       
   258   visited=FALSE;
       
   259   setReference(lref);
       
   260   m_impl = new ClassDefImpl;
       
   261   m_impl->compType = ct;
       
   262   m_impl->isObjC   = FALSE;
       
   263   m_impl->init(defFileName,name(),compoundTypeString(),fName);
       
   264 
       
   265 }
       
   266 
       
   267 // destroy the class definition
       
   268 ClassDef::~ClassDef()
       
   269 {
       
   270   delete m_impl;
       
   271 }
       
   272 
       
   273 QCString ClassDef::getMemberListFileName() const
       
   274 {
       
   275   return convertNameToFile(compoundTypeString()+name()+"-members");
       
   276 }
       
   277 
       
   278 QCString ClassDef::displayName() const
       
   279 {
       
   280   static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
       
   281   static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
   282   QCString n;
       
   283   if (vhdlOpt)
       
   284   {
       
   285     n = VhdlDocGen::getClassName(this);
       
   286   }
       
   287   else 
       
   288   {
       
   289     n=qualifiedNameWithTemplateParameters();
       
   290   }
       
   291   if (optimizeOutputForJava)
       
   292   {
       
   293     n=substitute(n,"::",".");
       
   294   }
       
   295   if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
       
   296   {
       
   297     n="<"+n.left(n.length()-2)+">";
       
   298   }
       
   299   return n;
       
   300 }
       
   301 
       
   302 // inserts a base class in the inheritance list
       
   303 void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,
       
   304                                Specifier s,const char *t)
       
   305 {
       
   306   //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
       
   307   //inherits->inSort(new BaseClassDef(cd,p,s,t));
       
   308   if (m_impl->inherits==0)
       
   309   {
       
   310     m_impl->inherits = new BaseClassList;
       
   311     m_impl->inherits->setAutoDelete(TRUE);
       
   312   }
       
   313   if (Config_getBool("PREPROCESS_INCLUDES")) {
       
   314     // If we are preprocessing the #included files we might have seen
       
   315     // this class declaration, and inheritance more than once so we
       
   316     // only add a relationship where one did not exist before
       
   317     bool hasAlready = false;
       
   318 	BaseClassListIterator bcli(*baseClasses());
       
   319 	BaseClassDef *bcd;
       
   320 	for (bcli.toFirst();(bcd=bcli.current());++bcli) {
       
   321 	  if (bcd->usedName == n) {
       
   322 		hasAlready = true;
       
   323 		//printf("*** Seen it...\n");
       
   324 		break;
       
   325 	  }
       
   326 	}
       
   327 	if (!hasAlready) {
       
   328 	  m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
       
   329 	}
       
   330   } else {
       
   331 	m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
       
   332   }
       
   333 }
       
   334 
       
   335 // inserts a sub class in the inherited list
       
   336 void ClassDef::insertSubClass(ClassDef *cd,Protection p,
       
   337                                 Specifier s,const char *t)
       
   338 {
       
   339   //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
       
   340   if (m_impl->inheritedBy==0)
       
   341   {
       
   342     m_impl->inheritedBy   = new BaseClassList;
       
   343     m_impl->inheritedBy->setAutoDelete(TRUE);
       
   344   }
       
   345   m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
       
   346 }
       
   347 
       
   348 void ClassDef::addMembersToMemberGroup()
       
   349 {
       
   350   QListIterator<MemberList> mli(m_impl->memberLists);
       
   351   MemberList *ml;
       
   352   for (mli.toFirst();(ml=mli.current());++mli)
       
   353   {
       
   354     if ((ml->listType()&MemberList::detailedLists)==0)
       
   355     {
       
   356       ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
       
   357     }
       
   358   }
       
   359 
       
   360   // add members inside sections to their groups
       
   361   if (m_impl->memberGroupSDict)
       
   362   {
       
   363     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
   364     MemberGroup *mg;
       
   365     for (;(mg=mgli.current());++mgli)
       
   366     {
       
   367       if (mg->allMembersInSameSection() && m_impl->subGrouping) 
       
   368       {
       
   369         //printf("addToDeclarationSection(%s)\n",mg->header().data());
       
   370         mg->addToDeclarationSection();
       
   371       }
       
   372     }
       
   373   }
       
   374 }
       
   375 
       
   376 // adds new member definition to the class
       
   377 void ClassDef::internalInsertMember(MemberDef *md,
       
   378                                     Protection prot,
       
   379                                     bool addToAllList
       
   380                                    )
       
   381 {
       
   382   //printf("%p:insertInternalMember(%s) isHidden()=%d\n", this, md->name().data(),md->isHidden());
       
   383   if (md->isHidden()) return;
       
   384 
       
   385   if (!isReference())
       
   386   {
       
   387     static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
       
   388 
       
   389     /********************************************/
       
   390     /* insert member in the declaration section */
       
   391     /********************************************/
       
   392     if (md->isRelated() && (extractPrivate || prot!=Private))
       
   393     {
       
   394       addMemberToList(MemberList::related,md,true);
       
   395     }
       
   396     else if (md->isFriend())
       
   397     {
       
   398       addMemberToList(MemberList::friends,md,true);
       
   399     }
       
   400     else
       
   401     {
       
   402       switch (md->memberType())
       
   403       {
       
   404         case MemberDef::Signal: // Qt specific
       
   405           addMemberToList(MemberList::signals,md,true);
       
   406           break;
       
   407         case MemberDef::DCOP:   // KDE2 specific
       
   408           addMemberToList(MemberList::dcopMethods,md,true);
       
   409           break;
       
   410         case MemberDef::Property:
       
   411           addMemberToList(MemberList::properties,md,true);
       
   412           break;
       
   413         case MemberDef::Event:
       
   414           addMemberToList(MemberList::events,md,true);
       
   415           break;
       
   416         case MemberDef::Slot:   // Qt specific
       
   417           switch (prot)
       
   418           {
       
   419             case Protected: 
       
   420             case Package: // slots in packages are not possible!
       
   421               addMemberToList(MemberList::proSlots,md,true);
       
   422               break;
       
   423             case Public:    
       
   424               addMemberToList(MemberList::pubSlots,md,true);
       
   425               break;
       
   426             case Private:   
       
   427               addMemberToList(MemberList::priSlots,md,true);
       
   428               break;
       
   429           }
       
   430           break;
       
   431         default: // any of the other members
       
   432           if (md->isStatic())
       
   433           {
       
   434             if (md->isVariable())
       
   435             {
       
   436               switch (prot)
       
   437               {
       
   438                 case Protected: 
       
   439                   addMemberToList(MemberList::proStaticAttribs,md,true);
       
   440                   break;
       
   441                 case Package: 
       
   442                   addMemberToList(MemberList::pacStaticAttribs,md,true);
       
   443                   break;
       
   444                 case Public:    
       
   445                   addMemberToList(MemberList::pubStaticAttribs,md,true);
       
   446                   break;
       
   447                 case Private:   
       
   448                   addMemberToList(MemberList::priStaticAttribs,md,true);
       
   449                   break;
       
   450               }
       
   451             }
       
   452             else // function
       
   453             {
       
   454               switch (prot)
       
   455               {
       
   456                 case Protected: 
       
   457                   addMemberToList(MemberList::proStaticMethods,md,true);
       
   458                   break;
       
   459                 case Package: 
       
   460                   addMemberToList(MemberList::pacStaticMethods,md,true);
       
   461                   break;
       
   462                 case Public:    
       
   463                   addMemberToList(MemberList::pubStaticMethods,md,true);
       
   464                   break;
       
   465                 case Private:   
       
   466                   addMemberToList(MemberList::priStaticMethods,md,true);
       
   467                   break;
       
   468               }
       
   469             }
       
   470           }
       
   471           else // not static
       
   472           {
       
   473             if (md->isVariable())
       
   474             {
       
   475               switch (prot)
       
   476               {
       
   477                 case Protected: 
       
   478                   addMemberToList(MemberList::proAttribs,md,true);
       
   479                   break;
       
   480                 case Package:
       
   481                   addMemberToList(MemberList::pacAttribs,md,true);
       
   482                   break;
       
   483                 case Public:    
       
   484                   addMemberToList(MemberList::pubAttribs,md,true);
       
   485                   break;
       
   486                 case Private:   
       
   487                   addMemberToList(MemberList::priAttribs,md,true);
       
   488                   break;
       
   489               }
       
   490             }
       
   491             else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
       
   492             {
       
   493               switch (prot)
       
   494               {
       
   495                 case Protected: 
       
   496                   addMemberToList(MemberList::proTypes,md,true);
       
   497                   break;
       
   498                 case Package: 
       
   499                   addMemberToList(MemberList::pacTypes,md,true);
       
   500                   break;
       
   501                 case Public:    
       
   502                   addMemberToList(MemberList::pubTypes,md,true);
       
   503                   break;
       
   504                 case Private:   
       
   505                   addMemberToList(MemberList::priTypes,md,true);
       
   506                   break;
       
   507               }
       
   508             }
       
   509             else // member function
       
   510             {
       
   511               switch (prot)
       
   512               {
       
   513                 case Protected: 
       
   514                   addMemberToList(MemberList::proMethods,md,true);
       
   515                   break;
       
   516                 case Package: 
       
   517                   addMemberToList(MemberList::pacMethods,md,true);
       
   518                   break;
       
   519                 case Public:    
       
   520                   addMemberToList(MemberList::pubMethods,md,true);
       
   521                   break;
       
   522                 case Private:   
       
   523                   addMemberToList(MemberList::priMethods,md,true);
       
   524                   break;
       
   525               }
       
   526             }
       
   527           }
       
   528           break; 
       
   529       }
       
   530     }
       
   531 
       
   532     /*******************************************************/
       
   533     /* insert member in the detailed documentation section */
       
   534     /*******************************************************/
       
   535     if ((md->isRelated() && (extractPrivate || prot!=Private)) || md->isFriend())
       
   536     {
       
   537       addMemberToList(MemberList::relatedMembers,md,false);
       
   538     }
       
   539     else
       
   540     {
       
   541       switch (md->memberType())
       
   542       {
       
   543         case MemberDef::Property:
       
   544           addMemberToList(MemberList::propertyMembers,md,false);
       
   545           break;
       
   546         case MemberDef::Event:
       
   547           addMemberToList(MemberList::eventMembers,md,false);
       
   548           break;
       
   549         case MemberDef::Signal: // fall through
       
   550         case MemberDef::DCOP:
       
   551           addMemberToList(MemberList::functionMembers,md,false);
       
   552           break;
       
   553         case MemberDef::Slot:
       
   554           switch (prot)
       
   555           {
       
   556             case Protected: 
       
   557             case Package: 
       
   558             case Public:    
       
   559               addMemberToList(MemberList::functionMembers,md,false);
       
   560               break;
       
   561             case Private:   
       
   562               if (extractPrivate)
       
   563               {
       
   564                 addMemberToList(MemberList::functionMembers,md,false);
       
   565               }
       
   566               break;
       
   567           }
       
   568           break;
       
   569         default: // any of the other members
       
   570           if (prot!=Private || extractPrivate)
       
   571           {
       
   572             switch (md->memberType())
       
   573             {
       
   574               case MemberDef::Typedef:
       
   575                 addMemberToList(MemberList::typedefMembers,md,false);
       
   576                 break;
       
   577               case MemberDef::Enumeration:
       
   578                 addMemberToList(MemberList::enumMembers,md,false);
       
   579                 break;
       
   580               case MemberDef::EnumValue:
       
   581                 addMemberToList(MemberList::enumValMembers,md,false);
       
   582                 break;
       
   583               case MemberDef::Function:
       
   584                 if (md->isConstructor() || md->isDestructor())
       
   585                 {
       
   586                   MemberList *ml = createMemberList(MemberList::constructors);
       
   587                   ml->append(md);
       
   588                 }
       
   589                 else
       
   590                 {
       
   591                   addMemberToList(MemberList::functionMembers,md,false);
       
   592                 }
       
   593                 break;
       
   594               case MemberDef::Variable:
       
   595                 addMemberToList(MemberList::variableMembers,md,false);
       
   596                 break;
       
   597               default:
       
   598                 err("Unexpected member type %d found!\n",md->memberType());
       
   599             }
       
   600           }
       
   601           break; 
       
   602       }
       
   603     }
       
   604 
       
   605     /*************************************************/
       
   606     /* insert member in the appropriate member group */
       
   607     /*************************************************/
       
   608     // Note: this must be done AFTER inserting the member in the 
       
   609     // regular groups
       
   610     //addMemberToGroup(md,groupId);
       
   611     
       
   612   }
       
   613 
       
   614   if (md->virtualness()==Pure)
       
   615   {
       
   616     m_impl->isAbstract=TRUE;
       
   617   }
       
   618 
       
   619   //::addClassMemberNameToIndex(md);
       
   620   if (addToAllList && 
       
   621       !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
       
   622         md->isFriend() &&
       
   623         (QCString(md->typeString())=="friend class" || 
       
   624          QCString(md->typeString())=="friend struct" ||
       
   625          QCString(md->typeString())=="friend union")))
       
   626   {
       
   627     //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
       
   628     MemberInfo *mi = new MemberInfo((MemberDef *)md,
       
   629                                      prot,md->virtualness(),FALSE);
       
   630     MemberNameInfo *mni=0;
       
   631     if (m_impl->allMemberNameInfoSDict==0)
       
   632     {
       
   633       m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
       
   634       m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
       
   635     }
       
   636     if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
       
   637     {
       
   638       mni->append(mi);
       
   639     }
       
   640     else
       
   641     {
       
   642       mni = new MemberNameInfo(md->name());
       
   643       mni->append(mi);
       
   644       m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
       
   645     }
       
   646   }
       
   647 }
       
   648 
       
   649 void ClassDef::insertMember(MemberDef *md)
       
   650 {
       
   651   internalInsertMember(md,md->protection(),TRUE);
       
   652 }
       
   653 
       
   654 // compute the anchors for all members
       
   655 void ClassDef::computeAnchors()
       
   656 {
       
   657   ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;
       
   658   const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
       
   659   QListIterator<MemberList> mli(m_impl->memberLists);
       
   660   MemberList *ml;
       
   661   int index = 0;
       
   662   for (mli.toFirst();(ml=mli.current());++mli)
       
   663   {
       
   664     if ((ml->listType()&MemberList::detailedLists)==0)
       
   665     {
       
   666       setAnchors(context,letters[index++],ml);
       
   667     }
       
   668   }
       
   669 
       
   670   if (m_impl->memberGroupSDict)
       
   671   {
       
   672     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
   673     MemberGroup *mg;
       
   674     for (;(mg=mgli.current());++mgli)
       
   675     {
       
   676       mg->setAnchors(context);
       
   677     }
       
   678   }
       
   679 }
       
   680 
       
   681 void ClassDef::distributeMemberGroupDocumentation()
       
   682 {
       
   683   if (m_impl->memberGroupSDict)
       
   684   {
       
   685     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
   686     MemberGroup *mg;
       
   687     for (;(mg=mgli.current());++mgli)
       
   688     {
       
   689       mg->distributeMemberGroupDocumentation();
       
   690     }
       
   691   }
       
   692 }
       
   693 
       
   694 void ClassDef::findSectionsInDocumentation()
       
   695 {
       
   696   docFindSections(documentation(),this,0,docFile());
       
   697   if (m_impl->memberGroupSDict)
       
   698   {
       
   699     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
   700     MemberGroup *mg;
       
   701     for (;(mg=mgli.current());++mgli)
       
   702     {
       
   703       mg->findSectionsInDocumentation();
       
   704     }
       
   705   }
       
   706   QListIterator<MemberList> mli(m_impl->memberLists);
       
   707   MemberList *ml;
       
   708   for (mli.toFirst();(ml=mli.current());++mli)
       
   709   {
       
   710     if ((ml->listType()&MemberList::detailedLists)==0)
       
   711     {
       
   712       ml->findSectionsInDocumentation();
       
   713     }
       
   714   }
       
   715 }
       
   716 
       
   717 
       
   718 // add a file name to the used files set
       
   719 void ClassDef::insertUsedFile(const char *f)
       
   720 {
       
   721   if (m_impl->files.find(f)==-1) m_impl->files.append(f);
       
   722   if (m_impl->templateInstances)
       
   723   {
       
   724     QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
       
   725     ClassDef *cd;
       
   726     for (qdi.toFirst();(cd=qdi.current());++qdi)
       
   727     {
       
   728       cd->insertUsedFile(f);
       
   729     }
       
   730   }
       
   731 }
       
   732 
       
   733 static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
       
   734 {
       
   735   if (bcd->prot!=Public || bcd->virt!=Normal)
       
   736   {
       
   737     ol.startTypewriter();
       
   738     ol.docify(" [");
       
   739     QStrList sl;
       
   740     if (bcd->prot==Protected)    sl.append("protected");
       
   741     else if (bcd->prot==Private) sl.append("private");
       
   742     if (bcd->virt==Virtual)      sl.append("virtual");
       
   743     const char *s=sl.first();
       
   744     while (s)
       
   745     {
       
   746       ol.docify(s);
       
   747       s=sl.next();
       
   748       if (s) ol.docify(", ");
       
   749     }
       
   750     ol.docify("]");
       
   751     ol.endTypewriter();
       
   752   }
       
   753 }
       
   754 
       
   755 void ClassDef::setIncludeFile(FileDef *fd,
       
   756              const char *includeName,bool local, bool force)
       
   757 {
       
   758   //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
       
   759   if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
       
   760   if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
       
   761       (fd!=0 && m_impl->incInfo->fileDef==0)
       
   762      )
       
   763   {
       
   764     //printf("Setting file info\n");
       
   765     m_impl->incInfo->fileDef     = fd;
       
   766     m_impl->incInfo->includeName = includeName;
       
   767     m_impl->incInfo->local       = local;
       
   768   }
       
   769   if (force && includeName) m_impl->incInfo->includeName = includeName;
       
   770 }
       
   771 
       
   772 // TODO: fix this: a nested template class can have multiple outer templates
       
   773 //ArgumentList *ClassDef::outerTemplateArguments() const
       
   774 //{
       
   775 //  int ti;
       
   776 //  ClassDef *pcd=0;
       
   777 //  int pi=0;
       
   778 //  if (m_impl->tempArgs) return m_impl->tempArgs;
       
   779 //  // find the outer most class scope
       
   780 //  while ((ti=name().find("::",pi))!=-1 && 
       
   781 //      (pcd=getClass(name().left(ti)))==0
       
   782 //        ) pi=ti+2;
       
   783 //  if (pcd)
       
   784 //  {
       
   785 //    return pcd->templateArguments();
       
   786 //  }
       
   787 //  return 0;
       
   788 //}
       
   789 
       
   790 static void searchTemplateSpecs(/*in*/  Definition *d,
       
   791                                 /*out*/ QList<ArgumentList> &result,
       
   792                                 /*out*/ QCString &name)
       
   793 {
       
   794   if (d->definitionType()==Definition::TypeClass)
       
   795   {
       
   796     if (d->getOuterScope())
       
   797     {
       
   798       searchTemplateSpecs(d->getOuterScope(),result,name);
       
   799     }
       
   800     ClassDef *cd=(ClassDef *)d;
       
   801     if (!name.isEmpty()) name+="::";
       
   802     name+=d->localName();
       
   803     bool isSpecialization = d->localName().find('<')!=-1;
       
   804     if (cd->templateArguments()) 
       
   805     {
       
   806       result.append(cd->templateArguments());
       
   807       if (!isSpecialization)
       
   808       {
       
   809         name+=tempArgListToString(cd->templateArguments());
       
   810       }
       
   811     }
       
   812   }
       
   813   else
       
   814   {
       
   815     name+=d->qualifiedName();
       
   816   }
       
   817 }
       
   818 
       
   819 static void writeTemplateSpec(OutputList &ol,Definition *d,
       
   820             const QCString &type)
       
   821 {
       
   822   QList<ArgumentList> specs;
       
   823   QCString name;
       
   824   searchTemplateSpecs(d,specs,name);
       
   825   if (specs.count()>0) // class has template scope specifiers
       
   826   {
       
   827     ol.startSubsubsection(); 
       
   828     QListIterator<ArgumentList> spi(specs);
       
   829     ArgumentList *al;
       
   830     for (spi.toFirst();(al=spi.current());++spi)
       
   831     {
       
   832       ol.docify("template<");
       
   833       Argument *a=al->first();
       
   834       while (a)
       
   835       {
       
   836         ol.docify(a->type);
       
   837         if (!a->name.isEmpty())
       
   838         {
       
   839           ol.docify(" ");
       
   840           ol.docify(a->name);
       
   841         }
       
   842         if (a->defval.length()!=0)
       
   843         {
       
   844           ol.docify(" = ");
       
   845           ol.docify(a->defval);
       
   846         } 
       
   847         a=al->next();
       
   848         if (a) ol.docify(", ");
       
   849       }
       
   850       ol.docify(">");
       
   851       ol.pushGeneratorState();
       
   852       ol.disableAllBut(OutputGenerator::Html);
       
   853       ol.lineBreak();
       
   854       ol.popGeneratorState();
       
   855     }
       
   856     ol.docify(type.lower()+" "+name);
       
   857     ol.endSubsubsection();
       
   858     ol.writeString("\n");
       
   859   }
       
   860 }
       
   861 
       
   862 void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
       
   863 {
       
   864   if (!briefDescription().isEmpty())
       
   865   {
       
   866     ol.startParagraph();
       
   867     ol.parseDoc(briefFile(),briefLine(),this,0,
       
   868                 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
       
   869     ol.pushGeneratorState();
       
   870     ol.disable(OutputGenerator::RTF);
       
   871     ol.writeString(" \n");
       
   872     ol.enable(OutputGenerator::RTF);
       
   873 
       
   874     if (Config_getBool("REPEAT_BRIEF") || 
       
   875         !documentation().isEmpty() || 
       
   876         exampleFlag
       
   877        )
       
   878     {
       
   879       ol.disableAllBut(OutputGenerator::Html);
       
   880       ol.startTextLink(0,"_details");
       
   881       ol.parseText(theTranslator->trMore());
       
   882       ol.endTextLink();
       
   883     }
       
   884     ol.popGeneratorState();
       
   885 
       
   886     //ol.pushGeneratorState();
       
   887     //ol.disable(OutputGenerator::RTF);
       
   888     //ol.newParagraph(); // FIXME:PARA
       
   889     //ol.popGeneratorState();
       
   890     ol.endParagraph();
       
   891   }
       
   892   ol.writeSynopsis();
       
   893 }
       
   894 
       
   895 // write the detailed description for this class
       
   896 void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType, bool exampleFlag, 
       
   897                                         const QCString &title)
       
   898 {
       
   899   if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) || 
       
   900       !documentation().isEmpty() || 
       
   901       (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef()) ||
       
   902       exampleFlag)
       
   903   {
       
   904     ol.writeRuler();
       
   905     ol.pushGeneratorState();
       
   906       ol.disableAllBut(OutputGenerator::Html);
       
   907       ol.writeAnchor(0,"_details");
       
   908     ol.popGeneratorState();
       
   909     ol.startGroupHeader();
       
   910     ol.parseText(title);
       
   911     ol.endGroupHeader();
       
   912 
       
   913     ol.startTextBlock();
       
   914     
       
   915     writeTemplateSpec(ol,this,pageType);
       
   916     
       
   917     // repeat brief description
       
   918     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
       
   919     {
       
   920       ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
       
   921     }
       
   922     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
       
   923         !documentation().isEmpty())
       
   924     {
       
   925       ol.pushGeneratorState();
       
   926         ol.disable(OutputGenerator::Man);
       
   927         ol.disable(OutputGenerator::RTF);
       
   928         //ol.newParagraph(); // FIXME:PARA
       
   929         ol.enableAll();
       
   930         ol.disableAllBut(OutputGenerator::Man);
       
   931         ol.writeString("\n\n");
       
   932       ol.popGeneratorState();
       
   933     }
       
   934     // write documentation
       
   935     if (!documentation().isEmpty())
       
   936     {
       
   937       ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
       
   938     }
       
   939     // write type constraints
       
   940     writeTypeConstraints(ol,this,m_impl->typeConstraints);
       
   941 
       
   942     // write examples
       
   943     if (exampleFlag && m_impl->exampleSDict)
       
   944     {
       
   945       ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
       
   946       ol.startDescForItem();
       
   947       ol.startParagraph();
       
   948       writeExample(ol,m_impl->exampleSDict);
       
   949       ol.endParagraph();
       
   950       ol.endDescForItem();
       
   951       ol.endSimpleSect();
       
   952     }
       
   953     //ol.newParagraph();
       
   954     writeSourceDef(ol,name());
       
   955     ol.endTextBlock();
       
   956   }
       
   957   else
       
   958   {
       
   959     writeTemplateSpec(ol,this,pageType);
       
   960   }
       
   961 }
       
   962     
       
   963 void ClassDef::showUsedFiles(OutputList &ol)
       
   964 {
       
   965   ol.pushGeneratorState();
       
   966   ol.disable(OutputGenerator::Man);
       
   967   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
       
   968 
       
   969   ol.writeRuler();
       
   970   if (fortranOpt)
       
   971   {
       
   972     ol.parseText(theTranslator->trGeneratedFromFilesFortran(
       
   973           m_impl->isObjC && m_impl->compType==Interface ? Class : m_impl->compType,
       
   974           m_impl->files.count()==1));
       
   975   }
       
   976   else
       
   977   {
       
   978     ol.parseText(theTranslator->trGeneratedFromFiles(
       
   979           m_impl->isObjC && m_impl->compType==Interface ? Class : m_impl->compType,
       
   980           m_impl->files.count()==1));  
       
   981   }
       
   982 
       
   983 
       
   984   bool first=TRUE;
       
   985   const char *file = m_impl->files.first();
       
   986   while (file)
       
   987   {
       
   988     bool ambig;
       
   989     FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
       
   990     if (fd)
       
   991     {
       
   992       if (first)
       
   993       {
       
   994         first=FALSE;   
       
   995         ol.startItemList();
       
   996       }
       
   997 
       
   998       ol.startItemListItem();
       
   999       QCString path=fd->getPath();
       
  1000       if (Config_getBool("FULL_PATH_NAMES"))
       
  1001       {
       
  1002         ol.docify(stripFromPath(path));
       
  1003       }
       
  1004 
       
  1005       QCString fname = fd->name();
       
  1006       if (!fd->getVersion().isEmpty()) // append version if available
       
  1007       {
       
  1008         fname += " (" + fd->getVersion() + ")";
       
  1009       }
       
  1010 
       
  1011       // for HTML 
       
  1012       ol.pushGeneratorState();
       
  1013       ol.disableAllBut(OutputGenerator::Html);
       
  1014       if (fd->generateSourceFile())
       
  1015       {
       
  1016         ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
       
  1017       }
       
  1018       else if (fd->isLinkable())
       
  1019       {
       
  1020         ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
       
  1021             fname);
       
  1022       }
       
  1023       else
       
  1024       {
       
  1025         ol.docify(fname);
       
  1026       }
       
  1027       ol.popGeneratorState();
       
  1028 
       
  1029       // for other output formats
       
  1030       ol.pushGeneratorState();
       
  1031       ol.disable(OutputGenerator::Html);
       
  1032       if (fd->isLinkable())
       
  1033       {
       
  1034         ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
       
  1035             fname);
       
  1036       }
       
  1037       else
       
  1038       {
       
  1039         ol.docify(fname);
       
  1040       }
       
  1041       ol.popGeneratorState();
       
  1042 
       
  1043       ol.endItemListItem();
       
  1044     }
       
  1045     file=m_impl->files.next();
       
  1046   }
       
  1047   if (!first) ol.endItemList();
       
  1048 
       
  1049   ol.popGeneratorState();
       
  1050 }
       
  1051 
       
  1052 
       
  1053 void ClassDef::writeInheritanceGraph(OutputList &ol)
       
  1054 {
       
  1055   // count direct inheritance relations
       
  1056   int count=0;
       
  1057   BaseClassDef *ibcd;
       
  1058   if (m_impl->inheritedBy)
       
  1059   {
       
  1060     ibcd=m_impl->inheritedBy->first();
       
  1061     while (ibcd)
       
  1062     {
       
  1063       ClassDef *icd=ibcd->classDef;
       
  1064       if ( icd->isVisibleInHierarchy()) count++;
       
  1065       ibcd=m_impl->inheritedBy->next();
       
  1066     }
       
  1067   }
       
  1068   if (m_impl->inherits)
       
  1069   {
       
  1070     ibcd=m_impl->inherits->first();
       
  1071     while (ibcd)
       
  1072     {
       
  1073       ClassDef *icd=ibcd->classDef;
       
  1074       if ( icd->isVisibleInHierarchy()) count++;
       
  1075       ibcd=m_impl->inherits->next();
       
  1076     }
       
  1077   }
       
  1078 
       
  1079   
       
  1080   bool renderDiagram = FALSE;
       
  1081   if (Config_getBool("HAVE_DOT") && Config_getBool("CLASS_DIAGRAMS"))
       
  1082     // write class diagram using dot
       
  1083   {
       
  1084     DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
       
  1085     if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
       
  1086     {
       
  1087       ol.pushGeneratorState();
       
  1088       ol.disable(OutputGenerator::Man);
       
  1089       ol.startDotGraph();
       
  1090       ol.parseText(theTranslator->trClassDiagram(displayName()));
       
  1091       ol.endDotGraph(inheritanceGraph);
       
  1092       ol.popGeneratorState();
       
  1093       renderDiagram = TRUE;
       
  1094     }
       
  1095   }
       
  1096   else if (Config_getBool("CLASS_DIAGRAMS") && count>0) 
       
  1097     // write class diagram using build-in generator
       
  1098   {
       
  1099     ClassDiagram diagram(this); // create a diagram of this class.
       
  1100     ol.startClassDiagram();
       
  1101     ol.disable(OutputGenerator::Man);
       
  1102     ol.parseText(theTranslator->trClassDiagram(displayName()));
       
  1103     ol.enable(OutputGenerator::Man);
       
  1104     ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
       
  1105     renderDiagram = TRUE;
       
  1106   } 
       
  1107 
       
  1108   if (renderDiagram) // if we already show the inheritance relations graphically,
       
  1109                      // then hide the text version
       
  1110   {
       
  1111     ol.disableAllBut(OutputGenerator::Man);
       
  1112   }
       
  1113 
       
  1114   if (m_impl->inherits && (count=m_impl->inherits->count())>0)
       
  1115   {
       
  1116     ol.startParagraph();
       
  1117     //parseText(ol,theTranslator->trInherits()+" ");
       
  1118 
       
  1119     QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
       
  1120     QRegExp marker("@[0-9]+");
       
  1121     int index=0,newIndex,matchLen;
       
  1122     // now replace all markers in inheritLine with links to the classes
       
  1123     while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
       
  1124     {
       
  1125       ol.parseText(inheritLine.mid(index,newIndex-index));
       
  1126       bool ok;
       
  1127       uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
       
  1128       BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
       
  1129       if (ok && bcd)
       
  1130       {
       
  1131         ClassDef *cd=bcd->classDef;
       
  1132 
       
  1133         // use the class name but with the template arguments as given
       
  1134         // in the inheritance relation
       
  1135         QCString displayName = insertTemplateSpecifierInScope(
       
  1136             cd->name(),bcd->templSpecifiers);
       
  1137 
       
  1138         if (cd->isLinkable())
       
  1139         {
       
  1140           if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
  1141           {
       
  1142             Doxygen::tagFile << "    <base";
       
  1143             if (bcd->prot==Protected)
       
  1144             {
       
  1145               Doxygen::tagFile << " protection=\"protected\"";
       
  1146             }
       
  1147             else if (bcd->prot==Private)
       
  1148             {
       
  1149               Doxygen::tagFile << " protection=\"private\"";
       
  1150             }
       
  1151             if (bcd->virt==Virtual)
       
  1152             {
       
  1153               Doxygen::tagFile << " virtualness=\"virtual\"";
       
  1154             }
       
  1155             Doxygen::tagFile << ">" << convertToXML(cd->name()) 
       
  1156                              << "</base>" << endl;
       
  1157           }
       
  1158           ol.writeObjectLink(cd->getReference(),
       
  1159                              cd->getOutputFileBase(),
       
  1160                              0,
       
  1161                              displayName);
       
  1162         }
       
  1163         else
       
  1164         {
       
  1165           ol.docify(displayName);
       
  1166         }
       
  1167       }
       
  1168       else
       
  1169       {
       
  1170         err("Error: invalid marker %d in inherits list!\n",entryIndex);
       
  1171       }
       
  1172       index=newIndex+matchLen;
       
  1173     } 
       
  1174     ol.parseText(inheritLine.right(inheritLine.length()-index));
       
  1175     ol.endParagraph();
       
  1176   }
       
  1177 
       
  1178   // write subclasses
       
  1179   if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
       
  1180   {
       
  1181     ol.startParagraph();
       
  1182     QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
       
  1183     QRegExp marker("@[0-9]+");
       
  1184     int index=0,newIndex,matchLen;
       
  1185     // now replace all markers in inheritLine with links to the classes
       
  1186     while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
       
  1187     {
       
  1188       ol.parseText(inheritLine.mid(index,newIndex-index));
       
  1189       bool ok;
       
  1190       uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
       
  1191       BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
       
  1192       if (ok && bcd)
       
  1193       {
       
  1194         ClassDef *cd=bcd->classDef;
       
  1195         if (cd->isLinkable())
       
  1196         {
       
  1197           ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),0,cd->displayName());
       
  1198         }
       
  1199         else
       
  1200         {
       
  1201           ol.docify(cd->displayName());
       
  1202         }
       
  1203         writeInheritanceSpecifier(ol,bcd);
       
  1204       }
       
  1205       index=newIndex+matchLen;
       
  1206     } 
       
  1207     ol.parseText(inheritLine.right(inheritLine.length()-index));
       
  1208     ol.endParagraph();
       
  1209   }
       
  1210 
       
  1211   if (renderDiagram) 
       
  1212   {
       
  1213     ol.enableAll();
       
  1214   }
       
  1215 }
       
  1216 
       
  1217 void ClassDef::writeCollaborationGraph(OutputList &ol)
       
  1218 {
       
  1219   if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)
       
  1220   {
       
  1221     DotClassGraph usageImplGraph(this,DotNode::Collaboration);
       
  1222     if (!usageImplGraph.isTrivial())
       
  1223     {
       
  1224       ol.pushGeneratorState();
       
  1225       ol.disable(OutputGenerator::Man);
       
  1226       ol.startDotGraph();
       
  1227       ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
       
  1228       ol.endDotGraph(usageImplGraph);
       
  1229       ol.popGeneratorState();
       
  1230     }
       
  1231   }
       
  1232 }
       
  1233 
       
  1234 void ClassDef::writeIncludeFiles(OutputList &ol)
       
  1235 {
       
  1236   if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
       
  1237   {
       
  1238     QCString nm=m_impl->incInfo->includeName.isEmpty() ? 
       
  1239       (m_impl->incInfo->fileDef ?
       
  1240        m_impl->incInfo->fileDef->docName().data() : "" 
       
  1241       ) :
       
  1242       m_impl->incInfo->includeName.data();
       
  1243     if (!nm.isEmpty())
       
  1244     {
       
  1245       ol.startParagraph();
       
  1246       ol.startTypewriter();
       
  1247       bool isIDLorJava = nm.right(4)==".idl" || 
       
  1248                          nm.right(5)==".pidl" || 
       
  1249                          nm.right(5)==".java";
       
  1250       if (isIDLorJava)
       
  1251       {
       
  1252         ol.docify("import ");
       
  1253       }
       
  1254       else if (isObjectiveC())
       
  1255       {
       
  1256         ol.docify("#import ");
       
  1257       }
       
  1258       else
       
  1259       {
       
  1260         ol.docify("#include ");
       
  1261       }
       
  1262       if (m_impl->incInfo->local || isIDLorJava)
       
  1263         ol.docify("\"");
       
  1264       else
       
  1265         ol.docify("<");
       
  1266       ol.pushGeneratorState();
       
  1267       ol.disable(OutputGenerator::Html);
       
  1268       ol.docify(nm);
       
  1269       ol.disableAllBut(OutputGenerator::Html);
       
  1270       ol.enable(OutputGenerator::Html);
       
  1271       if (m_impl->incInfo->fileDef)
       
  1272       {
       
  1273         ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);
       
  1274       }
       
  1275       else
       
  1276       {
       
  1277         ol.docify(nm);
       
  1278       }
       
  1279       ol.popGeneratorState();
       
  1280       if (m_impl->incInfo->local || isIDLorJava)
       
  1281         ol.docify("\"");
       
  1282       else
       
  1283         ol.docify(">");
       
  1284       if (isIDLorJava) 
       
  1285         ol.docify(";");
       
  1286       ol.endTypewriter();
       
  1287       ol.endParagraph();
       
  1288     }
       
  1289   }
       
  1290 }
       
  1291 
       
  1292 void ClassDef::writeAllMembersLink(OutputList &ol)
       
  1293 {
       
  1294   // write link to list of all members (HTML only)
       
  1295   if (m_impl->allMemberNameInfoSDict &&
       
  1296       !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
       
  1297      )
       
  1298   {
       
  1299     ol.pushGeneratorState();
       
  1300     ol.disableAllBut(OutputGenerator::Html);
       
  1301     ol.startParagraph();
       
  1302     ol.startTextLink(getMemberListFileName(),0);
       
  1303     ol.parseText(theTranslator->trListOfAllMembers());
       
  1304     ol.endTextLink();
       
  1305     ol.endParagraph();
       
  1306     ol.enableAll();
       
  1307     ol.popGeneratorState();
       
  1308   }
       
  1309 }
       
  1310 
       
  1311 void ClassDef::writeMemberGroups(OutputList &ol)
       
  1312 {
       
  1313   // write user defined member groups
       
  1314   if (m_impl->memberGroupSDict)
       
  1315   {
       
  1316     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
  1317     MemberGroup *mg;
       
  1318     for (;(mg=mgli.current());++mgli)
       
  1319     {
       
  1320       if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
       
  1321       {
       
  1322         mg->writeDeclarations(ol,this,0,0,0);
       
  1323       }
       
  1324       else // add this group to the corresponding member section
       
  1325       {
       
  1326         //printf("addToDeclarationSection(%s)\n",mg->header().data());
       
  1327         //mg->addToDeclarationSection();
       
  1328       }
       
  1329     }
       
  1330   }
       
  1331 }
       
  1332 
       
  1333 void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
       
  1334 {
       
  1335   // nested classes
       
  1336   if (m_impl->innerClasses) 
       
  1337   {
       
  1338     m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
       
  1339   }
       
  1340 }
       
  1341 
       
  1342 void ClassDef::startMemberDocumentation(OutputList &ol)
       
  1343 {
       
  1344   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
  1345   {
       
  1346     ol.disable(OutputGenerator::Html);
       
  1347     Doxygen::suppressDocWarnings = TRUE;
       
  1348   }
       
  1349 }
       
  1350 
       
  1351 void ClassDef::endMemberDocumentation(OutputList &ol)
       
  1352 {
       
  1353   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
  1354   {
       
  1355     ol.enable(OutputGenerator::Html);
       
  1356     Doxygen::suppressDocWarnings = FALSE;
       
  1357   }
       
  1358 }
       
  1359 
       
  1360 void ClassDef::startMemberDeclarations(OutputList &ol)
       
  1361 {
       
  1362   ol.startMemberSections();
       
  1363 }
       
  1364 
       
  1365 void ClassDef::endMemberDeclarations(OutputList &ol)
       
  1366 {
       
  1367   ol.endMemberSections();
       
  1368 }
       
  1369 
       
  1370 void ClassDef::writeAuthorSection(OutputList &ol)
       
  1371 {
       
  1372   ol.pushGeneratorState();
       
  1373   ol.disableAllBut(OutputGenerator::Man);
       
  1374   ol.writeString("\n");
       
  1375   ol.startGroupHeader();
       
  1376   ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
       
  1377   ol.endGroupHeader();
       
  1378   ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
       
  1379   ol.popGeneratorState();
       
  1380 }
       
  1381 
       
  1382 // write all documentation for this class
       
  1383 void ClassDef::writeDocumentation(OutputList &ol)
       
  1384 {
       
  1385   static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
       
  1386   static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  1387   QCString pageType = " ";
       
  1388   QCString pageTitle = " ";
       
  1389     
       
  1390   pageType += compoundTypeString();
       
  1391   toupper(pageType.at(1));
       
  1392   if (fortranOpt)
       
  1393   {
       
  1394     pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),
       
  1395               m_impl->compType,
       
  1396               m_impl->tempArgs != 0);  
       
  1397   }
       
  1398   else if (vhdlOpt)
       
  1399   {
       
  1400     // TODO: translate
       
  1401     pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
       
  1402   }
       
  1403   else
       
  1404   {
       
  1405     pageTitle = theTranslator->trCompoundReference(displayName(),
       
  1406               m_impl->compType == Interface && m_impl->isObjC ? Class : m_impl->compType,
       
  1407               m_impl->tempArgs != 0);
       
  1408   }
       
  1409   
       
  1410   startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,TRUE);  
       
  1411   if (getOuterScope()!=Doxygen::globalScope)
       
  1412   {
       
  1413     writeNavigationPath(ol);
       
  1414   }
       
  1415   ol.endQuickIndices();
       
  1416   ol.startContents();
       
  1417   startTitle(ol,getOutputFileBase());
       
  1418   ol.parseText(pageTitle);
       
  1419   addGroupListToTitle(ol,this);
       
  1420   endTitle(ol,getOutputFileBase(),name());
       
  1421 
       
  1422   {
       
  1423     ol.pushGeneratorState();
       
  1424     ol.disableAllBut(OutputGenerator::Html);
       
  1425     ol.writeString("<!-- doxytag: class=\"");
       
  1426     ol.docify(name());
       
  1427     ol.writeString("\" -->");
       
  1428     if (m_impl->inherits && m_impl->inherits->count()>0)
       
  1429     {
       
  1430       BaseClassListIterator bli(*m_impl->inherits);
       
  1431       ol.writeString("<!-- doxytag: inherits=\"");
       
  1432       BaseClassDef *bcd=0;
       
  1433       bool first=TRUE;
       
  1434       for (bli.toFirst();(bcd=bli.current());++bli)
       
  1435       {
       
  1436         if (!first) ol.writeString(",");
       
  1437         ol.docify(bcd->classDef->name());
       
  1438         first=FALSE;
       
  1439       }
       
  1440       ol.writeString("\" -->");
       
  1441     }
       
  1442     ol.popGeneratorState();
       
  1443   }
       
  1444 
       
  1445   Doxygen::indexList.addIndexItem(this,0);
       
  1446 
       
  1447   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
  1448   {
       
  1449     Doxygen::tagFile << "  <compound kind=\"" << compoundTypeString();
       
  1450     Doxygen::tagFile << "\"";
       
  1451     if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }
       
  1452     Doxygen::tagFile << ">" << endl;
       
  1453     Doxygen::tagFile << "    <name>" << convertToXML(name()) << "</name>" << endl;
       
  1454     Doxygen::tagFile << "    <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
       
  1455     if (m_impl->tempArgs)
       
  1456     {
       
  1457       ArgumentListIterator ali(*m_impl->tempArgs);
       
  1458       Argument *a;
       
  1459       for (;(a=ali.current());++ali)
       
  1460       {
       
  1461         Doxygen::tagFile << "    <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
       
  1462       }
       
  1463     }
       
  1464   }
       
  1465 
       
  1466   if (Doxygen::searchIndex)
       
  1467   {
       
  1468     Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase());
       
  1469     Doxygen::searchIndex->addWord(localName(),TRUE);
       
  1470   }
       
  1471   bool exampleFlag=hasExamples();
       
  1472 
       
  1473   //---------------------------------------- start flexible part -------------------------------
       
  1474 
       
  1475   QListIterator<LayoutDocEntry> eli(
       
  1476       LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
       
  1477   LayoutDocEntry *lde;
       
  1478   for (eli.toFirst();(lde=eli.current());++eli)
       
  1479   {
       
  1480     switch (lde->kind())
       
  1481     {
       
  1482       case LayoutDocEntry::BriefDesc: 
       
  1483         writeBriefDescription(ol,exampleFlag);
       
  1484         break; 
       
  1485       case LayoutDocEntry::ClassIncludes: 
       
  1486         writeIncludeFiles(ol);
       
  1487         break;
       
  1488       case LayoutDocEntry::ClassInheritanceGraph: 
       
  1489         writeInheritanceGraph(ol); 
       
  1490         break; 
       
  1491       case LayoutDocEntry::ClassCollaborationGraph: 
       
  1492         writeCollaborationGraph(ol); 
       
  1493         break; 
       
  1494       case LayoutDocEntry::ClassAllMembersLink: 
       
  1495         writeAllMembersLink(ol);
       
  1496         break;
       
  1497       case LayoutDocEntry::MemberDeclStart: 
       
  1498         startMemberDeclarations(ol);
       
  1499         break; 
       
  1500       case LayoutDocEntry::MemberGroups: 
       
  1501         writeMemberGroups(ol);
       
  1502         break;
       
  1503       case LayoutDocEntry::MemberDecl: 
       
  1504         {
       
  1505           LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
       
  1506           writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript);
       
  1507         }
       
  1508         break; 
       
  1509       case LayoutDocEntry::ClassNestedClasses: 
       
  1510         {
       
  1511           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
  1512           writeNestedClasses(ol,ls->title);
       
  1513         }
       
  1514         break;
       
  1515       case LayoutDocEntry::MemberDeclEnd: 
       
  1516         endMemberDeclarations(ol);
       
  1517         break;
       
  1518       case LayoutDocEntry::DetailedDesc: 
       
  1519         {
       
  1520           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
  1521           writeDetailedDescription(ol,pageType,exampleFlag,ls->title);
       
  1522         }
       
  1523         break; 
       
  1524       case LayoutDocEntry::MemberDefStart: 
       
  1525         startMemberDocumentation(ol);
       
  1526         break; 
       
  1527       case LayoutDocEntry::MemberDef: 
       
  1528         {
       
  1529           LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
       
  1530           writeMemberDocumentation(ol,lmd->type,lmd->title);
       
  1531         }
       
  1532         break; 
       
  1533       case LayoutDocEntry::MemberDefEnd: 
       
  1534         endMemberDocumentation(ol);
       
  1535         break;
       
  1536       case LayoutDocEntry::ClassUsedFiles: 
       
  1537         showUsedFiles(ol);
       
  1538         break;
       
  1539       case LayoutDocEntry::AuthorSection: 
       
  1540         writeAuthorSection(ol);
       
  1541         break;
       
  1542       case LayoutDocEntry::NamespaceNestedNamespaces:
       
  1543       case LayoutDocEntry::NamespaceClasses:
       
  1544       case LayoutDocEntry::FileClasses:
       
  1545       case LayoutDocEntry::FileNamespaces:
       
  1546       case LayoutDocEntry::FileIncludes:
       
  1547       case LayoutDocEntry::FileIncludeGraph:
       
  1548       case LayoutDocEntry::FileIncludedByGraph: 
       
  1549       case LayoutDocEntry::FileSourceLink:
       
  1550       case LayoutDocEntry::GroupClasses: 
       
  1551       case LayoutDocEntry::GroupNamespaces:
       
  1552       case LayoutDocEntry::GroupDirs: 
       
  1553       case LayoutDocEntry::GroupNestedGroups: 
       
  1554       case LayoutDocEntry::GroupFiles:
       
  1555       case LayoutDocEntry::GroupGraph: 
       
  1556       case LayoutDocEntry::GroupPageDocs:
       
  1557       case LayoutDocEntry::DirSubDirs:
       
  1558       case LayoutDocEntry::DirFiles:
       
  1559       case LayoutDocEntry::DirGraph:
       
  1560         err("Internal inconsistency: member %d should not be part of "
       
  1561             "LayoutDocManager::Class entry list\n",lde->kind());
       
  1562         break;
       
  1563     }
       
  1564   }
       
  1565 
       
  1566   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
  1567   {
       
  1568     writeDocAnchorsToTagFile();
       
  1569     Doxygen::tagFile << "  </compound>" << endl;
       
  1570   }
       
  1571  
       
  1572   endFile(ol);
       
  1573 
       
  1574   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
  1575   {
       
  1576     writeMemberPages(ol);
       
  1577   }
       
  1578 }
       
  1579 
       
  1580 void ClassDef::writeMemberPages(OutputList &ol)
       
  1581 {
       
  1582   ///////////////////////////////////////////////////////////////////////////
       
  1583   //// Member definitions on separate pages
       
  1584   ///////////////////////////////////////////////////////////////////////////
       
  1585 
       
  1586   ol.pushGeneratorState();
       
  1587   ol.disableAllBut(OutputGenerator::Html);
       
  1588   
       
  1589   QListIterator<MemberList> mli(m_impl->memberLists);
       
  1590   MemberList *ml;
       
  1591   for (mli.toFirst();(ml=mli.current());++mli)
       
  1592   {
       
  1593     if (ml->listType()&MemberList::detailedLists)
       
  1594     {
       
  1595       ml->writeDocumentationPage(ol,name(),this);
       
  1596     }
       
  1597   }
       
  1598 
       
  1599   ol.popGeneratorState();
       
  1600 }
       
  1601 
       
  1602 void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
       
  1603 {
       
  1604   static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
       
  1605 
       
  1606   ol.writeString("      <div class=\"navtab\">\n");
       
  1607   ol.writeString("        <table>\n");
       
  1608 
       
  1609   if (m_impl->allMemberNameInfoSDict)
       
  1610   {
       
  1611     MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
       
  1612     MemberNameInfo *mni;
       
  1613     for (;(mni=mnili.current());++mnili)
       
  1614     {
       
  1615       MemberNameInfoIterator mnii(*mni);
       
  1616       MemberInfo *mi;
       
  1617       for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  1618       {
       
  1619         MemberDef *md=mi->memberDef;
       
  1620         if (md->getClassDef()==this && md->isLinkable())
       
  1621         {
       
  1622           ol.writeString("          <tr><td class=\"navtab\">");
       
  1623           if (md->isLinkableInProject())
       
  1624           {
       
  1625             if (md==currentMd) // selected item => highlight
       
  1626             {
       
  1627               ol.writeString("<a class=\"qindexHL\" ");
       
  1628             }
       
  1629             else
       
  1630             {
       
  1631               ol.writeString("<a class=\"qindex\" ");
       
  1632             }
       
  1633             ol.writeString("href=\"");
       
  1634             if (createSubDirs) ol.writeString("../../");
       
  1635             ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
       
  1636             ol.writeString("\">");
       
  1637             ol.writeString(md->name());
       
  1638             ol.writeString("</a>");
       
  1639           }
       
  1640           ol.writeString("</td></tr>\n");
       
  1641         }
       
  1642       }
       
  1643     }
       
  1644   }
       
  1645 
       
  1646   ol.writeString("        </table>\n");
       
  1647   ol.writeString("      </div>\n");
       
  1648 }
       
  1649 
       
  1650 
       
  1651 
       
  1652 void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)
       
  1653 {
       
  1654   // write inner classes after the parent, so the tag files contain
       
  1655   // the definition in proper order!
       
  1656   if (m_impl->innerClasses)
       
  1657   {
       
  1658     ClassSDict::Iterator cli(*m_impl->innerClasses);
       
  1659     ClassDef *innerCd;
       
  1660     for (cli.toFirst();(innerCd=cli.current());++cli)
       
  1661     {
       
  1662       if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
       
  1663           (innerCd->protection()!=Private || Config_getBool("EXTRACT_PRIVATE"))
       
  1664          )
       
  1665       {
       
  1666         msg("Generating docs for nested compound %s...\n",innerCd->name().data());
       
  1667         innerCd->writeDocumentation(ol);
       
  1668         innerCd->writeMemberList(ol);
       
  1669       }
       
  1670       innerCd->writeDocumentationForInnerClasses(ol);
       
  1671     }
       
  1672   }
       
  1673 }
       
  1674 
       
  1675 // write the list of all (inherited) members for this class
       
  1676 void ClassDef::writeMemberList(OutputList &ol)
       
  1677 {
       
  1678   static bool cOpt    = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
       
  1679   static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  1680   if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
       
  1681   // only for HTML
       
  1682   ol.pushGeneratorState();
       
  1683   ol.disableAllBut(OutputGenerator::Html);
       
  1684 
       
  1685   QCString memListFile = getMemberListFileName();
       
  1686   startFile(ol,memListFile,memListFile,
       
  1687             theTranslator->trMemberList(),HLI_ClassVisible);
       
  1688   startTitle(ol,0);
       
  1689   ol.parseText(displayName()+" "+theTranslator->trMemberList());
       
  1690   endTitle(ol,0,0);
       
  1691   ol.parseText(theTranslator->trThisIsTheListOfAllMembers());
       
  1692   ol.writeObjectLink(getReference(),getOutputFileBase(),0,displayName());
       
  1693   ol.parseText(theTranslator->trIncludingInheritedMembers());
       
  1694   
       
  1695   //ol.startItemList();
       
  1696   ol.writeString("<table>\n");
       
  1697   
       
  1698   //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
       
  1699   MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict); 
       
  1700   MemberNameInfo *mni;
       
  1701   for (mnii.toFirst();(mni=mnii.current());++mnii)
       
  1702   {
       
  1703     MemberInfo *mi=mni->first();
       
  1704     while (mi)
       
  1705     {
       
  1706       MemberDef *md=mi->memberDef;
       
  1707       ClassDef  *cd=md->getClassDef();
       
  1708       Protection prot = mi->prot;
       
  1709       Specifier virt=md->virtualness();
       
  1710       
       
  1711       //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
       
  1712       //    name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
       
  1713 
       
  1714 
       
  1715       if (cd && !md->name().isEmpty() && md->name()[0]!='@')
       
  1716       {
       
  1717         bool memberWritten=FALSE;
       
  1718         if (cd->isLinkable() && md->isLinkable()) 
       
  1719           // create a link to the documentation
       
  1720         {
       
  1721           QCString name=mi->ambiguityResolutionScope+md->name();
       
  1722           //ol.writeListItem();
       
  1723           ol.writeString("  <tr class=\"memlist\"><td>");
       
  1724           if (cd->isObjectiveC())
       
  1725           {
       
  1726             if (md->isObjCMethod())
       
  1727             {
       
  1728               if (md->isStatic())
       
  1729                 ol.writeString("+&nbsp;</td><td>");
       
  1730               else
       
  1731                 ol.writeString("-&nbsp;</td><td>");
       
  1732             }
       
  1733             else
       
  1734               ol.writeString("</td><td>");
       
  1735           }
       
  1736           if (md->isObjCMethod())
       
  1737           {
       
  1738             ol.writeObjectLink(md->getReference(),
       
  1739                 md->getOutputFileBase(),
       
  1740                 md->anchor(),md->name());
       
  1741           }
       
  1742           else
       
  1743           {
       
  1744             //Definition *bd = md->getGroupDef();
       
  1745             //if (bd==0) bd=cd;
       
  1746             ol.writeObjectLink(md->getReference(),
       
  1747                 md->getOutputFileBase(),
       
  1748                 md->anchor(),name);
       
  1749 
       
  1750             if ( md->isFunction() || md->isSignal() || md->isSlot() ||
       
  1751                 (md->isFriend() && md->argsString())) 
       
  1752               ol.docify(md->argsString());
       
  1753             else if (md->isEnumerate())
       
  1754               ol.parseText(" "+theTranslator->trEnumName());
       
  1755             else if (md->isEnumValue())
       
  1756               ol.parseText(" "+theTranslator->trEnumValue());
       
  1757             else if (md->isTypedef())
       
  1758               ol.docify(" typedef");
       
  1759             else if (md->isFriend() && !strcmp(md->typeString(),"friend class"))
       
  1760               ol.docify(" class");
       
  1761             //ol.writeString("\n");
       
  1762           }
       
  1763           ol.writeString("</td>");
       
  1764           memberWritten=TRUE;
       
  1765         }
       
  1766         else if (!Config_getBool("HIDE_UNDOC_MEMBERS") && 
       
  1767                   (md->protection()!=Private || Config_getBool("EXTRACT_PRIVATE") || md->isFriend()) 
       
  1768                 ) // no documentation, 
       
  1769                   // generate link to the class instead.
       
  1770         {
       
  1771           //ol.writeListItem();
       
  1772           ol.writeString("  <tr bgcolor=\"#f0f0f0\"><td>");
       
  1773           if (cd->isObjectiveC())
       
  1774           {
       
  1775             if (md->isObjCMethod())
       
  1776             {
       
  1777               if (md->isStatic())
       
  1778                 ol.writeString("+&nbsp;</td><td>");
       
  1779               else
       
  1780                 ol.writeString("-&nbsp;</td><td>");
       
  1781             }
       
  1782             else
       
  1783               ol.writeString("</td><td>");
       
  1784           }
       
  1785           ol.startBold();
       
  1786           ol.docify(md->name());
       
  1787           ol.endBold();
       
  1788           if (!md->isObjCMethod())
       
  1789           {
       
  1790             if ( md->isFunction() || md->isSignal() || md->isSlot() ) 
       
  1791               ol.docify(md->argsString());
       
  1792             else if (md->isEnumerate())
       
  1793               ol.parseText(" "+theTranslator->trEnumName());
       
  1794             else if (md->isEnumValue())
       
  1795               ol.parseText(" "+theTranslator->trEnumValue());
       
  1796             else if (md->isTypedef())
       
  1797               ol.docify(" typedef");
       
  1798           }
       
  1799           ol.writeString(" (");
       
  1800           ol.parseText(theTranslator->trDefinedIn()+" ");
       
  1801           if (cd->isLinkable())
       
  1802           {
       
  1803             ol.writeObjectLink(
       
  1804                 cd->getReference(),
       
  1805                 cd->getOutputFileBase(),
       
  1806                 0,
       
  1807                 cd->displayName());
       
  1808           }
       
  1809           else
       
  1810           {
       
  1811             ol.startBold();
       
  1812             ol.docify(cd->displayName());
       
  1813             ol.endBold();
       
  1814           }
       
  1815           ol.writeString(")");
       
  1816           ol.writeString("</td>");
       
  1817           memberWritten=TRUE;
       
  1818         }
       
  1819         if (memberWritten)
       
  1820         {
       
  1821           ol.writeString("<td>");
       
  1822           ol.writeObjectLink(cd->getReference(),
       
  1823                              cd->getOutputFileBase(),
       
  1824                              0,
       
  1825                              md->category() ? 
       
  1826                                 md->category()->displayName() : 
       
  1827                                 cd->displayName());
       
  1828           ol.writeString("</td>");
       
  1829           ol.writeString("<td>");
       
  1830         }
       
  1831         if (
       
  1832             (prot!=Public || (virt!=Normal && !m_impl->isObjC) || 
       
  1833              md->isFriend() || md->isRelated() || md->isExplicit() ||
       
  1834              md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
       
  1835              md->isSignal() || md->isSlot() ||
       
  1836              md->isStatic() || vhdlOpt
       
  1837             )
       
  1838             && memberWritten)
       
  1839         {
       
  1840           ol.startTypewriter();
       
  1841           ol.docify(" [");
       
  1842           QStrList sl;
       
  1843           if (vhdlOpt) sl.append(VhdlDocGen::trVhdlType(
       
  1844                           md->getMemberSpecifiers())); //append vhdl type
       
  1845           else if (md->isFriend()) sl.append("friend");
       
  1846           else if (md->isRelated()) sl.append("related");
       
  1847           else
       
  1848           {
       
  1849             if (Config_getBool("INLINE_INFO") && md->isInline())        
       
  1850                                        sl.append("inline");
       
  1851             if (md->isExplicit())      sl.append("explicit");
       
  1852             if (md->isMutable())       sl.append("mutable");
       
  1853             if (prot==Protected)       sl.append("protected");
       
  1854             else if (prot==Private)    sl.append("private");
       
  1855             else if (prot==Package)    sl.append("package");
       
  1856             if (virt==Virtual && 
       
  1857                 !m_impl->isObjC)             sl.append("virtual");
       
  1858             else if (virt==Pure)       sl.append("pure virtual");
       
  1859             if (md->isStatic())        sl.append("static");
       
  1860             if (md->isSignal())        sl.append("signal");
       
  1861             if (md->isSlot())          sl.append("slot");
       
  1862           }
       
  1863           const char *s=sl.first();
       
  1864           while (s)
       
  1865           {
       
  1866             ol.docify(s);
       
  1867             s=sl.next();
       
  1868             if (s) ol.docify(", ");
       
  1869           }
       
  1870           ol.docify("]");
       
  1871           ol.endTypewriter();
       
  1872         }
       
  1873         if (memberWritten)
       
  1874         {
       
  1875           ol.writeString("</td>");
       
  1876           ol.writeString("</tr>\n");
       
  1877         }
       
  1878       }
       
  1879       mi=mni->next();
       
  1880     }
       
  1881   }
       
  1882   //ol.endItemList();
       
  1883 
       
  1884   ol.writeString("</table>");
       
  1885   
       
  1886   endFile(ol);
       
  1887   ol.popGeneratorState();
       
  1888 }
       
  1889 
       
  1890 
       
  1891 // add a reference to an example
       
  1892 bool ClassDef::addExample(const char *anchor,const char *nameStr,
       
  1893     const char *file)
       
  1894 {
       
  1895   if (m_impl->exampleSDict==0)
       
  1896   {
       
  1897     m_impl->exampleSDict = new ExampleSDict;
       
  1898     m_impl->exampleSDict->setAutoDelete(TRUE);
       
  1899   }
       
  1900   if (!m_impl->exampleSDict->find(nameStr))
       
  1901   {
       
  1902     Example *e=new Example;
       
  1903     e->anchor=anchor;
       
  1904     e->name=nameStr;
       
  1905     e->file=file;
       
  1906     m_impl->exampleSDict->inSort(nameStr,e);
       
  1907     return TRUE;
       
  1908   }
       
  1909   return FALSE;
       
  1910 }
       
  1911 
       
  1912 // returns TRUE if this class is used in an example
       
  1913 bool ClassDef::hasExamples()
       
  1914 {
       
  1915   if (m_impl->exampleSDict==0) 
       
  1916     return FALSE;
       
  1917   else
       
  1918     return m_impl->exampleSDict->count()>0;
       
  1919 }
       
  1920 
       
  1921 
       
  1922 void ClassDef::setTemplateArguments(ArgumentList *al)
       
  1923 {
       
  1924   if (al==0) return;
       
  1925   if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
       
  1926   m_impl->tempArgs=new ArgumentList; 
       
  1927   ArgumentListIterator ali(*al);
       
  1928   Argument *a;
       
  1929   for (;(a=ali.current());++ali)
       
  1930   {
       
  1931     m_impl->tempArgs->append(new Argument(*a));
       
  1932   }
       
  1933 }
       
  1934 
       
  1935 void ClassDef::setTypeConstraints(ArgumentList *al)
       
  1936 {
       
  1937   if (al==0) return;
       
  1938   if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
       
  1939   m_impl->typeConstraints = new ArgumentList;
       
  1940   ArgumentListIterator ali(*al);
       
  1941   Argument *a;
       
  1942   for (;(a=ali.current());++ali)
       
  1943   {
       
  1944     m_impl->typeConstraints->append(new Argument(*a));
       
  1945   }
       
  1946 }
       
  1947 
       
  1948 /*! Returns \c TRUE iff this class or a class inheriting from this class
       
  1949  *  is \e not defined in an external tag file. 
       
  1950  */
       
  1951 bool ClassDef::hasNonReferenceSuperClass()
       
  1952 {
       
  1953   bool found=!isReference() && isLinkableInProject() && !isHidden(); 
       
  1954   if (found) 
       
  1955   {
       
  1956     return TRUE; // we're done if this class is not a reference
       
  1957   }
       
  1958   if (m_impl->inheritedBy)
       
  1959   {
       
  1960     BaseClassListIterator bcli(*m_impl->inheritedBy);
       
  1961     for ( ; bcli.current() && !found ; ++bcli ) // for each super class
       
  1962     {
       
  1963       ClassDef *bcd=bcli.current()->classDef;
       
  1964       // recurse into the super class branch
       
  1965       found = found || bcd->hasNonReferenceSuperClass(); 
       
  1966       if (!found)
       
  1967       {
       
  1968         // look for template instances that might have non-reference super classes
       
  1969         QDict<ClassDef> *cil = bcd->getTemplateInstances();
       
  1970         if (cil)
       
  1971         {
       
  1972           QDictIterator<ClassDef> tidi(*cil);
       
  1973           for ( ; tidi.current() && !found ; ++tidi) // for each template instance
       
  1974           {
       
  1975             // recurse into the template instance branch
       
  1976             found = found || tidi.current()->hasNonReferenceSuperClass();
       
  1977           }
       
  1978         }
       
  1979       }
       
  1980     }
       
  1981   }
       
  1982   return found;
       
  1983 }
       
  1984 
       
  1985 /*! called from MemberDef::writeDeclaration() to (recusively) write the 
       
  1986  *  definition of an annonymous struct, union or class.
       
  1987  */
       
  1988 void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)
       
  1989 {
       
  1990   //ol.insertMemberAlign();
       
  1991   //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
       
  1992 
       
  1993   //if (inGroup && md && md->getClassDef()==this) return;
       
  1994 
       
  1995   ol.docify(compoundTypeString());
       
  1996   int ri=name().findRev("::");
       
  1997   if (ri==-1) ri=name().length();
       
  1998   QCString cn=name().right(name().length()-ri-2);
       
  1999   if (!cn.isEmpty() && cn.at(0)!='@' && md)
       
  2000   { 
       
  2001     ol.docify(" ");
       
  2002     if (isLinkable())
       
  2003     {
       
  2004       ol.writeObjectLink(0,0,md->anchor(),cn);
       
  2005     }
       
  2006     else
       
  2007     {
       
  2008       ol.startBold();
       
  2009       ol.docify(cn);
       
  2010       ol.endBold();
       
  2011     }
       
  2012   }
       
  2013   ol.docify(" {");
       
  2014   ol.endMemberItem(); 
       
  2015 
       
  2016   // write user defined member groups
       
  2017   if (m_impl->memberGroupSDict)
       
  2018   {
       
  2019     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
  2020     MemberGroup *mg;
       
  2021     for (;(mg=mgli.current());++mgli)
       
  2022     {
       
  2023       mg->setInGroup(inGroup);
       
  2024       mg->writePlainDeclarations(ol,this,0,0,0);
       
  2025     }
       
  2026   }
       
  2027 
       
  2028   writePlainMemberDeclaration(ol,MemberList::pubTypes,inGroup);
       
  2029   writePlainMemberDeclaration(ol,MemberList::pubMethods,inGroup);
       
  2030   writePlainMemberDeclaration(ol,MemberList::pubAttribs,inGroup);
       
  2031   writePlainMemberDeclaration(ol,MemberList::pubSlots,inGroup);
       
  2032   writePlainMemberDeclaration(ol,MemberList::signals,inGroup);
       
  2033   writePlainMemberDeclaration(ol,MemberList::dcopMethods,inGroup);
       
  2034   writePlainMemberDeclaration(ol,MemberList::properties,inGroup);
       
  2035   writePlainMemberDeclaration(ol,MemberList::events,inGroup);
       
  2036   writePlainMemberDeclaration(ol,MemberList::pubStaticMethods,inGroup);
       
  2037   writePlainMemberDeclaration(ol,MemberList::pubStaticAttribs,inGroup);
       
  2038   writePlainMemberDeclaration(ol,MemberList::proTypes,inGroup);
       
  2039   writePlainMemberDeclaration(ol,MemberList::proMethods,inGroup);
       
  2040   writePlainMemberDeclaration(ol,MemberList::proAttribs,inGroup);
       
  2041   writePlainMemberDeclaration(ol,MemberList::proSlots,inGroup);
       
  2042   writePlainMemberDeclaration(ol,MemberList::proStaticMethods,inGroup);
       
  2043   writePlainMemberDeclaration(ol,MemberList::proStaticAttribs,inGroup);
       
  2044   writePlainMemberDeclaration(ol,MemberList::pacTypes,inGroup);
       
  2045   writePlainMemberDeclaration(ol,MemberList::pacMethods,inGroup);
       
  2046   writePlainMemberDeclaration(ol,MemberList::pacAttribs,inGroup);
       
  2047   writePlainMemberDeclaration(ol,MemberList::pacStaticMethods,inGroup);
       
  2048   writePlainMemberDeclaration(ol,MemberList::pacStaticAttribs,inGroup);
       
  2049   if (Config_getBool("EXTRACT_PRIVATE"))
       
  2050   {
       
  2051     writePlainMemberDeclaration(ol,MemberList::priTypes,inGroup);
       
  2052     writePlainMemberDeclaration(ol,MemberList::priMethods,inGroup);
       
  2053     writePlainMemberDeclaration(ol,MemberList::priAttribs,inGroup);
       
  2054     writePlainMemberDeclaration(ol,MemberList::priSlots,inGroup);
       
  2055     writePlainMemberDeclaration(ol,MemberList::priStaticMethods,inGroup);
       
  2056     writePlainMemberDeclaration(ol,MemberList::priStaticAttribs,inGroup);
       
  2057   }
       
  2058   writePlainMemberDeclaration(ol,MemberList::friends,inGroup);
       
  2059   writePlainMemberDeclaration(ol,MemberList::related,inGroup);
       
  2060 }
       
  2061 
       
  2062 /*! a link to this class is possible within this project */
       
  2063 bool ClassDef::isLinkableInProject() const
       
  2064 { 
       
  2065   static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
       
  2066   static bool extractLocal   = Config_getBool("EXTRACT_LOCAL_CLASSES");
       
  2067   static bool extractStatic  = Config_getBool("EXTRACT_STATIC");
       
  2068   static bool hideUndoc      = Config_getBool("HIDE_UNDOC_CLASSES");
       
  2069   if (m_impl->templateMaster)
       
  2070   {
       
  2071     return m_impl->templateMaster->isLinkableInProject();
       
  2072   }
       
  2073   else
       
  2074   {
       
  2075     return !name().isEmpty() &&                    /* has a name */
       
  2076       !isArtificial() && !isHidden() &&            /* not hidden */
       
  2077       name().find('@')==-1 &&                      /* not anonymous */
       
  2078       (m_impl->prot!=Private || extractPrivate) && /* private */
       
  2079       (!m_impl->isLocal      || extractLocal)   && /* local */
       
  2080       (hasDocumentation()    || !hideUndoc)     && /* documented */ 
       
  2081       (!m_impl->isStatic     || extractStatic)  && /* static */
       
  2082       !isReference();                 /* not an external reference */
       
  2083   }
       
  2084 }
       
  2085 
       
  2086 bool ClassDef::isLinkable() const
       
  2087 {
       
  2088   if (m_impl->templateMaster)
       
  2089   {
       
  2090     return m_impl->templateMaster->isLinkable();
       
  2091   }
       
  2092   else
       
  2093   {
       
  2094     return isLinkableInProject() || isReference();
       
  2095   }
       
  2096 }
       
  2097 
       
  2098 
       
  2099 /*! the class is visible in a class diagram, or class hierarchy */
       
  2100 bool ClassDef::isVisibleInHierarchy() 
       
  2101 { 
       
  2102   static bool allExternals     = Config_getBool("ALLEXTERNALS");
       
  2103   static bool extractPrivate   = Config_getBool("EXTRACT_PRIVATE");
       
  2104   static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
       
  2105   static bool extractStatic    = Config_getBool("EXTRACT_STATIC");
       
  2106 
       
  2107   return // show all classes or a subclass is visible
       
  2108       (allExternals || hasNonReferenceSuperClass()) &&
       
  2109       // and not an annonymous compound
       
  2110       name().find('@')==-1 &&
       
  2111       // not an artifically introduced class
       
  2112       !isArtificial() &&
       
  2113       // and not privately inherited
       
  2114       (m_impl->prot!=Private || extractPrivate) &&
       
  2115       // documented or shown anyway or documentation is external 
       
  2116       (hasDocumentation() || 
       
  2117        !hideUndocClasses || 
       
  2118        (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) || 
       
  2119        isReference()
       
  2120       ) &&
       
  2121       // is not part of an unnamed namespace or shown anyway
       
  2122       (!m_impl->isStatic || extractStatic);
       
  2123 }
       
  2124 
       
  2125 bool ClassDef::hasDocumentation() const
       
  2126 {
       
  2127   return Definition::hasDocumentation();
       
  2128 }
       
  2129 
       
  2130 //----------------------------------------------------------------------
       
  2131 // recursive function:
       
  2132 // returns TRUE iff class definition `bcd' represents an (in)direct base 
       
  2133 // class of class definition `cd'.
       
  2134 
       
  2135 bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
       
  2136 {
       
  2137   bool found=FALSE;
       
  2138   //printf("isBaseClass(cd=%s) looking for %s\n",cd->name().data(),bcd->name().data());
       
  2139   if (level>256)
       
  2140   {
       
  2141     err("Possible recursive class relation while inside %s and looking for %s\n",name().data(),bcd->name().data());
       
  2142     abort();
       
  2143     return FALSE;
       
  2144   }
       
  2145   if (baseClasses())
       
  2146   {
       
  2147     BaseClassListIterator bcli(*baseClasses());
       
  2148     for ( ; bcli.current() && !found ; ++bcli)
       
  2149     {
       
  2150       ClassDef *ccd=bcli.current()->classDef;
       
  2151       if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
       
  2152       //printf("isBaseClass() baseclass %s\n",ccd->name().data());
       
  2153       if (ccd==bcd) 
       
  2154         found=TRUE;
       
  2155       else 
       
  2156         found=ccd->isBaseClass(bcd,followInstances,level+1);
       
  2157     }
       
  2158   }
       
  2159   return found;
       
  2160 }
       
  2161 
       
  2162 //----------------------------------------------------------------------------
       
  2163 
       
  2164 static bool isStandardFunc(MemberDef *md)
       
  2165 {
       
  2166   return md->name()=="operator=" || // assignment operator
       
  2167          md->isConstructor() ||     // constructor
       
  2168          md->isDestructor();        // destructor
       
  2169 }
       
  2170 
       
  2171 /*! 
       
  2172  * recusively merges the `all members' lists of a class base 
       
  2173  * with that of this class. Must only be called for classes without
       
  2174  * subclasses!
       
  2175  */
       
  2176 void ClassDef::mergeMembers()
       
  2177 {
       
  2178   if (m_impl->membersMerged) return;
       
  2179 
       
  2180   static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
       
  2181   static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  2182   QCString sep="::";
       
  2183   if (optimizeOutputForJava || vhdlOpt) sep=".";
       
  2184   int sepLen = sep.length();
       
  2185 
       
  2186   m_impl->membersMerged=TRUE;
       
  2187   //printf("  mergeMembers for %s\n",name().data());
       
  2188   bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );
       
  2189   if (baseClasses())
       
  2190   {
       
  2191     //printf("  => has base classes!\n");
       
  2192     BaseClassListIterator bcli(*baseClasses());
       
  2193     BaseClassDef *bcd;
       
  2194     for ( ; (bcd=bcli.current()) ; ++bcli )
       
  2195     {
       
  2196       ClassDef *bClass=bcd->classDef; 
       
  2197 
       
  2198       // merge the members in the base class of this inheritance branch first
       
  2199       bClass->mergeMembers();
       
  2200 
       
  2201       MemberNameInfoSDict *srcMnd  = bClass->memberNameInfoSDict();
       
  2202       MemberNameInfoSDict *dstMnd  = m_impl->allMemberNameInfoSDict;
       
  2203 
       
  2204       if (srcMnd)
       
  2205       {
       
  2206         MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
       
  2207         MemberNameInfo *srcMni;
       
  2208         for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
       
  2209         {
       
  2210           //printf("    Base member name %s\n",srcMni->memberName());
       
  2211           MemberNameInfo *dstMni;
       
  2212           if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
       
  2213             // a member with that name is already in the class.
       
  2214             // the member may hide or reimplement the one in the sub class
       
  2215             // or there may be another path to the base class that is already 
       
  2216             // visited via another branch in the class hierarchy.
       
  2217           {
       
  2218             MemberNameInfoIterator srcMnii(*srcMni); 
       
  2219             MemberInfo *srcMi;
       
  2220             for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
       
  2221             {
       
  2222               MemberDef *srcMd = srcMi->memberDef;
       
  2223               bool found=FALSE;
       
  2224               bool ambigue=FALSE;
       
  2225               bool hidden=FALSE;
       
  2226               MemberNameInfoIterator dstMnii(*dstMni); 
       
  2227               MemberInfo *dstMi;
       
  2228               ClassDef *srcCd = srcMd->getClassDef();
       
  2229               for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
       
  2230               {
       
  2231                 MemberDef *dstMd = dstMi->memberDef;
       
  2232                 if (srcMd!=dstMd) // different members
       
  2233                 {
       
  2234                   ClassDef *dstCd = dstMd->getClassDef();
       
  2235                   //printf("  Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
       
  2236                   if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE)) 
       
  2237                     // member is in the same or a base class
       
  2238                   {
       
  2239                     LockingPtr<ArgumentList> srcAl = srcMd->argumentList();
       
  2240                     LockingPtr<ArgumentList> dstAl = dstMd->argumentList();
       
  2241                     found=matchArguments2(
       
  2242                         srcMd->getOuterScope(),srcMd->getFileDef(),srcAl.pointer(),
       
  2243                         dstMd->getOuterScope(),dstMd->getFileDef(),dstAl.pointer(),
       
  2244                         TRUE
       
  2245                         );
       
  2246                     //printf("  Yes, matching (%s<->%s): %d\n",
       
  2247                     //    argListToString(srcMd->argumentList()).data(),
       
  2248                     //    argListToString(dstMd->argumentList()).data(),
       
  2249                     //    found);
       
  2250                     hidden = hidden  || !found;
       
  2251                   }
       
  2252                   else // member is in a non base class => multiple inheritance
       
  2253                     // using the same base class.
       
  2254                   {
       
  2255                     //printf("$$ Existing member %s %s add scope %s\n",
       
  2256                     //    dstMi->ambiguityResolutionScope.data(),
       
  2257                     //    dstMd->name().data(),
       
  2258                     //    dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
       
  2259 
       
  2260                     QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
       
  2261                     if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
       
  2262                       dstMi->ambiguityResolutionScope.prepend(scope);
       
  2263                     ambigue=TRUE;
       
  2264                   }
       
  2265                 }
       
  2266                 else // same members
       
  2267                 {
       
  2268                   // do not add if base class is virtual or 
       
  2269                   // if scope paths are equal or
       
  2270                   // if base class is an interface (and thus implicitly virtual).
       
  2271                   //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
       
  2272                   if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
       
  2273                       bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
       
  2274                       dstMd->getClassDef()->compoundType()==Interface
       
  2275                      ) 
       
  2276                   {
       
  2277                     found=TRUE;
       
  2278                   }
       
  2279                   else // member can be reached via multiple paths in the 
       
  2280                     // inheritance tree
       
  2281                   {
       
  2282                     //printf("$$ Existing member %s %s add scope %s\n",
       
  2283                     //    dstMi->ambiguityResolutionScope.data(),
       
  2284                     //    dstMd->name().data(),
       
  2285                     //    dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
       
  2286 
       
  2287                     QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
       
  2288                     if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
       
  2289                     {
       
  2290                       dstMi->ambiguityResolutionScope.prepend(scope);
       
  2291                     }
       
  2292                     ambigue=TRUE;
       
  2293                   }
       
  2294                 }
       
  2295               }
       
  2296               //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
       
  2297               //    srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
       
  2298 
       
  2299               // TODO: fix the case where a member is hidden by inheritance
       
  2300               //       of a member with the same name but with another prototype,
       
  2301               //       while there is more than one path to the member in the 
       
  2302               //       base class due to multiple inheritance. In this case
       
  2303               //       it seems that the member is not reachable by prefixing a 
       
  2304               //       scope name either (according to my compiler). Currently, 
       
  2305               //       this case is shown anyway.
       
  2306               if (!found && srcMd->protection()!=Private)
       
  2307               {
       
  2308                 Protection prot=srcMd->protection();
       
  2309                 if (bcd->prot==Protected && prot==Public)       prot=bcd->prot;
       
  2310                 else if (bcd->prot==Private)                    prot=bcd->prot;
       
  2311 
       
  2312                 if (inlineInheritedMembers)
       
  2313                 {
       
  2314                   if (!isStandardFunc(srcMd))
       
  2315                   {
       
  2316                     //printf("    insertMember `%s'\n",srcMd->name().data());
       
  2317                     internalInsertMember(srcMd,prot,FALSE);
       
  2318                   }
       
  2319                 }
       
  2320 
       
  2321                 Specifier virt=srcMi->virt;
       
  2322                 if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
       
  2323 
       
  2324                 MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
       
  2325                 newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
       
  2326                 if (ambigue)
       
  2327                 {
       
  2328                   //printf("$$ New member %s %s add scope %s::\n",
       
  2329                   //     srcMi->ambiguityResolutionScope.data(),
       
  2330                   //     srcMd->name().data(),
       
  2331                   //     bClass->name().data());
       
  2332 
       
  2333                   QCString scope=bClass->name()+sep;
       
  2334                   if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
       
  2335                   {
       
  2336                     newMi->ambiguityResolutionScope=
       
  2337                       scope+srcMi->ambiguityResolutionScope.copy();
       
  2338                   }
       
  2339                 }
       
  2340                 if (hidden)
       
  2341                 {
       
  2342                   if (srcMi->ambigClass==0)
       
  2343                   {
       
  2344                     newMi->ambigClass=bClass;
       
  2345                     newMi->ambiguityResolutionScope=bClass->name()+sep;
       
  2346                   }
       
  2347                   else
       
  2348                   {
       
  2349                     newMi->ambigClass=srcMi->ambigClass;
       
  2350                     newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
       
  2351                   }
       
  2352                 }
       
  2353                 dstMni->append(newMi);
       
  2354               }
       
  2355             }
       
  2356           }
       
  2357           else // base class has a member that is not in the sub class => copy
       
  2358           {
       
  2359             // create a deep copy of the list (only the MemberInfo's will be 
       
  2360             // copied, not the actual MemberDef's)
       
  2361             MemberNameInfo *newMni = 0;
       
  2362             newMni = new MemberNameInfo(srcMni->memberName()); 
       
  2363 
       
  2364             // copy the member(s) from the base to the sub class
       
  2365             MemberNameInfoIterator mnii(*srcMni);
       
  2366             MemberInfo *mi;
       
  2367             for (;(mi=mnii.current());++mnii)
       
  2368             {
       
  2369               Protection prot = mi->prot;
       
  2370               if (bcd->prot==Protected)
       
  2371               {
       
  2372                 if (prot==Public) prot=Protected;
       
  2373               }
       
  2374               else if (bcd->prot==Private)
       
  2375               {
       
  2376                 prot=Private;
       
  2377               }
       
  2378               //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
       
  2379               //    name().data(),mi->memberDef->name().data(),mi->prot,
       
  2380               //    bcd->prot,prot);
       
  2381 
       
  2382               if (mi->prot!=Private)
       
  2383               {
       
  2384                 Specifier virt=mi->virt;
       
  2385                 if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
       
  2386 
       
  2387                 if (inlineInheritedMembers)
       
  2388                 {
       
  2389                   if (!isStandardFunc(mi->memberDef))
       
  2390                   {
       
  2391                     //printf("    insertMember `%s'\n",mi->memberDef->name().data());
       
  2392                     internalInsertMember(mi->memberDef,prot,FALSE);
       
  2393                   }
       
  2394                 }
       
  2395                 //printf("Adding!\n");
       
  2396                 MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
       
  2397                 newMi->scopePath=bClass->name()+sep+mi->scopePath;
       
  2398                 newMi->ambigClass=mi->ambigClass;
       
  2399                 newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
       
  2400                 newMni->append(newMi);
       
  2401               }
       
  2402             }
       
  2403 
       
  2404             if (dstMnd==0)
       
  2405             {
       
  2406               m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
       
  2407               m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
       
  2408               dstMnd = m_impl->allMemberNameInfoSDict;
       
  2409             }
       
  2410             // add it to the dictionary
       
  2411             dstMnd->append(newMni->memberName(),newMni);
       
  2412           }
       
  2413         }
       
  2414       }
       
  2415     }
       
  2416   }
       
  2417   //printf("  end mergeMembers\n");
       
  2418 }
       
  2419 
       
  2420 //----------------------------------------------------------------------------
       
  2421 
       
  2422 /*! Merges the members of a Objective-C category into this class.
       
  2423  */
       
  2424 void ClassDef::mergeCategory(ClassDef *category)
       
  2425 {
       
  2426   category->setCategoryOf(this);
       
  2427   category->setArtificial(TRUE);
       
  2428     
       
  2429   MemberNameInfoSDict *srcMnd  = category->memberNameInfoSDict();
       
  2430   MemberNameInfoSDict *dstMnd  = m_impl->allMemberNameInfoSDict;
       
  2431 
       
  2432   if (srcMnd && dstMnd)
       
  2433   {
       
  2434     MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
       
  2435     MemberNameInfo *srcMni;
       
  2436     for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
       
  2437     {
       
  2438       MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
       
  2439       if (dstMni) // method is already defined in the class
       
  2440       {
       
  2441         // TODO: we should remove the other member and insert this one.
       
  2442       }
       
  2443       else // new method name
       
  2444       {
       
  2445         // create a deep copy of the list
       
  2446         MemberNameInfo *newMni = 0;
       
  2447         newMni = new MemberNameInfo(srcMni->memberName()); 
       
  2448 
       
  2449         // copy the member(s) from the category to this class
       
  2450         MemberNameInfoIterator mnii(*srcMni);
       
  2451         MemberInfo *mi;
       
  2452         for (;(mi=mnii.current());++mnii)
       
  2453         {
       
  2454           //printf("Adding '%s'\n",mi->memberDef->name().data());
       
  2455           MemberInfo *newMi=new MemberInfo(mi->memberDef,mi->prot,mi->virt,mi->inherited);
       
  2456           newMi->scopePath=mi->scopePath;
       
  2457           newMi->ambigClass=mi->ambigClass;
       
  2458           newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;
       
  2459           newMni->append(newMi);
       
  2460           mi->memberDef->moveTo(this);
       
  2461           mi->memberDef->setCategory(category);
       
  2462           internalInsertMember(mi->memberDef,mi->prot,FALSE);
       
  2463         }
       
  2464 
       
  2465         // add it to the dictionary
       
  2466         dstMnd->append(newMni->memberName(),newMni);
       
  2467       }
       
  2468     }
       
  2469   }
       
  2470 }
       
  2471 
       
  2472 //----------------------------------------------------------------------------
       
  2473 
       
  2474 void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)
       
  2475 {
       
  2476   //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
       
  2477   if (m_impl->usesImplClassDict==0) 
       
  2478   {
       
  2479     m_impl->usesImplClassDict = new UsesClassDict(17); 
       
  2480     m_impl->usesImplClassDict->setAutoDelete(TRUE);
       
  2481   }
       
  2482   UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
       
  2483   if (ucd==0)
       
  2484   {
       
  2485      ucd = new UsesClassDef(cd);
       
  2486      m_impl->usesImplClassDict->insert(cd->name(),ucd);
       
  2487      //printf("Adding used class %s to class %s\n",
       
  2488      //    cd->name().data(),name().data());
       
  2489   }
       
  2490   ucd->addAccessor(accessName);
       
  2491 }
       
  2492 
       
  2493 void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName)
       
  2494 {
       
  2495   if (m_impl->usedByImplClassDict==0) 
       
  2496   {
       
  2497     m_impl->usedByImplClassDict = new UsesClassDict(17); 
       
  2498     m_impl->usedByImplClassDict->setAutoDelete(TRUE);
       
  2499   }
       
  2500   UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
       
  2501   if (ucd==0)
       
  2502   {
       
  2503      ucd = new UsesClassDef(cd);
       
  2504      m_impl->usedByImplClassDict->insert(cd->name(),ucd);
       
  2505      //printf("Adding used by class %s to class %s\n",
       
  2506      //    cd->name().data(),name().data());
       
  2507   }
       
  2508   ucd->addAccessor(accessName);
       
  2509 }
       
  2510 
       
  2511 
       
  2512 #if 0
       
  2513 /*! Builds up a dictionary of all classes that are used by the state of this 
       
  2514  *  class (the "implementation"). 
       
  2515  *  Must be called before mergeMembers() is called!
       
  2516  */
       
  2517 
       
  2518 void ClassDef::determineImplUsageRelation()
       
  2519 {
       
  2520   MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
       
  2521   MemberNameInfo *mni;
       
  2522   for (;(mni=mnili.current());++mnili)
       
  2523   {
       
  2524     MemberNameInfoIterator mnii(*mni);
       
  2525     MemberInfo *mi;
       
  2526     for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  2527     {
       
  2528       MemberDef *md=mi->memberDef;
       
  2529       if (md->isVariable()) // for each member variable in this class
       
  2530       {
       
  2531         QCString type=removeRedundantWhiteSpace(md->typeString());
       
  2532         //printf("in class %s found var type=`%s' name=`%s'\n",
       
  2533         //            name().data(),type.data(),md->name().data());
       
  2534         int pos=0;
       
  2535         QCString usedClassName;
       
  2536         QCString templSpec;
       
  2537         bool found=FALSE;
       
  2538         while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
       
  2539         {
       
  2540           //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
       
  2541           // check if usedClassName is a template argument of its class
       
  2542           ClassDef *cd=md->getClassDef();
       
  2543           if (cd && cd->templateArguments())
       
  2544           {
       
  2545             ArgumentListIterator ali(*cd->templateArguments());
       
  2546             Argument *arg;
       
  2547             int count=0;
       
  2548             for (ali.toFirst();(arg=ali.current());++ali,++count)
       
  2549             {
       
  2550               if (arg->name==usedClassName) // type is a template argument
       
  2551               {
       
  2552                 found=TRUE;
       
  2553                 if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257); 
       
  2554                 cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
       
  2555                     usedClassName,ClassDef::Class);
       
  2556                 cd->setIsTemplateBaseClass(count);
       
  2557                 UsesClassDef *ucd = new UsesClassDef(cd);
       
  2558                 m_impl->usesImplClassDict->insert(cd->name(),ucd);
       
  2559                 ucd->templSpecifiers = templSpec;
       
  2560                 ucd->addAccessor(md->name());
       
  2561                 Doxygen::hiddenClasses.append(cd);
       
  2562                 //printf("Adding used template argument %s to class %s\n",
       
  2563                 //    cd->name().data(),name().data());
       
  2564                 //printf("Adding accessor %s to class %s\n",
       
  2565                 //    md->name().data(),ucd->classDef->name().data());
       
  2566               }
       
  2567             }
       
  2568           }
       
  2569 
       
  2570           if (!found)
       
  2571           {
       
  2572             cd=0;
       
  2573             if (getNamespaceDef()!=0)
       
  2574             {
       
  2575               cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
       
  2576             }
       
  2577             if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
       
  2578             if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try inbetween scopes!
       
  2579             //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
       
  2580             if (cd) // class exists 
       
  2581             {
       
  2582               found=TRUE;
       
  2583               if (m_impl->usesImplClassDict==0) 
       
  2584               {
       
  2585                 m_impl->usesImplClassDict = new UsesClassDict(257); 
       
  2586                 m_impl->usesImplClassDict->setAutoDelete(TRUE);
       
  2587               }
       
  2588               UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
       
  2589               if (ucd==0 || ucd->templSpecifiers!=templSpec)
       
  2590               {
       
  2591                 ucd = new UsesClassDef(cd);
       
  2592                 m_impl->usesImplClassDict->insert(cd->name(),ucd);
       
  2593                 ucd->templSpecifiers = templSpec;
       
  2594                 //printf("Adding used class %s to class %s\n",
       
  2595                 //    cd->name().data(),name().data());
       
  2596               }
       
  2597               ucd->addAccessor(md->name());
       
  2598               //printf("Adding accessor %s to class %s\n",
       
  2599               //    md->name().data(),ucd->classDef->name().data());
       
  2600             }
       
  2601           }
       
  2602         }
       
  2603       }
       
  2604     }
       
  2605   }
       
  2606 #ifdef DUMP
       
  2607   if (m_impl->usesClassDict)
       
  2608   {
       
  2609     msg("Class %s uses the following classes:\n",name().data());
       
  2610     UsesClassDictIterator ucdi(*m_impl->usesClassDict);
       
  2611     UsesClassDef *ucd;
       
  2612     for (;(ucd=ucdi.current());++ucdi)
       
  2613     {
       
  2614       msg("  %s via ",ucd->classDef->name().data());
       
  2615       QDictIterator<void> dvi(*ucd->accessors); 
       
  2616       const char *s;
       
  2617       for (;(s=dvi.currentKey());++dvi)
       
  2618       {
       
  2619         msg("%s ",s);
       
  2620       }
       
  2621       msg("\n");
       
  2622     }
       
  2623   }
       
  2624 #endif
       
  2625 }
       
  2626 
       
  2627 //----------------------------------------------------------------------------
       
  2628 
       
  2629 // I have disabled this code because the graphs it renders quickly become
       
  2630 // too large to be of practical use.
       
  2631 
       
  2632 void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
       
  2633 {
       
  2634   QCString type = typeStr;
       
  2635   static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
       
  2636   int p=0,i,l;
       
  2637   while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
       
  2638   {
       
  2639     ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
       
  2640     if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try inbetween scopes!
       
  2641     if (cd && cd!=this && !isBaseClass(cd))
       
  2642     {
       
  2643       if (m_impl->usesIntfClassDict==0) 
       
  2644       {
       
  2645         m_impl->usesIntfClassDict = new UsesClassDict(257); 
       
  2646       }
       
  2647       UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
       
  2648       if (ucd==0)
       
  2649       {
       
  2650         ucd = new UsesClassDef(cd);
       
  2651         m_impl->usesIntfClassDict->insert(cd->name(),ucd);
       
  2652         //printf("in class `%s' adding used intf class `%s'\n",
       
  2653         //  name().data(),cd->name().data());
       
  2654       }
       
  2655       ucd->addAccessor(md->name());
       
  2656       //printf("in class `%s' adding accessor `%s' to class `%s'\n",
       
  2657       //    name().data(),md->name().data(),ucd->classDef->name().data());
       
  2658     }
       
  2659     p=i+l;
       
  2660   }
       
  2661 }
       
  2662 
       
  2663 void ClassDef::determineIntfUsageRelation()
       
  2664 {
       
  2665   MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
       
  2666   MemberNameInfo *mni;
       
  2667   for (;(mni=mnili.current());++mnili)
       
  2668   {
       
  2669     MemberNameInfoIterator mnii(*mni);
       
  2670     MemberInfo *mi;
       
  2671     for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  2672     {
       
  2673       MemberDef *md=mi->memberDef;
       
  2674       
       
  2675       // compute the protection level for this member
       
  2676       Protection protect=md->protection();
       
  2677       if (mi->prot==Protected) // inherited protection
       
  2678       {
       
  2679         if (protect==Public) protect=Protected;
       
  2680         else if (protect==Protected) protect=Private;
       
  2681       }
       
  2682       
       
  2683       if (!md->name().isEmpty() && md->name()[0]!='@' && 
       
  2684           (mi->prot!=Private && protect!=Private)
       
  2685          )
       
  2686       {
       
  2687         // add classes found in the return type
       
  2688         addUsedInterfaceClasses(md,md->typeString());
       
  2689         ArgumentList *al = md->argumentList();
       
  2690         if (al) // member has arguments
       
  2691         {
       
  2692           // add classes found in the types of the argument list
       
  2693           ArgumentListIterator ali(*al);
       
  2694           Argument *a;
       
  2695           for (;(a=ali.current());++ali)
       
  2696           {
       
  2697             if (!a->type.isEmpty() && a->type.at(0)!='@')
       
  2698             {
       
  2699               addUsedInterfaceClasses(md,a->type);
       
  2700             }
       
  2701           }
       
  2702         }
       
  2703       }
       
  2704     }
       
  2705   }
       
  2706 }
       
  2707 #endif
       
  2708 
       
  2709 QCString ClassDef::compoundTypeString() const
       
  2710 {
       
  2711   if (m_impl->compType==Interface && m_impl->isObjC) return "class";
       
  2712   if (Config_getBool("OPTIMIZE_FOR_FORTRAN"))
       
  2713   {
       
  2714     switch (m_impl->compType)
       
  2715     {
       
  2716       case Class:     return "module";
       
  2717       case Struct:    return "type";
       
  2718       case Union:     return "union";
       
  2719       case Interface: return "interface";
       
  2720       case Protocol:  return "protocol";
       
  2721       case Category:  return "category";
       
  2722       case Exception: return "exception";
       
  2723       default:        return "unknown";
       
  2724     } 
       
  2725   }
       
  2726   else
       
  2727   {
       
  2728     switch (m_impl->compType)
       
  2729     {
       
  2730       case Class:     return "class";
       
  2731       case Struct:    return "struct";
       
  2732       case Union:     return "union";
       
  2733       case Interface: return "interface";
       
  2734       case Protocol:  return "protocol";
       
  2735       case Category:  return "category";
       
  2736       case Exception: return "exception";
       
  2737       default:        return "unknown";
       
  2738     }
       
  2739   }
       
  2740 }
       
  2741 
       
  2742 QCString ClassDef::getOutputFileBase() const 
       
  2743 { 
       
  2744   if (m_impl->templateMaster)
       
  2745   {
       
  2746     return m_impl->templateMaster->getOutputFileBase();
       
  2747   }
       
  2748   else if (isReference())
       
  2749   {
       
  2750     return m_impl->fileName;
       
  2751   }
       
  2752   else
       
  2753   {
       
  2754     return convertNameToFile(m_impl->fileName); 
       
  2755   }
       
  2756 }
       
  2757 
       
  2758 QCString ClassDef::getInstanceOutputFileBase() const 
       
  2759 { 
       
  2760   if (isReference())
       
  2761   {
       
  2762     return m_impl->fileName;
       
  2763   }
       
  2764   else
       
  2765   {
       
  2766     return convertNameToFile(m_impl->fileName); 
       
  2767   }
       
  2768 }
       
  2769 
       
  2770 QCString ClassDef::getFileBase() const 
       
  2771 { 
       
  2772   if (m_impl->templateMaster)
       
  2773   {
       
  2774     return m_impl->templateMaster->getFileBase();
       
  2775   }
       
  2776   else
       
  2777   {
       
  2778     return m_impl->fileName; 
       
  2779   }
       
  2780 }
       
  2781 
       
  2782 QCString ClassDef::getSourceFileBase() const 
       
  2783 { 
       
  2784   if (m_impl->templateMaster)
       
  2785   {
       
  2786     return m_impl->templateMaster->getSourceFileBase();
       
  2787   }
       
  2788   else
       
  2789   {
       
  2790     return convertNameToFile(m_impl->fileName)+"_source"; 
       
  2791   }
       
  2792 }
       
  2793 
       
  2794 void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
       
  2795 {
       
  2796   gd->addClass(this);
       
  2797   //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
       
  2798   if (m_impl->allMemberNameInfoSDict==0) return;
       
  2799   MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
       
  2800   MemberNameInfo *mni;
       
  2801   for (;(mni=mnili.current());++mnili)
       
  2802   {
       
  2803     MemberNameInfoIterator mnii(*mni);
       
  2804     MemberInfo *mi;
       
  2805     for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  2806     {
       
  2807       MemberDef *md=mi->memberDef;
       
  2808       md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
       
  2809       gd->insertMember(md,TRUE);
       
  2810       ClassDef *innerClass = md->getClassDefOfAnonymousType();
       
  2811       if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
       
  2812     }
       
  2813   }
       
  2814 }
       
  2815 
       
  2816 void ClassDef::addInnerCompound(Definition *d)
       
  2817 {
       
  2818   //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
       
  2819   if (d->definitionType()==Definition::TypeClass) // only classes can be
       
  2820                                                   // nested in classes.
       
  2821   {
       
  2822     if (m_impl->innerClasses==0)
       
  2823     {
       
  2824       m_impl->innerClasses = new ClassSDict(17);
       
  2825     }
       
  2826     m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);
       
  2827   }
       
  2828 }
       
  2829 
       
  2830 Definition *ClassDef::findInnerCompound(const char *name)
       
  2831 {
       
  2832   Definition *result=0;
       
  2833   if (name==0) return 0;
       
  2834   if (m_impl->innerClasses)
       
  2835   {
       
  2836     result = m_impl->innerClasses->find(name);
       
  2837   }
       
  2838   return result;
       
  2839 }
       
  2840 
       
  2841 //void ClassDef::initTemplateMapping()
       
  2842 //{
       
  2843 //  m_impl->templateMapping->clear();
       
  2844 //  ArgumentList *al = templateArguments();
       
  2845 //  if (al)
       
  2846 //  {
       
  2847 //    ArgumentListIterator ali(*al);
       
  2848 //    Argument *arg;
       
  2849 //    for (ali.toFirst();(arg=ali.current());++ali)
       
  2850 //    {
       
  2851 //      setTemplateArgumentMapping(arg->name,arg->defval);
       
  2852 //    }
       
  2853 //  }
       
  2854 //}
       
  2855 //void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
       
  2856 //{
       
  2857 //  //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
       
  2858 //  if (m_impl->templateMapping && formal)
       
  2859 //  {
       
  2860 //    if (m_impl->templateMapping->find(formal))
       
  2861 //    {
       
  2862 //      m_impl->templateMapping->remove(formal);
       
  2863 //    }
       
  2864 //    m_impl->templateMapping->insert(formal,new QCString(actual));
       
  2865 //  }
       
  2866 //}
       
  2867 //
       
  2868 //QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
       
  2869 //{
       
  2870 //  if (m_impl->templateMapping && formal)
       
  2871 //  {
       
  2872 //    QCString *s = m_impl->templateMapping->find(formal);
       
  2873 //    if (s)
       
  2874 //    {
       
  2875 //      return *s;
       
  2876 //    }
       
  2877 //  }
       
  2878 //  return "";
       
  2879 //}
       
  2880 
       
  2881 ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
       
  2882     int startLine, const QCString &templSpec,bool &freshInstance)
       
  2883 {
       
  2884   freshInstance = FALSE;
       
  2885   if (m_impl->templateInstances==0) 
       
  2886   {
       
  2887     m_impl->templateInstances = new QDict<ClassDef>(17);
       
  2888   }
       
  2889   ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
       
  2890   if (templateClass==0)
       
  2891   {
       
  2892     Debug::print(Debug::Classes,0,"      New template instance class `%s'`%s'\n",name().data(),templSpec.data());
       
  2893     templateClass = new ClassDef(
       
  2894         fileName,startLine,localName()+templSpec,ClassDef::Class);
       
  2895     templateClass->setTemplateMaster(this);
       
  2896     templateClass->setOuterScope(getOuterScope());
       
  2897     templateClass->setHidden(isHidden());
       
  2898     m_impl->templateInstances->insert(templSpec,templateClass);
       
  2899     freshInstance=TRUE;
       
  2900   }
       
  2901   return templateClass;
       
  2902 }
       
  2903 
       
  2904 ClassDef *ClassDef::getVariableInstance(const char *templSpec)
       
  2905 {
       
  2906   if (m_impl->variableInstances==0) 
       
  2907   {
       
  2908     m_impl->variableInstances = new QDict<ClassDef>(17);
       
  2909     m_impl->variableInstances->setAutoDelete(TRUE);
       
  2910   }
       
  2911   ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
       
  2912   if (templateClass==0)
       
  2913   {
       
  2914     Debug::print(Debug::Classes,0,"      New template variable instance class `%s'`%s'\n",name().data(),templSpec);
       
  2915     templateClass = new ClassDef("<code>",1,name()+templSpec,
       
  2916                         ClassDef::Class,0,0,FALSE);
       
  2917     templateClass->addMembersToTemplateInstance( this, templSpec );
       
  2918     templateClass->setTemplateMaster(this);
       
  2919     m_impl->variableInstances->insert(templSpec,templateClass);
       
  2920   }
       
  2921   return templateClass;
       
  2922 }
       
  2923 
       
  2924 void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
       
  2925 {
       
  2926   if (templateNames==0) return;
       
  2927   if (m_impl->templBaseClassNames==0)
       
  2928   {
       
  2929     m_impl->templBaseClassNames = new QDict<int>(17);
       
  2930     m_impl->templBaseClassNames->setAutoDelete(TRUE);
       
  2931   }
       
  2932   // make a deep copy of the dictionary.
       
  2933   QDictIterator<int> qdi(*templateNames);
       
  2934   for (;qdi.current();++qdi)
       
  2935   {
       
  2936     if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
       
  2937     {
       
  2938       m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
       
  2939     }
       
  2940   }
       
  2941 }
       
  2942 
       
  2943 QDict<int> *ClassDef::getTemplateBaseClassNames() const
       
  2944 {
       
  2945   return m_impl->templBaseClassNames;
       
  2946 }
       
  2947 
       
  2948 void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
       
  2949 {
       
  2950   //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
       
  2951   if (cd->memberNameInfoSDict()==0) return;
       
  2952   MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());
       
  2953   MemberNameInfo *mni;
       
  2954   for (;(mni=mnili.current());++mnili)
       
  2955   {
       
  2956     MemberNameInfoIterator mnii(*mni);
       
  2957     MemberInfo *mi;
       
  2958     for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  2959     {
       
  2960       ArgumentList *actualArguments = new ArgumentList;
       
  2961       stringToArgumentList(templSpec,actualArguments);
       
  2962       MemberDef *md = mi->memberDef;
       
  2963       MemberDef *imd = md->createTemplateInstanceMember(
       
  2964                           cd->templateArguments(),actualArguments);
       
  2965       delete actualArguments;
       
  2966       //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
       
  2967       imd->setMemberClass(this);
       
  2968       imd->setTemplateMaster(md);
       
  2969       imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
       
  2970       imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
       
  2971       imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
       
  2972       imd->setMemberSpecifiers(md->getMemberSpecifiers());
       
  2973       imd->setMemberGroupId(md->getMemberGroupId());
       
  2974       insertMember(imd);
       
  2975       //printf("Adding member=%s %s%s to class %s templSpec %s\n",
       
  2976       //    imd->typeString(),imd->name().data(),imd->argsString(),
       
  2977       //    imd->getClassDef()->name().data(),templSpec);
       
  2978       // insert imd in the list of all members
       
  2979       //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
       
  2980       MemberName *mn = Doxygen::memberNameSDict->find(imd->name());
       
  2981       if (mn==0)
       
  2982       {
       
  2983         mn = new MemberName(imd->name());
       
  2984         Doxygen::memberNameSDict->append(imd->name(),mn);
       
  2985       }
       
  2986       mn->append(imd);
       
  2987     }
       
  2988   }
       
  2989 }
       
  2990 
       
  2991 QCString ClassDef::getReference() const
       
  2992 {
       
  2993   if (m_impl->templateMaster)
       
  2994   {
       
  2995     return m_impl->templateMaster->getReference();
       
  2996   }
       
  2997   else
       
  2998   {
       
  2999     return Definition::getReference();
       
  3000   }
       
  3001 }
       
  3002 
       
  3003 bool ClassDef::isReference() const
       
  3004 {
       
  3005   if (m_impl->templateMaster)
       
  3006   {
       
  3007     return m_impl->templateMaster->isReference();
       
  3008   }
       
  3009   else
       
  3010   {
       
  3011     return Definition::isReference();
       
  3012   }
       
  3013 }
       
  3014 
       
  3015 void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
       
  3016 {
       
  3017   Definition *d=getOuterScope();
       
  3018   if (d)
       
  3019   {
       
  3020     if (d->definitionType()==Definition::TypeClass)
       
  3021     {
       
  3022       ClassDef *cd=(ClassDef *)d;
       
  3023       cd->getTemplateParameterLists(lists);
       
  3024     }
       
  3025   }
       
  3026   if (templateArguments())
       
  3027   {
       
  3028     lists.append(templateArguments());
       
  3029   }
       
  3030 }
       
  3031 
       
  3032 QCString ClassDef::qualifiedNameWithTemplateParameters(
       
  3033     QList<ArgumentList> *actualParams) const
       
  3034 {
       
  3035   static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
       
  3036   static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
       
  3037   //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
       
  3038   QCString scName;
       
  3039   if (!hideScopeNames)
       
  3040   {
       
  3041     Definition *d=getOuterScope();
       
  3042     if (d)
       
  3043     {
       
  3044       if (d->definitionType()==Definition::TypeClass)
       
  3045       {
       
  3046         ClassDef *cd=(ClassDef *)d;
       
  3047         scName = cd->qualifiedNameWithTemplateParameters(actualParams);
       
  3048       }
       
  3049       else
       
  3050       {
       
  3051         scName = d->qualifiedName();
       
  3052       }
       
  3053     }
       
  3054 
       
  3055     QCString scopeSeparator;
       
  3056     if (optimizeOutputJava)
       
  3057       scopeSeparator=".";
       
  3058     else
       
  3059       scopeSeparator="::";
       
  3060 
       
  3061     if (!scName.isEmpty()) scName+=scopeSeparator;
       
  3062   }
       
  3063   scName+=className();
       
  3064   ArgumentList *al=0;
       
  3065   bool isSpecialization = localName().find('<')!=-1;
       
  3066   if (templateArguments())
       
  3067   {
       
  3068     if (actualParams && (al=actualParams->current()))
       
  3069     {
       
  3070       if (!isSpecialization)
       
  3071       {
       
  3072         scName+=tempArgListToString(al);
       
  3073       }
       
  3074       actualParams->next();
       
  3075     }
       
  3076     else
       
  3077     {
       
  3078       if (!isSpecialization)
       
  3079       {
       
  3080         scName+=tempArgListToString(templateArguments());
       
  3081       }
       
  3082     }
       
  3083   }
       
  3084   //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
       
  3085   return scName;
       
  3086 }
       
  3087 
       
  3088 QCString ClassDef::className() const
       
  3089 {
       
  3090   if (m_impl->className.isEmpty())
       
  3091   {
       
  3092     return localName();
       
  3093   }
       
  3094   else
       
  3095   {
       
  3096     return m_impl->className;
       
  3097   }
       
  3098 };
       
  3099 
       
  3100 void ClassDef::setClassName(const char *name)
       
  3101 {
       
  3102   m_impl->className = name;
       
  3103 }
       
  3104 
       
  3105 void ClassDef::addListReferences()
       
  3106 {
       
  3107   bool fortranOpt=Config_getBool("OPTIMIZE_FOR_FORTRAN");
       
  3108   if (!isLinkableInProject()) return;
       
  3109   //printf("ClassDef(%s)::addListReferences()\n",name().data());
       
  3110   {
       
  3111     LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
       
  3112     addRefItem(xrefItems.pointer(),
       
  3113              qualifiedName(),
       
  3114              fortranOpt?theTranslator->trType(TRUE,TRUE):
       
  3115                         theTranslator->trClass(TRUE,TRUE),
       
  3116              getOutputFileBase(),
       
  3117              displayName(),
       
  3118              0
       
  3119             );
       
  3120   }
       
  3121   if (m_impl->memberGroupSDict)
       
  3122   {
       
  3123     MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
       
  3124     MemberGroup *mg;
       
  3125     for (;(mg=mgli.current());++mgli)
       
  3126     {
       
  3127       mg->addListReferences(this);
       
  3128     }
       
  3129   }
       
  3130   QListIterator<MemberList> mli(m_impl->memberLists);
       
  3131   MemberList *ml;
       
  3132   for (mli.toFirst();(ml=mli.current());++mli)
       
  3133   {
       
  3134     if (ml->listType()&MemberList::detailedLists)
       
  3135     {
       
  3136       ml->addListReferences(this);
       
  3137     }
       
  3138   }
       
  3139 }
       
  3140 
       
  3141 MemberDef *ClassDef::getMemberByName(const QCString &name) const
       
  3142 {
       
  3143   MemberDef *xmd = 0;
       
  3144   if (m_impl->allMemberNameInfoSDict)
       
  3145   {
       
  3146     MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);
       
  3147     if (mni)
       
  3148     {
       
  3149       const int maxInheritanceDepth = 100000;
       
  3150       int mdist=maxInheritanceDepth;
       
  3151       MemberNameInfoIterator mnii(*mni);
       
  3152       MemberInfo *mi;
       
  3153       for (mnii.toFirst();(mi=mnii.current());++mnii)
       
  3154       {
       
  3155         ClassDef *mcd=mi->memberDef->getClassDef();
       
  3156         int m=minClassDistance(this,mcd);
       
  3157         //printf("found member in %s linkable=%d m=%d\n",
       
  3158         //    mcd->name().data(),mcd->isLinkable(),m);
       
  3159         if (m<mdist && mcd->isLinkable())
       
  3160         {
       
  3161           mdist=m;
       
  3162           xmd=mi->memberDef;
       
  3163         }
       
  3164       }
       
  3165     }
       
  3166   }
       
  3167   //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
       
  3168   return xmd;
       
  3169 }
       
  3170 
       
  3171 bool ClassDef::isAccessibleMember(MemberDef *md)
       
  3172 {
       
  3173   return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
       
  3174 }
       
  3175 
       
  3176 MemberList *ClassDef::createMemberList(MemberList::ListType lt)
       
  3177 {
       
  3178   m_impl->memberLists.setAutoDelete(TRUE);
       
  3179   QListIterator<MemberList> mli(m_impl->memberLists);
       
  3180   MemberList *ml;
       
  3181   for (mli.toFirst();(ml=mli.current());++mli)
       
  3182   {
       
  3183     if (ml->listType()==lt)
       
  3184     {
       
  3185       return ml;
       
  3186     }
       
  3187   }
       
  3188   // not found, create a new member list
       
  3189   ml = new MemberList(lt);
       
  3190   m_impl->memberLists.append(ml);
       
  3191   return ml;
       
  3192 }
       
  3193 
       
  3194 MemberList *ClassDef::getMemberList(MemberList::ListType lt)
       
  3195 {
       
  3196   MemberList *ml = m_impl->memberLists.first();
       
  3197   while (ml)
       
  3198   {
       
  3199     if (ml->listType()==lt)
       
  3200     {
       
  3201       return ml;
       
  3202     }
       
  3203     ml = m_impl->memberLists.next();
       
  3204   }
       
  3205   return 0;
       
  3206 }
       
  3207 
       
  3208 /** Need this to check the function, If we wait until we are trying
       
  3209 to insert a MemberDef thatn we will (a) have a memory leak and
       
  3210 (b) call makeresident on that MemberDef prematurely.
       
  3211 */
       
  3212 bool ClassDef::hasFunction(const QCString &theDef, Protection prot)
       
  3213 {
       
  3214 	bool retVal = false;
       
  3215 	switch (prot) {
       
  3216 		case Protected: 
       
  3217 			retVal = hasFunction(MemberList::proMethods, theDef);
       
  3218 			break;
       
  3219 		case Package: 
       
  3220 			retVal = hasFunction(MemberList::pacMethods, theDef);
       
  3221 			break;
       
  3222 		case Public:    
       
  3223 			retVal = hasFunction(MemberList::pubMethods, theDef);
       
  3224 			break;
       
  3225 		case Private:   
       
  3226 			retVal = hasFunction(MemberList::priMethods, theDef);
       
  3227 			break;
       
  3228 	}
       
  3229 	return retVal;
       
  3230 }
       
  3231 
       
  3232 bool ClassDef::hasFunction(MemberList::ListType lt, const QCString &theDef)
       
  3233 {
       
  3234 	MemberList *ml = createMemberList(lt);
       
  3235 	MemberListIterator mli(*ml);
       
  3236 	MemberDef *cmd;
       
  3237 	for (mli.toFirst(); (cmd = mli.current()); ++mli) {
       
  3238 		if (theDef == cmd->declaration()) {
       
  3239 			//printf("ClassDef::addMemberToList() rejecting duplicate %d \"%s::%s\"\n", md->memberType(), name().data(), md->declaration() ? md->declaration() : "");
       
  3240 			return true;
       
  3241 		}
       
  3242 	}
       
  3243 	return false;
       
  3244 }
       
  3245 
       
  3246 void ClassDef::addMemberToList(MemberList::ListType lt,MemberDef *md,bool isBrief)
       
  3247 {
       
  3248   static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
       
  3249   static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
       
  3250   MemberList *ml = createMemberList(lt);
       
  3251   /*
       
  3252   if (Config_getBool("PREPROCESS_INCLUDES")) {
       
  3253     // If we are preprocessing the #included files we might have seen
       
  3254     // this member  more than once so we
       
  3255     // only add a member where one did not exist before
       
  3256 	MemberListIterator mli(*ml);
       
  3257 	MemberDef *cmd;
       
  3258 	for (mli.toFirst(); (cmd = mli.current()); ++mli) {
       
  3259 		if (strcmp(md->declaration(), cmd->declaration()) == 0) {
       
  3260 		//if (md->anchor() == cmd->anchor()) {
       
  3261 			printf("ClassDef::addMemberToList() rejecting duplicate %d \"%s::%s\"\n", md->memberType(), name().data(), md->declaration() ? md->declaration() : "");
       
  3262 			// TODO: Delete md to avoid memory leak???
       
  3263 			// But some callers still use md after it has been inserted...
       
  3264 			return;
       
  3265 		}
       
  3266 	}
       
  3267   }
       
  3268   printf("ClassDef::addMemberToList() adding %d, \"%s::%s\"\n", md->memberType(), name().data(), md->declaration() ? md->declaration() : "");
       
  3269   */
       
  3270   if (( isBrief && sortBriefDocs ) ||
       
  3271       (!isBrief && sortMemberDocs)
       
  3272      )
       
  3273     ml->inSort(md);
       
  3274   else
       
  3275     ml->append(md);
       
  3276 
       
  3277   // for members in the declaration lists we set the section, needed for member grouping
       
  3278   if ((ml->listType()&MemberList::detailedLists)==0) md->setSectionList(this,ml);
       
  3279 }
       
  3280 
       
  3281 void ClassDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title,
       
  3282                const char *subTitle)
       
  3283 {
       
  3284   static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  3285   MemberList * ml = getMemberList(lt);
       
  3286   if (ml) 
       
  3287   {
       
  3288     if (optimizeVhdl) // use specific declarations function
       
  3289     {
       
  3290       VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0);
       
  3291     }
       
  3292     else // ise generic declaration function
       
  3293     {
       
  3294       ml->writeDeclarations(ol,this,0,0,0,title,subTitle); 
       
  3295     }
       
  3296   }
       
  3297 }
       
  3298 
       
  3299 void ClassDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title)
       
  3300 {
       
  3301   MemberList * ml = getMemberList(lt);
       
  3302   if (ml) ml->writeDocumentation(ol,name(),this,title);
       
  3303 }
       
  3304 
       
  3305 void ClassDef::writePlainMemberDeclaration(OutputList &ol,MemberList::ListType lt,bool inGroup)
       
  3306 {
       
  3307   MemberList * ml = getMemberList(lt);
       
  3308   if (ml) 
       
  3309   {
       
  3310     ml->setInGroup(inGroup);
       
  3311     ml->writePlainDeclarations(ol,this,0,0,0); 
       
  3312   }
       
  3313 }
       
  3314 
       
  3315 bool ClassDef::isLocal() const 
       
  3316 { 
       
  3317   return m_impl->isLocal; 
       
  3318 }
       
  3319 
       
  3320 ClassSDict *ClassDef::getInnerClasses() 
       
  3321 { 
       
  3322   return m_impl->innerClasses; 
       
  3323 }
       
  3324 
       
  3325 ClassDef::CompoundType ClassDef::compoundType() const 
       
  3326 { 
       
  3327   return m_impl->compType; 
       
  3328 } 
       
  3329 
       
  3330 BaseClassList *ClassDef::baseClasses() const
       
  3331 { 
       
  3332   return m_impl->inherits; 
       
  3333 }
       
  3334 
       
  3335 BaseClassList *ClassDef::subClasses() const
       
  3336 { 
       
  3337   return m_impl->inheritedBy; 
       
  3338 }
       
  3339 
       
  3340 MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const
       
  3341 { 
       
  3342   return m_impl->allMemberNameInfoSDict; 
       
  3343 }
       
  3344 
       
  3345 Protection ClassDef::protection() const 
       
  3346 { 
       
  3347   return m_impl->prot; 
       
  3348 }
       
  3349 
       
  3350 ArgumentList *ClassDef::templateArguments() const 
       
  3351 { 
       
  3352   return m_impl->tempArgs; 
       
  3353 }
       
  3354 
       
  3355 NamespaceDef *ClassDef::getNamespaceDef() const
       
  3356 { 
       
  3357   return m_impl->nspace; 
       
  3358 }
       
  3359 
       
  3360 FileDef *ClassDef::getFileDef() const 
       
  3361 { 
       
  3362   return m_impl->fileDef; 
       
  3363 }
       
  3364 
       
  3365 QDict<ClassDef> *ClassDef::getTemplateInstances() const 
       
  3366 { 
       
  3367   return m_impl->templateInstances; 
       
  3368 }
       
  3369 
       
  3370 ClassDef *ClassDef::templateMaster() const 
       
  3371 { 
       
  3372   return m_impl->templateMaster; 
       
  3373 } 
       
  3374 
       
  3375 bool ClassDef::isTemplate() const 
       
  3376 { 
       
  3377   return m_impl->tempArgs!=0; 
       
  3378 }
       
  3379 
       
  3380 IncludeInfo *ClassDef::includeInfo() const 
       
  3381 { 
       
  3382   return m_impl->incInfo; 
       
  3383 }
       
  3384 
       
  3385 UsesClassDict *ClassDef::usedImplementationClasses() const 
       
  3386 { 
       
  3387   return m_impl->usesImplClassDict; 
       
  3388 }
       
  3389 
       
  3390 UsesClassDict *ClassDef::usedByImplementationClasses() const 
       
  3391 { 
       
  3392   return m_impl->usedByImplClassDict; 
       
  3393 }
       
  3394 
       
  3395 UsesClassDict *ClassDef::usedInterfaceClasses() const
       
  3396 {
       
  3397   return m_impl->usesIntfClassDict;
       
  3398 }
       
  3399 
       
  3400 bool ClassDef::isTemplateArgument() const
       
  3401 {
       
  3402   return m_impl->isTemplArg;
       
  3403 }
       
  3404 
       
  3405 bool ClassDef::isAbstract() const 
       
  3406 { 
       
  3407   return m_impl->isAbstract; 
       
  3408 }
       
  3409 
       
  3410 bool ClassDef::isObjectiveC() const 
       
  3411 { 
       
  3412   return m_impl->isObjC; 
       
  3413 }
       
  3414 
       
  3415 ClassDef *ClassDef::categoryOf() const 
       
  3416 { 
       
  3417   return m_impl->categoryOf; 
       
  3418 }
       
  3419 
       
  3420 const QList<MemberList> &ClassDef::getMemberLists() const 
       
  3421 { 
       
  3422   return m_impl->memberLists; 
       
  3423 }
       
  3424 
       
  3425 MemberGroupSDict *ClassDef::getMemberGroupSDict() const 
       
  3426 { 
       
  3427   return m_impl->memberGroupSDict; 
       
  3428 }
       
  3429 
       
  3430 void ClassDef::setNamespace(NamespaceDef *nd) 
       
  3431 { 
       
  3432   m_impl->nspace = nd; 
       
  3433 }
       
  3434 
       
  3435 void ClassDef::setFileDef(FileDef *fd) 
       
  3436 { 
       
  3437   m_impl->fileDef=fd; 
       
  3438 }
       
  3439 
       
  3440 void ClassDef::setSubGrouping(bool enabled) 
       
  3441 { 
       
  3442   m_impl->subGrouping = enabled; 
       
  3443 }
       
  3444 
       
  3445 void ClassDef::setProtection(Protection p) 
       
  3446 { 
       
  3447   m_impl->prot=p; 
       
  3448 }
       
  3449 
       
  3450 void ClassDef::setIsStatic(bool b) 
       
  3451 { 
       
  3452   m_impl->isStatic=b; 
       
  3453 }
       
  3454 
       
  3455 void ClassDef::setIsObjectiveC(bool b) 
       
  3456 { 
       
  3457   m_impl->isObjC=b; 
       
  3458 }
       
  3459 
       
  3460 void ClassDef::setCompoundType(CompoundType t) 
       
  3461 { 
       
  3462   m_impl->compType = t; 
       
  3463 } 
       
  3464 
       
  3465 void ClassDef::setTemplateMaster(ClassDef *tm) 
       
  3466 { 
       
  3467   m_impl->templateMaster=tm; 
       
  3468 }
       
  3469 
       
  3470 void ClassDef::makeTemplateArgument(bool b) 
       
  3471 { 
       
  3472   m_impl->isTemplArg = b; 
       
  3473 }
       
  3474 
       
  3475 void ClassDef::setCategoryOf(ClassDef *cd)
       
  3476 {
       
  3477   m_impl->categoryOf = cd;
       
  3478 }
       
  3479 
       
  3480 void ClassDef::setUsedOnly(bool b)
       
  3481 {
       
  3482   m_impl->usedOnly = b;
       
  3483 }
       
  3484 
       
  3485 bool ClassDef::isUsedOnly() const
       
  3486 {
       
  3487   return m_impl->usedOnly;
       
  3488 }
       
  3489 
       
  3490 void ClassDef::reclassifyMember(MemberDef *md,MemberDef::MemberType t)
       
  3491 {
       
  3492   md->setMemberType(t);
       
  3493   MemberList *ml = m_impl->memberLists.first();
       
  3494   while (ml)
       
  3495   {
       
  3496     ml->remove(md);
       
  3497     ml = m_impl->memberLists.next();
       
  3498   }
       
  3499   insertMember(md);
       
  3500 }
       
  3501