doxygen  1.8.18
About: Doxygen is a source code documentation generator tool for C++, C, Objective-C, C#, PHP, Java, Python, IDL (diverse flavors), Fortran, VHDL, Tcl, and to some extent D. Different output formats are supported.
  Fossies Dox: doxygen-1.8.18.src.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

classdef.cpp
Go to the documentation of this file.
1 
18 #include <stdio.h>
19 #include <qfile.h>
20 #include <qfileinfo.h>
21 #include <qregexp.h>
22 #include "classdef.h"
23 #include "classlist.h"
24 #include "entry.h"
25 #include "doxygen.h"
26 #include "membername.h"
27 #include "message.h"
28 #include "config.h"
29 #include "util.h"
30 #include "diagram.h"
31 #include "language.h"
32 #include "htmlhelp.h"
33 #include "example.h"
34 #include "outputlist.h"
35 #include "dot.h"
36 #include "dotclassgraph.h"
37 #include "dotrunner.h"
38 #include "defargs.h"
39 #include "debug.h"
40 #include "docparser.h"
41 #include "searchindex.h"
42 #include "vhdldocgen.h"
43 #include "layout.h"
44 #include "arguments.h"
45 #include "memberlist.h"
46 #include "groupdef.h"
47 #include "filedef.h"
48 #include "namespacedef.h"
49 #include "membergroup.h"
50 #include "definitionimpl.h"
51 
52 //-----------------------------------------------------------------------------
53 
54 
56 class ClassDefImpl : public DefinitionImpl, public ClassDef
57 {
58  public:
59  ClassDefImpl(const char *fileName,int startLine,int startColumn,
60  const char *name,CompoundType ct,
61  const char *ref=0,const char *fName=0,
62  bool isSymbol=TRUE,bool isJavaEnum=FALSE);
64  ~ClassDefImpl();
65 
66  virtual ClassDef *resolveAlias() { return this; }
67  virtual DefType definitionType() const { return TypeClass; }
68  virtual QCString getOutputFileBase() const;
69  virtual QCString getInstanceOutputFileBase() const;
70  virtual QCString getSourceFileBase() const;
71  virtual QCString getReference() const;
72  virtual bool isReference() const;
73  virtual bool isLocal() const;
74  virtual ClassSDict *getClassSDict() const;
75  virtual bool hasDocumentation() const;
76  virtual bool hasDetailedDescription() const;
77  virtual QCString collaborationGraphFileName() const;
78  virtual QCString inheritanceGraphFileName() const;
79  virtual QCString displayName(bool includeScope=TRUE) const;
80  virtual CompoundType compoundType() const;
81  virtual QCString compoundTypeString() const;
82  virtual BaseClassList *baseClasses() const;
83  virtual BaseClassList *subClasses() const;
85  virtual Protection protection() const;
86  virtual bool isLinkableInProject() const;
87  virtual bool isLinkable() const;
88  virtual bool isVisibleInHierarchy() const;
89  virtual bool visibleInParentsDeclList() const;
90  virtual const ArgumentList &templateArguments() const;
91  virtual NamespaceDef *getNamespaceDef() const;
92  virtual FileDef *getFileDef() const;
93  virtual MemberDef *getMemberByName(const QCString &) const;
94  virtual bool isBaseClass(const ClassDef *bcd,bool followInstances,int level=0) const;
95  virtual bool isSubClass(ClassDef *bcd,int level=0) const;
96  virtual bool isAccessibleMember(const MemberDef *md) const;
97  virtual QDict<ClassDef> *getTemplateInstances() const;
98  virtual const ClassDef *templateMaster() const;
99  virtual bool isTemplate() const;
100  virtual IncludeInfo *includeInfo() const;
101  virtual UsesClassDict *usedImplementationClasses() const;
103  virtual UsesClassDict *usedInterfaceClasses() const;
105  virtual bool isTemplateArgument() const;
106  virtual Definition *findInnerCompound(const char *name) const;
107  virtual std::vector<ArgumentList> getTemplateParameterLists() const;
109  const std::vector<ArgumentList> *actualParams=0,uint *actualParamIndex=0) const;
110  virtual bool isAbstract() const;
111  virtual bool isObjectiveC() const;
112  virtual bool isFortran() const;
113  virtual bool isCSharp() const;
114  virtual bool isFinal() const;
115  virtual bool isSealed() const;
116  virtual bool isPublished() const;
117  virtual bool isExtension() const;
118  virtual bool isForwardDeclared() const;
119  virtual bool isInterface() const;
120  virtual ClassDef *categoryOf() const;
121  virtual QCString className() const;
122  virtual MemberList *getMemberList(MemberListType lt) const;
123  virtual const QList<MemberList> &getMemberLists() const;
124  virtual MemberGroupSDict *getMemberGroupSDict() const;
125  virtual QDict<int> *getTemplateBaseClassNames() const;
126  virtual ClassDef *getVariableInstance(const char *templSpec) const;
127  virtual bool isUsedOnly() const;
128  virtual QCString anchor() const;
129  virtual bool isEmbeddedInOuterScope() const;
130  virtual bool isSimple() const;
131  virtual const ClassList *taggedInnerClasses() const;
132  virtual ClassDef *tagLessReference() const;
133  virtual MemberDef *isSmartPointer() const;
134  virtual bool isJavaEnum() const;
135  virtual bool isGeneric() const;
136  virtual const ClassSDict *innerClasses() const;
137  virtual QCString title() const;
138  virtual QCString generatedFromFiles() const;
139  virtual const FileList &usedFiles() const;
140  virtual const ArgumentList &typeConstraints() const;
141  virtual const ExampleSDict *exampleList() const;
142  virtual bool hasExamples() const;
143  virtual QCString getMemberListFileName() const;
144  virtual bool subGrouping() const;
145  virtual bool isSliceLocal() const;
146  virtual bool hasNonReferenceSuperClass() const;
147  virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn,
148  const QCString &templSpec,bool &freshInstance) const;
149 
150  virtual void insertBaseClass(ClassDef *,const char *name,Protection p,Specifier s,const char *t=0);
151  virtual void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0);
152  virtual void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force);
153  virtual void insertMember(MemberDef *);
154  virtual void insertUsedFile(FileDef *);
155  virtual bool addExample(const char *anchor,const char *name, const char *file);
156  virtual void mergeCategory(ClassDef *category);
157  virtual void setNamespace(NamespaceDef *nd);
158  virtual void setFileDef(FileDef *fd);
159  virtual void setSubGrouping(bool enabled);
160  virtual void setProtection(Protection p);
161  virtual void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs);
162  virtual void addInnerCompound(const Definition *d);
163  virtual void addUsedClass(ClassDef *cd,const char *accessName,Protection prot);
164  virtual void addUsedByClass(ClassDef *cd,const char *accessName,Protection prot);
165  virtual void setIsStatic(bool b);
166  virtual void setCompoundType(CompoundType t);
167  virtual void setClassName(const char *name);
168  virtual void setClassSpecifier(uint64 spec);
169  virtual void setTemplateArguments(const ArgumentList &al);
170  virtual void setTemplateBaseClassNames(QDict<int> *templateNames);
171  virtual void setTemplateMaster(const ClassDef *tm);
172  virtual void setTypeConstraints(const ArgumentList &al);
173  virtual void addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec);
174  virtual void makeTemplateArgument(bool b=TRUE);
175  virtual void setCategoryOf(ClassDef *cd);
176  virtual void setUsedOnly(bool b);
177  virtual void addTaggedInnerClass(ClassDef *cd);
178  virtual void setTagLessReference(ClassDef *cd);
179  virtual void setName(const char *name);
180  virtual void setMetaData(const char *md);
181  virtual void findSectionsInDocumentation();
182  virtual void addMembersToMemberGroup();
183  virtual void addListReferences();
184  virtual void addTypeConstraints();
185  virtual void computeAnchors();
186  virtual void mergeMembers();
187  virtual void sortMemberLists();
188  virtual void distributeMemberGroupDocumentation();
189  virtual void writeDocumentation(OutputList &ol) const;
190  virtual void writeDocumentationForInnerClasses(OutputList &ol) const;
191  virtual void writeMemberPages(OutputList &ol) const;
192  virtual void writeMemberList(OutputList &ol) const;
193  virtual void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup,
194  const ClassDef *inheritedFrom,const char *inheritId) const;
195  virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const;
196  virtual void writeSummaryLinks(OutputList &ol) const;
197  virtual void reclassifyMember(MemberDef *md,MemberType t);
198  virtual void writeInlineDocumentation(OutputList &ol) const;
199  virtual void writeDeclarationLink(OutputList &ol,bool &found,
200  const char *header,bool localNames) const;
201  virtual void removeMemberFromLists(MemberDef *md);
202  virtual void setAnonymousEnumType();
203  virtual void countMembers();
204 
206  const ClassDef *inheritedFrom,const QCString &inheritId) const;
207  virtual void writeTagFile(FTextStream &);
208 
209  virtual void setVisited(bool visited) const { m_visited = visited; }
210  virtual bool isVisited() const { return m_visited; }
211  virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const;
212  virtual int countInheritanceNodes() const;
213  virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom,
214  int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const;
216  const char *subTitle=0,bool showInline=FALSE,const ClassDef *inheritedFrom=0,
217  int lt2=-1,bool invert=FALSE,bool showAlways=FALSE,
218  QPtrDict<void> *visitedClasses=0) const;
219 
220  private:
221  mutable bool m_visited;
222  void addUsedInterfaceClasses(MemberDef *md,const char *typeStr);
223  void showUsedFiles(OutputList &ol) const;
224 
225  void writeDocumentationContents(OutputList &ol,const QCString &pageTitle) const;
226  void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList);
227  void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief);
230  const ClassDef *inheritedFrom,bool invert,
231  bool showAlways,QPtrDict<void> *visitedClasses) const;
232  void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline=FALSE) const;
234  void writePlainMemberDeclaration(OutputList &ol,MemberListType lt,bool inGroup,const ClassDef *inheritedFrom,const char *inheritId) const;
235  void writeBriefDescription(OutputList &ol,bool exampleFlag) const;
236  void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag,
237  const QCString &title,const QCString &anchor=QCString()) const;
238  void writeIncludeFiles(OutputList &ol) const;
239  void writeIncludeFilesForSlice(OutputList &ol) const;
240  //void writeAllMembersLink(OutputList &ol);
241  void writeInheritanceGraph(OutputList &ol) const;
242  void writeCollaborationGraph(OutputList &ol) const;
243  void writeMemberGroups(OutputList &ol,bool showInline=FALSE) const;
244  void writeNestedClasses(OutputList &ol,const QCString &title) const;
245  void writeInlineClasses(OutputList &ol) const;
246  void startMemberDeclarations(OutputList &ol) const;
247  void endMemberDeclarations(OutputList &ol) const;
248  void startMemberDocumentation(OutputList &ol) const;
249  void endMemberDocumentation(OutputList &ol) const;
250  void writeAuthorSection(OutputList &ol) const;
251  void writeMoreLink(OutputList &ol,const QCString &anchor) const;
253 
256  void addClassAttributes(OutputList &ol) const;
258  const ClassDef *inheritedFrom,bool invert,bool showAlways,
259  QPtrDict<void> *visitedClasses) const;
261  QCString &title,QCString &subtitle) const;
262  QCString includeStatement() const;
263  void addTypeConstraint(const QCString &typeConstraint,const QCString &type);
264 
265  // PIMPL idiom
266  class IMPL;
267  IMPL *m_impl = 0;
268 };
269 
271  const char *fileName,int startLine,int startColumn,
272  const char *name,ClassDef::CompoundType ct,
273  const char *ref,const char *fName,
274  bool isSymbol,bool isJavaEnum)
275 {
276  return new ClassDefImpl(fileName,startLine,startColumn,name,ct,ref,fName,isSymbol,isJavaEnum);
277 }
278 //-----------------------------------------------------------------------------
279 
281 {
282  public:
283  ClassDefAliasImpl(const Definition *newScope,const ClassDef *cd) : DefinitionAliasImpl(newScope,cd) {}
284  virtual ~ClassDefAliasImpl() {}
285  virtual DefType definitionType() const { return TypeClass; }
286 
287  const ClassDef *getCdAlias() const { return dynamic_cast<const ClassDef*>(getAlias()); }
288  virtual ClassDef *resolveAlias() { return const_cast<ClassDef*>(getCdAlias()); }
289 
290  virtual QCString getOutputFileBase() const
291  { return getCdAlias()->getOutputFileBase(); }
293  { return getCdAlias()->getInstanceOutputFileBase(); }
294  virtual QCString getSourceFileBase() const
295  { return getCdAlias()->getSourceFileBase(); }
296  virtual QCString getReference() const
297  { return getCdAlias()->getReference(); }
298  virtual bool isReference() const
299  { return getCdAlias()->isReference(); }
300  virtual bool isLocal() const
301  { return getCdAlias()->isLocal(); }
302  virtual ClassSDict *getClassSDict() const
303  { return getCdAlias()->getClassSDict(); }
304  virtual bool hasDocumentation() const
305  { return getCdAlias()->hasDocumentation(); }
306  virtual bool hasDetailedDescription() const
307  { return getCdAlias()->hasDetailedDescription(); }
309  { return getCdAlias()->collaborationGraphFileName(); }
311  { return getCdAlias()->inheritanceGraphFileName(); }
312  virtual QCString displayName(bool includeScope=TRUE) const
313  { return getCdAlias()->displayName(includeScope); }
314  virtual CompoundType compoundType() const
315  { return getCdAlias()->compoundType(); }
316  virtual QCString compoundTypeString() const
317  { return getCdAlias()->compoundTypeString(); }
318  virtual BaseClassList *baseClasses() const
319  { return getCdAlias()->baseClasses(); }
320  virtual BaseClassList *subClasses() const
321  { return getCdAlias()->subClasses(); }
323  { return getCdAlias()->memberNameInfoSDict(); }
324  virtual Protection protection() const
325  { return getCdAlias()->protection(); }
326  virtual bool isLinkableInProject() const
327  { return getCdAlias()->isLinkableInProject(); }
328  virtual bool isLinkable() const
329  { return getCdAlias()->isLinkable(); }
330  virtual bool isVisibleInHierarchy() const
331  { return getCdAlias()->isVisibleInHierarchy(); }
332  virtual bool visibleInParentsDeclList() const
333  { return getCdAlias()->visibleInParentsDeclList(); }
334  virtual const ArgumentList &templateArguments() const
335  { return getCdAlias()->templateArguments(); }
336  virtual NamespaceDef *getNamespaceDef() const
337  { return getCdAlias()->getNamespaceDef(); }
338  virtual FileDef *getFileDef() const
339  { return getCdAlias()->getFileDef(); }
340  virtual MemberDef *getMemberByName(const QCString &s) const
341  { return getCdAlias()->getMemberByName(s); }
342  virtual bool isBaseClass(const ClassDef *bcd,bool followInstances,int level=0) const
343  { return getCdAlias()->isBaseClass(bcd,followInstances,level); }
344  virtual bool isSubClass(ClassDef *bcd,int level=0) const
345  { return getCdAlias()->isSubClass(bcd,level); }
346  virtual bool isAccessibleMember(const MemberDef *md) const
347  { return getCdAlias()->isAccessibleMember(md); }
349  { return getCdAlias()->getTemplateInstances(); }
350  virtual const ClassDef *templateMaster() const
351  { return getCdAlias()->templateMaster(); }
352  virtual bool isTemplate() const
353  { return getCdAlias()->isTemplate(); }
354  virtual IncludeInfo *includeInfo() const
355  { return getCdAlias()->includeInfo(); }
357  { return getCdAlias()->usedImplementationClasses(); }
359  { return getCdAlias()->usedByImplementationClasses(); }
361  { return getCdAlias()->usedInterfaceClasses(); }
363  { return getCdAlias()->templateTypeConstraints(); }
364  virtual bool isTemplateArgument() const
365  { return getCdAlias()->isTemplateArgument(); }
366  virtual Definition *findInnerCompound(const char *name) const
367  { return getCdAlias()->findInnerCompound(name); }
368  virtual std::vector<ArgumentList> getTemplateParameterLists() const
369  { return getCdAlias()->getTemplateParameterLists(); }
371  const std::vector<ArgumentList> *actualParams=0,uint *actualParamIndex=0) const
372  { return getCdAlias()->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex); }
373  virtual bool isAbstract() const
374  { return getCdAlias()->isAbstract(); }
375  virtual bool isObjectiveC() const
376  { return getCdAlias()->isObjectiveC(); }
377  virtual bool isFortran() const
378  { return getCdAlias()->isFortran(); }
379  virtual bool isCSharp() const
380  { return getCdAlias()->isCSharp(); }
381  virtual bool isFinal() const
382  { return getCdAlias()->isFinal(); }
383  virtual bool isSealed() const
384  { return getCdAlias()->isSealed(); }
385  virtual bool isPublished() const
386  { return getCdAlias()->isPublished(); }
387  virtual bool isExtension() const
388  { return getCdAlias()->isExtension(); }
389  virtual bool isForwardDeclared() const
390  { return getCdAlias()->isForwardDeclared(); }
391  virtual bool isInterface() const
392  { return getCdAlias()->isInterface(); }
393  virtual ClassDef *categoryOf() const
394  { return getCdAlias()->categoryOf(); }
395  virtual QCString className() const
396  { return getCdAlias()->className(); }
398  { return getCdAlias()->getMemberList(lt); }
399  virtual const QList<MemberList> &getMemberLists() const
400  { return getCdAlias()->getMemberLists(); }
402  { return getCdAlias()->getMemberGroupSDict(); }
404  { return getCdAlias()->getTemplateBaseClassNames(); }
405  virtual ClassDef *getVariableInstance(const char *templSpec) const
406  { return getCdAlias()->getVariableInstance(templSpec); }
407  virtual bool isUsedOnly() const
408  { return getCdAlias()->isUsedOnly(); }
409  virtual QCString anchor() const
410  { return getCdAlias()->anchor(); }
411  virtual bool isEmbeddedInOuterScope() const
412  { return getCdAlias()->isEmbeddedInOuterScope(); }
413  virtual bool isSimple() const
414  { return getCdAlias()->isSimple(); }
415  virtual const ClassList *taggedInnerClasses() const
416  { return getCdAlias()->taggedInnerClasses(); }
417  virtual ClassDef *tagLessReference() const
418  { return getCdAlias()->tagLessReference(); }
419  virtual MemberDef *isSmartPointer() const
420  { return getCdAlias()->isSmartPointer(); }
421  virtual bool isJavaEnum() const
422  { return getCdAlias()->isJavaEnum(); }
423  virtual bool isGeneric() const
424  { return getCdAlias()->isGeneric(); }
425  virtual const ClassSDict *innerClasses() const
426  { return getCdAlias()->innerClasses(); }
427  virtual QCString title() const
428  { return getCdAlias()->title(); }
429  virtual QCString generatedFromFiles() const
430  { return getCdAlias()->generatedFromFiles(); }
431  virtual const FileList &usedFiles() const
432  { return getCdAlias()->usedFiles(); }
433  virtual const ArgumentList &typeConstraints() const
434  { return getCdAlias()->typeConstraints(); }
435  virtual const ExampleSDict *exampleList() const
436  { return getCdAlias()->exampleList(); }
437  virtual bool hasExamples() const
438  { return getCdAlias()->hasExamples(); }
440  { return getCdAlias()->getMemberListFileName(); }
441  virtual bool subGrouping() const
442  { return getCdAlias()->subGrouping(); }
443  virtual bool isSliceLocal() const
444  { return getCdAlias()->isSliceLocal(); }
445  virtual bool hasNonReferenceSuperClass() const
446  { return getCdAlias()->hasNonReferenceSuperClass(); }
447  virtual ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn,
448  const QCString &templSpec,bool &freshInstance) const
449  { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); }
450 
451  virtual void insertBaseClass(ClassDef *,const char *,Protection,Specifier,const char *) { }
452  virtual void insertSubClass(ClassDef *,Protection,Specifier,const char *) { }
453  virtual void setIncludeFile(FileDef *,const char *,bool,bool) {}
454  virtual void insertMember(MemberDef *) {}
455  virtual void insertUsedFile(FileDef *) {}
456  virtual bool addExample(const char *,const char *, const char *) { return FALSE; }
457  virtual void mergeCategory(ClassDef *) {}
458  virtual void setNamespace(NamespaceDef *) {}
459  virtual void setFileDef(FileDef *) {}
460  virtual void setSubGrouping(bool) {}
461  virtual void setProtection(Protection) {}
463  virtual void addInnerCompound(const Definition *) {}
464  virtual void addUsedClass(ClassDef *,const char *,Protection) {}
465  virtual void addUsedByClass(ClassDef *,const char *,Protection) {}
466  virtual void setIsStatic(bool) {}
467  virtual void setCompoundType(CompoundType) {}
468  virtual void setClassName(const char *) {}
469  virtual void setClassSpecifier(uint64) {}
470  virtual void setTemplateArguments(const ArgumentList &) {}
472  virtual void setTemplateMaster(const ClassDef *) {}
473  virtual void setTypeConstraints(const ArgumentList &) {}
474  virtual void addMembersToTemplateInstance(const ClassDef *,const char *) {}
475  virtual void makeTemplateArgument(bool=TRUE) {}
476  virtual void setCategoryOf(ClassDef *) {}
477  virtual void setUsedOnly(bool) {}
478  virtual void addTaggedInnerClass(ClassDef *) {}
479  virtual void setTagLessReference(ClassDef *) {}
480  virtual void setName(const char *) {}
481  virtual void setMetaData(const char *) {}
482  virtual void findSectionsInDocumentation() {}
483  virtual void addMembersToMemberGroup() {}
484  virtual void addListReferences() {}
485  virtual void addTypeConstraints() {}
486  virtual void computeAnchors() {}
487  virtual void mergeMembers() {}
488  virtual void sortMemberLists() {}
490  virtual void writeDocumentation(OutputList &) const {}
492  virtual void writeMemberPages(OutputList &) const {}
493  virtual void writeMemberList(OutputList &) const {}
494  virtual void writeDeclaration(OutputList &,const MemberDef *,bool,
495  const ClassDef *,const char *) const {}
496  virtual void writeQuickMemberLinks(OutputList &,const MemberDef *) const {}
497  virtual void writeSummaryLinks(OutputList &) const {}
499  virtual void writeInlineDocumentation(OutputList &) const {}
500  virtual void writeDeclarationLink(OutputList &ol,bool &found,
501  const char *header,bool localNames) const
502  { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); }
503  virtual void removeMemberFromLists(MemberDef *) {}
504  virtual void setAnonymousEnumType() {}
505  virtual void countMembers() {}
507  const ClassDef *,const QCString &) const {}
508  virtual void writeTagFile(FTextStream &) {}
509 
510  virtual void setVisited(bool visited) const { m_visited = visited; }
511  virtual bool isVisited() const { return m_visited; }
512  virtual int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const
513  { return getCdAlias()->countMembersIncludingGrouped(lt,inheritedFrom,additional); }
514  virtual int countInheritanceNodes() const
515  { return getCdAlias()->countInheritanceNodes(); }
516  virtual int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom,
517  int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const
518  { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); }
520  const char *,bool,const ClassDef *, int,bool,bool, QPtrDict<void> *) const {}
521 
522  private:
523  mutable bool m_visited = false;
524 };
525 
526 
527 ClassDef *createClassDefAlias(const Definition *newScope,const ClassDef *cd)
528 {
529  return new ClassDefAliasImpl(newScope,cd);
530 }
531 
532 //-----------------------------------------------------------------------------
533 
536 {
537  public:
538  IMPL();
539  ~IMPL();
540  void init(const char *defFileName, const char *name,
541  const QCString &ctStr, const char *fName);
542 
548 
551 
554 
557 
562 
567 
571 
576 
579 
582 
585 
588 
591 
594 
597 
603 
608 
609  /* classes for the collaboration diagram */
613 
615 
620 
626 
628 
631 
634 
639 
641 
642  /* user defined member groups */
644 
646  bool isAbstract = false;
647 
649  bool isStatic = false;
650 
652  bool membersMerged = false;
653 
655  bool isLocal = false;
656 
657  bool isTemplArg = false;
658 
663  bool subGrouping = false;
664 
666  bool usedOnly = false;
667 
670 
672  bool isSimple = false;
673 
676 
679 
681  bool isJavaEnum = false;
682 
683  bool isGeneric = false;
684 
686 
688 };
689 
690 void ClassDefImpl::IMPL::init(const char *defFileName, const char *name,
691  const QCString &ctStr, const char *fName)
692 {
693  if (fName)
694  {
695  fileName=stripExtension(fName);
696  }
697  else
698  {
699  fileName=ctStr+name;
700  }
701  exampleSDict = 0;
702  inherits = 0;
703  inheritedBy = 0;
705  incInfo=0;
706  prot=Public;
707  nspace=0;
708  fileDef=0;
713  memberGroupSDict = 0;
714  innerClasses = 0;
715  subGrouping=Config_getBool(SUBGROUPING);
716  templateInstances = 0;
717  variableInstances = 0;
718  templateMaster =0;
720  isAbstract = FALSE;
721  isStatic = FALSE;
722  isTemplArg = FALSE;
724  categoryOf = 0;
725  usedOnly = FALSE;
726  isSimple = Config_getBool(INLINE_SIMPLE_STRUCTS);
727  arrowOperator = 0;
728  taggedInnerClasses = 0;
729  tagLessRef = 0;
730  spec=0;
731  //QCString ns;
732  //extractNamespaceName(name,className,ns);
733  //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
734 
735  // we cannot use getLanguage at this point, as setLanguage has not been called.
736  SrcLangExt lang = getLanguageFromFileName(defFileName);
737  if ((lang==SrcLangExt_Cpp || lang==SrcLangExt_ObjC) &&
738  guessSection(defFileName)==Entry::SOURCE_SEC)
739  {
740  isLocal=TRUE;
741  }
742  else
743  {
744  isLocal=FALSE;
745  }
746  isGeneric = (lang==SrcLangExt_CSharp || lang==SrcLangExt_Java) && QCString(name).find('<')!=-1;
747 }
748 
749 ClassDefImpl::IMPL::IMPL() : vhdlSummaryTitles(17)
750 {
752 }
753 
755 {
756  delete inherits;
757  delete inheritedBy;
758  delete allMemberNameInfoSDict;
759  delete exampleSDict;
760  delete usesImplClassDict;
761  delete usedByImplClassDict;
762  delete usesIntfClassDict;
763  delete constraintClassDict;
764  delete incInfo;
765  delete memberGroupSDict;
766  delete innerClasses;
767  delete templateInstances;
768  delete variableInstances;
769  delete templBaseClassNames;
770  delete taggedInnerClasses;
771 }
772 
773 //-------------------------------------------------------------------------------------------
774 
775 // constructs a new class definition
777  const char *defFileName,int defLine,int defColumn,
778  const char *nm,CompoundType ct,
779  const char *lref,const char *fName,
780  bool isSymbol,bool isJavaEnum)
781  : DefinitionImpl(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),0,0,isSymbol)
782 {
784  setReference(lref);
786  m_impl->compType = ct;
788  m_impl->init(defFileName,name(),compoundTypeString(),fName);
792  if (!lref)
793  {
795  }
796 }
797 
798 // destroy the class definition
800 {
801  delete m_impl;
802 }
803 
805 {
806  return m_impl->memberListFileName;
807 }
808 
809 QCString ClassDefImpl::displayName(bool includeScope) const
810 {
811  //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
812  SrcLangExt lang = getLanguage();
813  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
814  QCString n;
815  if (lang==SrcLangExt_VHDL)
816  {
817  n = VhdlDocGen::getClassName(this);
818  }
819  else
820  {
821  if (includeScope)
822  {
824  }
825  else
826  {
827  n=className();
828  }
829  }
830  if (isAnonymous())
831  {
832  n = removeAnonymousScopes(n);
833  }
835  if (sep!="::")
836  {
837  n=substitute(n,"::",sep);
838  }
839  if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
840  {
841  n="<"+n.left(n.length()-2)+">";
842  }
843  //else if (n.right(2)=="-g")
844  //{
845  // n = n.left(n.length()-2);
846  //}
847  //printf("ClassDefImpl::displayName()=%s\n",n.data());
848  return n;
849 }
850 
851 // inserts a base/super class in the inheritance list
853  Specifier s,const char *t)
854 {
855  //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
856  //inherits->inSort(new BaseClassDef(cd,p,s,t));
857  if (m_impl->inherits==0)
858  {
861  }
862  m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
863  m_impl->isSimple = FALSE;
864 }
865 
866 // inserts a derived/sub class in the inherited-by list
868  Specifier s,const char *t)
869 {
870  //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
871  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
872  if (!extractPrivate && cd->protection()==Private) return;
873  if (m_impl->inheritedBy==0)
874  {
877  }
878  m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
879  m_impl->isSimple = FALSE;
880 }
881 
883 {
885  MemberList *ml;
886  for (mli.toFirst();(ml=mli.current());++mli)
887  {
888  if ((ml->listType()&MemberListType_detailedLists)==0)
889  {
891  }
892  }
893 
894  // add members inside sections to their groups
896  {
898  MemberGroup *mg;
899  for (;(mg=mgli.current());++mgli)
900  {
902  {
903  //printf("addToDeclarationSection(%s)\n",mg->header().data());
905  }
906  }
907  }
908 }
909 
910 // adds new member definition to the class
912  Protection prot,
913  bool addToAllList
914  )
915 {
916  //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
917  if (md->isHidden()) return;
918 
920  {
923  {
925  }
926  }
927 
928  if (1 ) // changed to 1 for showing members of external
929  // classes when HAVE_DOT and UML_LOOK are enabled.
930  {
931  bool isSimple=FALSE;
932 
933 
934  /* insert member in the declaration section */
935 
936  if (md->isRelated() && protectionLevelVisible(prot))
937  {
939  }
940  else if (md->isFriend())
941  {
943  }
944  else
945  {
946  switch (md->memberType())
947  {
948  case MemberType_Service: // UNO IDL
950  break;
951  case MemberType_Interface: // UNO IDL
953  break;
954  case MemberType_Signal: // Qt specific
956  break;
957  case MemberType_DCOP: // KDE2 specific
959  break;
960  case MemberType_Property:
962  break;
963  case MemberType_Event:
965  break;
966  case MemberType_Slot: // Qt specific
967  switch (prot)
968  {
969  case Protected:
970  case Package: // slots in packages are not possible!
972  break;
973  case Public:
975  break;
976  case Private:
978  break;
979  }
980  break;
981  default: // any of the other members
982  if (md->isStatic())
983  {
984  if (md->isVariable())
985  {
986  switch (prot)
987  {
988  case Protected:
990  break;
991  case Package:
993  break;
994  case Public:
996  break;
997  case Private:
999  break;
1000  }
1001  }
1002  else // function
1003  {
1004  switch (prot)
1005  {
1006  case Protected:
1008  break;
1009  case Package:
1011  break;
1012  case Public:
1014  break;
1015  case Private:
1017  break;
1018  }
1019  }
1020  }
1021  else // not static
1022  {
1023  if (md->isVariable())
1024  {
1025  switch (prot)
1026  {
1027  case Protected:
1029  break;
1030  case Package:
1032  break;
1033  case Public:
1035  isSimple=!md->isFunctionPtr();
1036  break;
1037  case Private:
1039  break;
1040  }
1041  }
1042  else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
1043  {
1044  switch (prot)
1045  {
1046  case Protected:
1048  break;
1049  case Package:
1051  break;
1052  case Public:
1054  isSimple=!md->isEnumerate() &&
1055  !md->isEnumValue() &&
1056  QCString(md->typeString()).find(")(")==-1; // func ptr typedef
1057  break;
1058  case Private:
1060  break;
1061  }
1062  }
1063  else // member function
1064  {
1065  switch (prot)
1066  {
1067  case Protected:
1069  break;
1070  case Package:
1072  break;
1073  case Public:
1075  break;
1076  case Private:
1078  break;
1079  }
1080  }
1081  }
1082  break;
1083  }
1084  }
1085  if (!isSimple) // not a simple field -> not a simple struct
1086  {
1087  m_impl->isSimple = FALSE;
1088  }
1089  //printf("adding %s simple=%d total_simple=%d\n",name().data(),isSimple,m_impl->isSimple);
1090 
1091 
1092  /* insert member in the detailed documentation section */
1093 
1094  if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
1095  {
1097  }
1098  else if (md->isFunction() && md->protection()==Private && md->virtualness()!=Normal && Config_getBool(EXTRACT_PRIV_VIRTUAL))
1099  {
1101  }
1102  else
1103  {
1104  switch (md->memberType())
1105  {
1106  case MemberType_Service: // UNO IDL
1108  break;
1109  case MemberType_Interface: // UNO IDL
1111  break;
1112  case MemberType_Property:
1114  break;
1115  case MemberType_Event:
1117  break;
1118  case MemberType_Signal: // fall through
1119  case MemberType_DCOP:
1121  break;
1122  case MemberType_Slot:
1123  if (protectionLevelVisible(prot))
1124  {
1126  }
1127  break;
1128  default: // any of the other members
1129  if (protectionLevelVisible(prot))
1130  {
1131  switch (md->memberType())
1132  {
1133  case MemberType_Typedef:
1135  break;
1138  break;
1139  case MemberType_EnumValue:
1141  break;
1142  case MemberType_Function:
1143  if (md->isConstructor() || md->isDestructor())
1144  {
1146  ml->append(md);
1147  }
1148  else
1149  {
1151  }
1152  break;
1153  case MemberType_Variable:
1155  break;
1156  case MemberType_Define:
1157  warn(md->getDefFileName(),md->getDefLine()-1,"A define (%s) cannot be made a member of %s",
1158  md->name().data(), this->name().data());
1159  break;
1160  default:
1161  err("Unexpected member type %d found!\n",md->memberType());
1162  }
1163  }
1164  break;
1165  }
1166  }
1167 
1168 
1169  /* insert member in the appropriate member group */
1170 
1171  // Note: this must be done AFTER inserting the member in the
1172  // regular groups
1173  //addMemberToGroup(md,groupId);
1174 
1175  }
1176 
1177  if (md->virtualness()==Pure)
1178  {
1180  }
1181 
1182  if (md->name()=="operator->")
1183  {
1184  m_impl->arrowOperator=md;
1185  }
1186 
1187  //::addClassMemberNameToIndex(md);
1188  if (addToAllList &&
1189  !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
1190  md->isFriend() &&
1191  (QCString(md->typeString())=="friend class" ||
1192  QCString(md->typeString())=="friend struct" ||
1193  QCString(md->typeString())=="friend union")))
1194  {
1195  //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
1196  MemberInfo *mi = new MemberInfo((MemberDef *)md,
1197  prot,md->virtualness(),FALSE);
1198  MemberNameInfo *mni=0;
1200  {
1203  }
1204  if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
1205  {
1206  mni->append(mi);
1207  }
1208  else
1209  {
1210  mni = new MemberNameInfo(md->name());
1211  mni->append(mi);
1213  }
1214  }
1215 }
1216 
1218 {
1220 }
1221 
1222 // compute the anchors for all members
1224 {
1225  //ClassDef *context = Config_getBool(INLINE_INHERITED_MEMB) ? this : 0;
1226  //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
1228  MemberList *ml;
1229  //int index = 0;
1230  for (mli.toFirst();(ml=mli.current());++mli)
1231  {
1232  if ((ml->listType()&MemberListType_detailedLists)==0)
1233  {
1234  setAnchors(ml);
1235  }
1236  }
1237 
1238  if (m_impl->memberGroupSDict)
1239  {
1241  MemberGroup *mg;
1242  for (;(mg=mgli.current());++mgli)
1243  {
1244  mg->setAnchors();
1245  }
1246  }
1247 }
1248 
1250 {
1251  if (m_impl->memberGroupSDict)
1252  {
1254  MemberGroup *mg;
1255  for (;(mg=mgli.current());++mgli)
1256  {
1258  }
1259  }
1260 }
1261 
1263 {
1265  if (m_impl->memberGroupSDict)
1266  {
1268  MemberGroup *mg;
1269  for (;(mg=mgli.current());++mgli)
1270  {
1271  mg->findSectionsInDocumentation(this);
1272  }
1273  }
1275  MemberList *ml;
1276  for (mli.toFirst();(ml=mli.current());++mli)
1277  {
1278  if ((ml->listType()&MemberListType_detailedLists)==0)
1279  {
1280  ml->findSectionsInDocumentation(this);
1281  }
1282  }
1283 }
1284 
1285 
1286 // add a file name to the used files set
1288 {
1289  if (fd==0) return;
1290  if (m_impl->files.find(fd)==-1) m_impl->files.append(fd);
1292  {
1294  ClassDef *cd;
1295  for (qdi.toFirst();(cd=qdi.current());++qdi)
1296  {
1297  cd->insertUsedFile(fd);
1298  }
1299  }
1300 }
1301 
1303 {
1304  if (bcd->prot!=Public || bcd->virt!=Normal)
1305  {
1306  ol.startTypewriter();
1307  ol.docify(" [");
1308  QStrList sl;
1309  if (bcd->prot==Protected) sl.append("protected");
1310  else if (bcd->prot==Private) sl.append("private");
1311  if (bcd->virt==Virtual) sl.append("virtual");
1312  const char *s=sl.first();
1313  while (s)
1314  {
1315  ol.docify(s);
1316  s=sl.next();
1317  if (s) ol.docify(", ");
1318  }
1319  ol.docify("]");
1320  ol.endTypewriter();
1321  }
1322 }
1323 
1325  const char *includeName,bool local, bool force)
1326 {
1327  //printf("ClassDefImpl::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
1328  if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
1329  if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
1330  (fd!=0 && m_impl->incInfo->fileDef==0)
1331  )
1332  {
1333  //printf("Setting file info\n");
1334  m_impl->incInfo->fileDef = fd;
1335  m_impl->incInfo->includeName = includeName;
1336  m_impl->incInfo->local = local;
1337  }
1338  if (force && includeName)
1339  {
1340  m_impl->incInfo->includeName = includeName;
1341  m_impl->incInfo->local = local;
1342  }
1343 }
1344 
1345 // TODO: fix this: a nested template class can have multiple outer templates
1346 //ArgumentList *ClassDefImpl::outerTemplateArguments() const
1347 //{
1348 // int ti;
1349 // ClassDef *pcd=0;
1350 // int pi=0;
1351 // if (m_impl->tempArgs) return m_impl->tempArgs;
1352 // // find the outer most class scope
1353 // while ((ti=name().find("::",pi))!=-1 &&
1354 // (pcd=getClass(name().left(ti)))==0
1355 // ) pi=ti+2;
1356 // if (pcd)
1357 // {
1358 // return pcd->templateArguments();
1359 // }
1360 // return 0;
1361 //}
1362 
1363 static void searchTemplateSpecs(/*in*/ const Definition *d,
1364  /*out*/ std::vector<ArgumentList> &result,
1365  /*out*/ QCString &name,
1366  /*in*/ SrcLangExt lang)
1367 {
1369  {
1370  if (d->getOuterScope())
1371  {
1372  searchTemplateSpecs(d->getOuterScope(),result,name,lang);
1373  }
1374  const ClassDef *cd=dynamic_cast<const ClassDef *>(d);
1375  if (!name.isEmpty()) name+="::";
1376  QCString clName = d->localName();
1377  if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p")
1378  {
1379  clName = clName.left(clName.length()-2);
1380  }
1381  name+=clName;
1382  bool isSpecialization = d->localName().find('<')!=-1;
1383  if (!cd->templateArguments().empty())
1384  {
1385  result.push_back(cd->templateArguments());
1386  if (!isSpecialization)
1387  {
1388  name+=tempArgListToString(cd->templateArguments(),lang);
1389  }
1390  }
1391  }
1392  else
1393  {
1394  name+=d->qualifiedName();
1395  }
1396 }
1397 
1398 static void writeTemplateSpec(OutputList &ol,const Definition *d,
1399  const QCString &type,SrcLangExt lang)
1400 {
1401  std::vector<ArgumentList> specs;
1402  QCString name;
1403  searchTemplateSpecs(d,specs,name,lang);
1404  if (!specs.empty()) // class has template scope specifiers
1405  {
1406  ol.startSubsubsection();
1407  for (const ArgumentList &al : specs)
1408  {
1409  ol.docify("template<");
1410  auto it = al.begin();
1411  while (it!=al.end())
1412  {
1413  Argument a = *it;
1414  ol.docify(a.type);
1415  if (!a.name.isEmpty())
1416  {
1417  ol.docify(" ");
1418  ol.docify(a.name);
1419  }
1420  if (a.defval.length()!=0)
1421  {
1422  ol.docify(" = ");
1423  ol.docify(a.defval);
1424  }
1425  ++it;
1426  if (it!=al.end()) ol.docify(", ");
1427  }
1428  ol.docify(">");
1429  ol.lineBreak();
1430  }
1431  ol.docify(type.lower()+" "+name);
1432  ol.endSubsubsection();
1433  ol.writeString("\n");
1434  }
1435 }
1436 
1437 void ClassDefImpl::writeBriefDescription(OutputList &ol,bool exampleFlag) const
1438 {
1439  if (hasBriefDescription())
1440  {
1441  ol.startParagraph();
1442  ol.pushGeneratorState();
1444  ol.writeString(" - ");
1445  ol.popGeneratorState();
1446  ol.generateDoc(briefFile(),briefLine(),this,0,
1448  ol.pushGeneratorState();
1450  ol.writeString(" \n");
1452  ol.popGeneratorState();
1453 
1454  if (hasDetailedDescription() || exampleFlag)
1455  {
1456  writeMoreLink(ol,anchor());
1457  }
1458 
1459  ol.endParagraph();
1460  }
1461  ol.writeSynopsis();
1462 }
1463 
1465 {
1466  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1467 
1468  ol.startTextBlock();
1469 
1470  if (getLanguage()==SrcLangExt_Cpp)
1471  {
1473  }
1474 
1475  // repeat brief description
1476  if (!briefDescription().isEmpty() && repeatBrief)
1477  {
1479  }
1480  if (!briefDescription().isEmpty() && repeatBrief &&
1481  !documentation().isEmpty())
1482  {
1483  ol.pushGeneratorState();
1485  ol.writeString("\n\n");
1486  ol.popGeneratorState();
1487  }
1488  // write documentation
1489  if (!documentation().isEmpty())
1490  {
1492  }
1493  // write type constraints
1495 
1496  // write examples
1497  if (hasExamples() && m_impl->exampleSDict)
1498  {
1499  ol.startExamples();
1500  ol.startDescForItem();
1501  //ol.startParagraph();
1503  //ol.endParagraph();
1504  ol.endDescForItem();
1505  ol.endExamples();
1506  }
1507  //ol.newParagraph();
1508  writeSourceDef(ol,name());
1509  ol.endTextBlock();
1510 }
1511 
1513 {
1514  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1515  static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
1516  return ((!briefDescription().isEmpty() && repeatBrief) ||
1517  !documentation().isEmpty() ||
1518  (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
1519 }
1520 
1521 // write the detailed description for this class
1522 void ClassDefImpl::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
1523  const QCString &title,const QCString &anchor) const
1524 {
1525  if (hasDetailedDescription() || exampleFlag)
1526  {
1527  ol.pushGeneratorState();
1529  ol.writeRuler();
1530  ol.popGeneratorState();
1531 
1532  ol.pushGeneratorState();
1534  ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
1535  ol.popGeneratorState();
1536 
1537  if (!anchor.isEmpty())
1538  {
1539  ol.pushGeneratorState();
1543  ol.popGeneratorState();
1544  }
1545 
1546  ol.startGroupHeader();
1547  ol.parseText(title);
1548  ol.endGroupHeader();
1549 
1551  }
1552  else
1553  {
1554  //writeTemplateSpec(ol,this,pageType);
1555  }
1556 }
1557 
1559 {
1560  QCString result;
1561  SrcLangExt lang = getLanguage();
1562  if (lang==SrcLangExt_Fortran)
1563  {
1566  m_impl->files.count()==1);
1567  }
1568  else if (isJavaEnum())
1569  {
1571  }
1572  else if (m_impl->compType==Service)
1573  {
1575  }
1576  else if (m_impl->compType==Singleton)
1577  {
1579  }
1580  else
1581  {
1584  m_impl->files.count()==1);
1585  }
1586  return result;
1587 }
1588 
1590 {
1591  ol.pushGeneratorState();
1593 
1594 
1595  ol.writeRuler();
1596  ol.pushGeneratorState();
1598  ol.startParagraph();
1600  ol.endParagraph();
1601  ol.popGeneratorState();
1605 
1606  bool first=TRUE;
1608  FileDef *fd;
1609  for (;(fd=li.current());++li)
1610  {
1611  if (first)
1612  {
1613  first=FALSE;
1614  ol.startItemList();
1615  }
1616 
1617  ol.startItemListItem();
1618  QCString path=fd->getPath();
1619  if (Config_getBool(FULL_PATH_NAMES))
1620  {
1621  ol.docify(stripFromPath(path));
1622  }
1623 
1624  QCString fname = fd->name();
1625  if (!fd->getVersion().isEmpty()) // append version if available
1626  {
1627  fname += " (" + fd->getVersion() + ")";
1628  }
1629 
1630  // for HTML
1631  ol.pushGeneratorState();
1633  if (fd->generateSourceFile())
1634  {
1635  ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
1636  }
1637  else if (fd->isLinkable())
1638  {
1640  fname);
1641  }
1642  else
1643  {
1644  ol.docify(fname);
1645  }
1646  ol.popGeneratorState();
1647 
1648  // for other output formats
1649  ol.pushGeneratorState();
1651  if (fd->isLinkable())
1652  {
1654  fname);
1655  }
1656  else
1657  {
1658  ol.docify(fname);
1659  }
1660  ol.popGeneratorState();
1661 
1662  ol.endItemListItem();
1663  }
1664  if (!first) ol.endItemList();
1665 
1666  ol.popGeneratorState();
1667 }
1668 
1670 {
1671  int count=0;
1672  BaseClassDef *ibcd;
1673  if (m_impl->inheritedBy)
1674  {
1676  for (;(ibcd=it.current());++it)
1677  {
1678  ClassDef *icd=ibcd->classDef;
1679  if ( icd->isVisibleInHierarchy()) count++;
1680  }
1681  }
1682  if (m_impl->inherits)
1683  {
1685  for (;(ibcd=it.current());++it)
1686  {
1687  ClassDef *icd=ibcd->classDef;
1688  if ( icd->isVisibleInHierarchy()) count++;
1689  }
1690  }
1691  return count;
1692 }
1693 
1695 {
1696  // count direct inheritance relations
1697  const int count=countInheritanceNodes();
1698 
1699  bool renderDiagram = FALSE;
1700  if (Config_getBool(HAVE_DOT) &&
1701  (Config_getBool(CLASS_DIAGRAMS) || Config_getBool(CLASS_GRAPH)))
1702  // write class diagram using dot
1703  {
1704  DotClassGraph inheritanceGraph(this,Inheritance);
1705  if (inheritanceGraph.isTooBig())
1706  {
1707  warn_uncond("Inheritance graph for '%s' not generated, too many nodes (%d), threshold is %d. Consider increasing DOT_GRAPH_MAX_NODES.\n",
1708  name().data(), inheritanceGraph.numNodes(), Config_getInt(DOT_GRAPH_MAX_NODES));
1709  }
1710  else if (!inheritanceGraph.isTrivial())
1711  {
1712  ol.pushGeneratorState();
1714  ol.startDotGraph();
1716  ol.endDotGraph(inheritanceGraph);
1717  ol.popGeneratorState();
1718  renderDiagram = TRUE;
1719  }
1720  }
1721  else if (Config_getBool(CLASS_DIAGRAMS) && count>0)
1722  // write class diagram using built-in generator
1723  {
1724  ClassDiagram diagram(this); // create a diagram of this class.
1725  ol.startClassDiagram();
1730  renderDiagram = TRUE;
1731  }
1732 
1733  if (renderDiagram) // if we already show the inheritance relations graphically,
1734  // then hide the text version
1735  {
1737  }
1738 
1739  if (m_impl->inherits && m_impl->inherits->count()>0)
1740  {
1741  ol.startParagraph();
1742  //parseText(ol,theTranslator->trInherits()+" ");
1743 
1744  QCString inheritLine = theTranslator->trInheritsList((int)m_impl->inherits->count());
1745  QRegExp marker("@[0-9]+");
1746  int index=0,newIndex,matchLen;
1747  // now replace all markers in inheritLine with links to the classes
1748  while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1749  {
1750  ol.parseText(inheritLine.mid(index,newIndex-index));
1751  bool ok;
1752  uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1753  BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
1754  if (ok && bcd)
1755  {
1756  ClassDef *cd=bcd->classDef;
1757 
1758  // use the class name but with the template arguments as given
1759  // in the inheritance relation
1761  cd->displayName(),bcd->templSpecifiers);
1762 
1763  if (cd->isLinkable())
1764  {
1765  ol.writeObjectLink(cd->getReference(),
1766  cd->getOutputFileBase(),
1767  cd->anchor(),
1768  displayName);
1769  }
1770  else
1771  {
1772  ol.docify(displayName);
1773  }
1774  }
1775  else
1776  {
1777  err("invalid marker %d in inherits list!\n",entryIndex);
1778  }
1779  index=newIndex+matchLen;
1780  }
1781  ol.parseText(inheritLine.right(inheritLine.length()-(uint)index));
1782  ol.endParagraph();
1783  }
1784 
1785  // write subclasses
1786  if (m_impl->inheritedBy && m_impl->inheritedBy->count()>0)
1787  {
1788  ol.startParagraph();
1790  QRegExp marker("@[0-9]+");
1791  int index=0,newIndex,matchLen;
1792  // now replace all markers in inheritLine with links to the classes
1793  while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1794  {
1795  ol.parseText(inheritLine.mid(index,newIndex-index));
1796  bool ok;
1797  uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1798  BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
1799  if (ok && bcd)
1800  {
1801  ClassDef *cd=bcd->classDef;
1802  if (cd->isLinkable())
1803  {
1804  ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1805  }
1806  else
1807  {
1808  ol.docify(cd->displayName());
1809  }
1810  writeInheritanceSpecifier(ol,bcd);
1811  }
1812  index=newIndex+matchLen;
1813  }
1814  ol.parseText(inheritLine.right(inheritLine.length()-(uint)index));
1815  ol.endParagraph();
1816  }
1817 
1818  if (renderDiagram)
1819  {
1820  ol.enableAll();
1821  }
1822 }
1823 
1825 {
1826  if (Config_getBool(HAVE_DOT) /*&& Config_getBool(COLLABORATION_GRAPH)*/)
1827  {
1828  DotClassGraph usageImplGraph(this,Collaboration);
1829  if (!usageImplGraph.isTrivial())
1830  {
1831  ol.pushGeneratorState();
1833  ol.startDotGraph();
1835  ol.endDotGraph(usageImplGraph);
1836  ol.popGeneratorState();
1837  }
1838  }
1839 }
1840 
1842 {
1843  SrcLangExt lang = getLanguage();
1844  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1845  if (isIDLorJava)
1846  {
1847  return "import";
1848  }
1849  else if (isObjectiveC())
1850  {
1851  return "#import ";
1852  }
1853  else
1854  {
1855  return "#include ";
1856  }
1857 }
1858 
1860 {
1861  if (m_impl->incInfo)
1862  {
1863  QCString nm;
1864  QStrList paths = Config_getList(STRIP_FROM_PATH);
1865  if (!paths.isEmpty() && m_impl->incInfo->fileDef)
1866  {
1868  const char *s = paths.first();
1869  QCString potential;
1870  unsigned int length = 0;
1871  while (s)
1872  {
1873  QFileInfo info(s);
1874  if (info.exists())
1875  {
1876  QCString prefix = info.absFilePath().utf8();
1877  if (prefix.at(prefix.length() - 1) != '/')
1878  {
1879  prefix += '/';
1880  }
1881 
1882  if (prefix.length() > length &&
1883  qstricmp(abs.left(prefix.length()).data(), prefix.data()) == 0) // case insensitive compare
1884  {
1885  length = prefix.length();
1886  potential = abs.right(abs.length() - prefix.length());
1887  }
1888  s = paths.next();
1889  }
1890  }
1891 
1892  if (length > 0)
1893  {
1894  nm = potential;
1895  }
1896  }
1897 
1898  if (nm.isEmpty())
1899  {
1900  nm = m_impl->incInfo->includeName.data();
1901  }
1902 
1903  ol.startParagraph();
1904  ol.docify(theTranslator->trDefinedIn()+" ");
1905  ol.startTypewriter();
1906  ol.docify("<");
1907  if (m_impl->incInfo->fileDef)
1908  {
1910  }
1911  else
1912  {
1913  ol.docify(nm);
1914  }
1915  ol.docify(">");
1916  ol.endTypewriter();
1917  ol.endParagraph();
1918  }
1919 
1920  // Write a summary of the Slice definition including metadata.
1921  ol.startParagraph();
1922  ol.startTypewriter();
1923  if (!m_impl->metaData.isEmpty())
1924  {
1925  ol.docify(m_impl->metaData);
1926  ol.lineBreak();
1927  }
1928  if (m_impl->spec & Entry::Local)
1929  {
1930  ol.docify("local ");
1931  }
1932  if (m_impl->spec & Entry::Interface)
1933  {
1934  ol.docify("interface ");
1935  }
1936  else if (m_impl->spec & Entry::Struct)
1937  {
1938  ol.docify("struct ");
1939  }
1940  else if (m_impl->spec & Entry::Exception)
1941  {
1942  ol.docify("exception ");
1943  }
1944  else
1945  {
1946  ol.docify("class ");
1947  }
1948  ol.docify(stripScope(name()));
1949  if (m_impl->inherits)
1950  {
1952  {
1953  ol.docify(" extends ");
1955  BaseClassDef *ibcd;
1956  for (;(ibcd=it.current());++it)
1957  {
1958  ClassDef *icd = ibcd->classDef;
1959  ol.docify(icd->name());
1960  if (!it.atLast())
1961  {
1962  ol.docify(", ");
1963  }
1964  }
1965  }
1966  else
1967  {
1968  // Must be a class.
1969  bool implements = FALSE;
1971  BaseClassDef *ibcd;
1972  for (;(ibcd=it.current());++it)
1973  {
1974  ClassDef *icd = ibcd->classDef;
1975  if (icd->isInterface())
1976  {
1977  implements = TRUE;
1978  }
1979  else
1980  {
1981  ol.docify(" extends ");
1982  ol.docify(icd->name());
1983  }
1984  }
1985  if (implements)
1986  {
1987  ol.docify(" implements ");
1988  bool first = TRUE;
1989  for (ibcd=it.toFirst();(ibcd=it.current());++it)
1990  {
1991  ClassDef *icd = ibcd->classDef;
1992  if (icd->isInterface())
1993  {
1994  if (!first)
1995  {
1996  ol.docify(", ");
1997  }
1998  else
1999  {
2000  first = FALSE;
2001  }
2002  ol.docify(icd->name());
2003  }
2004  }
2005  }
2006  }
2007  }
2008  ol.docify(" { ... }");
2009  ol.endTypewriter();
2010  ol.endParagraph();
2011 }
2012 
2014 {
2015  if (m_impl->incInfo /*&& Config_getBool(SHOW_INCLUDE_FILES)*/)
2016  {
2017  SrcLangExt lang = getLanguage();
2019  (m_impl->incInfo->fileDef ?
2020  m_impl->incInfo->fileDef->docName().data() : ""
2021  ) :
2023  if (!nm.isEmpty())
2024  {
2025  ol.startParagraph();
2026  ol.startTypewriter();
2027  ol.docify(includeStatement());
2028  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
2029  if (m_impl->incInfo->local || isIDLorJava)
2030  ol.docify("\"");
2031  else
2032  ol.docify("<");
2033  ol.pushGeneratorState();
2035  ol.docify(nm);
2038  if (m_impl->incInfo->fileDef)
2039  {
2041  }
2042  else
2043  {
2044  ol.docify(nm);
2045  }
2046  ol.popGeneratorState();
2047  if (m_impl->incInfo->local || isIDLorJava)
2048  ol.docify("\"");
2049  else
2050  ol.docify(">");
2051  if (isIDLorJava)
2052  ol.docify(";");
2053  ol.endTypewriter();
2054  ol.endParagraph();
2055  }
2056  }
2057 }
2058 
2059 #if 0
2060 void ClassDefImpl::writeAllMembersLink(OutputList &ol)
2061 {
2062  // write link to list of all members (HTML only)
2064  !Config_getBool(OPTIMIZE_OUTPUT_FOR_C)
2065  )
2066  {
2067  ol.pushGeneratorState();
2069  ol.startParagraph();
2072  ol.endTextLink();
2073  ol.endParagraph();
2074  ol.enableAll();
2075  ol.popGeneratorState();
2076  }
2077 }
2078 #endif
2079 
2080 void ClassDefImpl::writeMemberGroups(OutputList &ol,bool showInline) const
2081 {
2082  // write user defined member groups
2083  if (m_impl->memberGroupSDict)
2084  {
2087  MemberGroup *mg;
2088  for (;(mg=mgli.current());++mgli)
2089  {
2090  if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
2091  {
2092  mg->writeDeclarations(ol,this,0,0,0,showInline);
2093  }
2094  else // add this group to the corresponding member section
2095  {
2096  //printf("addToDeclarationSection(%s)\n",mg->header().data());
2097  //mg->addToDeclarationSection();
2098  }
2099  }
2100  }
2101 }
2102 
2104 {
2105  // nested classes
2106  if (m_impl->innerClasses)
2107  {
2109  }
2110 }
2111 
2113 {
2114  if (m_impl->innerClasses)
2115  {
2117  }
2118 }
2119 
2121 {
2122  //printf("%s: ClassDefImpl::startMemberDocumentation()\n",name().data());
2123  if (Config_getBool(SEPARATE_MEMBER_PAGES))
2124  {
2127  }
2128 }
2129 
2131 {
2132  //printf("%s: ClassDefImpl::endMemberDocumentation()\n",name().data());
2133  if (Config_getBool(SEPARATE_MEMBER_PAGES))
2134  {
2137  }
2138 }
2139 
2141 {
2142  //printf("%s: ClassDefImpl::startMemberDeclarations()\n",name().data());
2143  ol.startMemberSections();
2144 }
2145 
2147 {
2148  //printf("%s: ClassDefImpl::endMemberDeclarations()\n",name().data());
2149  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
2150  if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
2151  {
2152  ol.startMemberHeader("inherited");
2154  ol.endMemberHeader();
2156  }
2157  ol.endMemberSections();
2158 }
2159 
2161 {
2162  ol.pushGeneratorState();
2164  ol.writeString("\n");
2165  ol.startGroupHeader();
2167  ol.endGroupHeader();
2169  ol.popGeneratorState();
2170 }
2171 
2172 
2174 {
2175  ol.pushGeneratorState();
2179  LayoutDocEntry *lde;
2180  bool first=TRUE;
2181  SrcLangExt lang = getLanguage();
2182 
2183  if (lang!=SrcLangExt_VHDL)
2184  {
2185  for (eli.toFirst();(lde=eli.current());++eli)
2186  {
2188  m_impl->innerClasses &&
2190  )
2191  {
2193  ol.writeSummaryLink(0,"nested-classes",ls->title(lang),first);
2194  first=FALSE;
2195  }
2196  else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
2198  !Config_getBool(OPTIMIZE_OUTPUT_FOR_C)
2199  )
2200  {
2201  ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first);
2202  first=FALSE;
2203  }
2204  else if (lde->kind()== LayoutDocEntry::MemberDecl)
2205  {
2207  MemberList * ml = getMemberList(lmd->type);
2208  if (ml && ml->declVisible())
2209  {
2210  ol.writeSummaryLink(0,MemberList::listTypeAsString(ml->listType()),lmd->title(lang),first);
2211  first=FALSE;
2212  }
2213  }
2214  }
2215  }
2216  else // VDHL only
2217  {
2219  for (li.toFirst();li.current();++li)
2220  {
2221  ol.writeSummaryLink(0,convertToId(li.current()->data()),li.current()->data(),first);
2222  first=FALSE;
2223  }
2224  }
2225  if (!first)
2226  {
2227  ol.writeString(" </div>\n");
2228  }
2229  ol.popGeneratorState();
2230 }
2231 
2233 {
2234  if (!isLinkableInProject()) return;
2235  tagFile << " <compound kind=\"";
2236  if (isFortran() && (compoundTypeString() == "type"))
2237  tagFile << "struct";
2238  else
2239  tagFile << compoundTypeString();
2240  tagFile << "\"";
2241  if (isObjectiveC()) { tagFile << " objc=\"yes\""; }
2242  tagFile << ">" << endl;
2243  tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
2244  tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
2245  if (!anchor().isEmpty())
2246  {
2247  tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
2248  }
2249  QCString idStr = id();
2250  if (!idStr.isEmpty())
2251  {
2252  tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
2253  }
2254  for (const Argument &a : m_impl->tempArgs)
2255  {
2256  tagFile << " <templarg>" << convertToXML(a.name) << "</templarg>" << endl;
2257  }
2258  if (m_impl->inherits)
2259  {
2261  BaseClassDef *ibcd;
2262  for (it.toFirst();(ibcd=it.current());++it)
2263  {
2264  ClassDef *cd=ibcd->classDef;
2265  if (cd && cd->isLinkable())
2266  {
2267  if (!Config_getString(GENERATE_TAGFILE).isEmpty())
2268  {
2269  tagFile << " <base";
2270  if (ibcd->prot==Protected)
2271  {
2272  tagFile << " protection=\"protected\"";
2273  }
2274  else if (ibcd->prot==Private)
2275  {
2276  tagFile << " protection=\"private\"";
2277  }
2278  if (ibcd->virt==Virtual)
2279  {
2280  tagFile << " virtualness=\"virtual\"";
2281  }
2282  tagFile << ">" << convertToXML(cd->name()) << "</base>" << endl;
2283  }
2284  }
2285  }
2286  }
2289  LayoutDocEntry *lde;
2290  for (eli.toFirst();(lde=eli.current());++eli)
2291  {
2292  switch (lde->kind())
2293  {
2295  {
2296  if (m_impl->innerClasses)
2297  {
2299  ClassDef *innerCd;
2300  for (cli.toFirst();(innerCd=cli.current());++cli)
2301  {
2302  if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
2303  protectionLevelVisible(innerCd->protection()) &&
2304  !innerCd->isEmbeddedInOuterScope()
2305  )
2306  {
2307  tagFile << " <class kind=\"" << innerCd->compoundTypeString() <<
2308  "\">" << convertToXML(innerCd->name()) << "</class>" << endl;
2309  }
2310  }
2311  }
2312  }
2313  break;
2315  {
2317  MemberList * ml = getMemberList(lmd->type);
2318  if (ml)
2319  {
2320  ml->writeTagFile(tagFile);
2321  }
2322  }
2323  break;
2325  {
2326  if (m_impl->memberGroupSDict)
2327  {
2329  MemberGroup *mg;
2330  for (;(mg=mgli.current());++mgli)
2331  {
2332  mg->writeTagFile(tagFile);
2333  }
2334  }
2335  }
2336  break;
2337  default:
2338  break;
2339  }
2340  }
2341  writeDocAnchorsToTagFile(tagFile);
2342  tagFile << " </compound>" << endl;
2343 }
2344 
2347 {
2348  bool isSimple = m_impl->isSimple;
2349 
2350  ol.addIndexItem(name(),0);
2351  //printf("ClassDefImpl::writeInlineDocumentation(%s)\n",name().data());
2354  LayoutDocEntry *lde;
2355 
2356  // part 1: anchor and title
2357  QCString s = compoundTypeString()+" "+name();
2358 
2359  // part 1a
2360  ol.pushGeneratorState();
2362  { // only HTML only
2363  ol.writeAnchor(0,anchor());
2364  ol.startMemberDoc(0,0,anchor(),name(),1,1,FALSE);
2366  ol.parseText(s);
2367  ol.endMemberDocName();
2368  ol.endMemberDoc(FALSE);
2369  ol.writeString("</div>");
2370  ol.startIndent();
2371  }
2372  ol.popGeneratorState();
2373 
2374  // part 1b
2375  ol.pushGeneratorState();
2378  { // for LaTeX/RTF only
2380  }
2381  ol.popGeneratorState();
2382 
2383  // part 1c
2384  ol.pushGeneratorState();
2386  {
2387  // for LaTeX/RTF/Man
2388  ol.startGroupHeader(1);
2389  ol.parseText(s);
2390  ol.endGroupHeader(1);
2391  }
2392  ol.popGeneratorState();
2393 
2394  SrcLangExt lang=getLanguage();
2395 
2396  // part 2: the header and detailed description
2397  for (eli.toFirst();(lde=eli.current());++eli)
2398  {
2399  switch (lde->kind())
2400  {
2402  {
2403  // since we already shown the brief description in the
2404  // declaration part of the container, so we use this to
2405  // show the details on top.
2407  }
2408  break;
2411  break;
2414  break;
2417  break;
2419  {
2421  if (!isSimple) writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
2422  }
2423  break;
2425  if (!isSimple) writeMemberGroups(ol,TRUE);
2426  break;
2428  if (!isSimple) endMemberDeclarations(ol);
2429  break;
2432  break;
2434  {
2436  if (isSimple)
2437  {
2439  }
2440  else
2441  {
2442  writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
2443  }
2444  }
2445  break;
2447  if (!isSimple) endMemberDocumentation(ol);
2448  break;
2449  default:
2450  break;
2451  }
2452  }
2453 
2454  // part 3: close the block
2455  ol.pushGeneratorState();
2457  { // HTML only
2458  ol.endIndent();
2459  }
2460  ol.popGeneratorState();
2461 }
2462 
2463 void ClassDefImpl::writeMoreLink(OutputList &ol,const QCString &anchor) const
2464 {
2465  // TODO: clean up this mess by moving it to
2466  // the output generators...
2467  static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2468  static bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS);
2469  static bool usePDFLatex = Config_getBool(USE_PDFLATEX);
2470 
2471  // HTML only
2472  ol.pushGeneratorState();
2474  ol.docify(" ");
2476  anchor.isEmpty() ? QCString("details") : anchor);
2478  ol.endTextLink();
2479  ol.popGeneratorState();
2480 
2481  if (!anchor.isEmpty())
2482  {
2483  ol.pushGeneratorState();
2484  // LaTeX + RTF
2488  if (!(usePDFLatex && pdfHyperlinks))
2489  {
2491  }
2492  if (!rtfHyperlinks)
2493  {
2495  }
2496  ol.docify(" ");
2499  ol.endTextLink();
2500  // RTF only
2502  ol.writeString("\\par");
2503  ol.popGeneratorState();
2504  }
2505 }
2506 
2508 {
2509  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2510  static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
2511  static bool extractLocalClasses = Config_getBool(EXTRACT_LOCAL_CLASSES);
2512  bool linkable = isLinkable();
2513  return (!isAnonymous() && !isExtension() &&
2514  (protection()!=::Private || extractPrivate) &&
2515  (linkable || (!hideUndocClasses && (!isLocal() || extractLocalClasses)))
2516  );
2517 }
2518 
2519 void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames) const
2520 {
2521  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2522  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2523  static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2524  SrcLangExt lang = getLanguage();
2526  {
2527  if (!found) // first class
2528  {
2529  if (sliceOpt)
2530  {
2531  if (compoundType()==Interface)
2532  {
2533  ol.startMemberHeader("interfaces");
2534  }
2535  else if (compoundType()==Struct)
2536  {
2537  ol.startMemberHeader("structs");
2538  }
2539  else if (compoundType()==Exception)
2540  {
2541  ol.startMemberHeader("exceptions");
2542  }
2543  else // compoundType==Class
2544  {
2545  ol.startMemberHeader("nested-classes");
2546  }
2547  }
2548  else // non-Slice optimization: single header for class/struct/..
2549  {
2550  ol.startMemberHeader("nested-classes");
2551  }
2552  if (header)
2553  {
2554  ol.parseText(header);
2555  }
2556  else if (lang==SrcLangExt_VHDL)
2557  {
2559  }
2560  else
2561  {
2562  ol.parseText(lang==SrcLangExt_Fortran ?
2565  }
2566  ol.endMemberHeader();
2567  ol.startMemberList();
2568  found=TRUE;
2569  }
2572  QCString ctype = compoundTypeString();
2573  QCString cname = displayName(!localNames);
2574 
2575  if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
2576  {
2577  if (isSliceLocal())
2578  {
2579  ol.writeString("local ");
2580  }
2581  ol.writeString(ctype);
2582  ol.writeString(" ");
2583  ol.insertMemberAlign();
2584  }
2585  if (isLinkable())
2586  {
2589  anchor(),
2590  cname
2591  );
2592  }
2593  else
2594  {
2595  ol.startBold();
2596  ol.docify(cname);
2597  ol.endBold();
2598  }
2599  if (lang==SrcLangExt_VHDL) // now write the type
2600  {
2601  ol.writeString(" ");
2602  ol.insertMemberAlign();
2604  }
2605  ol.endMemberItem();
2606 
2607  // add the brief description if available
2608  if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
2609  {
2610  DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
2612  if (rootNode && !rootNode->isEmpty())
2613  {
2615  ol.writeDoc(rootNode,this,0);
2616  if (isLinkableInProject())
2617  {
2618  writeMoreLink(ol,anchor());
2619  }
2620  ol.endMemberDescription();
2621  }
2622  delete rootNode;
2623  }
2624  ol.endMemberDeclaration(anchor(),0);
2625  }
2626 }
2627 
2629 {
2630  QStrList sl;
2631  if (isFinal()) sl.append("final");
2632  if (isSealed()) sl.append("sealed");
2633  if (isAbstract()) sl.append("abstract");
2634  if (getLanguage()==SrcLangExt_IDL && isPublished()) sl.append("published");
2635 
2636  ol.pushGeneratorState();
2638  if (sl.count()>0)
2639  {
2640  ol.startLabels();
2641  const char *s=sl.first();
2642  while (s)
2643  {
2644  const char *ns = sl.next();
2645  ol.writeLabel(s,ns==0);
2646  s=ns;
2647  }
2648  ol.endLabels();
2649  }
2650  ol.popGeneratorState();
2651 }
2652 
2653 void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/) const
2654 {
2655  ol.startContents();
2656 
2657  QCString pageType = " ";
2658  pageType += compoundTypeString();
2659 
2661 
2663  {
2666  }
2667  bool exampleFlag=hasExamples();
2668 
2669  //---------------------------------------- start flexible part -------------------------------
2670 
2671  SrcLangExt lang = getLanguage();
2672 
2675  LayoutDocEntry *lde;
2676  for (eli.toFirst();(lde=eli.current());++eli)
2677  {
2678  switch (lde->kind())
2679  {
2681  writeBriefDescription(ol,exampleFlag);
2682  break;
2684  if (lang==SrcLangExt_Slice)
2685  {
2687  }
2688  else
2689  {
2690  writeIncludeFiles(ol);
2691  }
2692  break;
2695  break;
2698  break;
2700  //writeAllMembersLink(ol); // this is now part of the summary links
2701  break;
2704  break;
2706  writeMemberGroups(ol);
2707  break;
2709  {
2711  writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang));
2712  }
2713  break;
2715  {
2717  writeNestedClasses(ol,ls->title(lang));
2718  }
2719  break;
2722  break;
2724  {
2726  writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
2727  }
2728  break;
2731  break;
2733  writeInlineClasses(ol);
2734  break;
2736  {
2738  writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
2739  }
2740  break;
2743  break;
2745  showUsedFiles(ol);
2746  break;
2748  writeAuthorSection(ol);
2749  break;
2779  err("Internal inconsistency: member %d should not be part of "
2780  "LayoutDocManager::Class entry list\n",lde->kind());
2781  break;
2782  }
2783  }
2784 
2785  ol.endContents();
2786 }
2787 
2789 {
2790  QCString pageTitle;
2791  SrcLangExt lang = getLanguage();
2792 
2793  if (lang==SrcLangExt_Fortran)
2794  {
2796  m_impl->compType,
2797  !m_impl->tempArgs.empty());
2798  }
2799  else if (lang==SrcLangExt_Slice)
2800  {
2802  m_impl->compType,
2803  isSliceLocal());
2804  }
2805  else if (lang==SrcLangExt_VHDL)
2806  {
2808  }
2809  else if (isJavaEnum())
2810  {
2811  pageTitle = theTranslator->trEnumReference(displayName());
2812  }
2813  else if (m_impl->compType==Service)
2814  {
2816  }
2817  else if (m_impl->compType==Singleton)
2818  {
2820  }
2821  else
2822  {
2823  if (Config_getBool(HIDE_COMPOUND_REFERENCE))
2824  {
2825  pageTitle = displayName();
2826  }
2827  else
2828  {
2831  !m_impl->tempArgs.empty());
2832  }
2833  }
2834  return pageTitle;
2835 }
2836 
2837 // write all documentation for this class
2839 {
2840  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2841  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2842  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2843  static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2844  QCString pageTitle = title();
2845 
2846  HighlightedItem hli;
2847  if (sliceOpt)
2848  {
2849  if (compoundType()==Interface)
2850  {
2851  hli = HLI_InterfaceVisible;
2852  }
2853  else if (compoundType()==Struct)
2854  {
2855  hli = HLI_StructVisible;
2856  }
2857  else if (compoundType()==Exception)
2858  {
2859  hli = HLI_ExceptionVisible;
2860  }
2861  else
2862  {
2863  hli = HLI_ClassVisible;
2864  }
2865  }
2866  else
2867  {
2868  hli = HLI_ClassVisible;
2869  }
2870 
2871  startFile(ol,getOutputFileBase(),name(),pageTitle,hli,!generateTreeView);
2872  if (!generateTreeView)
2873  {
2875  {
2876  writeNavigationPath(ol);
2877  }
2878  ol.endQuickIndices();
2879  }
2880 
2881  startTitle(ol,getOutputFileBase(),this);
2882  ol.parseText(pageTitle);
2883  addClassAttributes(ol);
2884  addGroupListToTitle(ol,this);
2886  writeDocumentationContents(ol,pageTitle);
2887 
2888  endFileWithNavPath(this,ol);
2889 
2890  if (Config_getBool(SEPARATE_MEMBER_PAGES))
2891  {
2892  writeMemberPages(ol);
2893  }
2894 }
2895 
2897 {
2901 
2902  ol.pushGeneratorState();
2904 
2906  MemberList *ml;
2907  for (mli.toFirst();(ml=mli.current());++mli)
2908  {
2910  {
2911  ml->writeDocumentationPage(ol,displayName(),this);
2912  }
2913  }
2914 
2915  ol.popGeneratorState();
2916 }
2917 
2919 {
2920  static bool createSubDirs=Config_getBool(CREATE_SUBDIRS);
2921 
2922  ol.writeString(" <div class=\"navtab\">\n");
2923  ol.writeString(" <table>\n");
2924 
2926  {
2928  MemberNameInfo *mni;
2929  for (;(mni=mnili.current());++mnili)
2930  {
2931  MemberNameInfoIterator mnii(*mni);
2932  MemberInfo *mi;
2933  for (mnii.toFirst();(mi=mnii.current());++mnii)
2934  {
2935  MemberDef *md=mi->memberDef;
2936  if (md->getClassDef()==this && md->isLinkable() && !md->isEnumValue())
2937  {
2938  ol.writeString(" <tr><td class=\"navtab\">");
2939  if (md->isLinkableInProject())
2940  {
2941  if (md==currentMd) // selected item => highlight
2942  {
2943  ol.writeString("<a class=\"qindexHL\" ");
2944  }
2945  else
2946  {
2947  ol.writeString("<a class=\"qindex\" ");
2948  }
2949  ol.writeString("href=\"");
2950  if (createSubDirs) ol.writeString("../../");
2952  ol.writeString("\">");
2953  ol.writeString(convertToHtml(md->name()));
2954  ol.writeString("</a>");
2955  }
2956  ol.writeString("</td></tr>\n");
2957  }
2958  }
2959  }
2960  }
2961 
2962  ol.writeString(" </table>\n");
2963  ol.writeString(" </div>\n");
2964 }
2965 
2966 
2967 
2969 {
2970  // write inner classes after the parent, so the tag files contain
2971  // the definition in proper order!
2972  if (m_impl->innerClasses)
2973  {
2975  ClassDef *innerCd;
2976  for (cli.toFirst();(innerCd=cli.current());++cli)
2977  {
2978  if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
2979  protectionLevelVisible(innerCd->protection()) &&
2980  !innerCd->isEmbeddedInOuterScope()
2981  )
2982  {
2983  msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
2984  innerCd->writeDocumentation(ol);
2985  innerCd->writeMemberList(ol);
2986  }
2987  innerCd->writeDocumentationForInnerClasses(ol);
2988  }
2989  }
2990 }
2991 
2992 // write the list of all (inherited) members for this class
2994 {
2995  static bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
2996  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2997  static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2998  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2999  if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
3000  // only for HTML
3001  ol.pushGeneratorState();
3003 
3004  HighlightedItem hli;
3005  if (sliceOpt)
3006  {
3007  if (compoundType()==Interface)
3008  {
3009  hli = HLI_InterfaceVisible;
3010  }
3011  else if (compoundType()==Struct)
3012  {
3013  hli = HLI_StructVisible;
3014  }
3015  else if (compoundType()==Exception)
3016  {
3017  hli = HLI_ExceptionVisible;
3018  }
3019  else
3020  {
3021  hli = HLI_ClassVisible;
3022  }
3023  }
3024  else
3025  {
3026  hli = HLI_ClassVisible;
3027  }
3028 
3029  QCString memListFile = getMemberListFileName();
3030  startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),hli,!generateTreeView,getOutputFileBase());
3031  if (!generateTreeView)
3032  {
3034  {
3035  writeNavigationPath(ol);
3036  }
3037  ol.endQuickIndices();
3038  }
3039  startTitle(ol,0);
3041  endTitle(ol,0,0);
3042  ol.startContents();
3043  ol.startParagraph();
3047  ol.endParagraph();
3048 
3049  //ol.startItemList();
3050 
3051  bool first = true; // to prevent empty table
3052  int idx=0;
3053  //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
3055  MemberNameInfo *mni;
3056  for (mnii.toFirst();(mni=mnii.current());++mnii)
3057  {
3058  MemberNameInfoIterator it(*mni);
3059  MemberInfo *mi;
3060  for (;(mi=it.current());++it)
3061  {
3062  MemberDef *md=mi->memberDef;
3063  const ClassDef *cd=md->getClassDef();
3064  Protection prot = mi->prot;
3065  Specifier virt=md->virtualness();
3066 
3067  //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
3068  // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
3069 
3070  if (cd && !md->name().isEmpty() && !md->isAnonymous())
3071  {
3072  bool memberWritten=FALSE;
3073  if (cd->isLinkable() && md->isLinkable())
3074  // create a link to the documentation
3075  {
3077  //ol.writeListItem();
3078  if (first)
3079  {
3080  ol.writeString("<table class=\"directory\">\n");
3081  first = false;
3082  }
3083  ol.writeString(" <tr");
3084  if ((idx&1)==0) ol.writeString(" class=\"even\"");
3085  idx++;
3086  ol.writeString("><td class=\"entry\">");
3087  if (cd->isObjectiveC())
3088  {
3089  if (md->isObjCMethod())
3090  {
3091  if (md->isStatic())
3092  ol.writeString("+&#160;</td><td>");
3093  else
3094  ol.writeString("-&#160;</td><td>");
3095  }
3096  else
3097  ol.writeString("</td><td class=\"entry\">");
3098  }
3099  if (md->isObjCMethod())
3100  {
3101  ol.writeObjectLink(md->getReference(),
3102  md->getOutputFileBase(),
3103  md->anchor(),md->name());
3104  }
3105  else
3106  {
3107  //Definition *bd = md->getGroupDef();
3108  //if (bd==0) bd=cd;
3109  ol.writeObjectLink(md->getReference(),
3110  md->getOutputFileBase(),
3111  md->anchor(),name);
3112 
3113  if ( md->isFunction() || md->isSignal() || md->isSlot() ||
3114  (md->isFriend() && md->argsString()))
3115  ol.docify(md->argsString());
3116  else if (md->isEnumerate())
3117  ol.parseText(" "+theTranslator->trEnumName());
3118  else if (md->isEnumValue())
3119  ol.parseText(" "+theTranslator->trEnumValue());
3120  else if (md->isTypedef())
3121  ol.docify(" typedef");
3122  else if (md->isFriend() && !qstrcmp(md->typeString(),"friend class"))
3123  ol.docify(" class");
3124  //ol.writeString("\n");
3125  }
3126  ol.writeString("</td>");
3127  memberWritten=TRUE;
3128  }
3129  else if (!cd->isArtificial() &&
3130  !Config_getBool(HIDE_UNDOC_MEMBERS) &&
3131  (protectionLevelVisible(md->protection()) || md->isFriend())
3132  ) // no documentation,
3133  // generate link to the class instead.
3134  {
3135  //ol.writeListItem();
3136  if (first)
3137  {
3138  ol.writeString("<table class=\"directory\">\n");
3139  first = false;
3140  }
3141  ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
3142  if ((idx&1)==0) ol.writeString(" class=\"even\"");
3143  idx++;
3144  ol.writeString("><td class=\"entry\">");
3145  if (cd->isObjectiveC())
3146  {
3147  if (md->isObjCMethod())
3148  {
3149  if (md->isStatic())
3150  ol.writeString("+&#160;</td><td class=\"entry\">");
3151  else
3152  ol.writeString("-&#160;</td><td class=\"entry\">");
3153  }
3154  else
3155  ol.writeString("</td><td class=\"entry\">");
3156  }
3157  ol.startBold();
3158  ol.docify(md->name());
3159  ol.endBold();
3160  if (!md->isObjCMethod())
3161  {
3162  if ( md->isFunction() || md->isSignal() || md->isSlot() )
3163  ol.docify(md->argsString());
3164  else if (md->isEnumerate())
3165  ol.parseText(" "+theTranslator->trEnumName());
3166  else if (md->isEnumValue())
3167  ol.parseText(" "+theTranslator->trEnumValue());
3168  else if (md->isTypedef())
3169  ol.docify(" typedef");
3170  }
3171  ol.writeString(" (");
3172  ol.parseText(theTranslator->trDefinedIn()+" ");
3173  if (cd->isLinkable())
3174  {
3175  ol.writeObjectLink(
3176  cd->getReference(),
3177  cd->getOutputFileBase(),
3178  cd->anchor(),
3179  cd->displayName());
3180  }
3181  else
3182  {
3183  ol.startBold();
3184  ol.docify(cd->displayName());
3185  ol.endBold();
3186  }
3187  ol.writeString(")");
3188  ol.writeString("</td>");
3189  memberWritten=TRUE;
3190  }
3191  if (memberWritten)
3192  {
3193  ol.writeString("<td class=\"entry\">");
3194  ol.writeObjectLink(cd->getReference(),
3195  cd->getOutputFileBase(),
3196  cd->anchor(),
3197  md->category() ?
3198  md->category()->displayName() :
3199  cd->displayName());
3200  ol.writeString("</td>");
3201  ol.writeString("<td class=\"entry\">");
3202  }
3203  SrcLangExt lang = md->getLanguage();
3204  if (
3205  (prot!=Public || (virt!=Normal && getLanguage()!=SrcLangExt_ObjC) ||
3206  md->isFriend() || md->isRelated() || md->isExplicit() ||
3207  md->isMutable() || (md->isInline() && Config_getBool(INLINE_INFO)) ||
3208  md->isSignal() || md->isSlot() ||
3210  (md->isOptional() || md->isAttribute() || md->isUNOProperty())) ||
3211  md->isStatic() || lang==SrcLangExt_VHDL
3212  )
3213  && memberWritten)
3214  {
3215  ol.writeString("<span class=\"mlabel\">");
3216  QStrList sl;
3217  if (lang==SrcLangExt_VHDL)
3218  {
3219  sl.append(theTranslator->trVhdlType(md->getMemberSpecifiers(),TRUE)); //append vhdl type
3220  }
3221  else if (md->isFriend()) sl.append("friend");
3222  else if (md->isRelated()) sl.append("related");
3223  else
3224  {
3225  if (Config_getBool(INLINE_INFO) && md->isInline())
3226  sl.append("inline");
3227  if (md->isExplicit()) sl.append("explicit");
3228  if (md->isMutable()) sl.append("mutable");
3229  if (prot==Protected) sl.append("protected");
3230  else if (prot==Private) sl.append("private");
3231  else if (prot==Package) sl.append("package");
3232  if (virt==Virtual && getLanguage()!=SrcLangExt_ObjC)
3233  sl.append("virtual");
3234  else if (virt==Pure) sl.append("pure virtual");
3235  if (md->isStatic()) sl.append("static");
3236  if (md->isSignal()) sl.append("signal");
3237  if (md->isSlot()) sl.append("slot");
3238 // this is the extra member page
3239  if (md->isOptional()) sl.append("optional");
3240  if (md->isAttribute()) sl.append("attribute");
3241  if (md->isUNOProperty()) sl.append("property");
3242  if (md->isReadonly()) sl.append("readonly");
3243  if (md->isBound()) sl.append("bound");
3244  if (md->isRemovable()) sl.append("removable");
3245  if (md->isConstrained()) sl.append("constrained");
3246  if (md->isTransient()) sl.append("transient");
3247  if (md->isMaybeVoid()) sl.append("maybevoid");
3248  if (md->isMaybeDefault()) sl.append("maybedefault");
3249  if (md->isMaybeAmbiguous())sl.append("maybeambiguous");
3250  }
3251  const char *s=sl.first();
3252  while (s)
3253  {
3254  ol.docify(s);
3255  s=sl.next();
3256  if (s) ol.writeString("</span><span class=\"mlabel\">");
3257  }
3258  ol.writeString("</span>");
3259  }
3260  if (memberWritten)
3261  {
3262  ol.writeString("</td>");
3263  ol.writeString("</tr>\n");
3264  }
3265  }
3266  }
3267  }
3268  //ol.endItemList();
3269 
3270  if (!first) ol.writeString("</table>");
3271 
3272  endFile(ol);
3273  ol.popGeneratorState();
3274 }
3275 
3276 // add a reference to an example
3277 bool ClassDefImpl::addExample(const char *anchor,const char *nameStr,
3278  const char *file)
3279 {
3280  if (m_impl->exampleSDict==0)
3281  {
3284  }
3285  if (!m_impl->exampleSDict->find(nameStr))
3286  {
3287  Example *e=new Example;
3288  e->anchor=anchor;
3289  e->name=nameStr;
3290  e->file=file;
3291  m_impl->exampleSDict->inSort(nameStr,e);
3292  return TRUE;
3293  }
3294  return FALSE;
3295 }
3296 
3297 // returns TRUE if this class is used in an example
3299 {
3300  bool result=FALSE;
3301  if (m_impl->exampleSDict)
3302  {
3303  result = m_impl->exampleSDict->count()>0;
3304  }
3305  return result;
3306 }
3307 
3308 void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCString &type)
3309 {
3310  //printf("addTypeConstraint(%s,%s)\n",type.data(),typeConstraint.data());
3311  static bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS);
3312  if (typeConstraint.isEmpty() || type.isEmpty()) return;
3313  ClassDef *cd = const_cast<ClassDef*>(getResolvedClass(this,getFileDef(),typeConstraint));
3314  if (cd==0 && !hideUndocRelation)
3315  {
3316  cd = new ClassDefImpl(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class);
3317  cd->setUsedOnly(TRUE);
3318  cd->setLanguage(getLanguage());
3319  Doxygen::hiddenClasses->append(typeConstraint,cd);
3320  //printf("Adding undocumented constraint '%s' to class %s on type %s\n",
3321  // typeConstraint.data(),name().data(),type.data());
3322  }
3323  if (cd)
3324  {
3325  if (m_impl->constraintClassDict==0)
3326  {
3328  m_impl->constraintClassDict->setAutoDelete(TRUE);
3329  }
3330  ConstraintClassDef *ccd=m_impl->constraintClassDict->find(typeConstraint);
3331  if (ccd==0)
3332  {
3333  ccd = new ConstraintClassDef(cd);
3334  m_impl->constraintClassDict->insert(typeConstraint,ccd);
3335  }
3336  ccd->addAccessor(type);
3337  //printf("Adding constraint '%s' to class %s on type %s\n",
3338  // typeConstraint.data(),name().data(),type.data());
3339  }
3340 }
3341 
3342 // Java Type Constrains: A<T extends C & I>
3344 {
3345  for (const Argument &a : m_impl->tempArgs)
3346  {
3347  if (!a.typeConstraint.isEmpty())
3348  {
3349  QCString typeConstraint;
3350  int i=0,p=0;
3351  while ((i=a.typeConstraint.find('&',p))!=-1) // typeConstraint="A &I" for C<T extends A & I>
3352  {
3353  typeConstraint = a.typeConstraint.mid(p,i-p).stripWhiteSpace();
3354  addTypeConstraint(typeConstraint,a.type);
3355  p=i+1;
3356  }
3357  typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-(uint)p).stripWhiteSpace();
3358  addTypeConstraint(typeConstraint,a.type);
3359  }
3360  }
3361 }
3362 
3363 // C# Type Constraints: D<T> where T : C, I
3365 {
3366  m_impl->typeConstraints = al;
3367 }
3368 
3370 {
3371  m_impl->tempArgs = al;
3372 }
3373 
3378 {
3379  bool found=!isReference() && isLinkableInProject() && !isHidden();
3380  if (found)
3381  {
3382  return TRUE; // we're done if this class is not a reference
3383  }
3384  if (m_impl->inheritedBy)
3385  {
3387  for ( ; bcli.current() && !found ; ++bcli ) // for each super class
3388  {
3389  ClassDef *bcd=bcli.current()->classDef;
3390  // recurse into the super class branch
3391  found = found || bcd->hasNonReferenceSuperClass();
3392  if (!found)
3393  {
3394  // look for template instances that might have non-reference super classes
3395  QDict<ClassDef> *cil = bcd->getTemplateInstances();
3396  if (cil)
3397  {
3398  QDictIterator<ClassDef> tidi(*cil);
3399  for ( ; tidi.current() && !found ; ++tidi) // for each template instance
3400  {
3401  // recurse into the template instance branch
3402  found = found || tidi.current()->hasNonReferenceSuperClass();
3403  }
3404  }
3405  }
3406  }
3407  }
3408  return found;
3409 }
3410 
3414 void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup,
3415  const ClassDef *inheritedFrom,const char *inheritId) const
3416 {
3417  //printf("ClassName='%s' inGroup=%d\n",name().data(),inGroup);
3418 
3419  ol.docify(compoundTypeString());
3420  QCString cn = displayName(FALSE);
3421  if (!cn.isEmpty())
3422  {
3423  ol.docify(" ");
3424  if (md && isLinkable())
3425  {
3426  ol.writeObjectLink(0,0,md->anchor(),cn);
3427  }
3428  else
3429  {
3430  ol.startBold();
3431  ol.docify(cn);
3432  ol.endBold();
3433  }
3434  }
3435  ol.docify(" {");
3436  ol.endMemberItem();
3437 
3438  // write user defined member groups
3439  if (m_impl->memberGroupSDict)
3440  {
3442  MemberGroup *mg;
3443  for (;(mg=mgli.current());++mgli)
3444  {
3445  mg->setInGroup(inGroup);
3446  mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
3447  }
3448  }
3449 
3452  LayoutDocEntry *lde;
3453  for (eli.toFirst();(lde=eli.current());++eli)
3454  {
3455  if (lde->kind()==LayoutDocEntry::MemberDecl)
3456  {
3458  writePlainMemberDeclaration(ol,lmd->type,inGroup,inheritedFrom,inheritId);
3459  }
3460  }
3461 }
3462 
3465 {
3466  static bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES);
3467  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
3468  static bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES);
3469  if (m_impl->templateMaster)
3470  {
3472  }
3473  else
3474  {
3475  return !name().isEmpty() && /* has a name */
3476  !isArtificial() && !isHidden() && /* not hidden */
3477  !isAnonymous() && /* not anonymous */
3478  protectionLevelVisible(m_impl->prot) && /* private/internal */
3479  (!m_impl->isLocal || extractLocal) && /* local */
3480  (hasDocumentation() || !hideUndoc) && /* documented */
3481  (!m_impl->isStatic || extractStatic) && /* static */
3482  !isReference(); /* not an external reference */
3483  }
3484 }
3485 
3487 {
3488  if (m_impl->templateMaster)
3489  {
3490  return m_impl->templateMaster->isLinkable();
3491  }
3492  else
3493  {
3494  return isReference() || isLinkableInProject();
3495  }
3496 }
3497 
3498 
3501 {
3502  static bool allExternals = Config_getBool(ALLEXTERNALS);
3503  static bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
3504  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
3505 
3506  return // show all classes or a subclass is visible
3507  (allExternals || hasNonReferenceSuperClass()) &&
3508  // and not an anonymous compound
3509  !isAnonymous() &&
3510  // not an artificially introduced class // 1.8.2: allowed these to appear
3512  // and not privately inherited
3514  // documented or shown anyway or documentation is external
3515  (hasDocumentation() ||
3516  !hideUndocClasses ||
3518  isReference()
3519  ) &&
3520  // is not part of an unnamed namespace or shown anyway
3521  (!m_impl->isStatic || extractStatic);
3522 }
3523 
3525 {
3527 }
3528 
3529 //----------------------------------------------------------------------
3530 // recursive function:
3531 // returns TRUE iff class definition 'bcd' represents an (in)direct base
3532 // class of class definition 'cd'.
3533 
3534 bool ClassDefImpl::isBaseClass(const ClassDef *bcd, bool followInstances,int level) const
3535 {
3536  bool found=FALSE;
3537  //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3538  if (level>256)
3539  {
3540  err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
3541  return FALSE;
3542  }
3543  if (baseClasses())
3544  {
3545  // Beware: trying to optimise the iterator away using ->first() & ->next()
3546  // causes bug 625531
3548  for ( ; bcli.current() && !found ; ++bcli)
3549  {
3550  const ClassDef *ccd=bcli.current()->classDef;
3551  if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3552  //printf("isBaseClass() baseclass %s\n",ccd->name().data());
3553  if (ccd==bcd)
3554  found=TRUE;
3555  else
3556  found=ccd->isBaseClass(bcd,followInstances,level+1);
3557  }
3558  }
3559  return found;
3560 }
3561 
3562 //----------------------------------------------------------------------
3563 
3564 bool ClassDefImpl::isSubClass(ClassDef *cd,int level) const
3565 {
3566  bool found=FALSE;
3567  if (level>256)
3568  {
3569  err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
3570  return FALSE;
3571  }
3572  if (subClasses())
3573  {
3575  for ( ; bcli.current() && !found ; ++bcli)
3576  {
3577  ClassDef *ccd=bcli.current()->classDef;
3578  if (ccd==cd)
3579  found=TRUE;
3580  else
3581  found=ccd->isSubClass(cd,level+1);
3582  }
3583  }
3584  return found;
3585 }
3586 
3587 //----------------------------------------------------------------------------
3588 
3589 static bool isStandardFunc(MemberDef *md)
3590 {
3591  return md->name()=="operator=" || // assignment operator
3592  md->isConstructor() || // constructor
3593  md->isDestructor(); // destructor
3594 }
3595 
3602 {
3603  if (m_impl->membersMerged) return;
3604 
3605  //static bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3606  //static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
3607  SrcLangExt lang = getLanguage();
3609  uint sepLen = sep.length();
3610 
3612  //printf(" mergeMembers for %s\n",name().data());
3613  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
3614  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
3615  if (baseClasses())
3616  {
3617  //printf(" => has base classes!\n");
3619  BaseClassDef *bcd;
3620  for ( ; (bcd=bcli.current()) ; ++bcli )
3621  {
3622  ClassDef *bClass=bcd->classDef;
3623 
3624  // merge the members in the base class of this inheritance branch first
3625  bClass->mergeMembers();
3626 
3627  MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
3629 
3630  if (srcMnd)
3631  {
3632  MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
3633  MemberNameInfo *srcMni;
3634  for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
3635  {
3636  //printf(" Base member name %s\n",srcMni->memberName());
3637  MemberNameInfo *dstMni;
3638  if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
3639  // a member with that name is already in the class.
3640  // the member may hide or reimplement the one in the sub class
3641  // or there may be another path to the base class that is already
3642  // visited via another branch in the class hierarchy.
3643  {
3644  MemberNameInfoIterator srcMnii(*srcMni);
3645  MemberInfo *srcMi;
3646  for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
3647  {
3648  MemberDef *srcMd = srcMi->memberDef;
3649  bool found=FALSE;
3650  bool ambiguous=FALSE;
3651  bool hidden=FALSE;
3652  MemberNameInfoIterator dstMnii(*dstMni);
3653  MemberInfo *dstMi;
3654  const ClassDef *srcCd = srcMd->getClassDef();
3655  for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
3656  {
3657  MemberDef *dstMd = dstMi->memberDef;
3658  if (srcMd!=dstMd) // different members
3659  {
3660  const ClassDef *dstCd = dstMd->getClassDef();
3661  //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
3662  if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
3663  // member is in the same or a base class
3664  {
3665  ArgumentList &srcAl = srcMd->argumentList();
3666  ArgumentList &dstAl = dstMd->argumentList();
3667  found=matchArguments2(
3668  srcMd->getOuterScope(),srcMd->getFileDef(),srcAl,
3669  dstMd->getOuterScope(),dstMd->getFileDef(),dstAl,
3670  TRUE
3671  );
3672  //printf(" Yes, matching (%s<->%s): %d\n",
3673  // argListToString(srcMd->argumentList()).data(),
3674  // argListToString(dstMd->argumentList()).data(),
3675  // found);
3676  hidden = hidden || !found;
3677  }
3678  else // member is in a non base class => multiple inheritance
3679  // using the same base class.
3680  {
3681  //printf("$$ Existing member %s %s add scope %s\n",
3682  // dstMi->ambiguityResolutionScope.data(),
3683  // dstMd->name().data(),
3684  // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
3685 
3686  QCString scope=dstMi->scopePath.left((uint)dstMi->scopePath.find(sep)+sepLen);
3687  if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
3688  dstMi->ambiguityResolutionScope.prepend(scope);
3689  ambiguous=TRUE;
3690  }
3691  }
3692  else // same members
3693  {
3694  // do not add if base class is virtual or
3695  // if scope paths are equal or
3696  // if base class is an interface (and thus implicitly virtual).
3697  //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
3698  if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
3699  bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
3700  dstMd->getClassDef()->compoundType()==Interface
3701  )
3702  {
3703  found=TRUE;
3704  }
3705  else // member can be reached via multiple paths in the
3706  // inheritance tree
3707  {
3708  //printf("$$ Existing member %s %s add scope %s\n",
3709  // dstMi->ambiguityResolutionScope.data(),
3710  // dstMd->name().data(),
3711  // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
3712 
3713  QCString scope=dstMi->scopePath.left((uint)dstMi->scopePath.find(sep)+sepLen);
3714  if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
3715  {
3716  dstMi->ambiguityResolutionScope.prepend(scope);
3717  }
3718  ambiguous=TRUE;
3719  }
3720  }
3721  }
3722  //printf("member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p\n",
3723  // srcCd->name().data(),srcMd->name().data(),hidden,ambiguous,srcMi->ambigClass);
3724 
3725  // TODO: fix the case where a member is hidden by inheritance
3726  // of a member with the same name but with another prototype,
3727  // while there is more than one path to the member in the
3728  // base class due to multiple inheritance. In this case
3729  // it seems that the member is not reachable by prefixing a
3730  // scope name either (according to my compiler). Currently,
3731  // this case is shown anyway.
3732  if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
3733  {
3734  Protection prot=srcMd->protection();
3735  if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
3736  else if (bcd->prot==Private) prot=bcd->prot;
3737 
3738  if (inlineInheritedMembers)
3739  {
3740  if (!isStandardFunc(srcMd))
3741  {
3742  //printf(" insertMember '%s'\n",srcMd->name().data());
3743  internalInsertMember(srcMd,prot,FALSE);
3744  }
3745  }
3746 
3747  Specifier virt=srcMi->virt;
3748  if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
3749 
3750  MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
3751  newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
3752  if (ambiguous)
3753  {
3754  //printf("$$ New member %s %s add scope %s::\n",
3755  // srcMi->ambiguityResolutionScope.data(),
3756  // srcMd->name().data(),
3757  // bClass->name().data());
3758 
3759  QCString scope=bClass->name()+sep;
3760  if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
3761  {
3762  newMi->ambiguityResolutionScope=
3763  scope+srcMi->ambiguityResolutionScope.copy();
3764  }
3765  }
3766  if (hidden)
3767  {
3768  if (srcMi->ambigClass==0)
3769  {
3770  newMi->ambigClass=bClass;
3771  newMi->ambiguityResolutionScope=bClass->name()+sep;
3772  }
3773  else
3774  {
3775  newMi->ambigClass=srcMi->ambigClass;
3776  newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
3777  }
3778  }
3779  dstMni->append(newMi);
3780  }
3781  }
3782  }
3783  else // base class has a member that is not in the sub class => copy
3784  {
3785  // create a deep copy of the list (only the MemberInfo's will be
3786  // copied, not the actual MemberDef's)
3787  MemberNameInfo *newMni = 0;
3788  newMni = new MemberNameInfo(srcMni->memberName());
3789 
3790  // copy the member(s) from the base to the sub class
3791  MemberNameInfoIterator mnii(*srcMni);
3792  MemberInfo *mi;
3793  for (;(mi=mnii.current());++mnii)
3794  {
3795  if (!mi->memberDef->isFriend()) // don't inherit friends
3796  {
3797  Protection prot = mi->prot;
3798  if (bcd->prot==Protected)
3799  {
3800  if (prot==Public) prot=Protected;
3801  }
3802  else if (bcd->prot==Private)
3803  {
3804  prot=Private;
3805  }
3806  //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
3807  // name().data(),mi->memberDef->name().data(),mi->prot,
3808  // bcd->prot,prot);
3809 
3810  if (prot!=Private || extractPrivate)
3811  {
3812  Specifier virt=mi->virt;
3813  if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
3814 
3815  if (inlineInheritedMembers)
3816  {
3817  if (!isStandardFunc(mi->memberDef))
3818  {
3819  //printf(" insertMember '%s'\n",mi->memberDef->name().data());
3821  }
3822  }
3823  //printf("Adding!\n");
3824  MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
3825  newMi->scopePath=bClass->name()+sep+mi->scopePath;
3826  newMi->ambigClass=mi->ambigClass;
3828  newMni->append(newMi);
3829  }
3830  }
3831  }
3832 
3833  if (dstMnd==0)
3834  {
3837  dstMnd = m_impl->allMemberNameInfoSDict;
3838  }
3839  // add it to the dictionary
3840  dstMnd->append(newMni->memberName(),newMni);
3841  }
3842  }
3843  }
3844  }
3845  }
3846  //printf(" end mergeMembers\n");
3847 }
3848 
3849 //----------------------------------------------------------------------------
3850 
3854 {
3855  static bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS);
3856  bool makePrivate = category->isLocal();
3857  // in case extract local methods is not enabled we don't add the methods
3858  // of the category in case it is defined in the .m file.
3859  if (makePrivate && !extractLocalMethods) return;
3860  bool isExtension = category->isExtension();
3861 
3862  category->setCategoryOf(this);
3863  if (isExtension)
3864  {
3865  category->setArtificial(TRUE);
3866 
3867  // copy base classes/protocols from extension
3868  if (category->baseClasses())
3869  {
3870  BaseClassListIterator bcli(*category->baseClasses());
3871  BaseClassDef *bcd;
3872  for ( ; (bcd=bcli.current()) ; ++bcli )
3873  {
3874  insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
3875  // correct bcd->classDef so that they do no longer derive from
3876  // category, but from this class!
3877  if (bcd->classDef->subClasses())
3878  {
3879  BaseClassListIterator scli(*bcd->classDef->subClasses());
3880  BaseClassDef *scd;
3881  for ( ; (scd=scli.current()) ; ++scli )
3882  {
3883  if (scd->classDef==category)
3884  {
3885  scd->classDef=this;
3886  }
3887  }
3888  }
3889  }
3890  }
3891 
3892  }
3893  // make methods private for categories defined in the .m file
3894  //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate);
3895 
3896  MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
3898 
3899  if (srcMnd && dstMnd)
3900  {
3901  MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
3902  MemberNameInfo *srcMni;
3903  for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
3904  {
3905  MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
3906  if (dstMni) // method is already defined in the class
3907  {
3908  //printf("Existing member %s\n",srcMni->memberName());
3909  MemberInfo *dstMi = dstMni->getFirst();
3910  MemberInfo *srcMi = srcMni->getFirst();
3911  if (srcMi && dstMi)
3912  {
3914  dstMi->memberDef->setCategory(category);
3915  dstMi->memberDef->setCategoryRelation(srcMi->memberDef);
3916  srcMi->memberDef->setCategoryRelation(dstMi->memberDef);
3917  }
3918  }
3919  else // new method name
3920  {
3921  //printf("New member %s\n",srcMni->memberName());
3922  // create a deep copy of the list
3923  MemberNameInfo *newMni = 0;
3924  newMni = new MemberNameInfo(srcMni->memberName());
3925 
3926  // copy the member(s) from the category to this class
3927  MemberNameInfoIterator mnii(*srcMni);
3928  MemberInfo *mi;
3929  for (;(mi=mnii.current());++mnii)
3930  {
3931  //printf("Adding '%s'\n",mi->memberDef->name().data());
3932  Protection prot = mi->prot;
3933  //if (makePrivate) prot = Private;
3934  std::unique_ptr<MemberDef> newMd { mi->memberDef->deepCopy() };
3935  if (newMd)
3936  {
3937  //printf("Copying member %s\n",mi->memberDef->name().data());
3938  newMd->moveTo(this);
3939 
3940  MemberInfo *newMi=new MemberInfo(newMd.get(),prot,mi->virt,mi->inherited);
3941  newMi->scopePath=mi->scopePath;
3942  newMi->ambigClass=mi->ambigClass;
3944  newMni->append(newMi);
3945 
3946  // also add the newly created member to the global members list
3947 
3948  QCString name = newMd->name();
3950 
3951  newMd->setCategory(category);
3952  newMd->setCategoryRelation(mi->memberDef);
3953  mi->memberDef->setCategoryRelation(newMd.get());
3954  if (makePrivate || isExtension)
3955  {
3956  newMd->makeImplementationDetail();
3957  }
3958  internalInsertMember(newMd.get(),prot,FALSE);
3959  mn->push_back(std::move(newMd));
3960  }
3961  }
3962 
3963  // add it to the dictionary
3964  dstMnd->append(newMni->memberName(),newMni);
3965  }
3966  }
3967  }
3968 }
3969 
3970 //----------------------------------------------------------------------------
3971 
3972 void ClassDefImpl::addUsedClass(ClassDef *cd,const char *accessName,
3973  Protection prot)
3974 {
3975  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
3976  static bool umlLook = Config_getBool(UML_LOOK);
3977  if (prot==Private && !extractPrivate) return;
3978  //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
3979  if (m_impl->usesImplClassDict==0)
3980  {
3982  m_impl->usesImplClassDict->setAutoDelete(TRUE);
3983  }
3984  UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
3985  if (ucd==0)
3986  {
3987  ucd = new UsesClassDef(cd);
3988  m_impl->usesImplClassDict->insert(cd->name(),ucd);
3989  //printf("Adding used class %s to class %s via accessor %s\n",
3990  // cd->name().data(),name().data(),accessName);
3991  }
3992  QCString acc = accessName;
3993  if (umlLook)
3994  {
3995  switch(prot)
3996  {
3997  case Public: acc.prepend("+"); break;
3998  case Private: acc.prepend("-"); break;
3999  case Protected: acc.prepend("#"); break;
4000  case Package: acc.prepend("~"); break;
4001  }
4002  }
4003  ucd->addAccessor(acc);
4004 }
4005 
4006 void ClassDefImpl::addUsedByClass(ClassDef *cd,const char *accessName,
4007  Protection prot)
4008 {
4009  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4010  static bool umlLook = Config_getBool(UML_LOOK);
4011  if (prot==Private && !extractPrivate) return;
4012  //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
4013  if (m_impl->usedByImplClassDict==0)
4014  {
4016  m_impl->usedByImplClassDict->setAutoDelete(TRUE);
4017  }
4018  UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
4019  if (ucd==0)
4020  {
4021  ucd = new UsesClassDef(cd);
4022  m_impl->usedByImplClassDict->insert(cd->name(),ucd);
4023  //printf("Adding used by class %s to class %s\n",
4024  // cd->name().data(),name().data());
4025  }
4026  QCString acc = accessName;
4027  if (umlLook)
4028  {
4029  switch(prot)
4030  {
4031  case Public: acc.prepend("+"); break;
4032  case Private: acc.prepend("-"); break;
4033  case Protected: acc.prepend("#"); break;
4034  case Package: acc.prepend("~"); break;
4035  }
4036  }
4037  ucd->addAccessor(acc);
4038 }
4039 
4040 
4042 {
4044  {
4045  switch (m_impl->compType)
4046  {
4047  case Class: return "module";
4048  case Struct: return "type";
4049  case Union: return "union";
4050  case Interface: return "interface";
4051  case Protocol: return "protocol";
4052  case Category: return "category";
4053  case Exception: return "exception";
4054  default: return "unknown";
4055  }
4056  }
4057  else
4058  {
4059  switch (m_impl->compType)
4060  {
4061  case Class: return isJavaEnum() ? "enum" : "class";
4062  case Struct: return "struct";
4063  case Union: return "union";
4064  case Interface: return getLanguage()==SrcLangExt_ObjC ? "class" : "interface";
4065  case Protocol: return "protocol";
4066  case Category: return "category";
4067  case Exception: return "exception";
4068  case Service: return "service";
4069  case Singleton: return "singleton";
4070  default: return "unknown";
4071  }
4072  }
4073 }
4074 
4076 {
4077  static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
4078  static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
4080  {
4081  Definition *scope=0;
4082  if (inlineGroupedClasses && partOfGroups()!=0)
4083  {
4084  // point to the group that embeds this class
4085  return partOfGroups()->at(0)->getOutputFileBase();
4086  }
4087  else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
4088  {
4089  // point to simple struct inside a group
4090  return partOfGroups()->at(0)->getOutputFileBase();
4091  }
4092  else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
4093  {
4094  if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
4095  {
4096  return getFileDef()->getOutputFileBase();
4097  }
4098  else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
4099  {
4100  return getOuterScope()->getOutputFileBase();
4101  }
4102  }
4103  }
4104  if (m_impl->templateMaster)
4105  {
4106  // point to the template of which this class is an instance
4108  }
4109  return m_impl->fileName;
4110 }
4111 
4113 {
4114  return m_impl->fileName;
4115 }
4116 
4118 {
4119  if (m_impl->templateMaster)
4120  {
4122  }
4123  else
4124  {
4126  }
4127 }
4128 
4129 void ClassDefImpl::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
4130 {
4131  gd->addClass(this);
4132  //printf("ClassDefImpl::setGroupDefForAllMembers(%s)\n",gd->name().data());
4133  if (m_impl->allMemberNameInfoSDict==0) return;
4135  MemberNameInfo *mni;
4136  for (;(mni=mnili.current());++mnili)
4137  {
4138  MemberNameInfoIterator mnii(*mni);
4139  MemberInfo *mi;
4140  for (mnii.toFirst();(mi=mnii.current());++mnii)
4141  {
4142  MemberDef *md=mi->memberDef;
4143  md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
4144  gd->insertMember(md,TRUE);
4145  ClassDef *innerClass = md->getClassDefOfAnonymousType();
4146  if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
4147  }
4148  }
4149 }
4150 
4152 {
4153  //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
4154  if (d->definitionType()==Definition::TypeClass) // only classes can be
4155  // nested in classes.
4156  {
4157  if (m_impl->innerClasses==0)
4158  {
4159  m_impl->innerClasses = new ClassSDict(17);
4160  }
4161  m_impl->innerClasses->inSort(d->localName(),dynamic_cast<const ClassDef *>(d));
4162  }
4163 }
4164 
4166 {
4167  Definition *result=0;
4168  if (name==0) return 0;
4169  if (m_impl->innerClasses)
4170  {
4171  result = m_impl->innerClasses->find(name);
4172  }
4173  return result;
4174 }
4175 
4177  int startLine, int startColumn, const QCString &templSpec,bool &freshInstance) const
4178 {
4179  freshInstance = FALSE;
4180  if (m_impl->templateInstances==0)
4181  {
4183  }
4184  ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
4185  if (templateClass==0)
4186  {
4187  Debug::print(Debug::Classes,0," New template instance class '%s''%s'\n",qPrint(name()),qPrint(templSpec));
4188  QCString tcname = removeRedundantWhiteSpace(localName()+templSpec);
4189  templateClass = new ClassDefImpl(
4190  fileName,startLine,startColumn,tcname,ClassDef::Class);
4191  templateClass->setTemplateMaster(this);
4192  templateClass->setOuterScope(getOuterScope());
4193  templateClass->setHidden(isHidden());
4194  m_impl->templateInstances->insert(templSpec,templateClass);
4195  freshInstance=TRUE;
4196  }
4197  return templateClass;
4198 }
4199 
4200 ClassDef *ClassDefImpl::getVariableInstance(const char *templSpec) const
4201 {
4202  if (m_impl->variableInstances==0)
4203  {
4205  m_impl->variableInstances->setAutoDelete(TRUE);
4206  }
4207  ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
4208  if (templateClass==0)
4209  {
4210  Debug::print(Debug::Classes,0," New template variable instance class '%s' '%s'\n",qPrint(name()),qPrint(templSpec));
4211  QCString tcname = removeRedundantWhiteSpace(name()+templSpec);
4212  templateClass = new ClassDefImpl("<code>",1,1,tcname,
4213  ClassDef::Class,0,0,FALSE);
4214  templateClass->addMembersToTemplateInstance( this, templSpec );
4215  templateClass->setTemplateMaster(this);
4216  m_impl->variableInstances->insert(templSpec,templateClass);
4217  }
4218  return templateClass;
4219 }
4220 
4222 {
4223  if (templateNames==0) return;
4224  if (m_impl->templBaseClassNames==0)
4225  {
4227  m_impl->templBaseClassNames->setAutoDelete(TRUE);
4228  }
4229  // make a deep copy of the dictionary.
4230  QDictIterator<int> qdi(*templateNames);
4231  for (;qdi.current();++qdi)
4232  {
4233  if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
4234  {
4235  m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
4236  }
4237  }
4238 }
4239 
4241 {
4242  return m_impl->templBaseClassNames;
4243 }
4244 
4245 void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const char *templSpec)
4246 {
4247  //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
4248  if (cd->memberNameInfoSDict()==0) return;
4250  MemberNameInfo *mni;
4251  for (;(mni=mnili.current());++mnili)
4252  {
4253  MemberNameInfoIterator mnii(*mni);
4254  MemberInfo *mi;
4255  for (mnii.toFirst();(mi=mnii.current());++mnii)
4256  {
4257  ArgumentList actualArguments;
4258  stringToArgumentList(getLanguage(),templSpec,actualArguments);
4259  MemberDef *md = mi->memberDef;
4260  std::unique_ptr<MemberDef> imd { md->createTemplateInstanceMember(
4261  cd->templateArguments(),actualArguments) };
4262  //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
4263  imd->setMemberClass(this);
4264  imd->setTemplateMaster(md);
4265  imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
4266  imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
4267  imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
4268  imd->setMemberSpecifiers(md->getMemberSpecifiers());
4269  imd->setMemberGroupId(md->getMemberGroupId());
4270  insertMember(imd.get());
4271  //printf("Adding member=%s %s%s to class %s templSpec %s\n",
4272  // imd->typeString(),imd->name().data(),imd->argsString(),
4273  // imd->getClassDef()->name().data(),templSpec);
4274  // insert imd in the list of all members
4275  //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
4276  MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name());
4277  mn->push_back(std::move(imd));
4278  }
4279  }
4280 }
4281 
4283 {
4284  if (m_impl->templateMaster)
4285  {
4286  return m_impl->templateMaster->getReference();
4287  }
4288  else
4289  {
4291  }
4292 }
4293 
4295 {
4296  if (m_impl->templateMaster)
4297  {
4298  return m_impl->templateMaster->isReference();
4299  }
4300  else
4301  {
4302  return DefinitionImpl::isReference();
4303  }
4304 }
4305 
4306 std::vector<ArgumentList> ClassDefImpl::getTemplateParameterLists() const
4307 {
4308  std::vector<ArgumentList> result;
4310  while (d && d->definitionType()==Definition::TypeClass)
4311  {
4312  result.insert(result.begin(),dynamic_cast<ClassDef*>(d)->templateArguments());
4313  d = d->getOuterScope();
4314  }
4315  if (!templateArguments().empty())
4316  {
4317  result.push_back(templateArguments());
4318  }
4319  return result;
4320 }
4321 
4323  const std::vector<ArgumentList> *actualParams,uint *actualParamIndex) const
4324 {
4325  //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
4326  static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
4327  //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
4328  QCString scName;
4330  if (d)
4331  {
4333  {
4334  ClassDef *cd=dynamic_cast<ClassDef *>(d);
4335  scName = cd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex);
4336  }
4337  else if (!hideScopeNames)
4338  {
4339  scName = d->qualifiedName();
4340  }
4341  }
4342 
4343  SrcLangExt lang = getLanguage();
4344  QCString scopeSeparator = getLanguageSpecificSeparator(lang);
4345  if (!scName.isEmpty()) scName+=scopeSeparator;
4346 
4347  bool isSpecialization = localName().find('<')!=-1;
4348 
4349  QCString clName = className();
4350  //bool isGeneric = getLanguage()==SrcLangExt_CSharp;
4351  //if (isGeneric && clName.right(2)=="-g")
4352  //{
4353  // clName = clName.left(clName.length()-2);
4354  //}
4355  //printf("m_impl->lang=%d clName=%s isSpecialization=%d\n",getLanguage(),clName.data(),isSpecialization);
4356  scName+=clName;
4357  if (!templateArguments().empty())
4358  {
4359  if (actualParams && *actualParamIndex<actualParams->size())
4360  {
4361  const ArgumentList &al = actualParams->at(*actualParamIndex);
4362  if (!isSpecialization)
4363  {
4364  scName+=tempArgListToString(al,lang);
4365  }
4366  (*actualParamIndex)++;
4367  }
4368  else
4369  {
4370  if (!isSpecialization)
4371  {
4372  scName+=tempArgListToString(templateArguments(),lang);
4373  }
4374  }
4375  }
4376  //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
4377  return scName;
4378 }
4379 
4381 {
4382  if (m_impl->className.isEmpty())
4383  {
4384  return localName();
4385  }
4386  else
4387  {
4388  return m_impl->className;
4389  }
4390 }
4391 
4392 void ClassDefImpl::setClassName(const char *name)
4393 {
4394  m_impl->className = name;
4395 }
4396 
4398 {
4399  SrcLangExt lang = getLanguage();
4400  if (!isLinkableInProject()) return;
4401  //printf("ClassDef(%s)::addListReferences()\n",name().data());
4402  {
4403  const std::vector<RefItem*> &xrefItems = xrefListItems();
4404  addRefItem(xrefItems,
4405  qualifiedName(),
4409  displayName(),
4410  0,
4411  this
4412  );
4413  }
4414  if (m_impl->memberGroupSDict)
4415  {
4417  MemberGroup *mg;
4418  for (;(mg=mgli.current());++mgli)
4419  {
4420  mg->addListReferences(this);
4421  }
4422  }
4424  MemberList *ml;
4425  for (mli.toFirst();(ml=mli.current());++mli)
4426  {
4428  {
4429  ml->addListReferences(this);
4430  }
4431  }
4432 }
4433 
4435 {
4436  MemberDef *xmd = 0;
4438  {
4440  if (mni)
4441  {
4442  const int maxInheritanceDepth = 100000;
4443  int mdist=maxInheritanceDepth;
4444  MemberNameInfoIterator mnii(*mni);
4445  MemberInfo *mi;
4446  for (mnii.toFirst();(mi=mnii.current());++mnii)
4447  {
4448  const ClassDef *mcd=mi->memberDef->getClassDef();
4449  int m=minClassDistance(this,mcd);
4450  //printf("found member in %s linkable=%d m=%d\n",
4451  // mcd->name().data(),mcd->isLinkable(),m);
4452  if (m<mdist && mcd->isLinkable())
4453  {
4454  mdist=m;
4455  xmd=mi->memberDef;
4456  }
4457  }
4458  }
4459  }
4460  //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
4461  return xmd;
4462 }
4463 
4465 {
4466  return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
4467 }
4468 
4470 {
4473  MemberList *ml;
4474  for (mli.toFirst();(ml=mli.current());++mli)
4475  {
4476  if (ml->listType()==lt)
4477  {
4478  return ml;
4479  }
4480  }
4481  // not found, create a new member list
4482  ml = new MemberList(lt);
4483  m_impl->memberLists.append(ml);
4484  return ml;
4485 }
4486 
4488 {
4490  MemberList *ml;
4491  for (;(ml=mli.current());++mli)
4492  {
4493  if (ml->listType()==lt)
4494  {
4495  return ml;
4496  }
4497  }
4498  return 0;
4499 }
4500 
4502 {
4503  static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
4504  static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
4505  MemberList *ml = createMemberList(lt);
4506  ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
4507  ml->append(md);
4508 
4509  // for members in the declaration lists we set the section, needed for member grouping
4510  if ((ml->listType()&MemberListType_detailedLists)==0) md->setSectionList(ml);
4511 }
4512 
4514 {
4516  MemberList *ml;
4517  for (;(ml=mli.current());++mli)
4518  {
4519  if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
4520  }
4521  if (m_impl->innerClasses)
4522  {
4523  m_impl->innerClasses->sort();
4524  }
4525 }
4526 
4528  int lt2,bool invert,bool showAlways,QPtrDict<void> *visitedClasses) const
4529 {
4530  //printf("%s: countMemberDeclarations for %d and %d\n",name().data(),lt,lt2);
4531  int count=0;
4532  MemberList * ml = getMemberList(lt);
4533  MemberList * ml2 = getMemberList((MemberListType)lt2);
4534  if (getLanguage()!=SrcLangExt_VHDL) // use specific declarations function
4535  {
4536  if (ml)
4537  {
4538  count+=ml->numDecMembers();
4539  //printf("-> ml=%d\n",ml->numDecMembers());
4540  }
4541  if (ml2)
4542  {
4543  count+=ml2->numDecMembers();
4544  //printf("-> ml2=%d\n",ml2->numDecMembers());
4545  }
4546  // also include grouped members that have their own section in the class (see bug 722759)
4547  if (inheritedFrom && m_impl->memberGroupSDict)
4548  {
4550  MemberGroup *mg;
4551  for (;(mg=mgli.current());++mgli)
4552  {
4553  count+=mg->countGroupedInheritedMembers(lt);
4554  if (lt2!=1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2);
4555  }
4556  }
4557  static bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
4558  if (!inlineInheritedMembers) // show inherited members as separate lists
4559  {
4560  count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses);
4561  }
4562  }
4563  //printf("-> %d\n",count);
4564  return count;
4565 }
4566 
4568 {
4571  LayoutDocEntry *lde;
4572  for (eli.toFirst();(lde=eli.current());++eli)
4573  {
4574  if (lde->kind()==LayoutDocEntry::MemberDecl)
4575  {
4577  MemberList * ml = getMemberList(lmd->type);
4578  if (ml)
4579  {
4580  ml->setAnonymousEnumType();
4581  }
4582  }
4583  else if (lde->kind()==LayoutDocEntry::MemberGroups)
4584  {
4585  if (m_impl->memberGroupSDict)
4586  {
4588  MemberGroup *mg;
4589  for (;(mg=mgli.current());++mgli)
4590  {
4591  mg->setAnonymousEnumType();
4592  }
4593  }
4594  }
4595  }
4596 }
4597 
4599 {
4601  MemberList *ml;
4602  for (mli.toFirst();(ml=mli.current());++mli)
4603  {
4604  ml->countDecMembers();
4605  ml->countDocMembers();
4606  }
4607  if (m_impl->memberGroupSDict)
4608  {
4610  MemberGroup *mg;
4611  for (;(mg=mgli.current());++mgli)
4612  {
4613  mg->countDecMembers();
4614  mg->countDocMembers();
4615  }
4616  }
4617 }
4618 
4620  const ClassDef *inheritedFrom,bool invert,bool showAlways,
4621  QPtrDict<void> *visitedClasses) const
4622 {
4623  int inhCount = 0;
4624  int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4625  bool process = count>0;
4626  //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
4627  // name().data(),lt,process,count,invert);
4628  if ((process^invert) || showAlways)
4629  {
4630  if (m_impl->inherits)
4631  {
4633  BaseClassDef *ibcd;
4634  for (it.toFirst();(ibcd=it.current());++it)
4635  {
4636  ClassDef *icd=ibcd->classDef;
4637  int lt1,lt2;
4638  if (icd->isLinkable())
4639  {
4640  convertProtectionLevel(lt,ibcd->prot,&lt1,&lt2);
4641  //printf("%s: convert %d->(%d,%d) prot=%d\n",
4642  // icd->name().data(),lt,lt1,lt2,ibcd->prot);
4643  if (visitedClasses->find(icd)==0)
4644  {
4645  visitedClasses->insert(icd,icd); // guard for multiple virtual inheritance
4646  if (lt1!=-1)
4647  {
4648  inhCount+=icd->countMemberDeclarations((MemberListType)lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4649  }
4650  }
4651  }
4652  }
4653  }
4654  }
4655  return inhCount;
4656 }
4657 
4659  QCString &title,QCString &subtitle) const
4660 {
4661  SrcLangExt lang = getLanguage();
4664  LayoutDocEntry *lde;
4665  for (eli.toFirst();(lde=eli.current());++eli)
4666  {
4667  if (lde->kind()==LayoutDocEntry::MemberDecl)
4668  {
4670  if (lmd->type==type)
4671  {
4672  title = lmd->title(lang);
4673  subtitle = lmd->subtitle(lang);
4674  return;
4675  }
4676  }
4677  }
4678  title="";
4679  subtitle="";
4680 }
4681 
4683 {
4684  int totalCount=0;
4687  LayoutDocEntry *lde;
4688  for (eli.toFirst();(lde=eli.current());++eli)
4689  {
4690  if (lde->kind()==LayoutDocEntry::MemberDecl)
4691  {
4693  if (lmd->type!=MemberListType_friends) // friendship is not inherited
4694  {
4695  //MemberList *ml = getMemberList(lmd->type);
4696  //if (ml==0 || ml->numDecMembers()==0)
4697  //{
4698  QPtrDict<void> visited(17);
4699  totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,&visited);
4700  //}
4701  }
4702  }
4703  }
4704  //printf("countAdditionalInheritedMembers()=%d\n",totalCount);
4705  return totalCount;
4706 }
4707 
4709 {
4710  //printf("**** writeAdditionalInheritedMembers()\n");
4713  LayoutDocEntry *lde;
4714  for (eli.toFirst();(lde=eli.current());++eli)
4715  {
4716  if (lde->kind()==LayoutDocEntry::MemberDecl)
4717  {
4719  if (lmd->type!=MemberListType_friends)
4720  {
4721  QPtrDict<void> visited(17);
4722  writeInheritedMemberDeclarations(ol,lmd->type,-1,lmd->title(getLanguage()),this,TRUE,FALSE,&visited);
<