My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
classdef.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  * Copyright (C) 1997-2015 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 #include "arguments.h"
42 #include "memberlist.h"
43 #include "groupdef.h"
44 #include "filedef.h"
45 #include "namespacedef.h"
46 #include "membergroup.h"
47 
48 //-----------------------------------------------------------------------------
49 
52 {
53  public:
54  ClassDefImpl();
55  ~ClassDefImpl();
56  void init(const char *defFileName, const char *name,
57  const QCString &ctStr, const char *fName);
58 
63  QCString fileName;
64 
67 
69  QCString collabFileName;
70 
72  QCString inheritFileName;
73 
78 
83 
87 
92 
95 
98 
101 
104 
107 
110 
113 
119 
124 
125  /* classes for the collaboration diagram */
129 
131 
135  QDict<ClassDef> *templateInstances;
136 
141  QDict<ClassDef> *variableInstances;
142 
143  QDict<int> *templBaseClassNames;
144 
147 
149  QCString className;
150 
155 
156  QList<MemberList> memberLists;
157 
158  /* user defined member groups */
160 
163 
165  bool isStatic;
166 
169 
171  bool isLocal;
172 
174 
180 
182  bool usedOnly;
183 
186 
188  bool isSimple;
189 
192 
195 
198 
199  bool isGeneric;
200 
202 
203  uint64 spec;
204 };
205 
206 void ClassDefImpl::init(const char *defFileName, const char *name,
207  const QCString &ctStr, const char *fName)
208 {
209  if (fName)
210  {
211  fileName=stripExtension(fName);
212  }
213  else
214  {
215  fileName=ctStr+name;
216  }
217  exampleSDict = 0;
218  inherits = 0;
219  inheritedBy = 0;
221  incInfo=0;
222  tempArgs=0;
223  typeConstraints=0;
224  prot=Public;
225  nspace=0;
226  fileDef=0;
231  memberGroupSDict = 0;
232  innerClasses = 0;
233  subGrouping=Config_getBool(SUBGROUPING);
234  templateInstances = 0;
235  variableInstances = 0;
236  templateMaster =0;
238  isAbstract = FALSE;
239  isStatic = FALSE;
240  isTemplArg = FALSE;
241  membersMerged = FALSE;
242  categoryOf = 0;
243  usedOnly = FALSE;
244  isSimple = Config_getBool(INLINE_SIMPLE_STRUCTS);
245  arrowOperator = 0;
246  taggedInnerClasses = 0;
247  tagLessRef = 0;
248  spec=0;
249  //QCString ns;
250  //extractNamespaceName(name,className,ns);
251  //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
252 
253  // we cannot use getLanguage at this point, as setLanguage has not been called.
254  SrcLangExt lang = getLanguageFromFileName(defFileName);
255  if ((lang==SrcLangExt_Cpp || lang==SrcLangExt_ObjC) &&
256  guessSection(defFileName)==Entry::SOURCE_SEC)
257  {
258  isLocal=TRUE;
259  }
260  else
261  {
262  isLocal=FALSE;
263  }
264  isGeneric = (lang==SrcLangExt_CSharp || lang==SrcLangExt_Java) && QCString(name).find('<')!=-1;
265  isAnonymous = QCString(name).find('@')!=-1;
266 }
267 
268 ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)
269 {
271 }
272 
274 {
275  delete inherits;
276  delete inheritedBy;
277  delete allMemberNameInfoSDict;
278  delete exampleSDict;
279  delete usesImplClassDict;
280  delete usedByImplClassDict;
281  delete usesIntfClassDict;
282  delete constraintClassDict;
283  delete incInfo;
284  delete memberGroupSDict;
285  delete innerClasses;
286  delete templateInstances;
287  delete variableInstances;
288  delete templBaseClassNames;
289  delete tempArgs;
290  delete typeConstraints;
291  delete taggedInnerClasses;
292 }
293 
294 // constructs a new class definition
296  const char *defFileName,int defLine,int defColumn,
297  const char *nm,CompoundType ct,
298  const char *lref,const char *fName,
299  bool isSymbol,bool isJavaEnum)
300  : Definition(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol)
301 {
302  visited=FALSE;
303  setReference(lref);
304  m_impl = new ClassDefImpl;
305  m_impl->compType = ct;
307  m_impl->init(defFileName,name(),compoundTypeString(),fName);
311  if (!lref)
312  {
314  }
315 }
316 
317 // destroy the class definition
319 {
320  delete m_impl;
321 }
322 
324 {
325  return m_impl->memberListFileName;
326 }
327 
328 QCString ClassDef::displayName(bool includeScope) const
329 {
330  //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
331  SrcLangExt lang = getLanguage();
332  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
333  QCString n;
334  if (lang==SrcLangExt_VHDL)
335  {
336  n = VhdlDocGen::getClassName(this);
337  }
338  else
339  {
340  if (includeScope)
341  {
343  }
344  else
345  {
346  n=className();
347  }
348  }
349  QCString sep=getLanguageSpecificSeparator(lang);
350  if (sep!="::")
351  {
352  n=substitute(n,"::",sep);
353  }
354  if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
355  {
356  n="<"+n.left(n.length()-2)+">";
357  }
358  //else if (n.right(2)=="-g")
359  //{
360  // n = n.left(n.length()-2);
361  //}
362  //printf("ClassDef::displayName()=%s\n",n.data());
363  if (n.find('@')!=-1)
364  {
365  return removeAnonymousScopes(n);
366  }
367  else
368  {
369  return n;
370  }
371 }
372 
373 // inserts a base/super class in the inheritance list
375  Specifier s,const char *t)
376 {
377  //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
378  //inherits->inSort(new BaseClassDef(cd,p,s,t));
379  if (m_impl->inherits==0)
380  {
382  m_impl->inherits->setAutoDelete(TRUE);
383  }
384  m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
385  m_impl->isSimple = FALSE;
386 }
387 
388 // inserts a derived/sub class in the inherited-by list
390  Specifier s,const char *t)
391 {
392  //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
393  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
394  if (!extractPrivate && cd->protection()==Private) return;
395  if (m_impl->inheritedBy==0)
396  {
398  m_impl->inheritedBy->setAutoDelete(TRUE);
399  }
400  m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
401  m_impl->isSimple = FALSE;
402 }
403 
405 {
406  QListIterator<MemberList> mli(m_impl->memberLists);
407  MemberList *ml;
408  for (mli.toFirst();(ml=mli.current());++mli)
409  {
410  if ((ml->listType()&MemberListType_detailedLists)==0)
411  {
413  }
414  }
415 
416  // add members inside sections to their groups
418  {
420  MemberGroup *mg;
421  for (;(mg=mgli.current());++mgli)
422  {
424  {
425  //printf("addToDeclarationSection(%s)\n",mg->header().data());
427  }
428  }
429  }
430 }
431 
432 // adds new member definition to the class
434  Protection prot,
435  bool addToAllList
436  )
437 {
438  //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
439  if (md->isHidden()) return;
440 
442  {
443  QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
444  if (!m_impl->vhdlSummaryTitles.find(title))
445  {
446  m_impl->vhdlSummaryTitles.append(title,new QCString(title));
447  }
448  }
449 
450  if (1 ) // changed to 1 for showing members of external
451  // classes when HAVE_DOT and UML_LOOK are enabled.
452  {
453  bool isSimple=FALSE;
454 
455  /********************************************/
456  /* insert member in the declaration section */
457  /********************************************/
458  if (md->isRelated() && protectionLevelVisible(prot))
459  {
461  }
462  else if (md->isFriend())
463  {
465  }
466  else
467  {
468  switch (md->memberType())
469  {
470  case MemberType_Service: // UNO IDL
472  break;
473  case MemberType_Interface: // UNO IDL
475  break;
476  case MemberType_Signal: // Qt specific
478  break;
479  case MemberType_DCOP: // KDE2 specific
481  break;
482  case MemberType_Property:
484  break;
485  case MemberType_Event:
487  break;
488  case MemberType_Slot: // Qt specific
489  switch (prot)
490  {
491  case Protected:
492  case Package: // slots in packages are not possible!
494  break;
495  case Public:
497  break;
498  case Private:
500  break;
501  }
502  break;
503  default: // any of the other members
504  if (md->isStatic())
505  {
506  if (md->isVariable())
507  {
508  switch (prot)
509  {
510  case Protected:
512  break;
513  case Package:
515  break;
516  case Public:
518  break;
519  case Private:
521  break;
522  }
523  }
524  else // function
525  {
526  switch (prot)
527  {
528  case Protected:
530  break;
531  case Package:
533  break;
534  case Public:
536  break;
537  case Private:
539  break;
540  }
541  }
542  }
543  else // not static
544  {
545  if (md->isVariable())
546  {
547  switch (prot)
548  {
549  case Protected:
551  break;
552  case Package:
554  break;
555  case Public:
557  isSimple=!md->isFunctionPtr();
558  break;
559  case Private:
561  break;
562  }
563  }
564  else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
565  {
566  switch (prot)
567  {
568  case Protected:
570  break;
571  case Package:
573  break;
574  case Public:
576  isSimple=QCString(md->typeString()).find(")(")==-1;
577  break;
578  case Private:
580  break;
581  }
582  }
583  else // member function
584  {
585  switch (prot)
586  {
587  case Protected:
589  break;
590  case Package:
592  break;
593  case Public:
595  break;
596  case Private:
598  break;
599  }
600  }
601  }
602  break;
603  }
604  }
605  if (!isSimple) // not a simple field -> not a simple struct
606  {
607  m_impl->isSimple = FALSE;
608  }
609  //printf("adding %s simple=%d total_simple=%d\n",name().data(),isSimple,m_impl->isSimple);
610 
611  /*******************************************************/
612  /* insert member in the detailed documentation section */
613  /*******************************************************/
614  if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
615  {
617  }
618  else
619  {
620  switch (md->memberType())
621  {
622  case MemberType_Service: // UNO IDL
624  break;
625  case MemberType_Interface: // UNO IDL
627  break;
628  case MemberType_Property:
630  break;
631  case MemberType_Event:
633  break;
634  case MemberType_Signal: // fall through
635  case MemberType_DCOP:
637  break;
638  case MemberType_Slot:
639  if (protectionLevelVisible(prot))
640  {
642  }
643  break;
644  default: // any of the other members
645  if (protectionLevelVisible(prot))
646  {
647  switch (md->memberType())
648  {
649  case MemberType_Typedef:
651  break;
654  break;
657  break;
658  case MemberType_Function:
659  if (md->isConstructor() || md->isDestructor())
660  {
662  ml->append(md);
663  }
664  else
665  {
667  }
668  break;
669  case MemberType_Variable:
671  break;
672  default:
673  err("Unexpected member type %d found!\n",md->memberType());
674  }
675  }
676  break;
677  }
678  }
679 
680  /*************************************************/
681  /* insert member in the appropriate member group */
682  /*************************************************/
683  // Note: this must be done AFTER inserting the member in the
684  // regular groups
685  //addMemberToGroup(md,groupId);
686 
687  }
688 
689  if (md->virtualness()==Pure)
690  {
691  m_impl->isAbstract=TRUE;
692  }
693 
694  if (md->name()=="operator->")
695  {
696  m_impl->arrowOperator=md;
697  }
698 
699  //::addClassMemberNameToIndex(md);
700  if (addToAllList &&
701  !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
702  md->isFriend() &&
703  (QCString(md->typeString())=="friend class" ||
704  QCString(md->typeString())=="friend struct" ||
705  QCString(md->typeString())=="friend union")))
706  {
707  //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
708  MemberInfo *mi = new MemberInfo((MemberDef *)md,
709  prot,md->virtualness(),FALSE);
710  MemberNameInfo *mni=0;
712  {
715  }
716  if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
717  {
718  mni->append(mi);
719  }
720  else
721  {
722  mni = new MemberNameInfo(md->name());
723  mni->append(mi);
724  m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
725  }
726  }
727 }
728 
730 {
731  internalInsertMember(md,md->protection(),TRUE);
732 }
733 
734 // compute the anchors for all members
736 {
737  //ClassDef *context = Config_getBool(INLINE_INHERITED_MEMB) ? this : 0;
738  //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
739  QListIterator<MemberList> mli(m_impl->memberLists);
740  MemberList *ml;
741  //int index = 0;
742  for (mli.toFirst();(ml=mli.current());++mli)
743  {
744  if ((ml->listType()&MemberListType_detailedLists)==0)
745  {
746  setAnchors(ml);
747  }
748  }
749 
751  {
753  MemberGroup *mg;
754  for (;(mg=mgli.current());++mgli)
755  {
756  mg->setAnchors();
757  }
758  }
759 }
760 
762 {
764  {
766  MemberGroup *mg;
767  for (;(mg=mgli.current());++mgli)
768  {
770  }
771  }
772 }
773 
775 {
778  {
780  MemberGroup *mg;
781  for (;(mg=mgli.current());++mgli)
782  {
784  }
785  }
786  QListIterator<MemberList> mli(m_impl->memberLists);
787  MemberList *ml;
788  for (mli.toFirst();(ml=mli.current());++mli)
789  {
790  if ((ml->listType()&MemberListType_detailedLists)==0)
791  {
793  }
794  }
795 }
796 
797 
798 // add a file name to the used files set
800 {
801  if (fd==0) return;
802  if (m_impl->files.find(fd)==-1) m_impl->files.append(fd);
804  {
805  QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
806  ClassDef *cd;
807  for (qdi.toFirst();(cd=qdi.current());++qdi)
808  {
809  cd->insertUsedFile(fd);
810  }
811  }
812 }
813 
815 {
816  if (bcd->prot!=Public || bcd->virt!=Normal)
817  {
818  ol.startTypewriter();
819  ol.docify(" [");
820  QStrList sl;
821  if (bcd->prot==Protected) sl.append("protected");
822  else if (bcd->prot==Private) sl.append("private");
823  if (bcd->virt==Virtual) sl.append("virtual");
824  const char *s=sl.first();
825  while (s)
826  {
827  ol.docify(s);
828  s=sl.next();
829  if (s) ol.docify(", ");
830  }
831  ol.docify("]");
832  ol.endTypewriter();
833  }
834 }
835 
837  const char *includeName,bool local, bool force)
838 {
839  //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
841  if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
842  (fd!=0 && m_impl->incInfo->fileDef==0)
843  )
844  {
845  //printf("Setting file info\n");
846  m_impl->incInfo->fileDef = fd;
847  m_impl->incInfo->includeName = includeName;
848  m_impl->incInfo->local = local;
849  }
850  if (force && includeName)
851  {
852  m_impl->incInfo->includeName = includeName;
853  m_impl->incInfo->local = local;
854  }
855 }
856 
857 // TODO: fix this: a nested template class can have multiple outer templates
858 //ArgumentList *ClassDef::outerTemplateArguments() const
859 //{
860 // int ti;
861 // ClassDef *pcd=0;
862 // int pi=0;
863 // if (m_impl->tempArgs) return m_impl->tempArgs;
864 // // find the outer most class scope
865 // while ((ti=name().find("::",pi))!=-1 &&
866 // (pcd=getClass(name().left(ti)))==0
867 // ) pi=ti+2;
868 // if (pcd)
869 // {
870 // return pcd->templateArguments();
871 // }
872 // return 0;
873 //}
874 
875 static void searchTemplateSpecs(/*in*/ Definition *d,
876  /*out*/ QList<ArgumentList> &result,
877  /*out*/ QCString &name,
878  /*in*/ SrcLangExt lang)
879 {
881  {
882  if (d->getOuterScope())
883  {
884  searchTemplateSpecs(d->getOuterScope(),result,name,lang);
885  }
886  ClassDef *cd=(ClassDef *)d;
887  if (!name.isEmpty()) name+="::";
888  QCString clName = d->localName();
889  if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p")
890  {
891  clName = clName.left(clName.length()-2);
892  }
893  name+=clName;
894  bool isSpecialization = d->localName().find('<')!=-1;
895  if (cd->templateArguments())
896  {
897  result.append(cd->templateArguments());
898  if (!isSpecialization)
899  {
900  name+=tempArgListToString(cd->templateArguments(),lang);
901  }
902  }
903  }
904  else
905  {
906  name+=d->qualifiedName();
907  }
908 }
909 
911  const QCString &type,SrcLangExt lang)
912 {
913  QList<ArgumentList> specs;
914  QCString name;
915  searchTemplateSpecs(d,specs,name,lang);
916  if (specs.count()>0) // class has template scope specifiers
917  {
918  ol.startSubsubsection();
919  QListIterator<ArgumentList> spi(specs);
920  ArgumentList *al;
921  for (spi.toFirst();(al=spi.current());++spi)
922  {
923  ol.docify("template<");
924  QListIterator<Argument> ali(*al);
925  Argument *a;
926  while ((a=ali.current()))
927  {
928  ol.docify(a->type);
929  if (!a->name.isEmpty())
930  {
931  ol.docify(" ");
932  ol.docify(a->name);
933  }
934  if (a->defval.length()!=0)
935  {
936  ol.docify(" = ");
937  ol.docify(a->defval);
938  }
939  ++ali;
940  a=ali.current();
941  if (a) ol.docify(", ");
942  }
943  ol.docify(">");
944  ol.lineBreak();
945  }
946  ol.docify(type.lower()+" "+name);
947  ol.endSubsubsection();
948  ol.writeString("\n");
949  }
950 }
951 
952 void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
953 {
954  if (hasBriefDescription())
955  {
956  ol.startParagraph();
957  ol.generateDoc(briefFile(),briefLine(),this,0,
958  briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
959  ol.pushGeneratorState();
961  ol.writeString(" \n");
963  ol.popGeneratorState();
964 
965  if (hasDetailedDescription() || exampleFlag)
966  {
967  writeMoreLink(ol,anchor());
968  }
969 
970  ol.endParagraph();
971  }
972  ol.writeSynopsis();
973 }
974 
976 {
977  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
978 
979  ol.startTextBlock();
980 
982  {
984  }
985 
986  // repeat brief description
987  if (!briefDescription().isEmpty() && repeatBrief)
988  {
989  ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
990  }
991  if (!briefDescription().isEmpty() && repeatBrief &&
992  !documentation().isEmpty())
993  {
994  ol.pushGeneratorState();
996  ol.writeString("\n\n");
997  ol.popGeneratorState();
998  }
999  // write documentation
1000  if (!documentation().isEmpty())
1001  {
1002  ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
1003  }
1004  // write type constraints
1006 
1007  // write examples
1008  if (hasExamples() && m_impl->exampleSDict)
1009  {
1011  ol.startDescForItem();
1012  //ol.startParagraph();
1014  //ol.endParagraph();
1015  ol.endDescForItem();
1016  ol.endSimpleSect();
1017  }
1018  //ol.newParagraph();
1019  writeSourceDef(ol,name());
1020  ol.endTextBlock();
1021 }
1022 
1024 {
1025  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1026  static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
1027  return ((!briefDescription().isEmpty() && repeatBrief) ||
1028  !documentation().isEmpty() ||
1029  (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
1030 }
1031 
1032 // write the detailed description for this class
1033 void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
1034  const QCString &title,const QCString &anchor)
1035 {
1036  if (hasDetailedDescription() || exampleFlag)
1037  {
1038  ol.pushGeneratorState();
1040  ol.writeRuler();
1041  ol.popGeneratorState();
1042 
1043  ol.pushGeneratorState();
1045  ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
1046  ol.popGeneratorState();
1047 
1048  if (!anchor.isEmpty())
1049  {
1050  ol.pushGeneratorState();
1053  ol.writeAnchor(getOutputFileBase(),anchor);
1054  ol.popGeneratorState();
1055  }
1056 
1057  ol.startGroupHeader();
1058  ol.parseText(title);
1059  ol.endGroupHeader();
1060 
1062  }
1063  else
1064  {
1065  //writeTemplateSpec(ol,this,pageType);
1066  }
1067 }
1068 
1070 {
1071  QCString result;
1072  SrcLangExt lang = getLanguage();
1073  if (lang==SrcLangExt_Fortran)
1074  {
1077  m_impl->files.count()==1);
1078  }
1079  else if (isJavaEnum())
1080  {
1081  result = theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1);
1082  }
1083  else if (m_impl->compType==Service)
1084  {
1085  result = theTranslator->trServiceGeneratedFromFiles(m_impl->files.count()==1);
1086  }
1087  else if (m_impl->compType==Singleton)
1088  {
1090  }
1091  else
1092  {
1095  m_impl->files.count()==1);
1096  }
1097  return result;
1098 }
1099 
1101 {
1102  ol.pushGeneratorState();
1104 
1105 
1106  ol.writeRuler();
1108 
1109  bool first=TRUE;
1110  QListIterator<FileDef> li(m_impl->files);
1111  FileDef *fd;
1112  for (;(fd=li.current());++li)
1113  {
1114  if (first)
1115  {
1116  first=FALSE;
1117  ol.startItemList();
1118  }
1119 
1120  ol.startItemListItem();
1121  QCString path=fd->getPath();
1122  if (Config_getBool(FULL_PATH_NAMES))
1123  {
1124  ol.docify(stripFromPath(path));
1125  }
1126 
1127  QCString fname = fd->name();
1128  if (!fd->getVersion().isEmpty()) // append version if available
1129  {
1130  fname += " (" + fd->getVersion() + ")";
1131  }
1132 
1133  // for HTML
1134  ol.pushGeneratorState();
1136  if (fd->generateSourceFile())
1137  {
1138  ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
1139  }
1140  else if (fd->isLinkable())
1141  {
1143  fname);
1144  }
1145  else
1146  {
1147  ol.docify(fname);
1148  }
1149  ol.popGeneratorState();
1150 
1151  // for other output formats
1152  ol.pushGeneratorState();
1154  if (fd->isLinkable())
1155  {
1157  fname);
1158  }
1159  else
1160  {
1161  ol.docify(fname);
1162  }
1163  ol.popGeneratorState();
1164 
1165  ol.endItemListItem();
1166  }
1167  if (!first) ol.endItemList();
1168 
1169  ol.popGeneratorState();
1170 }
1171 
1173 {
1174  int count=0;
1175  BaseClassDef *ibcd;
1176  if (m_impl->inheritedBy)
1177  {
1179  for (;(ibcd=it.current());++it)
1180  {
1181  ClassDef *icd=ibcd->classDef;
1182  if ( icd->isVisibleInHierarchy()) count++;
1183  }
1184  }
1185  if (m_impl->inherits)
1186  {
1188  for (;(ibcd=it.current());++it)
1189  {
1190  ClassDef *icd=ibcd->classDef;
1191  if ( icd->isVisibleInHierarchy()) count++;
1192  }
1193  }
1194  return count;
1195 }
1196 
1198 {
1199  // count direct inheritance relations
1200  const int count=countInheritanceNodes();
1201 
1202  bool renderDiagram = FALSE;
1203  if (Config_getBool(HAVE_DOT) &&
1204  (Config_getBool(CLASS_DIAGRAMS) || Config_getBool(CLASS_GRAPH)))
1205  // write class diagram using dot
1206  {
1207  DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
1208  if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
1209  {
1210  ol.pushGeneratorState();
1212  ol.startDotGraph();
1214  ol.endDotGraph(inheritanceGraph);
1215  ol.popGeneratorState();
1216  renderDiagram = TRUE;
1217  }
1218  }
1219  else if (Config_getBool(CLASS_DIAGRAMS) && count>0)
1220  // write class diagram using build-in generator
1221  {
1222  ClassDiagram diagram(this); // create a diagram of this class.
1223  ol.startClassDiagram();
1228  renderDiagram = TRUE;
1229  }
1230 
1231  if (renderDiagram) // if we already show the inheritance relations graphically,
1232  // then hide the text version
1233  {
1235  }
1236 
1237  if (m_impl->inherits && m_impl->inherits->count()>0)
1238  {
1239  ol.startParagraph();
1240  //parseText(ol,theTranslator->trInherits()+" ");
1241 
1242  QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
1243  QRegExp marker("@[0-9]+");
1244  int index=0,newIndex,matchLen;
1245  // now replace all markers in inheritLine with links to the classes
1246  while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1247  {
1248  ol.parseText(inheritLine.mid(index,newIndex-index));
1249  bool ok;
1250  uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1251  BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
1252  if (ok && bcd)
1253  {
1254  ClassDef *cd=bcd->classDef;
1255 
1256  // use the class name but with the template arguments as given
1257  // in the inheritance relation
1259  cd->displayName(),bcd->templSpecifiers);
1260 
1261  if (cd->isLinkable())
1262  {
1263  ol.writeObjectLink(cd->getReference(),
1264  cd->getOutputFileBase(),
1265  cd->anchor(),
1266  displayName);
1267  }
1268  else
1269  {
1270  ol.docify(displayName);
1271  }
1272  }
1273  else
1274  {
1275  err("invalid marker %d in inherits list!\n",entryIndex);
1276  }
1277  index=newIndex+matchLen;
1278  }
1279  ol.parseText(inheritLine.right(inheritLine.length()-index));
1280  ol.endParagraph();
1281  }
1282 
1283  // write subclasses
1284  if (m_impl->inheritedBy && m_impl->inheritedBy->count()>0)
1285  {
1286  ol.startParagraph();
1287  QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
1288  QRegExp marker("@[0-9]+");
1289  int index=0,newIndex,matchLen;
1290  // now replace all markers in inheritLine with links to the classes
1291  while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1292  {
1293  ol.parseText(inheritLine.mid(index,newIndex-index));
1294  bool ok;
1295  uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1296  BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
1297  if (ok && bcd)
1298  {
1299  ClassDef *cd=bcd->classDef;
1300  if (cd->isLinkable())
1301  {
1302  ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1303  }
1304  else
1305  {
1306  ol.docify(cd->displayName());
1307  }
1308  writeInheritanceSpecifier(ol,bcd);
1309  }
1310  index=newIndex+matchLen;
1311  }
1312  ol.parseText(inheritLine.right(inheritLine.length()-index));
1313  ol.endParagraph();
1314  }
1315 
1316  if (renderDiagram)
1317  {
1318  ol.enableAll();
1319  }
1320 }
1321 
1323 {
1324  if (Config_getBool(HAVE_DOT) /*&& Config_getBool(COLLABORATION_GRAPH)*/)
1325  {
1326  DotClassGraph usageImplGraph(this,DotNode::Collaboration);
1327  if (!usageImplGraph.isTrivial())
1328  {
1329  ol.pushGeneratorState();
1331  ol.startDotGraph();
1333  ol.endDotGraph(usageImplGraph);
1334  ol.popGeneratorState();
1335  }
1336  }
1337 }
1338 
1340 {
1341  SrcLangExt lang = getLanguage();
1342  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1343  if (isIDLorJava)
1344  {
1345  return "import";
1346  }
1347  else if (isObjectiveC())
1348  {
1349  return "#import ";
1350  }
1351  else
1352  {
1353  return "#include ";
1354  }
1355 }
1356 
1358 {
1359  if (m_impl->incInfo /*&& Config_getBool(SHOW_INCLUDE_FILES)*/)
1360  {
1361  QCString nm=m_impl->incInfo->includeName.isEmpty() ?
1362  (m_impl->incInfo->fileDef ?
1363  m_impl->incInfo->fileDef->docName().data() : ""
1364  ) :
1365  m_impl->incInfo->includeName.data();
1366  if (!nm.isEmpty())
1367  {
1368  ol.startParagraph();
1369  ol.startTypewriter();
1370  ol.docify(includeStatement());
1371  SrcLangExt lang = getLanguage();
1372  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1373  if (m_impl->incInfo->local || isIDLorJava)
1374  ol.docify("\"");
1375  else
1376  ol.docify("<");
1377  ol.pushGeneratorState();
1379  ol.docify(nm);
1382  if (m_impl->incInfo->fileDef)
1383  {
1385  }
1386  else
1387  {
1388  ol.docify(nm);
1389  }
1390  ol.popGeneratorState();
1391  if (m_impl->incInfo->local || isIDLorJava)
1392  ol.docify("\"");
1393  else
1394  ol.docify(">");
1395  if (isIDLorJava)
1396  ol.docify(";");
1397  ol.endTypewriter();
1398  ol.endParagraph();
1399  }
1400  }
1401 }
1402 
1403 #if 0
1404 void ClassDef::writeAllMembersLink(OutputList &ol)
1405 {
1406  // write link to list of all members (HTML only)
1408  !Config_getBool(OPTIMIZE_OUTPUT_FOR_C)
1409  )
1410  {
1411  ol.pushGeneratorState();
1413  ol.startParagraph();
1416  ol.endTextLink();
1417  ol.endParagraph();
1418  ol.enableAll();
1419  ol.popGeneratorState();
1420  }
1421 }
1422 #endif
1423 
1424 void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)
1425 {
1426  // write user defined member groups
1427  if (m_impl->memberGroupSDict)
1428  {
1431  MemberGroup *mg;
1432  for (;(mg=mgli.current());++mgli)
1433  {
1434  if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
1435  {
1436  mg->writeDeclarations(ol,this,0,0,0,showInline);
1437  }
1438  else // add this group to the corresponding member section
1439  {
1440  //printf("addToDeclarationSection(%s)\n",mg->header().data());
1441  //mg->addToDeclarationSection();
1442  }
1443  }
1444  }
1445 }
1446 
1447 void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
1448 {
1449  // nested classes
1450  if (m_impl->innerClasses)
1451  {
1452  m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
1453  }
1454 }
1455 
1457 {
1458  if (m_impl->innerClasses)
1459  {
1461  }
1462 }
1463 
1465 {
1466  //printf("%s: ClassDef::startMemberDocumentation()\n",name().data());
1467  if (Config_getBool(SEPARATE_MEMBER_PAGES))
1468  {
1471  }
1472 }
1473 
1475 {
1476  //printf("%s: ClassDef::endMemberDocumentation()\n",name().data());
1477  if (Config_getBool(SEPARATE_MEMBER_PAGES))
1478  {
1481  }
1482 }
1483 
1485 {
1486  //printf("%s: ClassDef::startMemberDeclarations()\n",name().data());
1487  ol.startMemberSections();
1488 }
1489 
1491 {
1492  //printf("%s: ClassDef::endMemberDeclarations()\n",name().data());
1493  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
1494  if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
1495  {
1496  ol.startMemberHeader("inherited");
1498  ol.endMemberHeader();
1500  }
1501  ol.endMemberSections();
1502 }
1503 
1505 {
1506  ol.pushGeneratorState();
1508  ol.writeString("\n");
1509  ol.startGroupHeader();
1510  ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
1511  ol.endGroupHeader();
1513  ol.popGeneratorState();
1514 }
1515 
1516 
1518 {
1519  ol.pushGeneratorState();
1521  QListIterator<LayoutDocEntry> eli(
1523  LayoutDocEntry *lde;
1524  bool first=TRUE;
1525  SrcLangExt lang = getLanguage();
1526 
1527  if (lang!=SrcLangExt_VHDL)
1528  {
1529  for (eli.toFirst();(lde=eli.current());++eli)
1530  {
1532  m_impl->innerClasses &&
1534  )
1535  {
1537  ol.writeSummaryLink(0,"nested-classes",ls->title(lang),first);
1538  first=FALSE;
1539  }
1540  else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
1542  !Config_getBool(OPTIMIZE_OUTPUT_FOR_C)
1543  )
1544  {
1545  ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first);
1546  first=FALSE;
1547  }
1548  else if (lde->kind()== LayoutDocEntry::MemberDecl)
1549  {
1551  MemberList * ml = getMemberList(lmd->type);
1552  if (ml && ml->declVisible())
1553  {
1554  ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
1555  first=FALSE;
1556  }
1557  }
1558  }
1559  }
1560  else // VDHL only
1561  {
1563  for (li.toFirst();li.current();++li)
1564  {
1565  ol.writeSummaryLink(0,li.current()->data(),li.current()->data(),first);
1566  first=FALSE;
1567  }
1568  }
1569  if (!first)
1570  {
1571  ol.writeString(" </div>\n");
1572  }
1573  ol.popGeneratorState();
1574 }
1575 
1577 {
1578  if (!isLinkableInProject()) return;
1579  tagFile << " <compound kind=\"" << compoundTypeString();
1580  tagFile << "\"";
1581  if (isObjectiveC()) { tagFile << " objc=\"yes\""; }
1582  tagFile << ">" << endl;
1583  tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
1584  tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
1585  if (!anchor().isEmpty())
1586  {
1587  tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
1588  }
1589  QCString idStr = id();
1590  if (!idStr.isEmpty())
1591  {
1592  tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
1593  }
1594  if (m_impl->tempArgs)
1595  {
1597  Argument *a;
1598  for (;(a=ali.current());++ali)
1599  {
1600  tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
1601  }
1602  }
1603  if (m_impl->inherits)
1604  {
1606  BaseClassDef *ibcd;
1607  for (it.toFirst();(ibcd=it.current());++it)
1608  {
1609  ClassDef *cd=ibcd->classDef;
1610  if (cd && cd->isLinkable())
1611  {
1612  if (!Config_getString(GENERATE_TAGFILE).isEmpty())
1613  {
1614  tagFile << " <base";
1615  if (ibcd->prot==Protected)
1616  {
1617  tagFile << " protection=\"protected\"";
1618  }
1619  else if (ibcd->prot==Private)
1620  {
1621  tagFile << " protection=\"private\"";
1622  }
1623  if (ibcd->virt==Virtual)
1624  {
1625  tagFile << " virtualness=\"virtual\"";
1626  }
1627  tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
1628  }
1629  }
1630  }
1631  }
1632  QListIterator<LayoutDocEntry> eli(
1634  LayoutDocEntry *lde;
1635  for (eli.toFirst();(lde=eli.current());++eli)
1636  {
1637  switch (lde->kind())
1638  {
1640  {
1641  if (m_impl->innerClasses)
1642  {
1644  ClassDef *innerCd;
1645  for (cli.toFirst();(innerCd=cli.current());++cli)
1646  {
1647  if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
1648  protectionLevelVisible(innerCd->protection()) &&
1649  !innerCd->isEmbeddedInOuterScope()
1650  )
1651  {
1652  tagFile << " <class kind=\"" << innerCd->compoundTypeString() <<
1653  "\">" << convertToXML(innerCd->name()) << "</class>" << endl;
1654  }
1655  }
1656  }
1657  }
1658  break;
1660  {
1662  MemberList * ml = getMemberList(lmd->type);
1663  if (ml)
1664  {
1665  ml->writeTagFile(tagFile);
1666  }
1667  }
1668  break;
1670  {
1671  if (m_impl->memberGroupSDict)
1672  {
1674  MemberGroup *mg;
1675  for (;(mg=mgli.current());++mgli)
1676  {
1677  mg->writeTagFile(tagFile);
1678  }
1679  }
1680  }
1681  break;
1682  default:
1683  break;
1684  }
1685  }
1686  writeDocAnchorsToTagFile(tagFile);
1687  tagFile << " </compound>" << endl;
1688 }
1689 
1692 {
1693  bool isSimple = m_impl->isSimple;
1694 
1695  ol.addIndexItem(name(),0);
1696  //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());
1697  QListIterator<LayoutDocEntry> eli(
1699  LayoutDocEntry *lde;
1700 
1701  // part 1: anchor and title
1702  QCString s = compoundTypeString()+" "+name();
1703 
1704  // part 1a
1705  ol.pushGeneratorState();
1707  { // only HTML only
1708  ol.writeAnchor(0,anchor());
1709  ol.startMemberDoc(0,0,anchor(),name(),1,1,FALSE);
1710  ol.startMemberDocName(FALSE);
1711  ol.parseText(s);
1712  ol.endMemberDocName();
1713  ol.endMemberDoc(FALSE);
1714  ol.writeString("</div>");
1715  ol.startIndent();
1716  }
1717  ol.popGeneratorState();
1718 
1719  // part 1b
1720  ol.pushGeneratorState();
1723  { // for LaTeX/RTF only
1725  }
1726  ol.popGeneratorState();
1727 
1728  // part 1c
1729  ol.pushGeneratorState();
1731  {
1732  // for LaTeX/RTF/Man
1733  ol.startGroupHeader(1);
1734  ol.parseText(s);
1735  ol.endGroupHeader(1);
1736  }
1737  ol.popGeneratorState();
1738 
1739  SrcLangExt lang=getLanguage();
1740 
1741  // part 2: the header and detailed description
1742  for (eli.toFirst();(lde=eli.current());++eli)
1743  {
1744  switch (lde->kind())
1745  {
1747  {
1748  // since we already shown the brief description in the
1749  // declaration part of the container, so we use this to
1750  // show the details on top.
1752  }
1753  break;
1756  break;
1759  break;
1761  if (!isSimple) startMemberDeclarations(ol);
1762  break;
1764  {
1766  if (!isSimple) writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
1767  }
1768  break;
1770  if (!isSimple) writeMemberGroups(ol,TRUE);
1771  break;
1773  if (!isSimple) endMemberDeclarations(ol);
1774  break;
1776  if (!isSimple) startMemberDocumentation(ol);
1777  break;
1779  {
1781  if (isSimple)
1782  {
1784  }
1785  else
1786  {
1787  writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
1788  }
1789  }
1790  break;
1792  if (!isSimple) endMemberDocumentation(ol);
1793  break;
1794  default:
1795  break;
1796  }
1797  }
1798 
1799  // part 3: close the block
1800  ol.pushGeneratorState();
1802  { // HTML only
1803  ol.endIndent();
1804  }
1805  ol.popGeneratorState();
1806 }
1807 
1808 void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
1809 {
1810  // TODO: clean up this mess by moving it to
1811  // the output generators...
1812  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
1813  static bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS);
1814  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
1815 
1816  // HTML only
1817  ol.pushGeneratorState();
1819  ol.docify(" ");
1821  anchor.isEmpty() ? QCString("details") : anchor);
1823  ol.endTextLink();
1824  ol.popGeneratorState();
1825 
1826  if (!anchor.isEmpty())
1827  {
1828  ol.pushGeneratorState();
1829  // LaTeX + RTF
1832  if (!(usePDFLatex && pdfHyperlinks))
1833  {
1835  }
1836  if (!rtfHyperlinks)
1837  {
1839  }
1840  ol.docify(" ");
1841  ol.startTextLink(getOutputFileBase(), anchor);
1843  ol.endTextLink();
1844  // RTF only
1846  ol.writeString("\\par");
1847  ol.popGeneratorState();
1848  }
1849 }
1850 
1852 {
1853  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1854  static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
1855  static bool extractLocalClasses = Config_getBool(EXTRACT_LOCAL_CLASSES);
1856  bool linkable = isLinkable();
1857  return (!isAnonymous() && !isExtension() &&
1858  (protection()!=::Private || extractPrivate) &&
1859  (linkable || (!hideUndocClasses && (!isLocal() || extractLocalClasses)))
1860  );
1861 }
1862 
1863 void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)
1864 {
1865  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
1866  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
1867  SrcLangExt lang = getLanguage();
1869  {
1870  if (!found) // first class
1871  {
1872  ol.startMemberHeader("nested-classes");
1873  if (header)
1874  {
1875  ol.parseText(header);
1876  }
1877  else if (lang==SrcLangExt_VHDL)
1878  {
1880  }
1881  else
1882  {
1883  ol.parseText(lang==SrcLangExt_Fortran ?
1886  }
1887  ol.endMemberHeader();
1888  ol.startMemberList();
1889  found=TRUE;
1890  }
1892  ol.startMemberItem(anchor(),FALSE);
1893  QCString ctype = compoundTypeString();
1894  QCString cname = displayName(!localNames);
1895 
1896  if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
1897  {
1898  ol.writeString(ctype);
1899  ol.writeString(" ");
1900  ol.insertMemberAlign();
1901  }
1902  if (isLinkable())
1903  {
1906  anchor(),
1907  cname
1908  );
1909  }
1910  else
1911  {
1912  ol.startBold();
1913  ol.docify(cname);
1914  ol.endBold();
1915  }
1916  if (lang==SrcLangExt_VHDL) // now write the type
1917  {
1918  ol.writeString(" ");
1919  ol.insertMemberAlign();
1921  }
1922  ol.endMemberItem();
1923 
1924  // add the brief description if available
1925  if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
1926  {
1927  DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
1928  briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
1929  if (rootNode && !rootNode->isEmpty())
1930  {
1932  ol.writeDoc(rootNode,this,0);
1933  if (isLinkableInProject())
1934  {
1935  writeMoreLink(ol,anchor());
1936  }
1937  ol.endMemberDescription();
1938  }
1939  delete rootNode;
1940  }
1941  ol.endMemberDeclaration(anchor(),0);
1942  }
1943 }
1944 
1946 {
1947  QStrList sl;
1948  if (isFinal()) sl.append("final");
1949  if (isSealed()) sl.append("sealed");
1950  if (isAbstract()) sl.append("abstract");
1951  if (getLanguage()==SrcLangExt_IDL && isPublished()) sl.append("published");
1952 
1953  ol.pushGeneratorState();
1955  if (sl.count()>0)
1956  {
1957  ol.startLabels();
1958  const char *s=sl.first();
1959  while (s)
1960  {
1961  const char *ns = sl.next();
1962  ol.writeLabel(s,ns==0);
1963  s=ns;
1964  }
1965  ol.endLabels();
1966  }
1967  ol.popGeneratorState();
1968 }
1969 
1970 void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/)
1971 {
1972  ol.startContents();
1973 
1974  QCString pageType = " ";
1975  pageType += compoundTypeString();
1976 
1978 
1980  {
1981  Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
1983  }
1984  bool exampleFlag=hasExamples();
1985 
1986  //---------------------------------------- start flexible part -------------------------------
1987 
1988  SrcLangExt lang = getLanguage();
1989 
1990  QListIterator<LayoutDocEntry> eli(
1992  LayoutDocEntry *lde;
1993  for (eli.toFirst();(lde=eli.current());++eli)
1994  {
1995  switch (lde->kind())
1996  {
1998  writeBriefDescription(ol,exampleFlag);
1999  break;
2001  writeIncludeFiles(ol);
2002  break;
2005  break;
2008  break;
2010  //writeAllMembersLink(ol); // this is now part of the summary links
2011  break;
2014  break;
2016  writeMemberGroups(ol);
2017  break;
2019  {
2021  writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang));
2022  }
2023  break;
2025  {
2027  writeNestedClasses(ol,ls->title(lang));
2028  }
2029  break;
2032  break;
2034  {
2036  writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
2037  }
2038  break;
2041  break;
2043  writeInlineClasses(ol);
2044  break;
2046  {
2048  writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
2049  }
2050  break;
2053  break;
2055  showUsedFiles(ol);
2056  break;
2058  writeAuthorSection(ol);
2059  break;
2083  err("Internal inconsistency: member %d should not be part of "
2084  "LayoutDocManager::Class entry list\n",lde->kind());
2085  break;
2086  }
2087  }
2088 
2089  ol.endContents();
2090 }
2091 
2092 QCString ClassDef::title() const
2093 {
2094  QCString pageTitle;
2095  SrcLangExt lang = getLanguage();
2096 
2097  if (lang==SrcLangExt_Fortran)
2098  {
2100  m_impl->compType,
2101  m_impl->tempArgs != 0);
2102  }
2103  else if (lang==SrcLangExt_VHDL)
2104  {
2105  pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
2106  }
2107  else if (isJavaEnum())
2108  {
2109  pageTitle = theTranslator->trEnumReference(displayName());
2110  }
2111  else if (m_impl->compType==Service)
2112  {
2114  }
2115  else if (m_impl->compType==Singleton)
2116  {
2118  }
2119  else
2120  {
2121  if (Config_getBool(HIDE_COMPOUND_REFERENCE))
2122  {
2123  pageTitle = displayName();
2124  }
2125  else
2126  {
2129  m_impl->tempArgs != 0);
2130  }
2131  }
2132  return pageTitle;
2133 }
2134 
2135 // write all documentation for this class
2137 {
2138  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2139  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2140  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2141  QCString pageTitle = title();
2142 
2143  startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView);
2144  if (!generateTreeView)
2145  {
2147  {
2148  writeNavigationPath(ol);
2149  }
2150  ol.endQuickIndices();
2151  }
2152 
2153  startTitle(ol,getOutputFileBase(),this);
2154  ol.parseText(pageTitle);
2155  addClassAttributes(ol);
2156  addGroupListToTitle(ol,this);
2158  writeDocumentationContents(ol,pageTitle);
2159 
2160  endFileWithNavPath(this,ol);
2161 
2162  if (Config_getBool(SEPARATE_MEMBER_PAGES))
2163  {
2164  writeMemberPages(ol);
2165  }
2166 }
2167 
2169 {
2173 
2174  ol.pushGeneratorState();
2176 
2177  QListIterator<MemberList> mli(m_impl->memberLists);
2178  MemberList *ml;
2179  for (mli.toFirst();(ml=mli.current());++mli)
2180  {
2181  ml->countDocMembers();
2182  if (ml->numDocMembers()>0 && (ml->listType()&MemberListType_detailedLists))
2183  {
2184  ml->writeDocumentationPage(ol,displayName(),this);
2185  }
2186  }
2187 
2188  ol.popGeneratorState();
2189 }
2190 
2192 {
2193  static bool createSubDirs=Config_getBool(CREATE_SUBDIRS);
2194 
2195  ol.writeString(" <div class=\"navtab\">\n");
2196  ol.writeString(" <table>\n");
2197 
2199  {
2201  MemberNameInfo *mni;
2202  for (;(mni=mnili.current());++mnili)
2203  {
2204  MemberNameInfoIterator mnii(*mni);
2205  MemberInfo *mi;
2206  for (mnii.toFirst();(mi=mnii.current());++mnii)
2207  {
2208  MemberDef *md=mi->memberDef;
2209  if (md->getClassDef()==this && md->isLinkable() && !md->isEnumValue())
2210  {
2211  ol.writeString(" <tr><td class=\"navtab\">");
2212  if (md->isLinkableInProject())
2213  {
2214  if (md==currentMd) // selected item => highlight
2215  {
2216  ol.writeString("<a class=\"qindexHL\" ");
2217  }
2218  else
2219  {
2220  ol.writeString("<a class=\"qindex\" ");
2221  }
2222  ol.writeString("href=\"");
2223  if (createSubDirs) ol.writeString("../../");
2225  ol.writeString("\">");
2226  ol.writeString(convertToHtml(md->name()));
2227  ol.writeString("</a>");
2228  }
2229  ol.writeString("</td></tr>\n");
2230  }
2231  }
2232  }
2233  }
2234 
2235  ol.writeString(" </table>\n");
2236  ol.writeString(" </div>\n");
2237 }
2238 
2239 
2240 
2242 {
2243  // write inner classes after the parent, so the tag files contain
2244  // the definition in proper order!
2245  if (m_impl->innerClasses)
2246  {
2248  ClassDef *innerCd;
2249  for (cli.toFirst();(innerCd=cli.current());++cli)
2250  {
2251  if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
2252  protectionLevelVisible(innerCd->protection()) &&
2253  !innerCd->isEmbeddedInOuterScope()
2254  )
2255  {
2256  msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
2257  innerCd->writeDocumentation(ol);
2258  innerCd->writeMemberList(ol);
2259  }
2260  innerCd->writeDocumentationForInnerClasses(ol);
2261  }
2262  }
2263 }
2264 
2265 // write the list of all (inherited) members for this class
2267 {
2268  static bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
2269  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2270  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2271  if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
2272  // only for HTML
2273  ol.pushGeneratorState();
2275 
2276  QCString memListFile = getMemberListFileName();
2277  startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),
2278  HLI_ClassVisible,!generateTreeView,getOutputFileBase());
2279  if (!generateTreeView)
2280  {
2282  {
2283  writeNavigationPath(ol);
2284  }
2285  ol.endQuickIndices();
2286  }
2287  startTitle(ol,0);
2289  endTitle(ol,0,0);
2290  ol.startContents();
2291  ol.startParagraph();
2295  ol.endParagraph();
2296 
2297  //ol.startItemList();
2298  ol.writeString("<table class=\"directory\">\n");
2299 
2300  int idx=0;
2301  //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
2303  MemberNameInfo *mni;
2304  for (mnii.toFirst();(mni=mnii.current());++mnii)
2305  {
2306  MemberNameInfoIterator it(*mni);
2307  MemberInfo *mi;
2308  for (;(mi=it.current());++it)
2309  {
2310  MemberDef *md=mi->memberDef;
2311  ClassDef *cd=md->getClassDef();
2312  Protection prot = mi->prot;
2313  Specifier virt=md->virtualness();
2314 
2315  //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
2316  // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
2317 
2318  if (cd && !md->name().isEmpty() && md->name()[0]!='@')
2319  {
2320  bool memberWritten=FALSE;
2321  if (cd->isLinkable() && md->isLinkable())
2322  // create a link to the documentation
2323  {
2324  QCString name=mi->ambiguityResolutionScope+md->name();
2325  //ol.writeListItem();
2326  ol.writeString(" <tr");
2327  if ((idx&1)==0) ol.writeString(" class=\"even\"");
2328  idx++;
2329  ol.writeString("><td class=\"entry\">");
2330  if (cd->isObjectiveC())
2331  {
2332  if (md->isObjCMethod())
2333  {
2334  if (md->isStatic())
2335  ol.writeString("+&#160;</td><td>");
2336  else
2337  ol.writeString("-&#160;</td><td>");
2338  }
2339  else
2340  ol.writeString("</td><td class=\"entry\">");
2341  }
2342  if (md->isObjCMethod())
2343  {
2344  ol.writeObjectLink(md->getReference(),
2345  md->getOutputFileBase(),
2346  md->anchor(),md->name());
2347  }
2348  else
2349  {
2350  //Definition *bd = md->getGroupDef();
2351  //if (bd==0) bd=cd;
2352  ol.writeObjectLink(md->getReference(),
2353  md->getOutputFileBase(),
2354  md->anchor(),name);
2355 
2356  if ( md->isFunction() || md->isSignal() || md->isSlot() ||
2357  (md->isFriend() && md->argsString()))
2358  ol.docify(md->argsString());
2359  else if (md->isEnumerate())
2360  ol.parseText(" "+theTranslator->trEnumName());
2361  else if (md->isEnumValue())
2362  ol.parseText(" "+theTranslator->trEnumValue());
2363  else if (md->isTypedef())
2364  ol.docify(" typedef");
2365  else if (md->isFriend() && !qstrcmp(md->typeString(),"friend class"))
2366  ol.docify(" class");
2367  //ol.writeString("\n");
2368  }
2369  ol.writeString("</td>");
2370  memberWritten=TRUE;
2371  }
2372  else if (!cd->isArtificial() &&
2373  !Config_getBool(HIDE_UNDOC_MEMBERS) &&
2374  (protectionLevelVisible(md->protection()) || md->isFriend())
2375  ) // no documentation,
2376  // generate link to the class instead.
2377  {
2378  //ol.writeListItem();
2379  ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
2380  if ((idx&1)==0) ol.writeString(" class=\"even\"");
2381  idx++;
2382  ol.writeString("><td class=\"entry\">");
2383  if (cd->isObjectiveC())
2384  {
2385  if (md->isObjCMethod())
2386  {
2387  if (md->isStatic())
2388  ol.writeString("+&#160;</td><td class=\"entry\">");
2389  else
2390  ol.writeString("-&#160;</td><td class=\"entry\">");
2391  }
2392  else
2393  ol.writeString("</td><td class=\"entry\">");
2394  }
2395  ol.startBold();
2396  ol.docify(md->name());
2397  ol.endBold();
2398  if (!md->isObjCMethod())
2399  {
2400  if ( md->isFunction() || md->isSignal() || md->isSlot() )
2401  ol.docify(md->argsString());
2402  else if (md->isEnumerate())
2403  ol.parseText(" "+theTranslator->trEnumName());
2404  else if (md->isEnumValue())
2405  ol.parseText(" "+theTranslator->trEnumValue());
2406  else if (md->isTypedef())
2407  ol.docify(" typedef");
2408  }
2409  ol.writeString(" (");
2410  ol.parseText(theTranslator->trDefinedIn()+" ");
2411  if (cd->isLinkable())
2412  {
2413  ol.writeObjectLink(
2414  cd->getReference(),
2415  cd->getOutputFileBase(),
2416  cd->anchor(),
2417  cd->displayName());
2418  }
2419  else
2420  {
2421  ol.startBold();
2422  ol.docify(cd->displayName());
2423  ol.endBold();
2424  }
2425  ol.writeString(")");
2426  ol.writeString("</td>");
2427  memberWritten=TRUE;
2428  }
2429  if (memberWritten)
2430  {
2431  ol.writeString("<td class=\"entry\">");
2432  ol.writeObjectLink(cd->getReference(),
2433  cd->getOutputFileBase(),
2434  cd->anchor(),
2435  md->category() ?
2436  md->category()->displayName() :
2437  cd->displayName());
2438  ol.writeString("</td>");
2439  ol.writeString("<td class=\"entry\">");
2440  }
2441  SrcLangExt lang = md->getLanguage();
2442  if (
2443  (prot!=Public || (virt!=Normal && getLanguage()!=SrcLangExt_ObjC) ||
2444  md->isFriend() || md->isRelated() || md->isExplicit() ||
2445  md->isMutable() || (md->isInline() && Config_getBool(INLINE_INFO)) ||
2446  md->isSignal() || md->isSlot() ||
2448  (md->isOptional() || md->isAttribute() || md->isUNOProperty())) ||
2449  md->isStatic() || lang==SrcLangExt_VHDL
2450  )
2451  && memberWritten)
2452  {
2453  ol.writeString("<span class=\"mlabel\">");
2454  QStrList sl;
2455  if (lang==SrcLangExt_VHDL)
2456  {
2457  sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type
2458  }
2459  else if (md->isFriend()) sl.append("friend");
2460  else if (md->isRelated()) sl.append("related");
2461  else
2462  {
2463  if (Config_getBool(INLINE_INFO) && md->isInline())
2464  sl.append("inline");
2465  if (md->isExplicit()) sl.append("explicit");
2466  if (md->isMutable()) sl.append("mutable");
2467  if (prot==Protected) sl.append("protected");
2468  else if (prot==Private) sl.append("private");
2469  else if (prot==Package) sl.append("package");
2470  if (virt==Virtual && getLanguage()!=SrcLangExt_ObjC)
2471  sl.append("virtual");
2472  else if (virt==Pure) sl.append("pure virtual");
2473  if (md->isStatic()) sl.append("static");
2474  if (md->isSignal()) sl.append("signal");
2475  if (md->isSlot()) sl.append("slot");
2476 // this is the extra member page
2477  if (md->isOptional()) sl.append("optional");
2478  if (md->isAttribute()) sl.append("attribute");
2479  if (md->isUNOProperty()) sl.append("property");
2480  if (md->isReadonly()) sl.append("readonly");
2481  if (md->isBound()) sl.append("bound");
2482  if (md->isRemovable()) sl.append("removable");
2483  if (md->isConstrained()) sl.append("constrained");
2484  if (md->isTransient()) sl.append("transient");
2485  if (md->isMaybeVoid()) sl.append("maybevoid");
2486  if (md->isMaybeDefault()) sl.append("maybedefault");
2487  if (md->isMaybeAmbiguous())sl.append("maybeambiguous");
2488  }
2489  const char *s=sl.first();
2490  while (s)
2491  {
2492  ol.docify(s);
2493  s=sl.next();
2494  if (s) ol.writeString("</span><span class=\"mlabel\">");
2495  }
2496  ol.writeString("</span>");
2497  }
2498  if (memberWritten)
2499  {
2500  ol.writeString("</td>");
2501  ol.writeString("</tr>\n");
2502  }
2503  }
2504  }
2505  }
2506  //ol.endItemList();
2507 
2508  ol.writeString("</table>");
2509 
2510  endFile(ol);
2511  ol.popGeneratorState();
2512 }
2513 
2514 
2515 // add a reference to an example
2516 bool ClassDef::addExample(const char *anchor,const char *nameStr,
2517  const char *file)
2518 {
2519  if (m_impl->exampleSDict==0)
2520  {
2523  }
2524  if (!m_impl->exampleSDict->find(nameStr))
2525  {
2526  Example *e=new Example;
2527  e->anchor=anchor;
2528  e->name=nameStr;
2529  e->file=file;
2530  m_impl->exampleSDict->inSort(nameStr,e);
2531  return TRUE;
2532  }
2533  return FALSE;
2534 }
2535 
2536 // returns TRUE if this class is used in an example
2538 {
2539  bool result=FALSE;
2540  if (m_impl->exampleSDict)
2541  result = m_impl->exampleSDict->count()>0;
2542  return result;
2543 }
2544 
2545 void ClassDef::addTypeConstraint(const QCString &typeConstraint,const QCString &type)
2546 {
2547  //printf("addTypeContraint(%s,%s)\n",type.data(),typeConstraint.data());
2548  static bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS);
2549  if (typeConstraint.isEmpty() || type.isEmpty()) return;
2550  ClassDef *cd = getResolvedClass(this,getFileDef(),typeConstraint);
2551  if (cd==0 && !hideUndocRelation)
2552  {
2553  cd = new ClassDef(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class);
2554  cd->setUsedOnly(TRUE);
2555  cd->setLanguage(getLanguage());
2556  Doxygen::hiddenClasses->append(typeConstraint,cd);
2557  //printf("Adding undocumented constraint '%s' to class %s on type %s\n",
2558  // typeConstraint.data(),name().data(),type.data());
2559  }
2560  if (cd)
2561  {
2562  if (m_impl->constraintClassDict==0)
2563  {
2565  m_impl->constraintClassDict->setAutoDelete(TRUE);
2566  }
2567  ConstraintClassDef *ccd=m_impl->constraintClassDict->find(typeConstraint);
2568  if (ccd==0)
2569  {
2570  ccd = new ConstraintClassDef(cd);
2571  m_impl->constraintClassDict->insert(typeConstraint,ccd);
2572  }
2573  ccd->addAccessor(type);
2574  //printf("Adding constraint '%s' to class %s on type %s\n",
2575  // typeConstraint.data(),name().data(),type.data());
2576  }
2577 }
2578 
2579 // Java Type Constrains: A<T extends C & I>
2581 {
2582  if (m_impl->tempArgs)
2583  {
2585  Argument *a;
2586  for (;(a=ali.current());++ali)
2587  {
2588  if (!a->typeConstraint.isEmpty())
2589  {
2590  QCString typeConstraint;
2591  int i=0,p=0;
2592  while ((i=a->typeConstraint.find('&',p))!=-1) // typeConstraint="A &I" for C<T extends A & I>
2593  {
2594  typeConstraint = a->typeConstraint.mid(p,i-p).stripWhiteSpace();
2595  addTypeConstraint(typeConstraint,a->type);
2596  p=i+1;
2597  }
2598  typeConstraint = a->typeConstraint.right(a->typeConstraint.length()-p).stripWhiteSpace();
2599  addTypeConstraint(typeConstraint,a->type);
2600  }
2601  }
2602  }
2603 }
2604 
2605 // C# Type Constraints: D<T> where T : C, I
2607 {
2608  if (al==0) return;
2611  ArgumentListIterator ali(*al);
2612  Argument *a;
2613  for (;(a=ali.current());++ali)
2614  {
2615  m_impl->typeConstraints->append(new Argument(*a));
2616  }
2617 }
2618 
2620 {
2621  if (al==0) return;
2622  if (m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
2623  //printf("setting template args '%s' for '%s'\n",tempArgListToString(al,getLanguage()).data(),name().data());
2625  ArgumentListIterator ali(*al);
2626  Argument *a;
2627  for (;(a=ali.current());++ali)
2628  {
2629  m_impl->tempArgs->append(new Argument(*a));
2630  }
2631 }
2632 
2637 {
2638  bool found=!isReference() && isLinkableInProject() && !isHidden();
2639  if (found)
2640  {
2641  return TRUE; // we're done if this class is not a reference
2642  }
2643  if (m_impl->inheritedBy)
2644  {
2646  for ( ; bcli.current() && !found ; ++bcli ) // for each super class
2647  {
2648  ClassDef *bcd=bcli.current()->classDef;
2649  // recurse into the super class branch
2650  found = found || bcd->hasNonReferenceSuperClass();
2651  if (!found)
2652  {
2653  // look for template instances that might have non-reference super classes
2654  QDict<ClassDef> *cil = bcd->getTemplateInstances();
2655  if (cil)
2656  {
2657  QDictIterator<ClassDef> tidi(*cil);
2658  for ( ; tidi.current() && !found ; ++tidi) // for each template instance
2659  {
2660  // recurse into the template instance branch
2661  found = found || tidi.current()->hasNonReferenceSuperClass();
2662  }
2663  }
2664  }
2665  }
2666  }
2667  return found;
2668 }
2669 
2674  ClassDef *inheritedFrom,const char *inheritId)
2675 {
2676  //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
2677 
2678  ol.docify(compoundTypeString());
2679  QCString cn = displayName(FALSE);
2680  if (!cn.isEmpty())
2681  {
2682  ol.docify(" ");
2683  if (md && isLinkable())
2684  {
2685  ol.writeObjectLink(0,0,md->anchor(),cn);
2686  }
2687  else
2688  {
2689  ol.startBold();
2690  ol.docify(cn);
2691  ol.endBold();
2692  }
2693  }
2694  ol.docify(" {");
2695  ol.endMemberItem();
2696 
2697  // write user defined member groups
2698  if (m_impl->memberGroupSDict)
2699  {
2701  MemberGroup *mg;
2702  for (;(mg=mgli.current());++mgli)
2703  {
2704  mg->setInGroup(inGroup);
2705  mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
2706  }
2707  }
2708 
2709  QListIterator<LayoutDocEntry> eli(
2711  LayoutDocEntry *lde;
2712  for (eli.toFirst();(lde=eli.current());++eli)
2713  {
2714  if (lde->kind()==LayoutDocEntry::MemberDecl)
2715  {
2717  writePlainMemberDeclaration(ol,lmd->type,inGroup,inheritedFrom,inheritId);
2718  }
2719  }
2720 }
2721 
2724 {
2725  static bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES);
2726  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
2727  static bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES);
2728  if (m_impl->templateMaster)
2729  {
2731  }
2732  else
2733  {
2734  return !name().isEmpty() && /* has a name */
2735  !isArtificial() && !isHidden() && /* not hidden */
2736  !isAnonymous() && /* not anonymous */
2737  protectionLevelVisible(m_impl->prot) && /* private/internal */
2738  (!m_impl->isLocal || extractLocal) && /* local */
2739  (hasDocumentation() || !hideUndoc) && /* documented */
2740  (!m_impl->isStatic || extractStatic) && /* static */
2741  !isReference(); /* not an external reference */
2742  }
2743 }
2744 
2746 {
2747  if (m_impl->templateMaster)
2748  {
2749  return m_impl->templateMaster->isLinkable();
2750  }
2751  else
2752  {
2753  return isReference() || isLinkableInProject();
2754  }
2755 }
2756 
2757 
2760 {
2761  static bool allExternals = Config_getBool(ALLEXTERNALS);
2762  static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
2763  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
2764 
2765  return // show all classes or a subclass is visible
2766  (allExternals || hasNonReferenceSuperClass()) &&
2767  // and not an anonymous compound
2768  !isAnonymous() &&
2769  // not an artificially introduced class // 1.8.2: allowed these to appear
2771  // and not privately inherited
2773  // documented or shown anyway or documentation is external
2774  (hasDocumentation() ||
2775  !hideUndocClasses ||
2777  isReference()
2778  ) &&
2779  // is not part of an unnamed namespace or shown anyway
2780  (!m_impl->isStatic || extractStatic);
2781 }
2782 
2784 {
2786 }
2787 
2788 //----------------------------------------------------------------------
2789 // recursive function:
2790 // returns TRUE iff class definition `bcd' represents an (in)direct base
2791 // class of class definition `cd'.
2792 
2793 bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
2794 {
2795  bool found=FALSE;
2796  //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
2797  if (level>256)
2798  {
2799  err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
2800  return FALSE;
2801  }
2802  if (baseClasses())
2803  {
2804  // Beware: trying to optimise the iterator away using ->first() & ->next()
2805  // causes bug 625531
2807  for ( ; bcli.current() && !found ; ++bcli)
2808  {
2809  ClassDef *ccd=bcli.current()->classDef;
2810  if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
2811  //printf("isBaseClass() baseclass %s\n",ccd->name().data());
2812  if (ccd==bcd)
2813  found=TRUE;
2814  else
2815  found=ccd->isBaseClass(bcd,followInstances,level+1);
2816  }
2817  }
2818  return found;
2819 }
2820 
2821 //----------------------------------------------------------------------
2822 
2823 bool ClassDef::isSubClass(ClassDef *cd,int level)
2824 {
2825  bool found=FALSE;
2826  if (level>256)
2827  {
2828  err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
2829  return FALSE;
2830  }
2831  if (subClasses())
2832  {
2834  for ( ; bcli.current() && !found ; ++bcli)
2835  {
2836  ClassDef *ccd=bcli.current()->classDef;
2837  if (ccd==cd)
2838  found=TRUE;
2839  else
2840  found=ccd->isSubClass(cd,level+1);
2841  }
2842  }
2843  return found;
2844 }
2845 
2846 //----------------------------------------------------------------------------
2847 
2848 static bool isStandardFunc(MemberDef *md)
2849 {
2850  return md->name()=="operator=" || // assignment operator
2851  md->isConstructor() || // constructor
2852  md->isDestructor(); // destructor
2853 }
2854 
2861 {
2862  if (m_impl->membersMerged) return;
2863 
2864  //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
2865  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2866  SrcLangExt lang = getLanguage();
2867  QCString sep=getLanguageSpecificSeparator(lang,TRUE);
2868  int sepLen = sep.length();
2869 
2870  m_impl->membersMerged=TRUE;
2871  //printf(" mergeMembers for %s\n",name().data());
2872  bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
2873  if (baseClasses())
2874  {
2875  //printf(" => has base classes!\n");
2877  BaseClassDef *bcd;
2878  for ( ; (bcd=bcli.current()) ; ++bcli )
2879  {
2880  ClassDef *bClass=bcd->classDef;
2881 
2882  // merge the members in the base class of this inheritance branch first
2883  bClass->mergeMembers();
2884 
2885  MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
2887 
2888  if (srcMnd)
2889  {
2890  MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
2891  MemberNameInfo *srcMni;
2892  for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
2893  {
2894  //printf(" Base member name %s\n",srcMni->memberName());
2895  MemberNameInfo *dstMni;
2896  if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
2897  // a member with that name is already in the class.
2898  // the member may hide or reimplement the one in the sub class
2899  // or there may be another path to the base class that is already
2900  // visited via another branch in the class hierarchy.
2901  {
2902  MemberNameInfoIterator srcMnii(*srcMni);
2903  MemberInfo *srcMi;
2904  for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
2905  {
2906  MemberDef *srcMd = srcMi->memberDef;
2907  bool found=FALSE;
2908  bool ambigue=FALSE;
2909  bool hidden=FALSE;
2910  MemberNameInfoIterator dstMnii(*dstMni);
2911  MemberInfo *dstMi;
2912  ClassDef *srcCd = srcMd->getClassDef();
2913  for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
2914  {
2915  MemberDef *dstMd = dstMi->memberDef;
2916  if (srcMd!=dstMd) // different members
2917  {
2918  ClassDef *dstCd = dstMd->getClassDef();
2919  //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
2920  if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
2921  // member is in the same or a base class
2922  {
2923  ArgumentList *srcAl = srcMd->argumentList();
2924  ArgumentList *dstAl = dstMd->argumentList();
2925  found=matchArguments2(
2926  srcMd->getOuterScope(),srcMd->getFileDef(),srcAl,
2927  dstMd->getOuterScope(),dstMd->getFileDef(),dstAl,
2928  TRUE
2929  );
2930  //printf(" Yes, matching (%s<->%s): %d\n",
2931  // argListToString(srcMd->argumentList()).data(),
2932  // argListToString(dstMd->argumentList()).data(),
2933  // found);
2934  hidden = hidden || !found;
2935  }
2936  else // member is in a non base class => multiple inheritance
2937  // using the same base class.
2938  {
2939  //printf("$$ Existing member %s %s add scope %s\n",
2940  // dstMi->ambiguityResolutionScope.data(),
2941  // dstMd->name().data(),
2942  // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2943 
2944  QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2945  if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2946  dstMi->ambiguityResolutionScope.prepend(scope);
2947  ambigue=TRUE;
2948  }
2949  }
2950  else // same members
2951  {
2952  // do not add if base class is virtual or
2953  // if scope paths are equal or
2954  // if base class is an interface (and thus implicitly virtual).
2955  //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
2956  if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
2957  bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
2958  dstMd->getClassDef()->compoundType()==Interface
2959  )
2960  {
2961  found=TRUE;
2962  }
2963  else // member can be reached via multiple paths in the
2964  // inheritance tree
2965  {
2966  //printf("$$ Existing member %s %s add scope %s\n",
2967  // dstMi->ambiguityResolutionScope.data(),
2968  // dstMd->name().data(),
2969  // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2970 
2971  QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2972  if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2973  {
2974  dstMi->ambiguityResolutionScope.prepend(scope);
2975  }
2976  ambigue=TRUE;
2977  }
2978  }
2979  }
2980  //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
2981  // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
2982 
2983  // TODO: fix the case where a member is hidden by inheritance
2984  // of a member with the same name but with another prototype,
2985  // while there is more than one path to the member in the
2986  // base class due to multiple inheritance. In this case
2987  // it seems that the member is not reachable by prefixing a
2988  // scope name either (according to my compiler). Currently,
2989  // this case is shown anyway.
2990  if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
2991  {
2992  Protection prot=srcMd->protection();
2993  if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
2994  else if (bcd->prot==Private) prot=bcd->prot;
2995 
2996  if (inlineInheritedMembers)
2997  {
2998  if (!isStandardFunc(srcMd))
2999  {
3000  //printf(" insertMember `%s'\n",srcMd->name().data());
3001  internalInsertMember(srcMd,prot,FALSE);
3002  }
3003  }
3004 
3005  Specifier virt=srcMi->virt;
3006  if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
3007 
3008  MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
3009  newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
3010  if (ambigue)
3011  {
3012  //printf("$$ New member %s %s add scope %s::\n",
3013  // srcMi->ambiguityResolutionScope.data(),
3014  // srcMd->name().data(),
3015  // bClass->name().data());
3016 
3017  QCString scope=bClass->name()+sep;
3018  if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
3019  {
3020  newMi->ambiguityResolutionScope=
3021  scope+srcMi->ambiguityResolutionScope.copy();
3022  }
3023  }
3024  if (hidden)
3025  {
3026  if (srcMi->ambigClass==0)
3027  {
3028  newMi->ambigClass=bClass;
3029  newMi->ambiguityResolutionScope=bClass->name()+sep;
3030  }
3031  else
3032  {
3033  newMi->ambigClass=srcMi->ambigClass;
3034  newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
3035  }
3036  }
3037  dstMni->append(newMi);
3038  }
3039  }
3040  }
3041  else // base class has a member that is not in the sub class => copy
3042  {
3043  // create a deep copy of the list (only the MemberInfo's will be
3044  // copied, not the actual MemberDef's)
3045  MemberNameInfo *newMni = 0;
3046  newMni = new MemberNameInfo(srcMni->memberName());
3047 
3048  // copy the member(s) from the base to the sub class
3049  MemberNameInfoIterator mnii(*srcMni);
3050  MemberInfo *mi;
3051  for (;(mi=mnii.current());++mnii)
3052  {
3053  if (!mi->memberDef->isFriend()) // don't inherit friends
3054  {
3055  Protection prot = mi->prot;
3056  if (bcd->prot==Protected)
3057  {
3058  if (prot==Public) prot=Protected;
3059  }
3060  else if (bcd->prot==Private)
3061  {
3062  prot=Private;
3063  }
3064  //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
3065  // name().data(),mi->memberDef->name().data(),mi->prot,
3066  // bcd->prot,prot);
3067 
3068  if (mi->prot!=Private)
3069  {
3070  Specifier virt=mi->virt;
3071  if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
3072 
3073  if (inlineInheritedMembers)
3074  {
3075  if (!isStandardFunc(mi->memberDef))
3076  {
3077  //printf(" insertMember `%s'\n",mi->memberDef->name().data());
3078  internalInsertMember(mi->memberDef,prot,FALSE);
3079  }
3080  }
3081  //printf("Adding!\n");
3082  MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
3083  newMi->scopePath=bClass->name()+sep+mi->scopePath;
3084  newMi->ambigClass=mi->ambigClass;
3086  newMni->append(newMi);
3087  }
3088  }
3089  }
3090 
3091  if (dstMnd==0)
3092  {
3095  dstMnd = m_impl->allMemberNameInfoSDict;
3096  }
3097  // add it to the dictionary
3098  dstMnd->append(newMni->memberName(),newMni);
3099  }
3100  }
3101  }
3102  }
3103  }
3104  //printf(" end mergeMembers\n");
3105 }
3106 
3107 //----------------------------------------------------------------------------
3108 
3112 {
3113  static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS);
3114  bool makePrivate = category->isLocal();
3115  // in case extract local methods is not enabled we don't add the methods
3116  // of the category in case it is defined in the .m file.
3117  if (makePrivate && !extractLocalMethods) return;
3118  bool isExtension = category->isExtension();
3119 
3120  category->setCategoryOf(this);
3121  if (isExtension)
3122  {
3123  category->setArtificial(TRUE);
3124 
3125  // copy base classes/protocols from extension
3126  if (category->baseClasses())
3127  {
3128  BaseClassListIterator bcli(*category->baseClasses());
3129  BaseClassDef *bcd;
3130  for ( ; (bcd=bcli.current()) ; ++bcli )
3131  {
3132  insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
3133  // correct bcd->classDef so that they do no longer derive from
3134  // category, but from this class!
3135  if (bcd->classDef->subClasses())
3136  {
3137  BaseClassListIterator scli(*bcd->classDef->subClasses());
3138  BaseClassDef *scd;
3139  for ( ; (scd=scli.current()) ; ++scli )
3140  {
3141  if (scd->classDef==category)
3142  {
3143  scd->classDef=this;
3144  }
3145  }
3146  }
3147  }
3148  }
3149 
3150  }
3151  // make methods private for categories defined in the .m file
3152  //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate);
3153 
3154  MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
3156 
3157  if (srcMnd && dstMnd)
3158  {
3159  MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
3160  MemberNameInfo *srcMni;
3161  for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
3162  {
3163  MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
3164  if (dstMni) // method is already defined in the class
3165  {
3166  //printf("Existing member %s\n",srcMni->memberName());
3167  MemberInfo *dstMi = dstMni->getFirst();
3168  MemberInfo *srcMi = srcMni->getFirst();
3169  //if (dstMi)
3170  //{
3171  // Protection prot = dstMi->prot;
3172  // if (makePrivate || isExtension)
3173  // {
3174  // prot = Private;
3175  // removeMemberFromLists(dstMi->memberDef);
3176  // internalInsertMember(dstMi->memberDef,prot,FALSE);
3177  // }
3178  //}
3179  if (srcMi && dstMi)
3180  {
3182  dstMi->memberDef->setCategory(category);
3183  dstMi->memberDef->setCategoryRelation(srcMi->memberDef);
3184  srcMi->memberDef->setCategoryRelation(dstMi->memberDef);
3185  }
3186  }
3187  else // new method name
3188  {
3189  //printf("New member %s\n",srcMni->memberName());
3190  // create a deep copy of the list
3191  MemberNameInfo *newMni = 0;
3192  newMni = new MemberNameInfo(srcMni->memberName());
3193 
3194  // copy the member(s) from the category to this class
3195  MemberNameInfoIterator mnii(*srcMni);
3196  MemberInfo *mi;
3197  for (;(mi=mnii.current());++mnii)
3198  {
3199  //printf("Adding '%s'\n",mi->memberDef->name().data());
3200  Protection prot = mi->prot;
3201  //if (makePrivate) prot = Private;
3202  MemberDef *newMd = mi->memberDef->deepCopy();
3203  if (newMd)
3204  {
3205  //printf("Copying member %s\n",mi->memberDef->name().data());
3206  newMd->moveTo(this);
3207 
3208  MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited);
3209  newMi->scopePath=mi->scopePath;
3210  newMi->ambigClass=mi->ambigClass;
3212  newMni->append(newMi);
3213 
3214  // also add the newly created member to the global members list
3215 
3216  MemberName *mn;
3217  QCString name = newMd->name();
3218  if ((mn=Doxygen::memberNameSDict->find(name)))
3219  {
3220  mn->append(newMd);
3221  }
3222  else
3223  {
3224  mn = new MemberName(newMd->name());
3225  mn->append(newMd);
3226  Doxygen::memberNameSDict->append(name,mn);
3227  }
3228 
3229  newMd->setCategory(category);
3230  newMd->setCategoryRelation(mi->memberDef);
3231  mi->memberDef->setCategoryRelation(newMd);
3232  if (makePrivate || isExtension)
3233  {
3234  newMd->makeImplementationDetail();
3235  }
3236  internalInsertMember(newMd,prot,FALSE);
3237  }
3238  }
3239 
3240  // add it to the dictionary
3241  dstMnd->append(newMni->memberName(),newMni);
3242  }
3243  }
3244  }
3245 }
3246 
3247 //----------------------------------------------------------------------------
3248 
3249 void ClassDef::addUsedClass(ClassDef *cd,const char *accessName,
3250  Protection prot)
3251 {
3252  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
3253  static bool umlLook = Config_getBool(UML_LOOK);
3254  if (prot==Private && !extractPrivate) return;
3255  //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
3256  if (m_impl->usesImplClassDict==0)
3257  {
3259  m_impl->usesImplClassDict->setAutoDelete(TRUE);
3260  }
3261  UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
3262  if (ucd==0)
3263  {
3264  ucd = new UsesClassDef(cd);
3265  m_impl->usesImplClassDict->insert(cd->name(),ucd);
3266  //printf("Adding used class %s to class %s via accessor %s\n",
3267  // cd->name().data(),name().data(),accessName);
3268  }
3269  QCString acc = accessName;
3270  if (umlLook)
3271  {
3272  switch(prot)
3273  {
3274  case Public: acc.prepend("+"); break;
3275  case Private: acc.prepend("-"); break;
3276  case Protected: acc.prepend("#"); break;
3277  case Package: acc.prepend("~"); break;
3278  }
3279  }
3280  ucd->addAccessor(acc);
3281 }
3282 
3283 void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName,
3284  Protection prot)
3285 {
3286  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
3287  static bool umlLook = Config_getBool(UML_LOOK);
3288  if (prot==Private && !extractPrivate) return;
3289  //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
3290  if (m_impl->usedByImplClassDict==0)
3291  {
3293  m_impl->usedByImplClassDict->setAutoDelete(TRUE);
3294  }
3295  UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
3296  if (ucd==0)
3297  {
3298  ucd = new UsesClassDef(cd);
3299  m_impl->usedByImplClassDict->insert(cd->name(),ucd);
3300  //printf("Adding used by class %s to class %s\n",
3301  // cd->name().data(),name().data());
3302  }
3303  QCString acc = accessName;
3304  if (umlLook)
3305  {
3306  switch(prot)
3307  {
3308  case Public: acc.prepend("+"); break;
3309  case Private: acc.prepend("-"); break;
3310  case Protected: acc.prepend("#"); break;
3311  case Package: acc.prepend("~"); break;
3312  }
3313  }
3314  ucd->addAccessor(acc);
3315 }
3316 
3317 
3318 #if 0
3319 
3324 void ClassDef::determineImplUsageRelation()
3325 {
3327  MemberNameInfo *mni;
3328  for (;(mni=mnili.current());++mnili)
3329  {
3330  MemberNameInfoIterator mnii(*mni);
3331  MemberInfo *mi;
3332  for (mnii.toFirst();(mi=mnii.current());++mnii)
3333  {
3334  MemberDef *md=mi->memberDef;
3335  if (md->isVariable()) // for each member variable in this class
3336  {
3337  QCString type=removeRedundantWhiteSpace(md->typeString());
3338  //printf("in class %s found var type=`%s' name=`%s'\n",
3339  // name().data(),type.data(),md->name().data());
3340  int pos=0;
3341  QCString usedClassName;
3342  QCString templSpec;
3343  bool found=FALSE;
3344  while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
3345  {
3346  //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
3347  // check if usedClassName is a template argument of its class
3348  ClassDef *cd=md->getClassDef();
3349  if (cd && cd->templateArguments())
3350  {
3352  Argument *arg;
3353  int count=0;
3354  for (ali.toFirst();(arg=ali.current());++ali,++count)
3355  {
3356  if (arg->name==usedClassName) // type is a template argument
3357  {
3358  found=TRUE;
3360  cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
3361  usedClassName,ClassDef::Class);
3362  cd->setIsTemplateBaseClass(count);
3363  UsesClassDef *ucd = new UsesClassDef(cd);
3364  m_impl->usesImplClassDict->insert(cd->name(),ucd);
3365  ucd->templSpecifiers = templSpec;
3366  ucd->addAccessor(md->name());
3368  //printf("Adding used template argument %s to class %s\n",
3369  // cd->name().data(),name().data());
3370  //printf("Adding accessor %s to class %s\n",
3371  // md->name().data(),ucd->classDef->name().data());
3372  }
3373  }
3374  }
3375 
3376  if (!found)
3377  {
3378  cd=0;
3379  if (getNamespaceDef()!=0)
3380  {
3381  cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
3382  }
3383  if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
3384  if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try in-between scopes!
3385  //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
3386  if (cd) // class exists
3387  {
3388  found=TRUE;
3389  if (m_impl->usesImplClassDict==0)
3390  {
3392  m_impl->usesImplClassDict->setAutoDelete(TRUE);
3393  }
3394  UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
3395  if (ucd==0 || ucd->templSpecifiers!=templSpec)
3396  {
3397  ucd = new UsesClassDef(cd);
3398  m_impl->usesImplClassDict->insert(cd->name(),ucd);
3399  ucd->templSpecifiers = templSpec;
3400  //printf("Adding used class %s to class %s\n",
3401  // cd->name().data(),name().data());
3402  }
3403  ucd->addAccessor(md->name());
3404  //printf("Adding accessor %s to class %s\n",
3405  // md->name().data(),ucd->classDef->name().data());
3406  }
3407  }
3408  }
3409  }
3410  }
3411  }
3412 #ifdef DUMP
3413  if (m_impl->usesClassDict)
3414  {
3415  msg("Class %s uses the following classes:\n",name().data());
3416  UsesClassDictIterator ucdi(*m_impl->usesClassDict);
3417  UsesClassDef *ucd;
3418  for (;(ucd=ucdi.current());++ucdi)
3419  {
3420  msg(" %s via ",ucd->classDef->name().data());
3421  QDictIterator<void> dvi(*ucd->accessors);
3422  const char *s;
3423  for (;(s=dvi.currentKey());++dvi)
3424  {
3425  msg("%s ",s);
3426  }
3427  msg("\n");
3428  }
3429  }
3430 #endif
3431 }
3432 
3433 //----------------------------------------------------------------------------
3434 
3435 // I have disabled this code because the graphs it renders quickly become
3436 // too large to be of practical use.
3437 
3438 void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
3439 {
3440  QCString type = typeStr;
3441  static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
3442  int p=0,i,l;
3443  while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
3444  {
3445  ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
3446  if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try in-between scopes!
3447  if (cd && cd!=this && !isBaseClass(cd))
3448  {
3449  if (m_impl->usesIntfClassDict==0)
3450  {
3452  }
3453  UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
3454  if (ucd==0)
3455  {
3456  ucd = new UsesClassDef(cd);
3457  m_impl->usesIntfClassDict->insert(cd->name(),ucd);
3458  //printf("in class `%s' adding used intf class `%s'\n",
3459  // name().data(),cd->name().data());
3460  }
3461  ucd->addAccessor(md->name());
3462  //printf("in class `%s' adding accessor `%s' to class `%s'\n",
3463  // name().data(),md->name().data(),ucd->classDef->name().data());
3464  }
3465  p=i+l;
3466  }
3467 }
3468 
3469 void ClassDef::determineIntfUsageRelation()
3470 {
3471  MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
3472  MemberNameInfo *mni;
3473  for (;(mni=mnili.current());++mnili)
3474  {
3475  MemberNameInfoIterator mnii(*mni);
3476  MemberInfo *mi;
3477  for (mnii.toFirst();(mi=mnii.current());++mnii)
3478  {
3479  MemberDef *md=mi->memberDef;
3480 
3481  // compute the protection level for this member
3482  Protection protect=md->protection();
3483  if (mi->prot==Protected) // inherited protection
3484  {
3485  if (protect==Public) protect=Protected;
3486  else if (protect==Protected) protect=Private;
3487  }
3488 
3489  if (!md->name().isEmpty() && md->name()[0]!='@' &&
3490  (mi->prot!=Private && protect!=Private)
3491  )
3492  {
3493  // add classes found in the return type
3495  ArgumentList *al = md->argumentList();
3496  if (al) // member has arguments
3497  {
3498  // add classes found in the types of the argument list
3499  ArgumentListIterator ali(*al);
3500  Argument *a;
3501  for (;(a=ali.current());++ali)
3502  {
3503  if (!a->type.isEmpty() && a->type.at(0)!='@')
3504  {
3506  }
3507  }
3508  }
3509  }
3510  }
3511  }
3512 }
3513 #endif
3514 
3516 {
3518  {
3519  switch (m_impl->compType)
3520  {
3521  case Class: return "module";
3522  case Struct: return "type";
3523  case Union: return "union";
3524  case Interface: return "interface";
3525  case Protocol: return "protocol";
3526  case Category: return "category";
3527  case Exception: return "exception";
3528  default: return "unknown";
3529  }
3530  }
3531  else
3532  {
3533  switch (m_impl->compType)
3534  {
3535  case Class: return isJavaEnum() ? "enum" : "class";
3536  case Struct: return "struct";
3537  case Union: return "union";
3538  case Interface: return getLanguage()==SrcLangExt_ObjC ? "class" : "interface";
3539  case Protocol: return "protocol";
3540  case Category: return "category";
3541  case Exception: return "exception";
3542  case Service: return "service";
3543  case Singleton: return "singleton";
3544  default: return "unknown";
3545  }
3546  }
3547 }
3548 
3550 {
3551  static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
3552  static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
3554  {
3555  Definition *scope=0;
3556  if (inlineGroupedClasses && partOfGroups()!=0)
3557  {
3558  // point to the group that embeds this class
3559  return partOfGroups()->at(0)->getOutputFileBase();
3560  }
3561  else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
3562  {
3563  // point to simple struct inside a group
3564  return partOfGroups()->at(0)->getOutputFileBase();
3565  }
3566  else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
3567  {
3568  if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
3569  {
3570  return getFileDef()->getOutputFileBase();
3571  }
3572  else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
3573  {
3574  return getOuterScope()->getOutputFileBase();
3575  }
3576  }
3577  }
3578  if (m_impl->templateMaster)
3579  {
3580  // point to the template of which this class is an instance
3582  }
3583  return m_impl->fileName;
3584 }
3585 
3587 {
3588  return m_impl->fileName;
3589 }
3590 
3592 {
3593  if (m_impl->templateMaster)
3594  {
3596  }
3597  else
3598  {
3600  }
3601 }
3602 
3603 void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
3604 {
3605  gd->addClass(this);
3606  //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
3607  if (m_impl->allMemberNameInfoSDict==0) return;
3609  MemberNameInfo *mni;
3610  for (;(mni=mnili.current());++mnili)
3611  {
3612  MemberNameInfoIterator mnii(*mni);
3613  MemberInfo *mi;
3614  for (mnii.toFirst();(mi=mnii.current());++mnii)
3615  {
3616  MemberDef *md=mi->memberDef;
3617  md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
3618  gd->insertMember(md,TRUE);
3619  ClassDef *innerClass = md->getClassDefOfAnonymousType();
3620  if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
3621  }
3622  }
3623 }
3624 
3626 {
3627  //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
3628  if (d->definitionType()==Definition::TypeClass) // only classes can be
3629  // nested in classes.
3630  {
3631  if (m_impl->innerClasses==0)
3632  {
3633  m_impl->innerClasses = new ClassSDict(17);
3634  }
3636  }
3637 }
3638 
3640 {
3641  Definition *result=0;
3642  if (name==0) return 0;
3643  if (m_impl->innerClasses)
3644  {
3645  result = m_impl->innerClasses->find(name);
3646  }
3647  return result;
3648 }
3649 
3650 //void ClassDef::initTemplateMapping()
3651 //{
3652 // m_impl->templateMapping->clear();
3653 // ArgumentList *al = templateArguments();
3654 // if (al)
3655 // {
3656 // ArgumentListIterator ali(*al);
3657 // Argument *arg;
3658 // for (ali.toFirst();(arg=ali.current());++ali)
3659 // {
3660 // setTemplateArgumentMapping(arg->name,arg->defval);
3661 // }
3662 // }
3663 //}
3664 //void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
3665 //{
3666 // //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
3667 // if (m_impl->templateMapping && formal)
3668 // {
3669 // if (m_impl->templateMapping->find(formal))
3670 // {
3671 // m_impl->templateMapping->remove(formal);
3672 // }
3673 // m_impl->templateMapping->insert(formal,new QCString(actual));
3674 // }
3675 //}
3676 //
3677 //QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
3678 //{
3679 // if (m_impl->templateMapping && formal)
3680 // {
3681 // QCString *s = m_impl->templateMapping->find(formal);
3682 // if (s)
3683 // {
3684 // return *s;
3685 // }
3686 // }
3687 // return "";
3688 //}
3689 
3690 ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
3691  int startLine, int startColumn, const QCString &templSpec,bool &freshInstance)
3692 {
3693  freshInstance = FALSE;
3694  if (m_impl->templateInstances==0)
3695  {
3696  m_impl->templateInstances = new QDict<ClassDef>(17);
3697  }
3698  ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
3699  if (templateClass==0)
3700  {
3701  Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
3702  QCString tcname = removeRedundantWhiteSpace(localName()+templSpec);
3703  templateClass = new ClassDef(
3704  fileName,startLine,startColumn,tcname,ClassDef::Class);
3705  templateClass->setTemplateMaster(this);
3706  templateClass->setOuterScope(getOuterScope());
3707  templateClass->setHidden(isHidden());
3708  m_impl->templateInstances->insert(templSpec,templateClass);
3709  freshInstance=TRUE;
3710  }
3711  return templateClass;
3712 }
3713 
3715 {
3716  if (m_impl->variableInstances==0)
3717  {
3718  m_impl->variableInstances = new QDict<ClassDef>(17);
3719  m_impl->variableInstances->setAutoDelete(TRUE);
3720  }
3721  ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
3722  if (templateClass==0)
3723  {
3724  Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
3725  QCString tcname = removeRedundantWhiteSpace(name()+templSpec);
3726  templateClass = new ClassDef("<code>",1,1,tcname,
3727  ClassDef::Class,0,0,FALSE);
3728  templateClass->addMembersToTemplateInstance( this, templSpec );
3729  templateClass->setTemplateMaster(this);
3730  m_impl->variableInstances->insert(templSpec,templateClass);
3731  }
3732  return templateClass;
3733 }
3734 
3735 void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
3736 {
3737  if (templateNames==0) return;
3738  if (m_impl->templBaseClassNames==0)
3739  {
3740  m_impl->templBaseClassNames = new QDict<int>(17);
3741  m_impl->templBaseClassNames->setAutoDelete(TRUE);
3742  }
3743  // make a deep copy of the dictionary.
3744  QDictIterator<int> qdi(*templateNames);
3745  for (;qdi.current();++qdi)
3746  {
3747  if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
3748  {
3749  m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
3750  }
3751  }
3752 }
3753 
3755 {
3756  return m_impl->templBaseClassNames;
3757 }
3758 
3759 void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
3760 {
3761  //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
3762  if (cd->memberNameInfoSDict()==0) return;
3764  MemberNameInfo *mni;
3765  for (;(mni=mnili.current());++mnili)
3766  {
3767  MemberNameInfoIterator mnii(*mni);
3768  MemberInfo *mi;
3769  for (mnii.toFirst();(mi=mnii.current());++mnii)
3770  {
3771  ArgumentList *actualArguments = new ArgumentList;
3772  stringToArgumentList(templSpec,actualArguments);
3773  MemberDef *md = mi->memberDef;
3775  cd->templateArguments(),actualArguments);
3776  delete actualArguments;
3777  //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
3778  imd->setMemberClass(this);
3779  imd->setTemplateMaster(md);
3780  imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
3781  imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
3784  imd->setMemberGroupId(md->getMemberGroupId());
3785  insertMember(imd);
3786  //printf("Adding member=%s %s%s to class %s templSpec %s\n",
3787  // imd->typeString(),imd->name().data(),imd->argsString(),
3788  // imd->getClassDef()->name().data(),templSpec);
3789  // insert imd in the list of all members
3790  //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
3792  if (mn==0)
3793  {
3794  mn = new MemberName(imd->name());
3795  Doxygen::memberNameSDict->append(imd->name(),mn);
3796  }
3797  mn->append(imd);
3798  }
3799  }
3800 }
3801 
3802 QCString ClassDef::getReference() const
3803 {
3804  if (m_impl->templateMaster)
3805  {
3806  return m_impl->templateMaster->getReference();
3807  }
3808  else
3809  {
3810  return Definition::getReference();
3811  }
3812 }
3813 
3815 {
3816  if (m_impl->templateMaster)
3817  {
3818  return m_impl->templateMaster->isReference();
3819  }
3820  else
3821  {
3822  return Definition::isReference();
3823  }
3824 }
3825 
3826 void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
3827 {
3829  if (d)
3830  {
3832  {
3833  ClassDef *cd=(ClassDef *)d;
3834  cd->getTemplateParameterLists(lists);
3835  }
3836  }
3837  if (templateArguments())
3838  {
3839  lists.append(templateArguments());
3840  }
3841 }
3842 
3844  QList<ArgumentList> *actualParams,int *actualParamIndex) const
3845 {
3846  //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3847  static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
3848  //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
3849  QCString scName;
3851  if (d)
3852  {
3854  {
3855  ClassDef *cd=(ClassDef *)d;
3856  scName = cd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex);
3857  }
3858  else if (!hideScopeNames)
3859  {
3860  scName = d->qualifiedName();
3861  }
3862  }
3863 
3864  SrcLangExt lang = getLanguage();
3865  QCString scopeSeparator = getLanguageSpecificSeparator(lang);
3866  if (!scName.isEmpty()) scName+=scopeSeparator;
3867 
3868  bool isSpecialization = localName().find('<')!=-1;
3869 
3870  QCString clName = className();
3871  //bool isGeneric = getLanguage()==SrcLangExt_CSharp;
3872  //if (isGeneric && clName.right(2)=="-g")
3873  //{
3874  // clName = clName.left(clName.length()-2);
3875  //}
3876  //printf("m_impl->lang=%d clName=%s isSpecialization=%d\n",getLanguage(),clName.data(),isSpecialization);
3877  scName+=clName;
3878  ArgumentList *al=0;
3879  if (templateArguments())
3880  {
3881  if (actualParams && *actualParamIndex<(int)actualParams->count())
3882  {
3883  al = actualParams->at(*actualParamIndex);
3884  if (!isSpecialization)
3885  {
3886  scName+=tempArgListToString(al,lang);
3887  }
3888  (*actualParamIndex)++;
3889  }
3890  else
3891  {
3892  if (!isSpecialization)
3893  {
3894  scName+=tempArgListToString(templateArguments(),lang);
3895  }
3896  }
3897  }
3898  //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
3899  return scName;
3900 }
3901 
3902 QCString ClassDef::className() const
3903 {
3904  if (m_impl->className.isEmpty())
3905  {
3906  return localName();
3907  }
3908  else
3909  {
3910  return m_impl->className;
3911  }
3912 };
3913 
3914 void ClassDef::setClassName(const char *name)
3915 {
3916  m_impl->className = name;
3917 }
3918 
3920 {
3921  SrcLangExt lang = getLanguage();
3922  if (!isLinkableInProject()) return;
3923  //printf("ClassDef(%s)::addListReferences()\n",name().data());
3924  {
3925  QList<ListItemInfo> *xrefItems = xrefListItems();
3926  addRefItem(xrefItems,
3927  qualifiedName(),
3928  lang==SrcLangExt_Fortran ? theTranslator->trType(TRUE,TRUE)
3929  : theTranslator->trClass(TRUE,TRUE),
3931  displayName(),
3932  0,
3933  this
3934  );
3935  }
3936  if (m_impl->memberGroupSDict)
3937  {
3939  MemberGroup *mg;
3940  for (;(mg=mgli.current());++mgli)
3941  {
3942  mg->addListReferences(this);
3943  }
3944  }
3945  QListIterator<MemberList> mli(m_impl->memberLists);
3946  MemberList *ml;
3947  for (mli.toFirst();(ml=mli.current());++mli)
3948  {
3950  {
3951  ml->addListReferences(this);
3952  }
3953  }
3954 }
3955 
3956 MemberDef *ClassDef::getMemberByName(const QCString &name) const
3957 {
3958  MemberDef *xmd = 0;
3960  {
3962  if (mni)
3963  {
3964  const int maxInheritanceDepth = 100000;
3965  int mdist=maxInheritanceDepth;
3966  MemberNameInfoIterator mnii(*mni);
3967  MemberInfo *mi;
3968  for (mnii.toFirst();(mi=mnii.current());++mnii)
3969  {
3970  ClassDef *mcd=mi->memberDef->getClassDef();
3971  int m=minClassDistance(this,mcd);
3972  //printf("found member in %s linkable=%d m=%d\n",
3973  // mcd->name().data(),mcd->isLinkable(),m);
3974  if (m<mdist && mcd->isLinkable())
3975  {
3976  mdist=m;
3977  xmd=mi->memberDef;
3978  }
3979  }
3980  }
3981  }
3982  //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
3983  return xmd;
3984 }
3985 
3987 {
3988  return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
3989 }
3990 
3992 {
3993  m_impl->memberLists.setAutoDelete(TRUE);
3994  QListIterator<MemberList> mli(m_impl->memberLists);
3995  MemberList *ml;
3996  for (mli.toFirst();(ml=mli.current());++mli)
3997  {
3998  if (ml->listType()==lt)
3999  {
4000  return ml;
4001  }
4002  }
4003  // not found, create a new member list
4004  ml = new MemberList(lt);
4005  m_impl->memberLists.append(ml);
4006  return ml;
4007 }
4008 
4010 {
4011  QListIterator<MemberList> mli(m_impl->memberLists);
4012  MemberList *ml;
4013  for (;(ml=mli.current());++mli)
4014  {
4015  if (ml->listType()==lt)
4016  {
4017  return ml;
4018  }
4019  }
4020  return 0;
4021 }
4022 
4024 {
4025  static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
4026  static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
4027  MemberList *ml = createMemberList(lt);
4028  ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
4029  ml->append(md);
4030 
4031  // for members in the declaration lists we set the section, needed for member grouping
4032  if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(this,ml);
4033 }
4034 
4036 {
4037  QListIterator<MemberList> mli(m_impl->memberLists);
4038  MemberList *ml;
4039  for (;(ml=mli.current());++mli)
4040  {
4041  if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
4042  }
4043  if (m_impl->innerClasses)
4044  {
4045  m_impl->innerClasses->sort();
4046  }
4047 }
4048 
4050  int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
4051 {
4052  //printf("%s: countMemberDeclarations for %d and %d\n",name().data(),lt,lt2);
4053  int count=0;
4054  MemberList * ml = getMemberList(lt);
4055  MemberList * ml2 = getMemberList((MemberListType)lt2);
4056  if (getLanguage()!=SrcLangExt_VHDL) // use specific declarations function
4057  {
4058  if (ml)
4059  {
4060  ml->countDecMembers();
4061  count+=ml->numDecMembers();
4062  //printf("-> ml=%d\n",ml->numDecMembers());
4063  }
4064  if (ml2)
4065  {
4066  ml2->countDecMembers();
4067  count+=ml2->numDecMembers();
4068  //printf("-> ml2=%d\n",ml2->numDecMembers());
4069  }
4070  // also include grouped members that have their own section in the class (see bug 722759)
4071  if (inheritedFrom && m_impl->memberGroupSDict)
4072  {
4074  MemberGroup *mg;
4075  for (;(mg=mgli.current());++mgli)
4076  {
4077  count+=mg->countGroupedInheritedMembers(lt);
4078  if (lt2!=1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2);
4079  }
4080  }
4081  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
4082  if (!inlineInheritedMembers) // show inherited members as separate lists
4083  {
4084  count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses);
4085  }
4086  }
4087  //printf("-> %d\n",count);
4088  return count;
4089 }
4090 
4091 
4093  ClassDef *inheritedFrom,bool invert,bool showAlways,
4094  QPtrDict<void> *visitedClasses)
4095 {
4096  int inhCount = 0;
4097  int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4098  bool process = count>0;
4099  //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
4100  // name().data(),lt,process,count,invert);
4101  if ((process^invert) || showAlways)
4102  {
4103  if (m_impl->inherits)
4104  {
4106  BaseClassDef *ibcd;
4107  for (it.toFirst();(ibcd=it.current());++it)
4108  {
4109  ClassDef *icd=ibcd->classDef;
4110  int lt1,lt2;
4111  if (icd->isLinkable())
4112  {
4113  convertProtectionLevel(lt,ibcd->prot,&lt1,&lt2);
4114  //printf("%s: convert %d->(%d,%d) prot=%d\n",
4115  // icd->name().data(),lt,lt1,lt2,ibcd->prot);
4116  if (visitedClasses->find(icd)==0)
4117  {
4118  visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
4119  if (lt1!=-1)
4120  {
4121  inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4122  }
4123  }
4124  }
4125  }
4126  }
4127  }
4128  return inhCount;
4129 }
4130 
4132  QCString &title,QCString &subtitle)
4133 {
4134  SrcLangExt lang = getLanguage();
4135  QListIterator<LayoutDocEntry> eli(
4137  LayoutDocEntry *lde;
4138  for (eli.toFirst();(lde=eli.current());++eli)
4139  {
4140  if (lde->kind()==LayoutDocEntry::MemberDecl)
4141  {
4143  if (lmd->type==type)
4144  {
4145  title = lmd->title(lang);
4146  subtitle = lmd->subtitle(lang);
4147  return;
4148  }
4149  }
4150  }
4151  title="";
4152  subtitle="";
4153 }
4154 
4156 {
4157  int totalCount=0;
4158  QListIterator<LayoutDocEntry> eli(
4160  LayoutDocEntry *lde;
4161  for (eli.toFirst();(lde=eli.current());++eli)
4162  {
4163  if (lde->kind()==LayoutDocEntry::MemberDecl)
4164  {
4166  if (lmd->type!=MemberListType_friends) // friendship is not inherited
4167  {
4168  //MemberList *ml = getMemberList(lmd->type);
4169  //if (ml==0 || ml->numDecMembers()==0)
4170  //{
4171  QPtrDict<void> visited(17);
4172  totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,&visited);
4173  //}
4174  }
4175  }
4176  }
4177  //printf("countAdditonalInheritedMembers()=%d\n",totalCount);
4178  return totalCount;
4179 }
4180 
4182 {
4183  //printf("**** writeAdditionalInheritedMembers()\n");
4184  QListIterator<LayoutDocEntry> eli(
4186  LayoutDocEntry *lde;
4187  for (eli.toFirst();(lde=eli.current());++eli)
4188  {
4189  if (lde->kind()==LayoutDocEntry::MemberDecl)
4190  {
4192  if (lmd->type!=MemberListType_friends)
4193  {
4194  QPtrDict<void> visited(17);
4195  writeInheritedMemberDeclarations(ol,lmd->type,-1,lmd->title(getLanguage()),this,TRUE,FALSE,&visited);
4196  }
4197  }
4198  }
4199 }
4200 
4202  ClassDef *inheritedFrom,bool additional)
4203 {
4204  int count=0;
4205  MemberList *ml = getMemberList(lt);
4206  if (ml)
4207  {
4208  count=ml->countInheritableMembers(inheritedFrom);
4209  }
4210  //printf("%s:countMembersIncludingGrouped: count=%d\n",name().data(),count);
4211  if (m_impl->memberGroupSDict)
4212  {
4214  MemberGroup *mg;
4215  for (;(mg=mgli.current());++mgli)
4216  {
4217  bool hasOwnSection = !mg->allMembersInSameSection() ||
4218  !m_impl->subGrouping; // group is in its own section
4219  if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
4220  {
4221  count+=mg->countGroupedInheritedMembers(lt);
4222  }
4223  }
4224  }
4225  //printf("%s:countMembersIncludingGrouped(lt=%d,%s)=%d\n",
4226  // name().data(),lt,ml?ml->listTypeAsString(ml->listType()).data():"<none>",count);
4227  return count;
4228 }
4229 
4231  MemberListType lt,int lt2,const QCString &title,
4232  ClassDef *inheritedFrom,bool invert,bool showAlways,
4233  QPtrDict<void> *visitedClasses)
4234 {
4235  ol.pushGeneratorState();
4237  int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4238  bool process = count>0;
4239  //printf("%s: writeInheritedMemberDec: lt=%d process=%d invert=%d always=%d\n",
4240  // name().data(),lt,process,invert,showAlways);
4241  if ((process^invert) || showAlways)
4242  {
4243  if (m_impl->inherits)
4244  {
4246  BaseClassDef *ibcd;
4247  for (it.toFirst();(ibcd=it.current());++it)
4248  {
4249  ClassDef *icd=ibcd->classDef;
4250  if (icd->isLinkable())
4251  {
4252  int lt1,lt3;
4253  convertProtectionLevel(lt,ibcd->prot,&lt1,&lt3);
4254  if (lt2==-1 && lt3!=-1)
4255  {
4256  lt2=lt3;
4257  }
4258  //printf("%s:convert %d->(%d,%d) prot=%d\n",icd->name().data(),lt,lt1,lt2,ibcd->prot);
4259  if (visitedClasses->find(icd)==0)
4260  {
4261  visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
4262  if (lt1!=-1)
4263  {
4265  title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4266  }
4267  }
4268  else
4269  {
4270  //printf("%s: class already visited!\n",icd->name().data());
4271  }
4272  }
4273  }
4274  }
4275  }
4276  ol.popGeneratorState();
4277 }
4278 
4280  const char *subTitle,bool showInline,ClassDef *inheritedFrom,int lt2,
4281  bool invert,bool showAlways,QPtrDict<void> *visitedClasses)
4282 {
4283  //printf("%s: ClassDef::writeMemberDeclarations lt=%d lt2=%d\n",name().data(),lt,lt2);
4284  MemberList * ml = getMemberList(lt);
4285  MemberList * ml2 = getMemberList((MemberListType)lt2);
4286  if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function
4287  {
4288  static ClassDef *cdef;
4289  if (cdef!=this)
4290  { // only one inline link
4292  cdef=this;
4293  }
4294  if (ml)
4295  {
4296  VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0,0);
4297  }
4298  }
4299  else
4300  {
4301  //printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",name().data(),title.data(),ml,ml2);
4302  QCString tt = title, st = subTitle;
4303  if (ml)
4304  {
4305  //printf(" writeDeclaration type=%d count=%d\n",lt,ml->numDecMembers());
4306  ml->writeDeclarations(ol,this,0,0,0,tt,st,FALSE,showInline,inheritedFrom,lt);
4307  tt.resize(0);
4308  st.resize(0);
4309  }
4310  if (ml2)
4311  {
4312  //printf(" writeDeclaration type=%d count=%d\n",lt2,ml2->numDecMembers());
4313  ml2->writeDeclarations(ol,this,0,0,0,tt,st,FALSE,showInline,inheritedFrom,lt);
4314  }
4315  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
4316  if (!inlineInheritedMembers) // show inherited members as separate lists
4317  {
4318  QPtrDict<void> visited(17);
4319  writeInheritedMemberDeclarations(ol,lt,lt2,title,
4320  inheritedFrom ? inheritedFrom : this,
4321  invert,showAlways,
4322  visitedClasses==0 ? &visited: visitedClasses);
4323  }
4324  }
4325 }
4326 
4328  ClassDef *inheritedFrom,const QCString &inheritId)
4329 {
4330  //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data());
4331  if (m_impl->memberGroupSDict)
4332  {
4334  MemberGroup *mg;
4335  for (;(mg=mgli.current());++mgli)
4336  {
4337  if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
4338  {
4339  mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
4340  }
4341  }
4342  }
4343 }
4344 
4345 void ClassDef::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline)
4346 {
4347  //printf("%s: ClassDef::writeMemberDocumentation()\n",name().data());
4348  MemberList * ml = getMemberList(lt);
4349  if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline);
4350 }
4351 
4353 {
4354  //printf("%s: ClassDef::writeSimpleMemberDocumentation()\n",name().data());
4355  MemberList * ml = getMemberList(lt);
4356  if (ml) ml->writeSimpleDocumentation(ol,this);
4357 }
4358 
4360  MemberListType lt,bool inGroup,
4361  ClassDef *inheritedFrom,const char *inheritId)
4362 {
4363  //printf("%s: ClassDef::writePlainMemberDeclaration()\n",name().data());
4364  MemberList * ml = getMemberList(lt);
4365  if (ml)
4366  {
4367  ml->setInGroup(inGroup);
4368  ml->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
4369  }
4370 }
4371 
4372 bool ClassDef::isLocal() const
4373 {
4374  return m_impl->isLocal;
4375 }
4376 
4378 {
4379  return m_impl->innerClasses;
4380 }
4381 
4383 {
4384  return m_impl->compType;
4385 }
4386 
4388 {
4389  return m_impl->inherits;
4390 }
4391 
4393 {
4394  return m_impl->inheritedBy;
4395 }
4396 
4398 {
4400 }
4401 
4403 {
4404  return m_impl->prot;
4405 }
4406 
4408 {
4409  return m_impl->tempArgs;
4410 }
4411 
4413 {
4414  return m_impl->nspace;
4415 }
4416 
4418 {
4419  return m_impl->fileDef;
4420 }
4421 
4422 QDict<ClassDef> *ClassDef::getTemplateInstances() const
4423 {
4424  return m_impl->templateInstances;
4425 }
4426 
4428 {
4429  return m_impl->templateMaster;
4430 }
4431 
4433 {
4434  return m_impl->tempArgs!=0;
4435 }
4436 
4438 {
4439  return m_impl->incInfo;
4440 }
4441 
4443 {
4444  return m_impl->usesImplClassDict;
4445 }
4446 
4448 {
4449  return m_impl->usedByImplClassDict;
4450 }
4451 
4453 {
4454  return m_impl->usesIntfClassDict;
4455 }
4456 
4458 {
4459  return m_impl->constraintClassDict;
4460 }
4461 
4463 {
4464  return m_impl->isTemplArg;
4465 }
4466 
4468 {
4470 }
4471 
4472 bool ClassDef::isFinal() const
4473 {
4474  return m_impl->spec&Entry::Final;
4475 }
4476 
4478 {
4479  return m_impl->spec&Entry::Sealed;
4480 }
4481 
4483 {
4484  return m_impl->spec&Entry::Published;
4485 }
4486 
4488 {
4489  return m_impl->spec&Entry::ForwardDecl;
4490 }
4491 
4493 {
4494  return getLanguage()==SrcLangExt_ObjC;
4495 }
4496 
4498 {
4499  return getLanguage()==SrcLangExt_CSharp;
4500 }
4501 
4503 {
4504  return m_impl->categoryOf;
4505 }
4506 
4507 const QList<MemberList> &ClassDef::getMemberLists() const
4508 {
4509  return m_impl->memberLists;
4510 }
4511 
4513 {
4514  return m_impl->memberGroupSDict;
4515 }
4516 
4518 {
4519  m_impl->nspace = nd;
4520 }
4521 
4523 {
4524  m_impl->fileDef=fd;
4525 }
4526 
4527 void ClassDef::setSubGrouping(bool enabled)
4528 {
4529  m_impl->subGrouping = enabled;
4530 }
4531 
4533 {
4534  m_impl->prot=p;
4535 }
4536 
4538 {
4539  m_impl->isStatic=b;
4540 }
4541 
4543 {
4544  m_impl->compType = t;
4545 }
4546 
4548 {
4549  m_impl->templateMaster=tm;
4550 }
4551 
4553 {
4554  m_impl->isTemplArg = b;
4555 }
4556 
4558 {
4559  m_impl->categoryOf = cd;
4560 }
4561 
4563 {
4564  m_impl->usedOnly = b;
4565 }
4566 
4568 {
4569  return m_impl->usedOnly;
4570 }
4571 
4573 {
4574  return m_impl->isSimple;
4575 }
4576 
4578 {
4579  return m_impl->arrowOperator;
4580 }
4581 
4583 {
4584  md->setMemberType(t);
4585  QListIterator<MemberList> mli(m_impl->memberLists);
4586  MemberList *ml;
4587  for (;(ml=mli.current());++mli)
4588  {
4589  ml->remove(md);
4590  }
4591  insertMember(md);
4592 }
4593 
4594 QCString ClassDef::anchor() const
4595 {
4596  QCString anc;
4598  {
4599  if (m_impl->templateMaster)
4600  {
4601  // point to the template of which this class is an instance
4603  }
4604  else
4605  {
4606  anc = m_impl->fileName;
4607  }
4608  }
4609  return anc;
4610 }
4611 
4613 {
4614  static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
4615  static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
4616 
4617  Definition *container = getOuterScope();
4618 
4619  bool containerLinkable =
4620  container &&
4621  (
4622  (container==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) || // global class in documented file
4623  container->isLinkableInProject() // class in documented scope
4624  );
4625 
4626  // inline because of INLINE_GROUPED_CLASSES=YES ?
4627  bool b1 = (inlineGroupedClasses && partOfGroups()!=0); // a grouped class
4628  // inline because of INLINE_SIMPLE_STRUCTS=YES ?
4629  bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
4630  (containerLinkable || // in a documented container
4631  partOfGroups()!=0 // or part of a group
4632  )
4633  );
4634  //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
4635  // "inlineSimpleClasses=%d partOfGroups()=%p m_impl->isSimple=%d "
4636  // "getOuterScope()=%s b1=%d b2=%d\n",
4637  // name().data(),inlineGroupedClasses,inlineSimpleClasses,
4638  // partOfGroups().pointer(),m_impl->isSimple,getOuterScope()?getOuterScope()->name().data():"<none>",b1,b2);
4639  return b1 || b2; // either reason will do
4640 }
4641 
4643 {
4644  return m_impl->taggedInnerClasses;
4645 }
4646 
4648 {
4649  if (m_impl->taggedInnerClasses==0)
4650  {
4652  }
4653  m_impl->taggedInnerClasses->append(cd);
4654 }
4655 
4657 {
4658  return m_impl->tagLessRef;
4659 }
4660 
4662 {
4663  m_impl->tagLessRef = cd;
4664 }
4665 
4667 {
4668  QListIterator<MemberList> mli(m_impl->memberLists);
4669  MemberList *ml;
4670  for (;(ml=mli.current());++mli)
4671  {
4672  ml->remove(md);
4673  }
4674 }
4675 
4677 {
4678  return m_impl->isJavaEnum;
4679 }
4680 
4682 {
4683  return m_impl->isGeneric;
4684 }
4685 
4687 {
4688  m_impl->spec = spec;
4689 }
4690 
4692 {
4693  QCString n = name();
4694  int si = n.find('(');
4695  int ei = n.find(')');
4696  bool b = ei>si && n.mid(si+1,ei-si-1).stripWhiteSpace().isEmpty();
4697  return b;
4698 }
4699 
4701 {
4702  return m_impl->innerClasses;
4703 }
4704 
4706 {
4707  return m_impl->files;
4708 }
4709 
4711 {
4712  return m_impl->typeConstraints;
4713 }
4714 
4716 {
4717  return m_impl->exampleSDict;
4718 }
4719 
4721 {
4722  return m_impl->subGrouping;
4723 }
4724 
4725 void ClassDef::setName(const char *name)
4726 {
4727  m_impl->isAnonymous = QCString(name).find('@')!=-1;
4728  Definition::setName(name);
4729 }
4730 
4732 {
4733  return m_impl->isAnonymous;
4734 }
4735 
4737 {
4738  return m_impl->collabFileName;
4739 }
4740 
4742 {
4743  return m_impl->inheritFileName;
4744 }
4745