Doxygen
Loading...
Searching...
No Matches
classdef.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2024 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#include <cstdio>
17#include <algorithm>
18
19#include "types.h"
20#include "classdef.h"
21#include "classlist.h"
22#include "entry.h"
23#include "doxygen.h"
24#include "membername.h"
25#include "message.h"
26#include "config.h"
27#include "util.h"
28#include "diagram.h"
29#include "language.h"
30#include "htmlhelp.h"
31#include "example.h"
32#include "outputlist.h"
33#include "dot.h"
34#include "dotclassgraph.h"
35#include "dotrunner.h"
36#include "defargs.h"
37#include "debug.h"
38#include "docparser.h"
39#include "searchindex.h"
40#include "vhdldocgen.h"
41#include "layout.h"
42#include "arguments.h"
43#include "memberlist.h"
44#include "groupdef.h"
45#include "filedef.h"
46#include "namespacedef.h"
47#include "membergroup.h"
48#include "definitionimpl.h"
49#include "symbolresolver.h"
50#include "fileinfo.h"
51#include "trace.h"
52#include "moduledef.h"
53
54//-----------------------------------------------------------------------------
55
57 const ArgumentLists *actualParams,uint32_t *actualParamIndex)
58{
59 //bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
60 bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
61 //printf("qualifiedNameWithTemplateParameters() localName=%s\n",qPrint(cd->localName()));
62 QCString scName;
63 const Definition *d=cd->getOuterScope();
64 if (d)
65 {
67 {
68 const ClassDef *ocd=toClassDef(d);
69 scName = ocd->qualifiedNameWithTemplateParameters(actualParams,actualParamIndex);
70 }
71 else if (!hideScopeNames)
72 {
73 scName = d->qualifiedName();
74 }
75 }
76
77 SrcLangExt lang = cd->getLanguage();
78 QCString scopeSeparator = getLanguageSpecificSeparator(lang);
79 if (!scName.isEmpty()) scName+=scopeSeparator;
80
81 bool isSpecialization = cd->localName().find('<')!=-1;
82
83 QCString clName = cd->className();
84 scName+=clName;
85 if (!cd->templateArguments().empty())
86 {
87 if (actualParams && *actualParamIndex<actualParams->size())
88 {
89 const ArgumentList &al = actualParams->at(*actualParamIndex);
91 {
92 scName+=tempArgListToString(al,lang);
93 }
94 (*actualParamIndex)++;
95 }
96 else
97 {
99 {
100 scName+=tempArgListToString(cd->templateArguments(),lang);
101 }
102 }
103 }
104 //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",qPrint(name()),qPrint(scName));
105 return scName;
106}
107
108static QCString makeDisplayName(const ClassDef *cd,bool includeScope)
109{
110 //bool optimizeOutputForJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
111 SrcLangExt lang = cd->getLanguage();
112 //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
113 QCString n;
114 if (lang==SrcLangExt::VHDL)
115 {
117 }
118 else
119 {
120 if (includeScope)
121 {
123 }
124 else
125 {
126 n=cd->className();
127 }
128 }
129 if (cd->isAnonymous())
130 {
132 }
134 if (sep!="::")
135 {
136 n=substitute(n,"::",sep);
137 }
138 if (cd->compoundType()==ClassDef::Protocol && n.endsWith("-p"))
139 {
140 n="<"+n.left(n.length()-2)+">";
141 }
142 return n;
143}
144
145//-----------------------------------------------------------------------------
146
148{
149 if (lang==SrcLangExt::Fortran)
150 {
151 switch (compType)
152 {
153 case ClassDef::Class: return "module";
154 case ClassDef::Struct: return "type";
155 case ClassDef::Union: return "union";
156 case ClassDef::Interface: return "interface";
157 case ClassDef::Protocol: return "protocol";
158 case ClassDef::Category: return "category";
159 case ClassDef::Exception: return "exception";
160 default: return "unknown";
161 }
162 }
163 else
164 {
165 switch (compType)
166 {
167 case ClassDef::Class: return isJavaEnum ? "enum" : "class";
168 case ClassDef::Struct: return "struct";
169 case ClassDef::Union: return "union";
170 case ClassDef::Interface: return lang==SrcLangExt::ObjC ? "class" : "interface";
171 case ClassDef::Protocol: return "protocol";
172 case ClassDef::Category: return "category";
173 case ClassDef::Exception: return "exception";
174 case ClassDef::Service: return "service";
175 case ClassDef::Singleton: return "singleton";
176 default: return "unknown";
177 }
178 }
179}
180
181//-----------------------------------------------------------------------------
182
183
184/** Implementation of the ClassDef interface */
185class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
186{
187 public:
188 ClassDefImpl(const QCString &fileName,int startLine,int startColumn,
189 const QCString &name,CompoundType ct,
190 const QCString &ref=QCString(),const QCString &fName=QCString(),
191 bool isSymbol=TRUE,bool isJavaEnum=FALSE);
192
193 DefType definitionType() const override { return TypeClass; }
194 std::unique_ptr<ClassDef> deepCopy(const QCString &name) const override;
195 void moveTo(Definition *) override;
196 CodeSymbolType codeSymbolType() const override;
197 QCString getOutputFileBase() const override;
198 QCString getInstanceOutputFileBase() const override;
199 QCString getSourceFileBase() const override;
200 QCString getReference() const override;
201 bool isReference() const override;
202 bool isLocal() const override;
203 ClassLinkedRefMap getClasses() const override;
204 bool hasDocumentation() const override;
205 bool hasDetailedDescription() const override;
206 QCString collaborationGraphFileName() const override;
207 QCString inheritanceGraphFileName() const override;
208 QCString displayName(bool includeScope=TRUE) const override;
209 CompoundType compoundType() const override;
210 QCString compoundTypeString() const override;
211 const BaseClassList &baseClasses() const override;
212 void updateBaseClasses(const BaseClassList &bcd) override;
213 const BaseClassList &subClasses() const override;
214 void updateSubClasses(const BaseClassList &bcd) override;
215 const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const override;
216 Protection protection() const override;
217 bool isLinkableInProject() const override;
218 bool isLinkable() const override;
219 bool isVisibleInHierarchy() const override;
220 bool visibleInParentsDeclList() const override;
221 const ArgumentList &templateArguments() const override;
222 FileDef *getFileDef() const override;
223 ModuleDef *getModuleDef() const override;
224 const MemberDef *getMemberByName(const QCString &) const override;
225 int isBaseClass(const ClassDef *bcd,bool followInstances,const QCString &templSpec) const override;
226 bool isSubClass(ClassDef *bcd,int level=0) const override;
227 bool isAccessibleMember(const MemberDef *md) const override;
228 const TemplateInstanceList &getTemplateInstances() const override;
229 const ClassDef *templateMaster() const override;
230 bool isTemplate() const override;
231 const IncludeInfo *includeInfo() const override;
232 const UsesClassList &usedImplementationClasses() const override;
233 const UsesClassList &usedByImplementationClasses() const override;
234 const ConstraintClassList &templateTypeConstraints() const override;
235 bool isTemplateArgument() const override;
236 const Definition *findInnerCompound(const QCString &name) const override;
239 const ArgumentLists *actualParams=nullptr,uint32_t *actualParamIndex=nullptr) const override;
240 bool isAbstract() const override;
241 bool isObjectiveC() const override;
242 bool isFortran() const override;
243 bool isCSharp() const override;
244 bool isFinal() const override;
245 bool isSealed() const override;
246 bool isPublished() const override;
247 bool isExtension() const override;
248 bool isForwardDeclared() const override;
249 bool isInterface() const override;
250 ClassDef *categoryOf() const override;
251 QCString className() const override;
252 MemberList *getMemberList(MemberListType lt) const override;
253 const MemberLists &getMemberLists() const override;
254 const MemberGroupList &getMemberGroups() const override;
255 const TemplateNameMap &getTemplateBaseClassNames() const override;
256 bool isUsedOnly() const override;
257 QCString anchor() const override;
258 bool isEmbeddedInOuterScope() const override;
259 bool isSimple() const override;
260 const ClassDef *tagLessReference() const override;
261 const MemberDef *isSmartPointer() const override;
262 bool isJavaEnum() const override;
263 QCString title() const override;
264 QCString generatedFromFiles() const override;
265 const FileList &usedFiles() const override;
266 const ArgumentList &typeConstraints() const override;
267 const ExampleList &getExamples() const override;
268 bool hasExamples() const override;
269 QCString getMemberListFileName() const override;
270 bool subGrouping() const override;
271 bool isSliceLocal() const override;
272 bool hasNonReferenceSuperClass() const override;
273 QCString requiresClause() const override;
274 StringVector getQualifiers() const override;
275 bool containsOverload(const MemberDef *md) const override;
276 ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn,
277 const QCString &templSpec,bool &freshInstance) const override;
278 bool isImplicitTemplateInstance() const override;
279
280 void insertBaseClass(ClassDef *,const QCString &name,Protection p,Specifier s,const QCString &t=QCString()) override;
281 void insertSubClass(ClassDef *,Protection p,Specifier s,const QCString &t=QCString()) override;
282 void insertExplicitTemplateInstance(ClassDef *instance,const QCString &spec) override;
283 void setIncludeFile(FileDef *fd,const QCString &incName,bool local,bool force) override;
284 void insertMember(MemberDef *) override;
285 void insertUsedFile(const FileDef *) override;
286 bool addExample(const QCString &anchor,const QCString &name, const QCString &file) override;
287 void mergeCategory(ClassDef *category) override;
288 void setFileDef(FileDef *fd) override;
289 void setModuleDef(ModuleDef *mod) override;
290 void setSubGrouping(bool enabled) override;
291 void setProtection(Protection p) override;
292 void setGroupDefForAllMembers(GroupDef *g,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs) override;
293 void addInnerCompound(Definition *d) override;
294 void addUsedClass(ClassDef *cd,const QCString &accessName,Protection prot) override;
295 void addUsedByClass(ClassDef *cd,const QCString &accessName,Protection prot) override;
296 void setIsStatic(bool b) override;
297 void setCompoundType(CompoundType t) override;
298 void setClassName(const QCString &name) override;
299 void setClassSpecifier(TypeSpecifier spec) override;
300 void addQualifiers(const StringVector &qualifiers) override;
301 void setTemplateArguments(const ArgumentList &al) override;
302 void setTemplateBaseClassNames(const TemplateNameMap &templateNames) override;
303 void setTemplateMaster(const ClassDef *tm) override;
304 void setImplicitTemplateInstance(bool b) override;
305 void setTypeConstraints(const ArgumentList &al) override;
306 void addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const QCString &templSpec) override;
307 void makeTemplateArgument(bool b=TRUE) override;
308 void setCategoryOf(ClassDef *cd) override;
309 void setUsedOnly(bool b) override;
310 void setTagLessReference(const ClassDef *cd) override;
311 void setMetaData(const QCString &md) override;
312 void findSectionsInDocumentation() override;
313 void addMembersToMemberGroup() override;
314 void addListReferences() override;
315 void addTypeConstraints() override;
316 void computeAnchors() override;
317 void mergeMembers() override;
318 void sortMemberLists() override;
320 void writeDocumentation(OutputList &ol) const override;
321 void writeDocumentationForInnerClasses(OutputList &ol) const override;
322 void writeMemberPages(OutputList &ol) const override;
323 void writeMemberList(OutputList &ol) const override;
324 void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup,int indentLevel,
325 const ClassDef *inheritedFrom,const QCString &inheritId) const override;
326 void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const override;
327 void writeSummaryLinks(OutputList &ol) const override;
328 void reclassifyMember(MemberDefMutable *md,MemberType t) override;
329 void writeInlineDocumentation(OutputList &ol) const override;
330 void writeDeclarationLink(OutputList &ol,bool &found,
331 const QCString &header,bool localNames) const override;
332 void removeMemberFromLists(MemberDef *md) override;
333 void setAnonymousEnumType() override;
334 void countMembers() override;
335 void sortAllMembersList() override;
336
337 void addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
338 const ClassDef *inheritedFrom,const QCString &inheritId) const override;
339 void writeTagFile(TextStream &) const override;
340
341 int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const override;
342 int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom,
343 MemberListType lt2,bool invert,bool showAlways,ClassDefSet &visitedClasses) const override;
344 void writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedClasses,
345 MemberListType lt,const QCString &title,
346 const QCString &subTitle=QCString(),
347 bool showInline=FALSE,const ClassDef *inheritedFrom=nullptr,
348 MemberListType lt2=MemberListType::Invalid(),bool invert=FALSE,bool showAlways=FALSE) const override;
349 void setRequiresClause(const QCString &req) override;
350
351 // inheritance graph related members
352 CLASS_GRAPH_t hasInheritanceGraph() const override;
353 void overrideInheritanceGraph(CLASS_GRAPH_t e) override;
354
355 // collaboration graph related members
356 bool hasCollaborationGraph() const override;
357 void overrideCollaborationGraph(bool e) override;
358 private:
359 int countInheritedByNodes() const;
360 int countInheritsNodes() const;
361 int countInheritanceNodes() const;
362 void addUsedInterfaceClasses(MemberDef *md,const QCString &typeStr);
363 void showUsedFiles(OutputList &ol) const;
364
365 void writeDocumentationContents(OutputList &ol,const QCString &pageTitle) const;
366 void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList);
367 void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief);
368 void writeInheritedMemberDeclarations(OutputList &ol,ClassDefSet &visitedClasses,
369 MemberListType lt,MemberListType lt2,const QCString &title,
370 const ClassDef *inheritedFrom,bool invert,
371 bool showAlways) const;
372 void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline=FALSE) const;
373 void writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt) const;
374 void writePlainMemberDeclaration(OutputList &ol,MemberListType lt,bool inGroup,
375 int indentLevel,const ClassDef *inheritedFrom,const QCString &inheritId) const;
376 void writeBriefDescription(OutputList &ol,bool exampleFlag) const;
377 void writeDetailedDescription(OutputList &ol,const QCString &pageType,bool exampleFlag,
378 const QCString &title,const QCString &anchor=QCString()) const;
379 void writeIncludeFiles(OutputList &ol) const;
380 void writeIncludeFilesForSlice(OutputList &ol) const;
381 void writeInheritanceGraph(OutputList &ol) const;
382 void writeCollaborationGraph(OutputList &ol) const;
383 void writeMemberGroups(OutputList &ol,bool showInline=FALSE) const;
384 void writeNestedClasses(OutputList &ol,const QCString &title) const;
385 void writeInlineClasses(OutputList &ol) const;
386 void startMemberDeclarations(OutputList &ol) const;
387 void endMemberDeclarations(OutputList &ol) const;
388 void startMemberDocumentation(OutputList &ol) const;
389 void endMemberDocumentation(OutputList &ol) const;
390 void writeAuthorSection(OutputList &ol) const;
391 void writeMoreLink(OutputList &ol,const QCString &anchor) const;
392 void writeDetailedDocumentationBody(OutputList &ol) const;
393
395 void writeAdditionalInheritedMembers(OutputList &ol) const;
396 void addClassAttributes(OutputList &ol) const;
397 int countInheritedDecMembers(MemberListType lt,
398 const ClassDef *inheritedFrom,bool invert,bool showAlways,
399 ClassDefSet &visitedClasses) const;
400 void getTitleForMemberListType(MemberListType type,
401 QCString &title,QCString &subtitle) const;
402 void addTypeConstraint(const QCString &typeConstraint,const QCString &type);
403 void writeTemplateSpec(OutputList &ol,const Definition *d,
404 const QCString &type,SrcLangExt lang) const;
405 void mergeMembersFromBaseClasses(bool mergeVirtualBaseClass);
406
407 // PIMPL idiom
408 class IMPL;
409 std::unique_ptr<IMPL> m_impl;
410};
411
412std::unique_ptr<ClassDef> createClassDef(
413 const QCString &fileName,int startLine,int startColumn,
414 const QCString &name,ClassDef::CompoundType ct,
415 const QCString &ref,const QCString &fName,
416 bool isSymbol,bool isJavaEnum)
417{
418 return std::make_unique<ClassDefImpl>(fileName,startLine,startColumn,name,ct,ref,fName,isSymbol,isJavaEnum);
419}
420//-----------------------------------------------------------------------------
421
423{
424 public:
425 ClassDefAliasImpl(const Definition *newScope,const ClassDef *cd)
426 : DefinitionAliasMixin(newScope,cd) { init(); }
427 ~ClassDefAliasImpl() override { deinit(); }
429
430 DefType definitionType() const override { return TypeClass; }
431
432 const ClassDef *getCdAlias() const { return toClassDef(getAlias()); }
433 std::unique_ptr<ClassDef> deepCopy(const QCString &name) const override {
435 }
436 void moveTo(Definition *) override {}
437
439 { return getCdAlias()->codeSymbolType(); }
440 QCString getOutputFileBase() const override
441 { return getCdAlias()->getOutputFileBase(); }
442 QCString getInstanceOutputFileBase() const override
444 QCString getSourceFileBase() const override
445 { return getCdAlias()->getSourceFileBase(); }
446 QCString getReference() const override
447 { return getCdAlias()->getReference(); }
448 bool isReference() const override
449 { return getCdAlias()->isReference(); }
450 bool isLocal() const override
451 { return getCdAlias()->isLocal(); }
452 ClassLinkedRefMap getClasses() const override
453 { return getCdAlias()->getClasses(); }
454 bool hasDocumentation() const override
455 { return getCdAlias()->hasDocumentation(); }
456 bool hasDetailedDescription() const override
457 { return getCdAlias()->hasDetailedDescription(); }
458 QCString collaborationGraphFileName() const override
460 QCString inheritanceGraphFileName() const override
461 { return getCdAlias()->inheritanceGraphFileName(); }
462 QCString displayName(bool includeScope=TRUE) const override
463 { return makeDisplayName(this,includeScope); }
464 CompoundType compoundType() const override
465 { return getCdAlias()->compoundType(); }
466 QCString compoundTypeString() const override
467 { return getCdAlias()->compoundTypeString(); }
468 const BaseClassList &baseClasses() const override
469 { return getCdAlias()->baseClasses(); }
470 const BaseClassList &subClasses() const override
471 { return getCdAlias()->subClasses(); }
472 const MemberNameInfoLinkedMap &memberNameInfoLinkedMap() const override
473 { return getCdAlias()->memberNameInfoLinkedMap(); }
474 Protection protection() const override
475 { return getCdAlias()->protection(); }
476 bool isLinkableInProject() const override
477 { return getCdAlias()->isLinkableInProject(); }
478 bool isLinkable() const override
479 { return getCdAlias()->isLinkable(); }
480 bool isVisibleInHierarchy() const override
481 { return getCdAlias()->isVisibleInHierarchy(); }
482 bool visibleInParentsDeclList() const override
483 { return getCdAlias()->visibleInParentsDeclList(); }
484 const ArgumentList &templateArguments() const override
485 { return getCdAlias()->templateArguments(); }
486 FileDef *getFileDef() const override
487 { return getCdAlias()->getFileDef(); }
488 ModuleDef *getModuleDef() const override
489 { return getCdAlias()->getModuleDef(); }
490 const MemberDef *getMemberByName(const QCString &s) const override
491 { return getCdAlias()->getMemberByName(s); }
492 int isBaseClass(const ClassDef *bcd,bool followInstances,const QCString &templSpec) const override
493 { return getCdAlias()->isBaseClass(bcd,followInstances,templSpec); }
494 bool isSubClass(ClassDef *bcd,int level=0) const override
495 { return getCdAlias()->isSubClass(bcd,level); }
496 bool isAccessibleMember(const MemberDef *md) const override
497 { return getCdAlias()->isAccessibleMember(md); }
499 { return getCdAlias()->getTemplateInstances(); }
500 const ClassDef *templateMaster() const override
501 { return getCdAlias()->templateMaster(); }
502 bool isTemplate() const override
503 { return getCdAlias()->isTemplate(); }
504 const IncludeInfo *includeInfo() const override
505 { return getCdAlias()->includeInfo(); }
506 const UsesClassList &usedImplementationClasses() const override
508 const UsesClassList &usedByImplementationClasses() const override
510 const ConstraintClassList &templateTypeConstraints() const override
511 { return getCdAlias()->templateTypeConstraints(); }
512 bool isTemplateArgument() const override
513 { return getCdAlias()->isTemplateArgument(); }
514 const Definition *findInnerCompound(const QCString &name) const override
515 { return getCdAlias()->findInnerCompound(name); }
519 const ArgumentLists *actualParams=nullptr,uint32_t *actualParamIndex=nullptr) const override
520 { return makeQualifiedNameWithTemplateParameters(this,actualParams,actualParamIndex); }
521 bool isAbstract() const override
522 { return getCdAlias()->isAbstract(); }
523 bool isObjectiveC() const override
524 { return getCdAlias()->isObjectiveC(); }
525 bool isFortran() const override
526 { return getCdAlias()->isFortran(); }
527 bool isCSharp() const override
528 { return getCdAlias()->isCSharp(); }
529 bool isFinal() const override
530 { return getCdAlias()->isFinal(); }
531 bool isSealed() const override
532 { return getCdAlias()->isSealed(); }
533 bool isPublished() const override
534 { return getCdAlias()->isPublished(); }
535 bool isExtension() const override
536 { return getCdAlias()->isExtension(); }
537 bool isForwardDeclared() const override
538 { return getCdAlias()->isForwardDeclared(); }
539 bool isInterface() const override
540 { return getCdAlias()->isInterface(); }
541 ClassDef *categoryOf() const override
542 { return getCdAlias()->categoryOf(); }
543 QCString className() const override
544 { return getCdAlias()->className(); }
545 MemberList *getMemberList(MemberListType lt) const override
546 { return getCdAlias()->getMemberList(lt); }
547 const MemberLists &getMemberLists() const override
548 { return getCdAlias()->getMemberLists(); }
549 const MemberGroupList &getMemberGroups() const override
550 { return getCdAlias()->getMemberGroups(); }
553 bool isUsedOnly() const override
554 { return getCdAlias()->isUsedOnly(); }
555 QCString anchor() const override
556 { return getCdAlias()->anchor(); }
557 bool isEmbeddedInOuterScope() const override
558 { return getCdAlias()->isEmbeddedInOuterScope(); }
559 bool isSimple() const override
560 { return getCdAlias()->isSimple(); }
561 const ClassDef *tagLessReference() const override
562 { return getCdAlias()->tagLessReference(); }
563 const MemberDef *isSmartPointer() const override
564 { return getCdAlias()->isSmartPointer(); }
565 bool isJavaEnum() const override
566 { return getCdAlias()->isJavaEnum(); }
567 QCString title() const override
568 { return getCdAlias()->title(); }
569 QCString generatedFromFiles() const override
570 { return getCdAlias()->generatedFromFiles(); }
571 const FileList &usedFiles() const override
572 { return getCdAlias()->usedFiles(); }
573 const ArgumentList &typeConstraints() const override
574 { return getCdAlias()->typeConstraints(); }
575 const ExampleList &getExamples() const override
576 { return getCdAlias()->getExamples(); }
577 bool hasExamples() const override
578 { return getCdAlias()->hasExamples(); }
579 QCString getMemberListFileName() const override
580 { return getCdAlias()->getMemberListFileName(); }
581 bool subGrouping() const override
582 { return getCdAlias()->subGrouping(); }
583 bool isSliceLocal() const override
584 { return getCdAlias()->isSliceLocal(); }
585 bool hasNonReferenceSuperClass() const override
587 QCString requiresClause() const override
588 { return getCdAlias()->requiresClause(); }
590 { return getCdAlias()->getQualifiers(); }
591 bool containsOverload(const MemberDef *md) const override
592 { return getCdAlias()->containsOverload(md); }
593
594 int countMembersIncludingGrouped(MemberListType lt,const ClassDef *inheritedFrom,bool additional) const override
595 { return getCdAlias()->countMembersIncludingGrouped(lt,inheritedFrom,additional); }
596 int countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom,
597 MemberListType lt2,bool invert,bool showAlways,ClassDefSet &visitedClasses) const override
598 { return getCdAlias()->countMemberDeclarations(lt,inheritedFrom,lt2,invert,showAlways,visitedClasses); }
599
600 void writeDeclarationLink(OutputList &ol,bool &found,
601 const QCString &header,bool localNames) const override
602 { getCdAlias()->writeDeclarationLink(ol,found,header,localNames); }
603 ClassDef *insertTemplateInstance(const QCString &fileName,int startLine,int startColumn,
604 const QCString &templSpec,bool &freshInstance) const override
605 { return getCdAlias()->insertTemplateInstance(fileName,startLine,startColumn,templSpec,freshInstance); }
606 bool isImplicitTemplateInstance() const override
608
609 void writeDocumentation(OutputList &ol) const override
611 void writeDocumentationForInnerClasses(OutputList &ol) const override
613 void writeMemberPages(OutputList &ol) const override
614 { getCdAlias()->writeMemberPages(ol); }
615 void writeMemberList(OutputList &ol) const override
616 { getCdAlias()->writeMemberList(ol); }
617 void writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup,
618 int indentLevel, const ClassDef *inheritedFrom,const QCString &inheritId) const override
619 { getCdAlias()->writeDeclaration(ol,md,inGroup,indentLevel,inheritedFrom,inheritId); }
620 void writeQuickMemberLinks(OutputList &ol,const MemberDef *md) const override
621 { getCdAlias()->writeQuickMemberLinks(ol,md); }
622 void writeSummaryLinks(OutputList &ol) const override
623 { getCdAlias()->writeSummaryLinks(ol); }
624 void writeInlineDocumentation(OutputList &ol) const override
626 void writeTagFile(TextStream &ol) const override
627 { getCdAlias()->writeTagFile(ol); }
628 void writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedClasses,
629 MemberListType lt,const QCString &title,
630 const QCString &subTitle=QCString(),
631 bool showInline=FALSE,const ClassDef *inheritedFrom=nullptr,
632 MemberListType lt2=MemberListType::Invalid(),bool invert=FALSE,bool showAlways=FALSE) const override
633 { getCdAlias()->writeMemberDeclarations(ol,visitedClasses,lt,title,subTitle,showInline,inheritedFrom,lt2,invert,showAlways); }
634 void addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
635 const ClassDef *inheritedFrom,const QCString &inheritId) const override
636 { getCdAlias()->addGroupedInheritedMembers(ol,lt,inheritedFrom,inheritId); }
637
638 void updateBaseClasses(const BaseClassList &) override {}
639 void updateSubClasses(const BaseClassList &) override {}
640};
641
642std::unique_ptr<ClassDef> createClassDefAlias(const Definition *newScope,const ClassDef *cd)
643{
644 auto acd = std::make_unique<ClassDefAliasImpl>(newScope,cd);
645 //printf("cd name=%s localName=%s qualifiedName=%s qualifiedNameWith=%s displayName()=%s\n",
646 // qPrint(acd->name()),qPrint(acd->localName()),qPrint(acd->qualifiedName()),
647 // qPrint(acd->qualifiedNameWithTemplateParameters()),qPrint(acd->displayName()));
648 return acd;
649}
650
651//-----------------------------------------------------------------------------
652
653/** Private data associated with a ClassDef object. */
655{
656 public:
657 void init(const QCString &defFileName, const QCString &name,
658 const QCString &ctStr, const QCString &fName);
659 std::unique_ptr<ClassDefImpl::IMPL> deepCopy() const;
660
661 /*! file name that forms the base for the output file containing the
662 * class documentation. For compatibility with Qt (e.g. links via tag
663 * files) this name cannot be derived from the class name directly.
664 */
665 QCString fileName;
666
667 /*! file name used for the list of all members */
669
670 /*! file name used for the collaboration diagram */
672
673 /*! file name used for the inheritance graph */
675
676 /*! Include information about the header file should be included
677 * in the documentation. 0 by default, set by setIncludeFile().
678 */
679 std::unique_ptr<IncludeInfo> incInfo;
680
681 /*! List of base class (or super-classes) from which this class derives
682 * directly.
683 */
685
686 /*! List of sub-classes that directly derive from this class
687 */
689
690 /*! Namespace this class is part of
691 * (this is the inner most namespace in case of nested namespaces)
692 */
693 //NamespaceDef *nspace = nullptr;
694
695 /*! File this class is defined in */
696 FileDef *fileDef = nullptr;
697
698 /*! Module this class is defined in */
699 ModuleDef *moduleDef = nullptr;
700
701 /*! List of all members (including inherited members) */
702 MemberNameInfoLinkedMap allMemberNameInfoLinkedMap;
703
704 /*! Template arguments of this class */
705 ArgumentList tempArgs;
706
707 /*! Type constraints for template parameters */
708 ArgumentList typeConstraints;
709
710 /*! Files that were used for generating the class documentation. */
711 FileList files;
712
713 /*! Examples that use this class */
714 ExampleList examples;
715
716 /*! Holds the kind of "class" this is. */
718
719 /*! The protection level in which this class was found.
720 * Typically Public, but for nested classes this can also be Protected
721 * or Private.
722 */
724
725 /*! The inner classes contained in this class. Will be 0 if there are
726 * no inner classes.
727 */
728 ClassLinkedRefMap innerClasses;
729
730 /* classes for the collaboration diagram */
731 UsesClassList usesImplClassList;
732 UsesClassList usedByImplClassList;
733
734 ConstraintClassList constraintClassList;
735
736 /*! Template instances that exists of this class, the key in the
737 * dictionary is the template argument list.
738 */
740
742
743 /*! The class this class is an instance of. */
744 const ClassDef *templateMaster = nullptr;
745
746 /*! local class name which could be a typedef'ed alias name. */
747 QCString className;
748
749 /*! If this class is a Objective-C category, then this points to the
750 * class which is extended.
751 */
752 ClassDef *categoryOf = nullptr;
753
754 MemberLists memberLists;
755
756 /* user defined member groups */
757 MemberGroupList memberGroups;
758
759 /*! Is this an abstract class? */
760 bool isAbstract = false;
761
762 /*! Is the class part of an unnamed namespace? */
763 bool isStatic = false;
764
765 /*! TRUE if classes members are merged with those of the base classes. */
766 bool membersMerged = false;
767
768 /*! TRUE if the class is defined in a source file rather than a header file. */
769 bool isLocal = false;
770
771 bool isTemplArg = false;
772
773 /*! Does this class group its user-grouped members
774 * as a sub-section of the normal (public/protected/..)
775 * groups?
776 */
777 bool subGrouping = false;
778
779 /** Reason of existence is a "use" relation */
780 bool usedOnly = false;
781
782 /** List of titles to use for the summary */
784
785 /** Is this a simple (non-nested) C structure? */
786 bool isSimple = false;
787
788 /** Does this class overloaded the -> operator? */
789 const MemberDef *arrowOperator = nullptr;
790
791 const ClassDef *tagLessRef = nullptr;
792
793 /** Does this class represent a Java style enum? */
794 bool isJavaEnum = false;
795
796 TypeSpecifier spec;
797
798 QCString metaData;
799
800 /** C++20 requires clause */
802
804
806 CLASS_GRAPH_t typeInheritanceGraph = CLASS_GRAPH_t::NO;
807
809};
810
811void ClassDefImpl::IMPL::init(const QCString &defFileName, const QCString &name,
812 const QCString &ctStr, const QCString &fName)
813{
814 if (!fName.isEmpty())
815 {
817 }
818 else
819 {
820 fileName=ctStr+name;
821 }
823 //nspace=nullptr;
824 fileDef=nullptr;
825 moduleDef=nullptr;
826 subGrouping=Config_getBool(SUBGROUPING);
827 templateMaster =nullptr;
829 isStatic = FALSE;
832 categoryOf = nullptr;
833 usedOnly = FALSE;
834 isSimple = Config_getBool(INLINE_SIMPLE_STRUCTS);
835 arrowOperator = nullptr;
836 tagLessRef = nullptr;
837 spec=TypeSpecifier();
838 //QCString ns;
839 //extractNamespaceName(name,className,ns);
840 //printf("m_name=%s m_className=%s ns=%s\n",qPrint(m_name),qPrint(m_className),qPrint(ns));
841
842 // we cannot use getLanguage at this point, as setLanguage has not been called.
843 SrcLangExt lang = getLanguageFromFileName(defFileName);
844 if ((lang==SrcLangExt::Cpp || lang==SrcLangExt::ObjC) && guessSection(defFileName).isSource())
845 {
847 }
848 else
849 {
851 }
852 hasCollaborationGraph = Config_getBool(COLLABORATION_GRAPH);
854}
855
856//-------------------------------------------------------------------------------------------
857
858// constructs a new class definition
860 const QCString &defFileName,int defLine,int defColumn,
861 const QCString &nm,CompoundType ct,
862 const QCString &lref,const QCString &fName,
863 bool isSymbol,bool isJavaEnum)
864 : DefinitionMixin(defFileName,defLine,defColumn,removeRedundantWhiteSpace(nm),nullptr,nullptr,isSymbol),
865 m_impl(std::make_unique<IMPL>())
866{
867 setReference(lref);
868 m_impl->compType = ct;
869 m_impl->isJavaEnum = isJavaEnum;
870 QCString compTypeString = getCompoundTypeString(getLanguage(),ct,isJavaEnum);
871 m_impl->init(defFileName,name(),compTypeString,fName);
872 m_impl->memberListFileName = convertNameToFile(compTypeString+name()+"-members");
873 m_impl->collabFileName = convertNameToFile(m_impl->fileName+"_coll_graph");
874 m_impl->inheritFileName = convertNameToFile(m_impl->fileName+"_inherit_graph");
875 if (lref.isEmpty())
876 {
877 m_impl->fileName = convertNameToFile(m_impl->fileName);
878 }
879}
880
881std::unique_ptr<ClassDefImpl::IMPL> ClassDefImpl::IMPL::deepCopy() const
882{
883 auto result = std::make_unique<ClassDefImpl::IMPL>();
884
885 result->memberListFileName = memberListFileName;
886 result->collabFileName = collabFileName;
887 result->inheritFileName = inheritFileName;
888 if (incInfo)
889 {
890 result->incInfo = std::make_unique<IncludeInfo>();
891 *(result->incInfo) = *incInfo;
892 }
893 result->inherits = inherits;
894 result->inheritedBy = inheritedBy;
895 result->fileDef = fileDef;
896 result->moduleDef = moduleDef;
897 result->tempArgs = tempArgs;
898 result->typeConstraints = typeConstraints;
899 result->files = files;
900 result->examples = examples;
901 result->compType = compType;
902 result->prot = prot;
903 result->usesImplClassList = usesImplClassList;
904 result->usedByImplClassList = usedByImplClassList;
905 result->constraintClassList = constraintClassList;
906 result->templateInstances = templateInstances;
907 result->templBaseClassNames = templBaseClassNames;
908 result->templateMaster = templateMaster;
909 result->className = className;
910 result->categoryOf = categoryOf;
911 result->isAbstract = isAbstract;
912 result->isStatic = isStatic;
913 result->membersMerged = membersMerged;
914 result->isLocal = isLocal;
915 result->isTemplArg = isTemplArg;
916 result->subGrouping = subGrouping;
917 result->usedOnly = usedOnly;
918 result->vhdlSummaryTitles = vhdlSummaryTitles;
919 result->isSimple = isSimple;
920 result->arrowOperator = arrowOperator;
921 result->tagLessRef = tagLessRef;
922 result->isJavaEnum = isJavaEnum;
923 result->spec = spec;
924 result->metaData = metaData;
925 result->requiresClause = requiresClause;
926 result->qualifiers = qualifiers;
927 result->hasCollaborationGraph = hasCollaborationGraph;
928 result->typeInheritanceGraph = typeInheritanceGraph;
929
930 return result;
931}
932
933std::unique_ptr<ClassDef> ClassDefImpl::deepCopy(const QCString &name) const
934{
935 AUTO_TRACE("name='{}'",name);
936 auto result = std::make_unique<ClassDefImpl>(
938 std::string(),std::string(),true,m_impl->isJavaEnum);
939 // copy other members
940 result->m_impl = m_impl->deepCopy();
941
942 // set new file name
943 QCString compTypeString = getCompoundTypeString(getLanguage(),m_impl->compType,m_impl->isJavaEnum);
944 result->m_impl->fileName = compTypeString+name;
945 result->m_impl->memberListFileName = convertNameToFile(compTypeString+name+"-members");
946 result->m_impl->collabFileName = convertNameToFile(result->m_impl->fileName+"_coll_graph");
947 result->m_impl->inheritFileName = convertNameToFile(result->m_impl->fileName+"_inherit_graph");
948 result->m_impl->fileName = convertNameToFile(result->m_impl->fileName);
949
950 // deep copy nested classes
951 for (const auto &innerCd : m_impl->innerClasses)
952 {
953 QCString innerName = name+"::"+innerCd->localName();
954 if (Doxygen::classLinkedMap->find(innerName)==nullptr)
955 {
956 auto cd = Doxygen::classLinkedMap->add(innerName,innerCd->deepCopy(innerName));
957 result->addInnerCompound(cd);
958 ClassDefMutable *cdm = toClassDefMutable(cd);
959 if (cdm)
960 {
961 cdm->setOuterScope(result.get());
962 }
963 }
964 }
965
966 // copy all member list (and make deep copies of members)
967 for (auto &mni : m_impl->allMemberNameInfoLinkedMap)
968 {
969 for (auto &mi : *mni)
970 {
971 const MemberDef *md=mi->memberDef();
972 auto newMd = md->deepCopy();
973 if (newMd)
974 {
975 auto mmd = toMemberDefMutable(newMd.get());
976 AUTO_TRACE_ADD("Copying member {}",mmd->name());
977 mmd->moveTo(result.get());
978
979 result->internalInsertMember(newMd.get(),newMd->protection(),true);
980
981 // also add to the global list (which will own newMd)
982 MemberName *mn = Doxygen::memberNameLinkedMap->add(newMd->name());
983 mn->push_back(std::move(newMd));
984 }
985 }
986 }
987
988 return result;
989}
990
991void ClassDefImpl::moveTo(Definition *scope)
992{
993 //printf("%s::moveTo(%s)\n",qPrint(name()),qPrint(scope->name()));
994 setOuterScope(scope);
996 {
997 m_impl->fileDef = toFileDef(scope);
998 }
999 else if (scope->definitionType()==Definition::TypeModule)
1000 {
1001 m_impl->moduleDef = toModuleDef(scope);
1002 }
1003}
1004
1006{
1007 return m_impl->memberListFileName;
1008}
1009
1010QCString ClassDefImpl::displayName(bool includeScope) const
1011{
1012 return makeDisplayName(this,includeScope);
1013}
1014
1015// inserts a base/super class in the inheritance list
1016void ClassDefImpl::insertBaseClass(ClassDef *cd,const QCString &n,Protection p,
1017 Specifier s,const QCString &t)
1018{
1019 //printf("*** insert base class %s into %s\n",qPrint(cd->name()),qPrint(name()));
1020 m_impl->inherits.emplace_back(cd,n,p,s,t);
1021 m_impl->isSimple = FALSE;
1022}
1023
1024// inserts a derived/sub class in the inherited-by list
1026 Specifier s,const QCString &t)
1027{
1028 //printf("*** insert sub class %s into %s\n",qPrint(cd->name()),qPrint(name()));
1029 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1030 if (!extractPrivate && cd->protection()==Protection::Private) return;
1031 m_impl->inheritedBy.emplace_back(cd,QCString(),p,s,t);
1032 m_impl->isSimple = FALSE;
1033}
1034
1036{
1037 for (auto &ml : m_impl->memberLists)
1038 {
1039 if (!ml->listType().isDetailed())
1040 {
1041 ::addMembersToMemberGroup(ml.get(),&m_impl->memberGroups,this);
1042 }
1043 }
1044
1045 // add members inside sections to their groups
1046 for (const auto &mg : m_impl->memberGroups)
1047 {
1048 if (mg->allMembersInSameSection() && m_impl->subGrouping)
1049 {
1050 //printf("addToDeclarationSection(%s)\n",qPrint(mg->header()));
1051 mg->addToDeclarationSection();
1052 }
1053 }
1054}
1055
1056// adds new member definition to the class
1058 Protection prot,
1059 bool addToAllList
1060 )
1061{
1062 AUTO_TRACE("{} name={} isHidden={}",name(),md->name(),md->isHidden());
1063 if (md->isHidden()) return;
1064
1066 {
1068 m_impl->vhdlSummaryTitles.insert(title.str());
1069 }
1070
1071 if (1 /*!isReference()*/) // changed to 1 for showing members of external
1072 // classes when HAVE_DOT and UML_LOOK are enabled.
1073 {
1074 bool isSimple=FALSE;
1075
1076 /********************************************/
1077 /* insert member in the declaration section */
1078 /********************************************/
1079 if (md->isRelated() && protectionLevelVisible(prot))
1080 {
1081 addMemberToList(MemberListType::Related(),md,TRUE);
1082 }
1083 else if (md->isFriend())
1084 {
1085 addMemberToList(MemberListType::Friends(),md,TRUE);
1086 }
1087 else
1088 {
1089 switch (md->memberType())
1090 {
1091 case MemberType::Service: // UNO IDL
1092 addMemberToList(MemberListType::Services(),md,TRUE);
1093 break;
1094 case MemberType::Interface: // UNO IDL
1095 addMemberToList(MemberListType::Interfaces(),md,TRUE);
1096 break;
1097 case MemberType::Signal: // Qt specific
1098 addMemberToList(MemberListType::Signals(),md,TRUE);
1099 break;
1100 case MemberType::DCOP: // KDE2 specific
1101 addMemberToList(MemberListType::DcopMethods(),md,TRUE);
1102 break;
1104 addMemberToList(MemberListType::Properties(),md,TRUE);
1105 break;
1106 case MemberType::Event:
1107 addMemberToList(MemberListType::Events(),md,TRUE);
1108 break;
1109 case MemberType::Slot: // Qt specific
1110 switch (prot)
1111 {
1113 case Protection::Package: // slots in packages are not possible!
1114 addMemberToList(MemberListType::ProSlots(),md,TRUE);
1115 break;
1116 case Protection::Public:
1117 addMemberToList(MemberListType::PubSlots(),md,TRUE);
1118 break;
1120 addMemberToList(MemberListType::PriSlots(),md,TRUE);
1121 break;
1122 }
1123 break;
1124 default: // any of the other members
1125 if (md->isStatic())
1126 {
1127 if (md->isVariable())
1128 {
1129 switch (prot)
1130 {
1132 addMemberToList(MemberListType::ProStaticAttribs(),md,TRUE);
1133 break;
1135 addMemberToList(MemberListType::PacStaticAttribs(),md,TRUE);
1136 break;
1137 case Protection::Public:
1138 addMemberToList(MemberListType::PubStaticAttribs(),md,TRUE);
1139 break;
1141 addMemberToList(MemberListType::PriStaticAttribs(),md,TRUE);
1142 break;
1143 }
1144 }
1145 else // function
1146 {
1147 switch (prot)
1148 {
1150 addMemberToList(MemberListType::ProStaticMethods(),md,TRUE);
1151 break;
1153 addMemberToList(MemberListType::PacStaticMethods(),md,TRUE);
1154 break;
1155 case Protection::Public:
1156 addMemberToList(MemberListType::PubStaticMethods(),md,TRUE);
1157 break;
1159 addMemberToList(MemberListType::PriStaticMethods(),md,TRUE);
1160 break;
1161 }
1162 }
1163 }
1164 else // not static
1165 {
1166 if (md->isVariable())
1167 {
1168 switch (prot)
1169 {
1171 addMemberToList(MemberListType::ProAttribs(),md,TRUE);
1172 break;
1174 addMemberToList(MemberListType::PacAttribs(),md,TRUE);
1175 break;
1176 case Protection::Public:
1177 addMemberToList(MemberListType::PubAttribs(),md,TRUE);
1178 isSimple=TRUE;
1179 break;
1181 addMemberToList(MemberListType::PriAttribs(),md,TRUE);
1182 break;
1183 }
1184 }
1185 else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
1186 {
1187 switch (prot)
1188 {
1190 addMemberToList(MemberListType::ProTypes(),md,TRUE);
1191 break;
1193 addMemberToList(MemberListType::PacTypes(),md,TRUE);
1194 break;
1195 case Protection::Public:
1196 addMemberToList(MemberListType::PubTypes(),md,TRUE);
1197 isSimple=!md->isEnumerate() &&
1198 !md->isEnumValue() &&
1199 QCString(md->typeString()).find(")(")==-1; // func ptr typedef
1200 break;
1202 addMemberToList(MemberListType::PriTypes(),md,TRUE);
1203 break;
1204 }
1205 }
1206 else // member function
1207 {
1208 switch (prot)
1209 {
1211 addMemberToList(MemberListType::ProMethods(),md,TRUE);
1212 break;
1214 addMemberToList(MemberListType::PacMethods(),md,TRUE);
1215 break;
1216 case Protection::Public:
1217 addMemberToList(MemberListType::PubMethods(),md,TRUE);
1218 break;
1220 addMemberToList(MemberListType::PriMethods(),md,TRUE);
1221 break;
1222 }
1223 }
1224 }
1225 break;
1226 }
1227 }
1228 if (!isSimple) // not a simple field -> not a simple struct
1229 {
1230 m_impl->isSimple = FALSE;
1231 }
1232 //printf("adding %s simple=%d total_simple=%d\n",qPrint(name()),isSimple,m_impl->isSimple);
1233
1234 /*******************************************************/
1235 /* insert member in the detailed documentation section */
1236 /*******************************************************/
1237 if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
1238 {
1239 addMemberToList(MemberListType::RelatedMembers(),md,FALSE);
1240 }
1241 else if (md->isFunction() &&
1243 (md->virtualness()!=Specifier::Normal || md->isOverride() || md->isFinal()) &&
1244 Config_getBool(EXTRACT_PRIV_VIRTUAL))
1245 {
1246 addMemberToList(MemberListType::FunctionMembers(),md,FALSE);
1247 }
1248 else
1249 {
1250 switch (md->memberType())
1251 {
1252 case MemberType::Service: // UNO IDL
1253 addMemberToList(MemberListType::ServiceMembers(),md,FALSE);
1254 break;
1255 case MemberType::Interface: // UNO IDL
1256 addMemberToList(MemberListType::InterfaceMembers(),md,FALSE);
1257 break;
1259 addMemberToList(MemberListType::PropertyMembers(),md,FALSE);
1260 break;
1261 case MemberType::Event:
1262 addMemberToList(MemberListType::EventMembers(),md,FALSE);
1263 break;
1264 case MemberType::Signal: // fall through
1265 case MemberType::DCOP:
1266 addMemberToList(MemberListType::FunctionMembers(),md,FALSE);
1267 break;
1268 case MemberType::Slot:
1269 if (protectionLevelVisible(prot))
1270 {
1271 addMemberToList(MemberListType::FunctionMembers(),md,FALSE);
1272 }
1273 break;
1274 default: // any of the other members
1275 if (protectionLevelVisible(prot))
1276 {
1277 switch (md->memberType())
1278 {
1280 addMemberToList(MemberListType::TypedefMembers(),md,FALSE);
1281 break;
1283 addMemberToList(MemberListType::EnumMembers(),md,FALSE);
1284 break;
1286 addMemberToList(MemberListType::EnumValMembers(),md,FALSE);
1287 break;
1289 if (md->isConstructor() || md->isDestructor())
1290 {
1291 m_impl->memberLists.get(MemberListType::Constructors(),MemberListContainer::Class)->push_back(md);
1292 }
1293 else
1294 {
1295 addMemberToList(MemberListType::FunctionMembers(),md,FALSE);
1296 }
1297 break;
1299 addMemberToList(MemberListType::VariableMembers(),md,FALSE);
1300 break;
1301 case MemberType::Define:
1302 warn(md->getDefFileName(),md->getDefLine()-1,"A define (%s) cannot be made a member of %s",
1303 qPrint(md->name()), qPrint(this->name()));
1304 break;
1305 default:
1306 err("Unexpected member type '%s' found!\n",qPrint(md->memberTypeName()));
1307 }
1308 }
1309 break;
1310 }
1311 }
1312
1313 /*************************************************/
1314 /* insert member in the appropriate member group */
1315 /*************************************************/
1316 // Note: this must be done AFTER inserting the member in the
1317 // regular groups
1318 //addMemberToGroup(md,groupId);
1319
1320 }
1321
1322 if (md->virtualness()==Specifier::Pure)
1323 {
1324 m_impl->isAbstract=true;
1325 }
1326
1327 if (md->name()=="operator->")
1328 {
1329 m_impl->arrowOperator=md;
1330 }
1331
1332 if (addToAllList &&
1333 !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
1334 md->isFriend() &&
1335 (QCString(md->typeString())=="friend class" ||
1336 QCString(md->typeString())=="friend struct" ||
1337 QCString(md->typeString())=="friend union")))
1338 {
1339 //printf("=======> adding member %s to class %s\n",qPrint(md->name()),qPrint(name()));
1340
1341 MemberNameInfo *mni = m_impl->allMemberNameInfoLinkedMap.add(md->name());
1342 mni->push_back(std::make_unique<MemberInfo>(md,prot,md->virtualness(),false,false));
1343 }
1344}
1345
1347{
1349}
1350
1351// compute the anchors for all members
1353{
1354 for (auto &ml : m_impl->memberLists)
1355 {
1356 if (!ml->listType().isDetailed())
1357 {
1358 ml->setAnchors();
1359 }
1360 }
1361
1362 for (const auto &mg : m_impl->memberGroups)
1363 {
1364 mg->setAnchors();
1365 }
1366}
1367
1369{
1370 for (const auto &mg : m_impl->memberGroups)
1371 {
1372 mg->distributeMemberGroupDocumentation();
1373 }
1374}
1375
1377{
1381 for (const auto &mg : m_impl->memberGroups)
1382 {
1383 mg->findSectionsInDocumentation(this);
1384 }
1385 for (auto &ml : m_impl->memberLists)
1386 {
1387 if (!ml->listType().isDetailed())
1388 {
1389 ml->findSectionsInDocumentation(this);
1390 }
1391 }
1392}
1393
1394
1395// add a file name to the used files set
1396void ClassDefImpl::insertUsedFile(const FileDef *fd)
1397{
1398 if (fd==nullptr) return;
1399 auto it = std::find(m_impl->files.begin(),m_impl->files.end(),fd);
1400 if (it==m_impl->files.end())
1401 {
1402 m_impl->files.push_back(fd);
1403 }
1404 for (const auto &ti : m_impl->templateInstances)
1405 {
1406 ClassDefMutable *cdm = toClassDefMutable(ti.classDef);
1407 if (cdm)
1408 {
1409 cdm->insertUsedFile(fd);
1410 }
1411 }
1412}
1413
1414static void writeInheritanceSpecifier(OutputList &ol,const BaseClassDef &bcd)
1415{
1417 {
1418 ol.startTypewriter();
1419 ol.docify(" [");
1420 StringVector sl;
1421 if (bcd.prot==Protection::Protected) sl.emplace_back("protected");
1422 else if (bcd.prot==Protection::Private) sl.emplace_back("private");
1423 if (bcd.virt==Specifier::Virtual) sl.emplace_back("virtual");
1424 bool first=true;
1425 for (const auto &s : sl)
1426 {
1427 if (!first) ol.docify(", ");
1428 ol.docify(s.c_str());
1429 first=false;
1430 }
1431 ol.docify("]");
1432 ol.endTypewriter();
1433 }
1434}
1435
1437 const QCString &includeName,bool local, bool force)
1438{
1439 //printf("ClassDefImpl::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
1440 if (!m_impl->incInfo) m_impl->incInfo = std::make_unique<IncludeInfo>();
1441 if ((!includeName.isEmpty() && m_impl->incInfo->includeName.isEmpty()) ||
1442 (fd!=nullptr && m_impl->incInfo->fileDef==nullptr)
1443 )
1444 {
1445 //printf("Setting file info\n");
1446 m_impl->incInfo->fileDef = fd;
1447 m_impl->incInfo->includeName = includeName;
1449 }
1450 if (force && !includeName.isEmpty())
1451 {
1452 m_impl->incInfo->includeName = includeName;
1454 }
1455}
1456
1457// TODO: fix this: a nested template class can have multiple outer templates
1458//ArgumentList *ClassDefImpl::outerTemplateArguments() const
1459//{
1460// int ti;
1461// ClassDef *pcd=nullptr;
1462// int pi=0;
1463// if (m_impl->tempArgs) return m_impl->tempArgs;
1464// // find the outer most class scope
1465// while ((ti=name().find("::",pi))!=-1 &&
1466// (pcd=getClass(name().left(ti)))==0
1467// ) pi=ti+2;
1468// if (pcd)
1469// {
1470// return pcd->templateArguments();
1471// }
1472// return nullptr;
1473//}
1474
1475static void searchTemplateSpecs(/*in*/ const Definition *d,
1476 /*out*/ ArgumentLists &result,
1477 /*out*/ QCString &name,
1478 /*in*/ SrcLangExt lang)
1479{
1481 {
1482 if (d->getOuterScope())
1483 {
1484 searchTemplateSpecs(d->getOuterScope(),result,name,lang);
1485 }
1486 const ClassDef *cd=toClassDef(d);
1487 if (!name.isEmpty()) name+="::";
1488 QCString clName = d->localName();
1489 if (clName.endsWith("-p"))
1490 {
1491 clName = clName.left(clName.length()-2);
1492 }
1493 name+=clName;
1494 bool isSpecialization = d->localName().find('<')!=-1;
1495 if (!cd->templateArguments().empty())
1496 {
1497 result.push_back(cd->templateArguments());
1498 if (!isSpecialization)
1499 {
1501 }
1502 }
1503 }
1504 else
1505 {
1506 name+=d->qualifiedName();
1507 }
1508}
1509
1510void ClassDefImpl::writeTemplateSpec(OutputList &ol,const Definition *d,
1511 const QCString &type,SrcLangExt lang) const
1512{
1513 ArgumentLists specs;
1514 QCString name;
1515 searchTemplateSpecs(d,specs,name,lang);
1516 if (!specs.empty()) // class has template scope specifiers
1517 {
1519 for (const ArgumentList &al : specs)
1520 {
1521 ol.docify("template<");
1522 auto it = al.begin();
1523 while (it!=al.end())
1524 {
1525 Argument a = *it;
1526 linkifyText(TextGeneratorOLImpl(ol), // out
1527 d, // scope
1528 getFileDef(), // fileScope
1529 this, // self
1530 a.type, // text
1531 FALSE // autoBreak
1532 );
1533 if (!a.name.isEmpty())
1534 {
1535 ol.docify(" ");
1536 ol.docify(a.name);
1537 }
1538 if (a.defval.length()!=0)
1539 {
1540 ol.docify(" = ");
1541 ol.docify(a.defval);
1542 }
1543 ++it;
1544 if (it!=al.end()) ol.docify(", ");
1545 }
1546 ol.docify(">");
1547 ol.lineBreak();
1548 }
1549 if (!m_impl->requiresClause.isEmpty())
1550 {
1551 ol.docify("requires ");
1552 linkifyText(TextGeneratorOLImpl(ol), // out
1553 d, // scope
1554 getFileDef(), // fileScope
1555 this, // self
1556 m_impl->requiresClause, // text
1557 FALSE // autoBreak
1558 );
1559 ol.lineBreak();
1560 }
1561 ol.docify(type.lower()+" "+name);
1563 }
1564}
1565
1566void ClassDefImpl::writeBriefDescription(OutputList &ol,bool exampleFlag) const
1567{
1568 if (hasBriefDescription())
1569 {
1570 ol.startParagraph();
1571 ol.pushGeneratorState();
1573 ol.writeString(" - ");
1574 ol.popGeneratorState();
1575 ol.generateDoc(briefFile(),briefLine(),this,nullptr,
1576 briefDescription(),TRUE,FALSE,QCString(),
1577 TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
1578 ol.pushGeneratorState();
1580 ol.writeString(" \n");
1582 ol.popGeneratorState();
1583
1584 if (hasDetailedDescription() || exampleFlag)
1585 {
1586 writeMoreLink(ol,anchor());
1587 }
1588
1589 ol.endParagraph();
1590 }
1591 ol.writeSynopsis();
1592}
1593
1595{
1596 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1597
1598 ol.startTextBlock();
1599
1601 {
1603 }
1604
1605 // repeat brief description
1606 if (!briefDescription().isEmpty() && repeatBrief)
1607 {
1609 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
1610 }
1611 if (!briefDescription().isEmpty() && repeatBrief &&
1612 !documentation().isEmpty())
1613 {
1614 ol.pushGeneratorState();
1616 ol.writeString("\n\n");
1617 ol.popGeneratorState();
1618 }
1619 // write documentation
1620 if (!documentation().isEmpty())
1621 {
1622 ol.generateDoc(docFile(),docLine(),this,nullptr,documentation(),TRUE,FALSE,
1623 QCString(),FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
1624 }
1625 // write type constraints
1626 writeTypeConstraints(ol,this,m_impl->typeConstraints);
1627
1628 // write examples
1629 if (hasExamples())
1630 {
1631 ol.startExamples();
1632 ol.startDescForItem();
1633 writeExamples(ol,m_impl->examples);
1634 ol.endDescForItem();
1635 ol.endExamples();
1636 }
1637 writeSourceDef(ol);
1638 ol.endTextBlock();
1639}
1640
1642{
1643 bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1644 bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
1645 return ((!briefDescription().isEmpty() && repeatBrief) ||
1646 !documentation().isEmpty() ||
1647 (sourceBrowser && getStartBodyLine()!=-1 && getBodyDef()));
1648}
1649
1650// write the detailed description for this class
1651void ClassDefImpl::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
1652 const QCString &title,const QCString &anchor) const
1653{
1654 if (hasDetailedDescription() || exampleFlag)
1655 {
1656 ol.pushGeneratorState();
1658 ol.writeRuler();
1659 ol.popGeneratorState();
1660
1661 ol.pushGeneratorState();
1663 ol.writeAnchor(QCString(),anchor.isEmpty() ? QCString("details") : anchor);
1664 ol.popGeneratorState();
1665
1666 if (!anchor.isEmpty())
1667 {
1668 ol.pushGeneratorState();
1672 ol.popGeneratorState();
1673 }
1674
1675 ol.startGroupHeader();
1676 ol.parseText(title);
1677 ol.endGroupHeader();
1678
1680 }
1681 else
1682 {
1683 //writeTemplateSpec(ol,this,pageType);
1684 }
1685}
1686
1688{
1689 QCString result;
1690 SrcLangExt lang = getLanguage();
1691 size_t numFiles = m_impl->files.size();
1692 if (lang==SrcLangExt::Fortran)
1693 {
1695 getLanguage()==SrcLangExt::ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
1696 numFiles==1);
1697 }
1698 else if (isJavaEnum())
1699 {
1700 result = theTranslator->trEnumGeneratedFromFiles(numFiles==1);
1701 }
1702 else if (m_impl->compType==Service)
1703 {
1704 result = theTranslator->trServiceGeneratedFromFiles(numFiles==1);
1705 }
1706 else if (m_impl->compType==Singleton)
1707 {
1708 result = theTranslator->trSingletonGeneratedFromFiles(numFiles==1);
1709 }
1710 else
1711 {
1713 getLanguage()==SrcLangExt::ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
1714 numFiles==1);
1715 }
1716 return result;
1717}
1718
1719void ClassDefImpl::showUsedFiles(OutputList &ol) const
1720{
1721 ol.pushGeneratorState();
1723
1724
1725 ol.writeRuler();
1726 ol.pushGeneratorState();
1728 ol.startParagraph();
1730 ol.endParagraph();
1731 ol.popGeneratorState();
1735
1736 bool first=TRUE;
1737 for (const auto &fd : m_impl->files)
1738 {
1739 if (first)
1740 {
1741 first=FALSE;
1742 ol.startItemList();
1743 }
1744
1745 ol.startItemListItem();
1746 QCString path=fd->getPath();
1747 if (Config_getBool(FULL_PATH_NAMES))
1748 {
1749 ol.docify(stripFromPath(path));
1750 }
1751
1752 QCString fname = fd->name();
1753 if (!fd->getVersion().isEmpty()) // append version if available
1754 {
1755 fname += " (" + fd->getVersion() + ")";
1756 }
1757
1758 // for HTML
1759 ol.pushGeneratorState();
1761 if (fd->generateSourceFile())
1762 {
1763 ol.writeObjectLink(QCString(),fd->getSourceFileBase(),QCString(),fname);
1764 }
1765 else if (fd->isLinkable())
1766 {
1767 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),fname);
1768 }
1769 else
1770 {
1771 ol.startBold();
1772 ol.docify(fname);
1773 ol.endBold();
1774 }
1775 ol.popGeneratorState();
1776
1777 // for other output formats
1778 ol.pushGeneratorState();
1780 if (fd->isLinkable())
1781 {
1782 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),QCString(),fname);
1783 }
1784 else
1785 {
1786 ol.docify(fname);
1787 }
1788 ol.popGeneratorState();
1789
1790 ol.endItemListItem();
1791 }
1792 if (!first) ol.endItemList();
1793
1794 ol.popGeneratorState();
1795}
1796
1798{
1799 int count=0;
1800 for (const auto &ibcd : m_impl->inheritedBy)
1801 {
1802 const ClassDef *icd=ibcd.classDef;
1803 if ( icd->isVisibleInHierarchy()) count++;
1804 }
1805 return count;
1806}
1807
1809{
1810 int count=0;
1811 for (const auto &ibcd : m_impl->inherits)
1812 {
1813 const ClassDef *icd=ibcd.classDef;
1814 if ( icd->isVisibleInHierarchy()) count++;
1815 }
1816 return count;
1817}
1818
1823
1824void ClassDefImpl::writeInheritanceGraph(OutputList &ol) const
1825{
1826 bool haveDot = Config_getBool(HAVE_DOT);
1827 auto classGraph = m_impl->typeInheritanceGraph;
1828
1829 if (classGraph == CLASS_GRAPH_t::NO) return;
1830 // count direct inheritance relations
1831 int count=countInheritanceNodes();
1832
1833 bool renderDiagram = FALSE;
1834 if (haveDot && (classGraph==CLASS_GRAPH_t::YES || classGraph==CLASS_GRAPH_t::GRAPH))
1835 // write class diagram using dot
1836 {
1837 DotClassGraph inheritanceGraph(this,GraphType::Inheritance);
1838 if (inheritanceGraph.isTooBig())
1839 {
1840 warn_uncond("Inheritance graph for '%s' not generated, too many nodes (%d), threshold is %d. Consider increasing DOT_GRAPH_MAX_NODES.\n",
1841 qPrint(name()), inheritanceGraph.numNodes(), Config_getInt(DOT_GRAPH_MAX_NODES));
1842 }
1843 else if (!inheritanceGraph.isTrivial())
1844 {
1845 ol.pushGeneratorState();
1847 ol.startDotGraph();
1849 ol.endDotGraph(inheritanceGraph);
1850 ol.popGeneratorState();
1851 renderDiagram = TRUE;
1852 }
1853 }
1854 else if ((classGraph==CLASS_GRAPH_t::YES || classGraph==CLASS_GRAPH_t::GRAPH || classGraph==CLASS_GRAPH_t::BUILTIN) && count>0)
1855 // write class diagram using built-in generator
1856 {
1857 ClassDiagram diagram(this); // create a diagram of this class.
1858 ol.startClassDiagram();
1863 renderDiagram = TRUE;
1864 }
1865
1866 if (renderDiagram) // if we already show the inheritance relations graphically,
1867 // then hide the text version
1868 {
1870 }
1871
1872 count = countInheritsNodes();
1873 if (count>0)
1874 {
1875 auto replaceFunc = [this,&ol](size_t entryIndex)
1876 {
1877 for (size_t index=0; index<m_impl->inherits.size() ; index++)
1878 {
1879 const BaseClassDef &bcd=m_impl->inherits[index];
1880 const ClassDef *cd=bcd.classDef;
1881
1882 if (cd->isVisibleInHierarchy()) // filter on the class we want to show
1883 {
1884 if (index==entryIndex) // found the requested index
1885 {
1886 // use the class name but with the template arguments as given
1887 // in the inheritance relation
1889 cd->displayName(),bcd.templSpecifiers);
1890
1891 if (cd->isLinkable())
1892 {
1894 cd->getOutputFileBase(),
1895 cd->anchor(),
1896 displayName);
1897 }
1898 else
1899 {
1900 ol.docify(displayName);
1901 }
1902 return;
1903 }
1904 }
1905 }
1906 };
1907
1908 ol.startParagraph();
1909 writeMarkerList(ol,
1911 static_cast<size_t>(count),
1912 replaceFunc);
1913 ol.endParagraph();
1914 }
1915
1916 // write subclasses
1917 count = countInheritedByNodes();
1918 if (count>0)
1919 {
1920 auto replaceFunc = [this,&ol](size_t entryIndex)
1921 {
1922 for (size_t index=0; index<m_impl->inheritedBy.size() ; index++)
1923 {
1924 const BaseClassDef &bcd=m_impl->inheritedBy[index];
1925 const ClassDef *cd=bcd.classDef;
1926 if (cd->isVisibleInHierarchy()) // filter on the class we want to show
1927 {
1928 if (index==entryIndex) // found the requested index
1929 {
1930 if (cd->isLinkable())
1931 {
1934 }
1935 else
1936 {
1937 ol.docify(cd->displayName());
1938 }
1939 return;
1940 }
1941 }
1942 }
1943 };
1944
1945 ol.startParagraph();
1946 writeMarkerList(ol,
1948 static_cast<size_t>(count),
1949 replaceFunc);
1950 ol.endParagraph();
1951 }
1952
1953 if (renderDiagram)
1954 {
1955 ol.enableAll();
1956 }
1957}
1958
1960{
1961 if (Config_getBool(HAVE_DOT) && m_impl->hasCollaborationGraph /*&& Config_getBool(COLLABORATION_GRAPH)*/)
1962 {
1963 DotClassGraph usageImplGraph(this,GraphType::Collaboration);
1964 if (usageImplGraph.isTooBig())
1965 {
1966 warn_uncond("Collaboration graph for '%s' not generated, too many nodes (%d), threshold is %d. Consider increasing DOT_GRAPH_MAX_NODES.\n",
1967 qPrint(name()), usageImplGraph.numNodes(), Config_getInt(DOT_GRAPH_MAX_NODES));
1968 }
1969 else if (!usageImplGraph.isTrivial())
1970 {
1971 ol.pushGeneratorState();
1973 ol.startDotGraph();
1975 ol.endDotGraph(usageImplGraph);
1976 ol.popGeneratorState();
1977 }
1978 }
1979}
1980
1981
1983{
1984 if (m_impl->incInfo)
1985 {
1986 QCString nm;
1987 const StringVector &paths = Config_getList(STRIP_FROM_PATH);
1988 if (!paths.empty() && m_impl->incInfo->fileDef)
1989 {
1990 QCString abs = m_impl->incInfo->fileDef->absFilePath();
1991 QCString potential;
1992 size_t length = 0;
1993 for (const auto &s : paths)
1994 {
1995 FileInfo info(s);
1996 if (info.exists())
1997 {
1998 QCString prefix = info.absFilePath();
1999 if (prefix.at(prefix.length() - 1) != '/')
2000 {
2001 prefix += '/';
2002 }
2003
2004 if (prefix.length() > length &&
2005 qstricmp(abs.left(prefix.length()).data(), prefix.data()) == 0) // case insensitive compare
2006 {
2007 length = prefix.length();
2008 potential = abs.right(abs.length() - prefix.length());
2009 }
2010 }
2011 }
2012
2013 if (length > 0)
2014 {
2015 nm = potential;
2016 }
2017 }
2018
2019 if (nm.isEmpty())
2020 {
2021 nm = m_impl->incInfo->includeName;
2022 }
2023
2024 ol.startParagraph();
2025 ol.docify(theTranslator->trDefinedIn()+" ");
2026 ol.startTypewriter();
2027 ol.docify("<");
2028 if (m_impl->incInfo->fileDef)
2029 {
2030 ol.writeObjectLink(QCString(),m_impl->incInfo->fileDef->includeName(),QCString(),nm);
2031 }
2032 else
2033 {
2034 ol.docify(nm);
2035 }
2036 ol.docify(">");
2037 ol.endTypewriter();
2038 ol.endParagraph();
2039 }
2040
2041 // Write a summary of the Slice definition including metadata.
2042 ol.startParagraph();
2043 ol.startTypewriter();
2044 if (!m_impl->metaData.isEmpty())
2045 {
2046 ol.docify(m_impl->metaData);
2047 ol.lineBreak();
2048 }
2049 if (m_impl->spec.isLocal())
2050 {
2051 ol.docify("local ");
2052 }
2053 if (m_impl->spec.isInterface())
2054 {
2055 ol.docify("interface ");
2056 }
2057 else if (m_impl->spec.isStruct())
2058 {
2059 ol.docify("struct ");
2060 }
2061 else if (m_impl->spec.isException())
2062 {
2063 ol.docify("exception ");
2064 }
2065 else
2066 {
2067 ol.docify("class ");
2068 }
2069 ol.docify(stripScope(name()));
2070 if (!m_impl->inherits.empty())
2071 {
2072 if (m_impl->spec.isInterface() || m_impl->spec.isException())
2073 {
2074 ol.docify(" extends ");
2075 bool first=true;
2076 for (const auto &ibcd : m_impl->inherits)
2077 {
2078 if (!first) ol.docify(", ");
2079 ClassDef *icd = ibcd.classDef;
2080 ol.docify(icd->name());
2081 first=false;
2082 }
2083 }
2084 else
2085 {
2086 // Must be a class.
2087 bool implements = false;
2088 for (const auto &ibcd : m_impl->inherits)
2089 {
2090 ClassDef *icd = ibcd.classDef;
2091 if (icd->isInterface())
2092 {
2093 implements = true;
2094 }
2095 else
2096 {
2097 ol.docify(" extends ");
2098 ol.docify(icd->name());
2099 }
2100 }
2101 if (implements)
2102 {
2103 ol.docify(" implements ");
2104 bool first = true;
2105 for (const auto &ibcd : m_impl->inherits)
2106 {
2107 ClassDef *icd = ibcd.classDef;
2108 if (icd->isInterface())
2109 {
2110 if (!first) ol.docify(", ");
2111 first = false;
2112 ol.docify(icd->name());
2113 }
2114 }
2115 }
2116 }
2117 }
2118 ol.docify(" { ... }");
2119 ol.endTypewriter();
2120 ol.endParagraph();
2121}
2122
2123void ClassDefImpl::writeIncludeFiles(OutputList &ol) const
2124{
2125 if (m_impl->incInfo /*&& Config_getBool(SHOW_HEADERFILE)*/)
2126 {
2127 SrcLangExt lang = getLanguage();
2128 QCString nm=m_impl->incInfo->includeName.isEmpty() ?
2129 (m_impl->incInfo->fileDef ?
2130 m_impl->incInfo->fileDef->docName() : QCString()
2131 ) :
2132 m_impl->incInfo->includeName;
2133 if (!nm.isEmpty())
2134 {
2135 ol.startParagraph();
2136 ol.startTypewriter();
2137 ol.docify(::includeStatement(lang,m_impl->incInfo->kind));
2138 ol.docify(::includeOpen(lang,m_impl->incInfo->kind));
2139 ol.pushGeneratorState();
2141 ol.docify(nm);
2144 if (m_impl->incInfo->fileDef)
2145 {
2146 ol.writeObjectLink(QCString(),m_impl->incInfo->fileDef->includeName(),QCString(),nm);
2147 }
2148 else
2149 {
2150 ol.docify(nm);
2151 }
2152 ol.popGeneratorState();
2153 ol.docify(::includeClose(lang,m_impl->incInfo->kind));
2154 ol.endTypewriter();
2155 ol.endParagraph();
2156 }
2157 }
2158}
2159
2160void ClassDefImpl::writeMemberGroups(OutputList &ol,bool showInline) const
2161{
2162 // write user defined member groups
2163 for (const auto &mg : m_impl->memberGroups)
2164 {
2165 if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
2166 {
2167 mg->writeDeclarations(ol,this,nullptr,nullptr,nullptr,nullptr,showInline);
2168 }
2169 else // add this group to the corresponding member section
2170 {
2171 //printf("addToDeclarationSection(%s)\n",qPrint(mg->header()));
2172 //mg->addToDeclarationSection();
2173 }
2174 }
2175}
2176
2177void ClassDefImpl::writeNestedClasses(OutputList &ol,const QCString &title) const
2178{
2179 // nested classes
2180 m_impl->innerClasses.writeDeclaration(ol,nullptr,title,TRUE);
2181}
2182
2183void ClassDefImpl::writeInlineClasses(OutputList &ol) const
2184{
2185 m_impl->innerClasses.writeDocumentation(ol,this);
2186}
2187
2189{
2190 //printf("%s: ClassDefImpl::startMemberDocumentation()\n",qPrint(name()));
2191 if (Config_getBool(SEPARATE_MEMBER_PAGES))
2192 {
2195 }
2196}
2197
2199{
2200 //printf("%s: ClassDefImpl::endMemberDocumentation()\n",qPrint(name()));
2201 if (Config_getBool(SEPARATE_MEMBER_PAGES))
2202 {
2205 }
2206}
2207
2209{
2210 //printf("%s: ClassDefImpl::startMemberDeclarations()\n",qPrint(name()));
2212}
2213
2214void ClassDefImpl::endMemberDeclarations(OutputList &ol) const
2215{
2216 //printf("%s: ClassDefImpl::endMemberDeclarations()\n",qPrint(name()));
2217 bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
2218 if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
2219 {
2220 ol.startMemberHeader("inherited");
2222 ol.endMemberHeader();
2224 }
2225 ol.endMemberSections();
2226}
2227
2228void ClassDefImpl::writeAuthorSection(OutputList &ol) const
2229{
2230 ol.pushGeneratorState();
2232 ol.writeString("\n");
2233 ol.startGroupHeader();
2235 ol.endGroupHeader();
2237 ol.popGeneratorState();
2238}
2239
2240
2241void ClassDefImpl::writeSummaryLinks(OutputList &ol) const
2242{
2243 static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2244 ol.pushGeneratorState();
2246 bool first=TRUE;
2247 SrcLangExt lang = getLanguage();
2248
2249 if (lang!=SrcLangExt::VHDL)
2250 {
2251 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
2252 {
2253 if (lde->kind()==LayoutDocEntry::ClassNestedClasses &&
2254 m_impl->innerClasses.declVisible()
2255 )
2256 {
2257 for (const auto &innerCd : m_impl->innerClasses)
2258 {
2259 if (!innerCd->isAnonymous() &&
2260 !innerCd->isExtension() &&
2261 (innerCd->protection()!=Protection::Private || extractPrivate) &&
2262 innerCd->visibleInParentsDeclList()
2263 )
2264 {
2265 const LayoutDocEntrySection *ls = (const LayoutDocEntrySection*)lde.get();
2266 ol.writeSummaryLink(QCString(),"nested-classes",ls->title(lang),first);
2267 first=FALSE;
2268 break;
2269 }
2270 }
2271 }
2272 else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
2273 !m_impl->allMemberNameInfoLinkedMap.empty() &&
2274 !Config_getBool(OPTIMIZE_OUTPUT_FOR_C)
2275 )
2276 {
2278 first=FALSE;
2279 }
2280 else if (lde->kind()==LayoutDocEntry::MemberDecl)
2281 {
2282 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
2283 if (lmd)
2284 {
2285 MemberList * ml = getMemberList(lmd->type);
2286 if (ml && ml->declVisible())
2287 {
2288 ol.writeSummaryLink(QCString(),ml->listType().toLabel(),lmd->title(lang),first);
2289 first=FALSE;
2290 }
2291 }
2292 }
2293 }
2294 }
2295 else // VDHL only
2296 {
2297 for (const auto &s : m_impl->vhdlSummaryTitles)
2298 {
2299 ol.writeSummaryLink(QCString(),convertToId(QCString(s)),QCString(s),first);
2300 first=FALSE;
2301 }
2302 }
2303 if (!first)
2304 {
2305 ol.writeString(" </div>\n");
2306 }
2307 ol.popGeneratorState();
2308}
2309
2310void ClassDefImpl::writeTagFile(TextStream &tagFile) const
2311{
2312 if (!isLinkableInProject() || isArtificial()) return;
2313 tagFile << " <compound kind=\"";
2314 if (isFortran() && (compoundTypeString() == "type"))
2315 tagFile << "struct";
2316 else
2317 tagFile << compoundTypeString();
2318 tagFile << "\"";
2319 if (isObjectiveC()) { tagFile << " objc=\"yes\""; }
2320 tagFile << ">\n";
2321 tagFile << " <name>" << convertToXML(name()) << "</name>\n";
2322 QCString fn = getOutputFileBase();
2324 tagFile << " <filename>" << convertToXML(fn) << "</filename>\n";
2325 if (!anchor().isEmpty())
2326 {
2327 tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>\n";
2328 }
2329 QCString idStr = id();
2330 if (!idStr.isEmpty())
2331 {
2332 tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>\n";
2333 }
2334 for (const Argument &a : m_impl->tempArgs)
2335 {
2336 tagFile << " <templarg>" << convertToXML(a.type);
2337 if (!a.name.isEmpty())
2338 {
2339 tagFile << " " << convertToXML(a.name);
2340 }
2341 tagFile << "</templarg>\n";
2342 }
2343 for (const auto &ibcd : m_impl->inherits)
2344 {
2345 ClassDef *cd=ibcd.classDef;
2346 if (cd && cd->isLinkable())
2347 {
2348 tagFile << " <base";
2349 if (ibcd.prot==Protection::Protected)
2350 {
2351 tagFile << " protection=\"protected\"";
2352 }
2353 else if (ibcd.prot==Protection::Private)
2354 {
2355 tagFile << " protection=\"private\"";
2356 }
2357 if (ibcd.virt==Specifier::Virtual)
2358 {
2359 tagFile << " virtualness=\"virtual\"";
2360 }
2362 cd->displayName(),ibcd.templSpecifiers);
2363 tagFile << ">" << convertToXML(displayName) << "</base>\n";
2364 }
2365 }
2366 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
2367 {
2368 switch (lde->kind())
2369 {
2370 case LayoutDocEntry::ClassNestedClasses:
2371 {
2372 for (const auto &innerCd : m_impl->innerClasses)
2373 {
2374 if (innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
2375 protectionLevelVisible(innerCd->protection()) &&
2376 !innerCd->isEmbeddedInOuterScope()
2377 )
2378 {
2379 tagFile << " <class kind=\"" << innerCd->compoundTypeString() <<
2380 "\">" << convertToXML(innerCd->name()) << "</class>\n";
2381 }
2382 }
2383 }
2384 break;
2385 case LayoutDocEntry::MemberDecl:
2386 {
2387 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
2388 if (lmd)
2389 {
2390 MemberList * ml = getMemberList(lmd->type);
2391 if (ml)
2392 {
2393 ml->writeTagFile(tagFile);
2394 }
2395 }
2396 }
2397 break;
2398 case LayoutDocEntry::MemberGroups:
2399 {
2400 for (const auto &mg : m_impl->memberGroups)
2401 {
2402 mg->writeTagFile(tagFile);
2403 }
2404 }
2405 break;
2406 default:
2407 break;
2408 }
2409 }
2410 writeDocAnchorsToTagFile(tagFile);
2411 tagFile << " </compound>\n";
2412}
2413
2414/** Write class documentation inside another container (i.e. a group) */
2416{
2417 bool isSimple = m_impl->isSimple;
2418
2419 ol.addIndexItem(name(),QCString());
2420 //printf("ClassDefImpl::writeInlineDocumentation(%s)\n",qPrint(name()));
2421
2422 // part 1: anchor and title
2423 QCString s = compoundTypeString()+" "+name();
2424
2425 // part 1a
2426 ol.pushGeneratorState();
2428 { // only HTML only
2429 ol.writeAnchor(QCString(),anchor());
2430 ol.startMemberDoc(QCString(),QCString(),anchor(),name(),1,1,FALSE);
2432 ol.parseText(s);
2433 ol.endMemberDocName();
2434 ol.endMemberDoc(FALSE);
2435 ol.writeString("</div>");
2436 ol.startIndent();
2437 }
2438 ol.popGeneratorState();
2439
2440 // part 1b
2441 ol.pushGeneratorState();
2444 { // for LaTeX/RTF only
2446 }
2447 ol.popGeneratorState();
2448
2449 // part 1c
2450 ol.pushGeneratorState();
2452 {
2453 // for LaTeX/RTF/Man
2454 ol.startGroupHeader(1);
2455 ol.parseText(s);
2456 ol.endGroupHeader(1);
2457 }
2458 ol.popGeneratorState();
2459
2460 SrcLangExt lang=getLanguage();
2461
2462 // part 2: the header and detailed description
2463 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
2464 {
2465 switch (lde->kind())
2466 {
2467 case LayoutDocEntry::BriefDesc:
2468 {
2469 // since we already shown the brief description in the
2470 // declaration part of the container, so we use this to
2471 // show the details on top.
2473 }
2474 break;
2475 case LayoutDocEntry::ClassInheritanceGraph:
2477 break;
2478 case LayoutDocEntry::ClassCollaborationGraph:
2480 break;
2481 case LayoutDocEntry::MemberDeclStart:
2483 break;
2484 case LayoutDocEntry::MemberDecl:
2485 {
2486 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
2487 if (lmd)
2488 {
2489 ClassDefSet visitedClasses;
2490 if (!isSimple) writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
2491 }
2492 }
2493 break;
2494 case LayoutDocEntry::MemberGroups:
2496 break;
2497 case LayoutDocEntry::MemberDeclEnd:
2499 break;
2500 case LayoutDocEntry::MemberDefStart:
2502 break;
2503 case LayoutDocEntry::MemberDef:
2504 {
2505 const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get());
2506 if (lmd)
2507 {
2508 if (isSimple)
2509 {
2511 }
2512 else
2513 {
2514 writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
2515 }
2516 }
2517 }
2518 break;
2519 case LayoutDocEntry::MemberDefEnd:
2521 break;
2522 default:
2523 break;
2524 }
2525 }
2526
2527 // part 3: close the block
2528 ol.pushGeneratorState();
2530 { // HTML only
2531 ol.endIndent();
2532 }
2533 ol.popGeneratorState();
2534}
2535
2536void ClassDefImpl::writeMoreLink(OutputList &ol,const QCString &anchor) const
2537{
2538 // TODO: clean up this mess by moving it to
2539 // the output generators...
2540 bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
2541 bool rtfHyperlinks = Config_getBool(RTF_HYPERLINKS);
2542 bool usePDFLatex = Config_getBool(USE_PDFLATEX);
2543
2544 // HTML only
2545 ol.pushGeneratorState();
2547 ol.docify(" ");
2549 anchor.isEmpty() ? QCString("details") : anchor);
2551 ol.endTextLink();
2552 ol.popGeneratorState();
2553
2554 if (!anchor.isEmpty())
2555 {
2556 ol.pushGeneratorState();
2557 // LaTeX + RTF
2561 if (!(usePDFLatex && pdfHyperlinks))
2562 {
2564 }
2565 if (!rtfHyperlinks)
2566 {
2568 }
2569 ol.docify(" ");
2572 ol.endTextLink();
2573 // RTF only
2575 ol.writeString("\\par");
2576 ol.popGeneratorState();
2577 }
2578}
2579
2581{
2582 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2583 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
2584 bool extractLocalClasses = Config_getBool(EXTRACT_LOCAL_CLASSES);
2585 bool linkable = isLinkable();
2586 return (!isAnonymous() && !isExtension() &&
2587 (protection()!=Protection::Private || extractPrivate) &&
2588 (linkable || (!hideUndocClasses && (!isLocal() || extractLocalClasses)))
2589 );
2590}
2591
2592void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const QCString &header,bool localNames) const
2593{
2594 //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2595 //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2596 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2597 SrcLangExt lang = getLanguage();
2599 {
2600 if (!found) // first class
2601 {
2602 if (sliceOpt)
2603 {
2604 if (compoundType()==Interface)
2605 {
2606 ol.startMemberHeader("interfaces");
2607 }
2608 else if (compoundType()==Struct)
2609 {
2610 ol.startMemberHeader("structs");
2611 }
2612 else if (compoundType()==Exception)
2613 {
2614 ol.startMemberHeader("exceptions");
2615 }
2616 else // compoundType==Class
2617 {
2618 ol.startMemberHeader("nested-classes");
2619 }
2620 }
2621 else // non-Slice optimization: single header for class/struct/..
2622 {
2623 ol.startMemberHeader("nested-classes");
2624 }
2625 if (!header.isEmpty())
2626 {
2627 ol.parseText(header);
2628 }
2629 else if (lang==SrcLangExt::VHDL)
2630 {
2632 }
2633 else
2634 {
2638 }
2639 ol.endMemberHeader();
2640 ol.startMemberList();
2641 found=TRUE;
2642 }
2645 QCString ctype = compoundTypeString();
2646 QCString cname = displayName(!localNames);
2647
2648 if (lang!=SrcLangExt::VHDL) // for VHDL we swap the name and the type
2649 {
2650 if (isSliceLocal())
2651 {
2652 ol.writeString("local ");
2653 }
2654 ol.writeString(ctype);
2655 ol.writeString(" ");
2656 ol.insertMemberAlign();
2657 }
2658 if (isLinkable())
2659 {
2662 anchor(),
2663 cname
2664 );
2665 }
2666 else
2667 {
2668 ol.startBold();
2669 ol.docify(cname);
2670 ol.endBold();
2671 }
2672 if (lang==SrcLangExt::VHDL) // now write the type
2673 {
2674 ol.writeString(" ");
2675 ol.insertMemberAlign();
2677 }
2679
2680 // add the brief description if available
2681 if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
2682 {
2683 auto parser { createDocParser() };
2684 auto ast { validatingParseDoc(*parser.get(),
2685 briefFile(),briefLine(),this,nullptr,
2687 QCString(),TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)) };
2688 if (!ast->isEmpty())
2689 {
2691 ol.writeDoc(ast.get(),this,nullptr);
2692 if (isLinkableInProject())
2693 {
2694 writeMoreLink(ol,anchor());
2695 }
2697 }
2698 }
2699 ol.endMemberDeclaration(anchor(),QCString());
2700 }
2701}
2702
2703void ClassDefImpl::addClassAttributes(OutputList &ol) const
2704{
2705 StringVector sl;
2706 if (isFinal()) sl.emplace_back("final");
2707 if (isSealed()) sl.emplace_back("sealed");
2708 if (isAbstract()) sl.emplace_back("abstract");
2709 if (isExported()) sl.emplace_back("export");
2710 if (getLanguage()==SrcLangExt::IDL && isPublished()) sl.emplace_back("published");
2711
2712 for (const auto &sx : m_impl->qualifiers)
2713 {
2714 bool alreadyAdded = std::find(sl.begin(), sl.end(), sx) != sl.end();
2715 if (!alreadyAdded)
2716 {
2717 sl.push_back(sx);
2718 }
2719 }
2720
2721 ol.pushGeneratorState();
2723 if (!sl.empty())
2724 {
2725 ol.startLabels();
2726 size_t i=0;
2727 for (const auto &s : sl)
2728 {
2729 i++;
2730 ol.writeLabel(s.c_str(),i==sl.size());
2731 }
2732 ol.endLabels();
2733 }
2734 ol.popGeneratorState();
2735}
2736
2737void ClassDefImpl::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/) const
2738{
2739 ol.startContents();
2740
2741 QCString pageType = " ";
2742 pageType += compoundTypeString();
2743
2744 bool exampleFlag=hasExamples();
2745
2746 //---------------------------------------- start flexible part -------------------------------
2747
2748 SrcLangExt lang = getLanguage();
2749
2750 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
2751 {
2752 switch (lde->kind())
2753 {
2754 case LayoutDocEntry::BriefDesc:
2755 writeBriefDescription(ol,exampleFlag);
2756 break;
2757 case LayoutDocEntry::ClassIncludes:
2758 if (lang==SrcLangExt::Slice)
2759 {
2761 }
2762 else
2763 {
2765 }
2766 break;
2767 case LayoutDocEntry::ClassInheritanceGraph:
2769 break;
2770 case LayoutDocEntry::ClassCollaborationGraph:
2772 break;
2773 case LayoutDocEntry::ClassAllMembersLink:
2774 //writeAllMembersLink(ol); // this is now part of the summary links
2775 break;
2776 case LayoutDocEntry::MemberDeclStart:
2778 break;
2779 case LayoutDocEntry::MemberGroups:
2781 break;
2782 case LayoutDocEntry::MemberDecl:
2783 {
2784 ClassDefSet visitedClasses;
2785 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
2786 if (lmd)
2787 {
2788 writeMemberDeclarations(ol,visitedClasses,lmd->type,lmd->title(lang),lmd->subtitle(lang));
2789 }
2790 }
2791 break;
2792 case LayoutDocEntry::ClassNestedClasses:
2793 {
2794 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
2795 if (ls)
2796 {
2797 writeNestedClasses(ol,ls->title(lang));
2798 }
2799 }
2800 break;
2801 case LayoutDocEntry::MemberDeclEnd:
2803 break;
2804 case LayoutDocEntry::DetailedDesc:
2805 {
2806 const LayoutDocEntrySection *ls = dynamic_cast<const LayoutDocEntrySection*>(lde.get());
2807 if (ls)
2808 {
2809 writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
2810 }
2811 }
2812 break;
2813 case LayoutDocEntry::MemberDefStart:
2815 break;
2816 case LayoutDocEntry::ClassInlineClasses:
2818 break;
2819 case LayoutDocEntry::MemberDef:
2820 {
2821 const LayoutDocEntryMemberDef *lmd = dynamic_cast<const LayoutDocEntryMemberDef*>(lde.get());
2822 if (lmd)
2823 {
2824 writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
2825 }
2826 }
2827 break;
2828 case LayoutDocEntry::MemberDefEnd:
2830 break;
2831 case LayoutDocEntry::ClassUsedFiles:
2832 showUsedFiles(ol);
2833 break;
2834 case LayoutDocEntry::AuthorSection:
2836 break;
2837 case LayoutDocEntry::NamespaceNestedNamespaces:
2838 case LayoutDocEntry::NamespaceNestedConstantGroups:
2839 case LayoutDocEntry::NamespaceClasses:
2840 case LayoutDocEntry::NamespaceConcepts:
2841 case LayoutDocEntry::NamespaceInterfaces:
2842 case LayoutDocEntry::NamespaceStructs:
2843 case LayoutDocEntry::NamespaceExceptions:
2844 case LayoutDocEntry::NamespaceInlineClasses:
2845 case LayoutDocEntry::ConceptDefinition:
2846 case LayoutDocEntry::FileClasses:
2847 case LayoutDocEntry::FileConcepts:
2848 case LayoutDocEntry::FileInterfaces:
2849 case LayoutDocEntry::FileStructs:
2850 case LayoutDocEntry::FileExceptions:
2851 case LayoutDocEntry::FileNamespaces:
2852 case LayoutDocEntry::FileConstantGroups:
2853 case LayoutDocEntry::FileIncludes:
2854 case LayoutDocEntry::FileIncludeGraph:
2855 case LayoutDocEntry::FileIncludedByGraph:
2856 case LayoutDocEntry::FileSourceLink:
2857 case LayoutDocEntry::FileInlineClasses:
2858 case LayoutDocEntry::GroupClasses:
2859 case LayoutDocEntry::GroupConcepts:
2860 case LayoutDocEntry::GroupModules:
2861 case LayoutDocEntry::GroupInlineClasses:
2862 case LayoutDocEntry::GroupNamespaces:
2863 case LayoutDocEntry::GroupDirs:
2864 case LayoutDocEntry::GroupNestedGroups:
2865 case LayoutDocEntry::GroupFiles:
2866 case LayoutDocEntry::GroupGraph:
2867 case LayoutDocEntry::GroupPageDocs:
2868 case LayoutDocEntry::ModuleExports:
2869 case LayoutDocEntry::ModuleClasses:
2870 case LayoutDocEntry::ModuleConcepts:
2871 case LayoutDocEntry::ModuleUsedFiles:
2872 case LayoutDocEntry::DirSubDirs:
2873 case LayoutDocEntry::DirFiles:
2874 case LayoutDocEntry::DirGraph:
2875 err("Internal inconsistency: member %d should not be part of "
2876 "LayoutDocManager::Class entry list\n",lde->kind());
2877 break;
2878 }
2879 }
2880
2881 ol.endContents();
2882}
2883
2884QCString ClassDefImpl::title() const
2885{
2886 QCString pageTitle;
2887 SrcLangExt lang = getLanguage();
2888
2889 if (lang==SrcLangExt::Fortran)
2890 {
2892 m_impl->compType,
2893 !m_impl->tempArgs.empty());
2894 }
2895 else if (lang==SrcLangExt::Slice)
2896 {
2898 m_impl->compType,
2899 isSliceLocal());
2900 }
2901 else if (lang==SrcLangExt::VHDL)
2902 {
2904 }
2905 else if (isJavaEnum())
2906 {
2908 }
2909 else if (m_impl->compType==Service)
2910 {
2912 }
2913 else if (m_impl->compType==Singleton)
2914 {
2916 }
2917 else
2918 {
2919 if (Config_getBool(HIDE_COMPOUND_REFERENCE))
2920 {
2921 pageTitle = displayName();
2922 }
2923 else
2924 {
2926 m_impl->compType == Interface && getLanguage()==SrcLangExt::ObjC ? Class : m_impl->compType,
2927 !m_impl->tempArgs.empty());
2928 }
2929 }
2930 return pageTitle;
2931}
2932
2933// write all documentation for this class
2934void ClassDefImpl::writeDocumentation(OutputList &ol) const
2935{
2936 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
2937 //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2938 //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2939 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
2940 QCString pageTitle = title();
2941
2943 if (sliceOpt)
2944 {
2945 if (compoundType()==Interface)
2946 {
2948 }
2949 else if (compoundType()==Struct)
2950 {
2952 }
2953 else if (compoundType()==Exception)
2954 {
2956 }
2957 else
2958 {
2960 }
2961 }
2962 else
2963 {
2965 }
2966
2967 startFile(ol,getOutputFileBase(),name(),pageTitle,hli,!generateTreeView);
2968 if (!generateTreeView)
2969 {
2971 {
2973 }
2974 ol.endQuickIndices();
2975 }
2976
2977 startTitle(ol,getOutputFileBase(),this);
2978 ol.parseText(pageTitle);
2980 addGroupListToTitle(ol,this);
2982 writeDocumentationContents(ol,pageTitle);
2983
2984 endFileWithNavPath(ol,this);
2985
2986 if (Config_getBool(SEPARATE_MEMBER_PAGES))
2987 {
2988 writeMemberPages(ol);
2989 }
2990}
2991
2992void ClassDefImpl::writeMemberPages(OutputList &ol) const
2993{
2994 ///////////////////////////////////////////////////////////////////////////
2995 //// Member definitions on separate pages
2996 ///////////////////////////////////////////////////////////////////////////
2997
2998 ol.pushGeneratorState();
3000
3001 for (const auto &ml : m_impl->memberLists)
3002 {
3003 if (ml->numDocMembers()>ml->numDocEnumValues() && ml->listType().isDetailed())
3004 {
3005 ml->writeDocumentationPage(ol,displayName(),this);
3006 }
3007 }
3008
3009 ol.popGeneratorState();
3010}
3011
3012void ClassDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const
3013{
3014 bool createSubDirs=Config_getBool(CREATE_SUBDIRS);
3015
3016 ol.writeString(" <div class=\"navtab\">\n");
3017 ol.writeString(" <table>\n");
3018
3019 for (auto &mni : m_impl->allMemberNameInfoLinkedMap)
3020 {
3021 for (auto &mi : *mni)
3022 {
3023 const MemberDef *md=mi->memberDef();
3024 if (md->getClassDef()==this && md->isLinkable() && !md->isEnumValue())
3025 {
3026 if (md->isLinkableInProject())
3027 {
3028 if (md==currentMd) // selected item => highlight
3029 {
3030 ol.writeString(" <tr><td class=\"navtabHL\">");
3031 }
3032 else
3033 {
3034 ol.writeString(" <tr><td class=\"navtab\">");
3035 }
3036 ol.writeString("<a class=\"navtab\" ");
3037 ol.writeString("href=\"");
3038 if (createSubDirs) ol.writeString("../../");
3039 QCString url = md->getOutputFileBase();
3041 ol.writeString(url+"#"+md->anchor());
3042 ol.writeString("\">");
3043 ol.writeString(convertToHtml(md->name()));
3044 ol.writeString("</a>");
3045 ol.writeString("</td></tr>\n");
3046 }
3047 }
3048 }
3049 }
3050
3051 ol.writeString(" </table>\n");
3052 ol.writeString(" </div>\n");
3053}
3054
3055
3056
3058{
3059 // write inner classes after the parent, so the tag files contain
3060 // the definition in proper order!
3061 for (const auto &innerCd : m_impl->innerClasses)
3062 {
3063 if (
3064 innerCd->isLinkableInProject() && innerCd->templateMaster()==nullptr &&
3065 protectionLevelVisible(innerCd->protection()) &&
3066 !innerCd->isEmbeddedInOuterScope()
3067 )
3068 {
3069 msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
3070 innerCd->writeDocumentation(ol);
3071 innerCd->writeMemberList(ol);
3072 }
3073 innerCd->writeDocumentationForInnerClasses(ol);
3074 }
3075}
3076
3077// write the list of all (inherited) members for this class
3078void ClassDefImpl::writeMemberList(OutputList &ol) const
3079{
3080 bool cOpt = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
3081 //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
3082 bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
3083 bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
3084 if (m_impl->allMemberNameInfoLinkedMap.empty() || cOpt) return;
3085 // only for HTML
3086 ol.pushGeneratorState();
3088
3090 if (sliceOpt)
3091 {
3092 if (compoundType()==Interface)
3093 {
3095 }
3096 else if (compoundType()==Struct)
3097 {
3099 }
3100 else if (compoundType()==Exception)
3101 {
3103 }
3104 else
3105 {
3107 }
3108 }
3109 else
3110 {
3112 }
3113
3114 QCString memListFile = getMemberListFileName();
3115 startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),hli,!generateTreeView,getOutputFileBase());
3116 if (!generateTreeView)
3117 {
3119 {
3121 }
3122 ol.endQuickIndices();
3123 }
3124 startTitle(ol,QCString());
3126 endTitle(ol,QCString(),QCString());
3127 ol.startContents();
3128 ol.startParagraph();
3130 ol.docify(" ");
3133 ol.endParagraph();
3134
3135 //ol.startItemList();
3136
3137 bool first = true; // to prevent empty table
3138 int idx=0;
3139 for (auto &mni : m_impl->allMemberNameInfoLinkedMap)
3140 {
3141 for (auto &mi : *mni)
3142 {
3143 const MemberDef *md=mi->memberDef();
3144 const ClassDef *cd=md->getClassDef();
3145 Protection prot = mi->prot();
3146 Specifier virt=md->virtualness();
3147
3148 //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
3149 // qPrint(name()),qPrint(md->name()),qPrint(cd->name()),md->protection(),mi->prot,prot,mi->inherited);
3150
3151 if (cd && !md->name().isEmpty() && !md->isAnonymous())
3152 {
3153 bool memberWritten=FALSE;
3154 if (cd->isLinkable() && md->isLinkable())
3155 // create a link to the documentation
3156 {
3157 QCString name=mi->ambiguityResolutionScope()+md->name();
3158 //ol.writeListItem();
3159 if (first)
3160 {
3161 ol.writeString("<table class=\"directory\">\n");
3162 first = false;
3163 }
3164 ol.writeString(" <tr");
3165 if ((idx&1)==0) ol.writeString(" class=\"even\""); else ol.writeString(" class=\"odd\"");
3166 idx++;
3167 ol.writeString("><td class=\"entry\">");
3168 if (cd->isObjectiveC())
3169 {
3170 if (md->isObjCMethod())
3171 {
3172 if (md->isStatic())
3173 ol.writeString("+&#160;</td><td>");
3174 else
3175 ol.writeString("-&#160;</td><td>");
3176 }
3177 else
3178 ol.writeString("</td><td class=\"entry\">");
3179 }
3180 if (md->isObjCMethod())
3181 {
3183 md->getOutputFileBase(),
3184 md->anchor(),md->name());
3185 }
3186 else
3187 {
3188 //Definition *bd = md->getGroupDef();
3189 //if (bd==nullptr) bd=cd;
3191 md->getOutputFileBase(),
3192 md->anchor(),name);
3193
3194 if ( md->isFunction() || md->isSignal() || md->isSlot() ||
3195 (md->isFriend() && !md->argsString().isEmpty()))
3196 ol.docify(md->argsString());
3197 else if (md->isEnumerate())
3199 else if (md->isEnumValue())
3201 else if (md->isTypedef())
3202 ol.docify(" typedef");
3203 else if (md->isFriend() && md->typeString()=="friend class")
3204 ol.docify(" class");
3205 //ol.writeString("\n");
3206 }
3207 ol.writeString("</td>");
3208 memberWritten=TRUE;
3209 }
3210 else if (!cd->isArtificial() &&
3211 !Config_getBool(HIDE_UNDOC_MEMBERS) &&
3213 ) // no documentation,
3214 // generate link to the class instead.
3215 {
3216 //ol.writeListItem();
3217 if (first)
3218 {
3219 ol.writeString("<table class=\"directory\">\n");
3220 first = false;
3221 }
3222 ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
3223 if ((idx&1)==0) ol.writeString(" class=\"even\""); else ol.writeString(" class=\"odd\"");
3224 idx++;
3225 ol.writeString("><td class=\"entry\">");
3226 if (cd->isObjectiveC())
3227 {
3228 if (md->isObjCMethod())
3229 {
3230 if (md->isStatic())
3231 ol.writeString("+&#160;</td><td class=\"entry\">");
3232 else
3233 ol.writeString("-&#160;</td><td class=\"entry\">");
3234 }
3235 else
3236 ol.writeString("</td><td class=\"entry\">");
3237 }
3238 ol.startBold();
3239 ol.docify(md->name());
3240 ol.endBold();
3241 if (!md->isObjCMethod())
3242 {
3243 if ( md->isFunction() || md->isSignal() || md->isSlot() )
3244 ol.docify(md->argsString());
3245 else if (md->isEnumerate())
3247 else if (md->isEnumValue())
3249 else if (md->isTypedef())
3250 ol.docify(" typedef");
3251 }
3252 ol.writeString(" (");
3254 if (cd->isLinkable())
3255 {
3256 ol.writeObjectLink(
3257 cd->getReference(),
3258 cd->getOutputFileBase(),
3259 cd->anchor(),
3260 cd->displayName());
3261 }
3262 else
3263 {
3264 ol.startBold();
3265 ol.docify(cd->displayName());
3266 ol.endBold();
3267 }
3268 ol.writeString(")");
3269 ol.writeString("</td>");
3270 memberWritten=TRUE;
3271 }
3272 if (memberWritten)
3273 {
3274 ol.writeString("<td class=\"entry\">");
3276 cd->getOutputFileBase(),
3277 cd->anchor(),
3278 md->category() ?
3279 md->category()->displayName() :
3280 cd->displayName());
3281 ol.writeString("</td>");
3282 ol.writeString("<td class=\"entry\">");
3283 }
3284 SrcLangExt lang = md->getLanguage();
3285 if (
3287 md->isFriend() || md->isRelated() || md->isExplicit() ||
3288 md->isMutable() || (md->isInline() && Config_getBool(INLINE_INFO)) ||
3289 md->isSignal() || md->isSlot() ||
3291 (md->isOptional() || md->isAttribute() || md->isUNOProperty())) ||
3292 md->isStatic() || lang==SrcLangExt::VHDL
3293 )
3294 && memberWritten)
3295 {
3296 StringVector sl;
3297 if (lang==SrcLangExt::VHDL)
3298 {
3299 sl.push_back(theTranslator->trVhdlType(md->getVhdlSpecifiers(),TRUE).str()); //append vhdl type
3300 }
3301 else if (md->isFriend()) sl.emplace_back("friend");
3302 else if (md->isRelated()) sl.emplace_back("related");
3303 else
3304 {
3305 if (Config_getBool(INLINE_INFO) && md->isInline())
3306 sl.emplace_back("inline");
3307 if (md->isExplicit()) sl.emplace_back("explicit");
3308 if (md->isMutable()) sl.emplace_back("mutable");
3309 if (prot==Protection::Protected) sl.emplace_back("protected");
3310 else if (prot==Protection::Private) sl.emplace_back("private");
3311 else if (prot==Protection::Package) sl.emplace_back("package");
3313 sl.emplace_back("virtual");
3314 else if (virt==Specifier::Pure) sl.emplace_back("pure virtual");
3315 if (md->isStatic()) sl.emplace_back("static");
3316 if (md->isSignal()) sl.emplace_back("signal");
3317 if (md->isSlot()) sl.emplace_back("slot");
3318// this is the extra member page
3319 if (md->isOptional()) sl.emplace_back("optional");
3320 if (md->isAttribute()) sl.emplace_back("attribute");
3321 if (md->isUNOProperty()) sl.emplace_back("property");
3322 if (md->isReadonly()) sl.emplace_back("readonly");
3323 if (md->isBound()) sl.emplace_back("bound");
3324 if (md->isRemovable()) sl.emplace_back("removable");
3325 if (md->isConstrained()) sl.emplace_back("constrained");
3326 if (md->isTransient()) sl.emplace_back("transient");
3327 if (md->isMaybeVoid()) sl.emplace_back("maybevoid");
3328 if (md->isMaybeDefault()) sl.emplace_back("maybedefault");
3329 if (md->isMaybeAmbiguous()) sl.emplace_back("maybeambiguous");
3330 }
3331 bool firstSpan=true;
3332 for (const auto &s : sl)
3333 {
3334 if (!firstSpan)
3335 {
3336 ol.writeString("</span><span class=\"mlabel\">");
3337 }
3338 else
3339 {
3340 ol.writeString("<span class=\"mlabel\">");
3341 firstSpan=false;
3342 }
3343 ol.docify(s.c_str());
3344 }
3345 if (!firstSpan) ol.writeString("</span>");
3346 }
3347 if (memberWritten)
3348 {
3349 ol.writeString("</td>");
3350 ol.writeString("</tr>\n");
3351 }
3352 }
3353 }
3354 }
3355 //ol.endItemList();
3356
3357 if (!first) ol.writeString("</table>");
3358
3359 endFile(ol);
3360 ol.popGeneratorState();
3361}
3362
3363// add a reference to an example
3364bool ClassDefImpl::addExample(const QCString &anchor,const QCString &nameStr, const QCString &file)
3365{
3366 return m_impl->examples.inSort(Example(anchor,nameStr,file));
3367}
3368
3369// returns TRUE if this class is used in an example
3371{
3372 return !m_impl->examples.empty();
3373}
3374
3375void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCString &type)
3376{
3377 //printf("addTypeConstraint(%s,%s)\n",qPrint(type),qPrint(typeConstraint));
3378 bool hideUndocRelation = Config_getBool(HIDE_UNDOC_RELATIONS);
3379 if (typeConstraint.isEmpty() || type.isEmpty()) return;
3380 SymbolResolver resolver(getFileDef());
3381 ClassDefMutable *cd = resolver.resolveClassMutable(this,typeConstraint);
3382 if (cd==nullptr && !hideUndocRelation)
3383 {
3384 cd = toClassDefMutable(
3385 Doxygen::hiddenClassLinkedMap->add(typeConstraint,
3386 std::unique_ptr<ClassDef>(
3387 new ClassDefImpl(
3389 getDefColumn(),
3390 typeConstraint,
3391 ClassDef::Class))));
3392 if (cd)
3393 {
3394 cd->setUsedOnly(TRUE);
3395 cd->setLanguage(getLanguage());
3396 //printf("Adding undocumented constraint '%s' to class %s on type %s\n",
3397 // qPrint(typeConstraint),qPrint(name()),qPrint(type));
3398 }
3399 }
3400 if (cd)
3401 {
3402 auto it = std::find_if(m_impl->constraintClassList.begin(),
3403 m_impl->constraintClassList.end(),
3404 [&cd](const auto &ccd) { return ccd.classDef==cd; });
3405
3406 if (it==m_impl->constraintClassList.end())
3407 {
3408 m_impl->constraintClassList.emplace_back(cd);
3409 it = m_impl->constraintClassList.end()-1;
3410 }
3411 (*it).addAccessor(type);
3412 //printf("Adding constraint '%s' to class %s on type %s\n",
3413 // qPrint(typeConstraint),qPrint(name()),qPrint(type));
3414 }
3415}
3416
3417// Java Type Constrains: A<T extends C & I>
3419{
3420 for (const Argument &a : m_impl->tempArgs)
3421 {
3422 if (!a.typeConstraint.isEmpty())
3423 {
3424 QCString typeConstraint;
3425 int i=0,p=0;
3426 while ((i=a.typeConstraint.find('&',p))!=-1) // typeConstraint="A &I" for C<T extends A & I>
3427 {
3428 typeConstraint = a.typeConstraint.mid(p,i-p).stripWhiteSpace();
3429 addTypeConstraint(typeConstraint,a.type);
3430 p=i+1;
3431 }
3432 typeConstraint = a.typeConstraint.right(a.typeConstraint.length()-p).stripWhiteSpace();
3433 addTypeConstraint(typeConstraint,a.type);
3434 }
3435 }
3436}
3437
3438// C# Type Constraints: D<T> where T : C, I
3439void ClassDefImpl::setTypeConstraints(const ArgumentList &al)
3440{
3441 m_impl->typeConstraints = al;
3442}
3443
3444void ClassDefImpl::setTemplateArguments(const ArgumentList &al)
3445{
3446 m_impl->tempArgs = al;
3447}
3448
3449static bool hasNonReferenceSuperClassRec(const ClassDef *cd,int level)
3450{
3451 bool found=!cd->isReference() && cd->isLinkableInProject() && !cd->isHidden();
3452 if (found)
3453 {
3454 return TRUE; // we're done if this class is not a reference
3455 }
3456 for (const auto &ibcd : cd->subClasses())
3457 {
3458 const ClassDef *bcd=ibcd.classDef;
3459 if (level>256)
3460 {
3461 err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(cd->name()),qPrint(bcd->name()));
3462 return FALSE;
3463 }
3464 // recurse into the super class branch
3465 found = found || hasNonReferenceSuperClassRec(bcd,level+1);
3466 if (!found)
3467 {
3468 // look for template instances that might have non-reference super classes
3469 for (const auto &cil : bcd->getTemplateInstances())
3470 {
3471 // recurse into the template instance branch
3472 found = hasNonReferenceSuperClassRec(cil.classDef,level+1);
3473 if (found) break;
3474 }
3475 }
3476 else
3477 {
3478 break;
3479 }
3480 }
3481 return found;
3482}
3483
3484/*! Returns \c TRUE iff this class or a class inheriting from this class
3485 * is \e not defined in an external tag file.
3486 */
3488{
3489 return hasNonReferenceSuperClassRec(this,0);
3490}
3491
3493{
3494 return m_impl->requiresClause;
3495}
3496
3497void ClassDefImpl::setRequiresClause(const QCString &req)
3498{
3499 m_impl->requiresClause = req;
3500}
3501
3502/*! called from MemberDef::writeDeclaration() to (recursively) write the
3503 * definition of an anonymous struct, union or class.
3504 */
3505void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGroup,int indentLevel,
3506 const ClassDef *inheritedFrom,const QCString &inheritId) const
3507{
3508 //printf("ClassName='%s' inGroup=%d\n",qPrint(name()),inGroup);
3509
3511 QCString cn = displayName(FALSE);
3512 if (!cn.isEmpty())
3513 {
3514 ol.docify(" ");
3515 if (md && isLinkable())
3516 {
3517 ol.writeObjectLink(QCString(),QCString(),md->anchor(),cn);
3518 }
3519 else
3520 {
3521 ol.startBold();
3522 ol.docify(cn);
3523 ol.endBold();
3524 }
3525 }
3526 ol.docify(" {");
3528 ol.endMemberDeclaration(md ? md->anchor() : QCString(),inheritId);
3529
3530 // write user defined member groups
3531 for (const auto &mg : m_impl->memberGroups)
3532 {
3533 mg->writePlainDeclarations(ol,inGroup,this,nullptr,nullptr,nullptr,nullptr,indentLevel,inheritedFrom,inheritId);
3534 }
3535
3536 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
3537 {
3538 if (lde->kind()==LayoutDocEntry::MemberDecl)
3539 {
3540 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
3541 if (lmd)
3542 {
3543 writePlainMemberDeclaration(ol,lmd->type,inGroup,indentLevel,inheritedFrom,inheritId);
3544 }
3545 }
3546 }
3547}
3548
3549/*! a link to this class is possible within this project */
3551{
3552 bool extractLocal = Config_getBool(EXTRACT_LOCAL_CLASSES);
3553 bool extractStatic = Config_getBool(EXTRACT_STATIC);
3554 bool hideUndoc = Config_getBool(HIDE_UNDOC_CLASSES);
3555 if (m_impl->templateMaster)
3556 {
3557 return m_impl->templateMaster->isLinkableInProject();
3558 }
3559 else
3560 {
3561 //printf("%s::isLinkableInProject() conditions: artificial=%d hidden=%d anonymous=%d protection=%d local=%d docs=%d static=%d ref=%d\n",
3562 // qPrint(name()),
3563 // !isArtificial(),
3564 // !isHidden(),
3565 // !isAnonymous(),
3566 // m_impl->prot,
3567 // !m_impl->isLocal || extractLocal,
3568 // hasDocumentation() || !hideUndoc,
3569 // !m_impl->isStatic || extractStatic,
3570 // !isReference());
3571 return
3572 !isArtificial() && !isHidden() && /* not hidden */
3573 !isAnonymous() && /* not anonymous */
3574 protectionLevelVisible(m_impl->prot) && /* private/internal */
3575 (!m_impl->isLocal || extractLocal) && /* local */
3576 (hasDocumentation() || !hideUndoc) && /* documented */
3577 (!m_impl->isStatic || extractStatic) && /* static */
3578 !isReference(); /* not an external reference */
3579 }
3580}
3581
3583{
3584 if (m_impl->templateMaster)
3585 {
3586 return m_impl->templateMaster->isLinkable();
3587 }
3588 else
3589 {
3590 return isReference() || isLinkableInProject();
3591 }
3592}
3593
3594
3595/*! the class is visible in a class diagram, or class hierarchy */
3597{
3598 bool allExternals = Config_getBool(ALLEXTERNALS);
3599 bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
3600 bool extractStatic = Config_getBool(EXTRACT_STATIC);
3601
3602 return // show all classes or a subclass is visible
3603 ((allExternals && !isArtificial()) || hasNonReferenceSuperClass()) &&
3604 // and not an anonymous compound
3605 !isAnonymous() &&
3606 // and not privately inherited
3608 // documented or shown anyway or documentation is external
3609 (hasDocumentation() ||
3610 !hideUndocClasses ||
3611 (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) ||
3612 isReference()
3613 ) &&
3614 // is not part of an unnamed namespace or shown anyway
3615 (!m_impl->isStatic || extractStatic);
3616}
3617
3622
3623//----------------------------------------------------------------------
3624// recursive function:
3625// returns the distance to the base class definition 'bcd' represents an (in)direct base
3626// class of class definition 'cd' or nullptr if it does not.
3627
3628int ClassDefImpl::isBaseClass(const ClassDef *bcd, bool followInstances,const QCString &templSpec) const
3629{
3630 int distance=0;
3631 //printf("isBaseClass(cd=%s) looking for %s templSpec=%s\n",qPrint(name()),qPrint(bcd->name()),qPrint(templSpec));
3632 for (const auto &bclass : baseClasses())
3633 {
3634 const ClassDef *ccd = bclass.classDef;
3635 if (!followInstances && ccd->templateMaster())
3636 {
3637 ccd=ccd->templateMaster();
3638 }
3639 if (ccd==bcd && (templSpec.isEmpty() || templSpec==bclass.templSpecifiers))
3640 {
3641 distance=1;
3642 break; // no shorter path possible
3643 }
3644 else
3645 {
3646 int d = ccd->isBaseClass(bcd,followInstances,templSpec);
3647 if (d>256)
3648 {
3649 err("Possible recursive class relation while inside %s and looking for base class %s\n",qPrint(name()),qPrint(bcd->name()));
3650 return 0;
3651 }
3652 else if (d>0) // path found
3653 {
3654 if (distance==0 || d+1<distance) // update if no path found yet or shorter path found
3655 {
3656 distance=d+1;
3657 }
3658 }
3659 }
3660 }
3661 return distance;
3662}
3663
3664//----------------------------------------------------------------------
3665
3666bool ClassDefImpl::isSubClass(ClassDef *cd,int level) const
3667{
3668 bool found=FALSE;
3669 if (level>256)
3670 {
3671 err("Possible recursive class relation while inside %s and looking for derived class %s\n",qPrint(name()),qPrint(cd->name()));
3672 return FALSE;
3673 }
3674 for (const auto &iscd : subClasses())
3675 {
3676 ClassDef *ccd=iscd.classDef;
3677 found = (ccd==cd) || ccd->isSubClass(cd,level+1);
3678 if (found) break;
3679 }
3680 return found;
3681}
3682
3683//----------------------------------------------------------------------------
3684
3685static bool isStandardFunc(const MemberDef *md)
3686{
3687 return md->name()=="operator=" || // assignment operator
3688 md->isConstructor() || // constructor
3689 md->isDestructor(); // destructor
3690}
3691
3692void ClassDefImpl::mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
3693{
3694 SrcLangExt lang = getLanguage();
3695 QCString sep=getLanguageSpecificSeparator(lang,TRUE);
3696 size_t sepLen = sep.length();
3697 bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
3698 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
3699
3700 //printf(" mergeMembers for %s mergeVirtualBaseClass=%d\n",qPrint(name()),mergeVirtualBaseClass);
3701 // the merge the base members with this class' members
3702 for (const auto &bcd : baseClasses())
3703 {
3704 ClassDefMutable *bClass=toClassDefMutable(bcd.classDef);
3705 if (bClass)
3706 {
3707 const MemberNameInfoLinkedMap &srcMnd = bClass->memberNameInfoLinkedMap();
3708 MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap;
3709
3710 for (auto &srcMni : srcMnd)
3711 {
3712 MemberNameInfo *dstMni=dstMnd.find(srcMni->memberName());
3713 if (dstMni)
3714 // a member with that name is already in the class.
3715 // the member may hide or reimplement the one in the sub class
3716 // or there may be another path to the base class that is already
3717 // visited via another branch in the class hierarchy.
3718 {
3719 //printf(" %s hides member name %s\n",qPrint(bClass->name()),qPrint(srcMni->memberName()));
3720 for (auto &srcMi : *srcMni)
3721 {
3722 MemberDef *srcMd = srcMi->memberDef();
3723 bool found=FALSE;
3724 bool ambiguous=FALSE;
3725 bool hidden=FALSE;
3726 const ClassDef *srcCd = srcMd->getClassDef();
3727 for (auto &dstMi : *dstMni)
3728 {
3729 const MemberDef *dstMd = dstMi->memberDef();
3730 if (srcMd!=dstMd) // different members
3731 {
3732 const ClassDef *dstCd = dstMd->getClassDef();
3733 //printf(" Is %s a base class of %s?\n",qPrint(srcCd->name()),qPrint(dstCd->name()));
3734 if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
3735 // member is in the same or a base class
3736 {
3737 const ArgumentList &srcAl = srcMd->argumentList();
3738 const ArgumentList &dstAl = dstMd->argumentList();
3740 srcMd->getOuterScope(),srcMd->getFileDef(),&srcAl,
3741 dstMd->getOuterScope(),dstMd->getFileDef(),&dstAl,
3743 );
3744 //printf(" Yes, matching (%s<->%s): %d\n",
3745 // qPrint(argListToString(srcMd->argumentList())),
3746 // qPrint(argListToString(dstMd->argumentList())),
3747 // found);
3748 hidden = hidden || !found;
3749 }
3750 else // member is in a non base class => multiple inheritance
3751 // using the same base class.
3752 {
3753 //printf(" $$ Existing member %s %s add scope %s\n",
3754 // qPrint(dstMi->ambiguityResolutionScope()),
3755 // qPrint(dstMd->name()),
3756 // qPrint(dstMi->scopePath().left(dstMi->scopePath().find("::")+2)));
3757
3758 QCString scope=dstMi->scopePath().left(dstMi->scopePath().find(sep)+sepLen);
3759 if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
3760 {
3761 dstMi->setAmbiguityResolutionScope(scope+dstMi->ambiguityResolutionScope());
3762 }
3763 ambiguous=TRUE;
3764 }
3765 }
3766 else // same members
3767 {
3768 // do not add if base class is virtual or
3769 // if scope paths are equal or
3770 // if base class is an interface (and thus implicitly virtual).
3771 //printf(" same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt(),dstMi->virt());
3772 if ((srcMi->virt()!=Specifier::Normal && dstMi->virt()!=Specifier::Normal) ||
3773 bClass->name()+sep+srcMi->scopePath() == dstMi->scopePath() ||
3775 )
3776 {
3777 found=TRUE;
3778 }
3779 else // member can be reached via multiple paths in the
3780 // inheritance tree
3781 {
3782 //printf(" $$ Existing member %s %s add scope %s\n",
3783 // qPrint(dstMi->ambiguityResolutionScope()),
3784 // qPrint(dstMd->name()),
3785 // qPrint(dstMi->scopePath().left(dstMi->scopePath().find("::")+2)));
3786
3787 QCString scope=dstMi->scopePath().left(dstMi->scopePath().find(sep)+sepLen);
3788 if (scope!=dstMi->ambiguityResolutionScope().left(scope.length()))
3789 {
3790 dstMi->setAmbiguityResolutionScope(dstMi->ambiguityResolutionScope()+scope);
3791 }
3792 ambiguous=TRUE;
3793 }
3794 }
3795 if (found) break;
3796 }
3797 //printf(" member %s::%s hidden %d ambiguous %d srcMi->ambigClass=%p found=%d\n",
3798 // qPrint(srcCd->name()),qPrint(srcMd->name()),hidden,ambiguous,
3799 // (void*)srcMi->ambigClass(),found);
3800
3801 // TODO: fix the case where a member is hidden by inheritance
3802 // of a member with the same name but with another prototype,
3803 // while there is more than one path to the member in the
3804 // base class due to multiple inheritance. In this case
3805 // it seems that the member is not reachable by prefixing a
3806 // scope name either (according to my compiler). Currently,
3807 // this case is shown anyway.
3808 if (!found && srcMd->protection()!=Protection::Private && !srcMd->isFriend() && srcMi->virtualBaseClass()==mergeVirtualBaseClass)
3809 {
3810 Protection prot = srcMd->protection();
3811 if (bcd.prot==Protection::Protected && prot==Protection::Public)
3812 {
3813 prot = bcd.prot;
3814 }
3815 else if (bcd.prot==Protection::Private)
3816 {
3817 prot = bcd.prot;
3818 }
3819
3820 if (inlineInheritedMembers)
3821 {
3822 if (!isStandardFunc(srcMd))
3823 {
3824 //printf(" %s::insertMember(%s)\n",qPrint(name()),qPrint(srcMd->name()));
3825 internalInsertMember(srcMd,prot,FALSE);
3826 }
3827 }
3828
3829 Specifier virt=srcMi->virt();
3830 if (virt==Specifier::Normal && bcd.virt!=Specifier::Normal) virt=bcd.virt;
3831 bool virtualBaseClass = bcd.virt!=Specifier::Normal;
3832
3833 std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(srcMd,prot,virt,TRUE,virtualBaseClass);
3834 newMi->setScopePath(bClass->name()+sep+srcMi->scopePath());
3835 if (ambiguous)
3836 {
3837 //printf("$$ New member %s %s add scope %s::\n",
3838 // qPrint(srcMi->ambiguityResolutionScope),
3839 // qPrint(srcMd->name()),
3840 // qPrint(bClass->name()));
3841
3842 QCString scope=bClass->name()+sep;
3843 if (scope!=srcMi->ambiguityResolutionScope().left(scope.length()))
3844 {
3845 newMi->setAmbiguityResolutionScope(scope+srcMi->ambiguityResolutionScope());
3846 }
3847 }
3848 if (hidden)
3849 {
3850 if (srcMi->ambigClass()==nullptr)
3851 {
3852 newMi->setAmbigClass(bClass);
3853 newMi->setAmbiguityResolutionScope(bClass->name()+sep);
3854 }
3855 else
3856 {
3857 newMi->setAmbigClass(srcMi->ambigClass());
3858 newMi->setAmbiguityResolutionScope(srcMi->ambigClass()->name()+sep);
3859 }
3860 }
3861 dstMni->push_back(std::move(newMi));
3862 }
3863 }
3864 }
3865 else // base class has a member that is not in the sub class => copy
3866 {
3867 //printf(" %s adds member name %s\n",qPrint(bClass->name()),qPrint(srcMni->memberName()));
3868 // create a deep copy of the list (only the MemberInfo's will be
3869 // copied, not the actual MemberDef's)
3870 MemberNameInfo *newMni = dstMnd.add(srcMni->memberName());
3871
3872 // copy the member(s) from the base to the sub class
3873 for (auto &mi : *srcMni)
3874 {
3875 if (mi->virtualBaseClass()==mergeVirtualBaseClass && !mi->memberDef()->isFriend()) // don't inherit friends
3876 {
3877 Protection prot = mi->prot();
3878 if (bcd.prot==Protection::Protected)
3879 {
3881 }
3882 else if (bcd.prot==Protection::Private)
3883 {
3885 }
3886 Specifier virt=mi->virt();
3887 bool virtualBaseClass = bcd.virt!=Specifier::Normal || mi->virtualBaseClass();
3888 if (virt==Specifier::Normal && bcd.virt!=Specifier::Normal) virt=bcd.virt;
3889 //printf(" %s::%s: [mi.prot=%d, bcd.prot=%d => prot=%d], [mi.virt=%d, bcd.virt=%d => virt=%d] virtualBase=%d\n",
3890 // qPrint(name()),qPrint(mi->memberDef()->name()),
3891 // mi->prot(),bcd.prot,prot,
3892 // mi->virt(),bcd.virt,virt,
3893 // virtualBaseClass
3894 // );
3895
3896 if (prot!=Protection::Private || extractPrivate)
3897 {
3898
3899 if (inlineInheritedMembers)
3900 {
3901 if (!isStandardFunc(mi->memberDef()))
3902 {
3903 //printf(" %s::insertMember '%s'\n",qPrint(name()),qPrint(mi->memberDef()->name()));
3904 internalInsertMember(mi->memberDef(),prot,FALSE);
3905 }
3906 }
3907 //printf("Adding!\n");
3908 std::unique_ptr<MemberInfo> newMi = std::make_unique<MemberInfo>(mi->memberDef(),prot,virt,TRUE,virtualBaseClass);
3909 newMi->setScopePath(bClass->name()+sep+mi->scopePath());
3910 newMi->setAmbigClass(mi->ambigClass());
3911 newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope());
3912 newMni->push_back(std::move(newMi));
3913 }
3914 }
3915 }
3916 }
3917 }
3918 }
3919 }
3920}
3921
3922/*!
3923 * recursively merges the 'all members' lists of a class base
3924 * with that of this class. Must only be called for classes without
3925 * subclasses!
3926 */
3928{
3929 if (m_impl->membersMerged) return;
3930 if (getLanguage()==SrcLangExt::Python) return; // python does not have member overloading, see issue 8480
3931
3932 //printf("> %s::mergeMembers()\n",qPrint(name()));
3933
3934 m_impl->membersMerged=TRUE;
3935
3936 // first merge the members of the base class recursively
3937 for (const auto &bcd : baseClasses())
3938 {
3939 ClassDefMutable *bClass=toClassDefMutable(bcd.classDef);
3940 if (bClass)
3941 {
3942 // merge the members in the base class of this inheritance branch first
3943 bClass->mergeMembers();
3944 }
3945 }
3946
3947 // first merge the member that are not inherited via a virtual base class
3948 // (as this can end up reimplemented via multiple paths, see #10717 for examples)
3950 // then process the member that are inherited via a virtual base class to add the
3951 // ones that are not reimplemented via any path
3953
3954 //printf("< %s::mergeMembers()\n",qPrint(name()));
3955}
3956
3957//----------------------------------------------------------------------------
3958
3959/*! Merges the members of a Objective-C category into this class.
3960 */
3962{
3963 AUTO_TRACE();
3964 ClassDefMutable *category = toClassDefMutable(cat);
3965 if (category)
3966 {
3967 bool extractLocalMethods = Config_getBool(EXTRACT_LOCAL_METHODS);
3968 bool makePrivate = category->isLocal();
3969 // in case extract local methods is not enabled we don't add the methods
3970 // of the category in case it is defined in the .m file.
3971 if (makePrivate && !extractLocalMethods) return;
3972 bool isExtension = category->isExtension();
3973
3974 category->setCategoryOf(this);
3975 if (isExtension)
3976 {
3977 category->setArtificial(TRUE);
3978
3979 // copy base classes/protocols from extension
3980 for (const auto &bcd : category->baseClasses())
3981 {
3982 insertBaseClass(bcd.classDef,bcd.usedName,bcd.prot,bcd.virt,bcd.templSpecifiers);
3983 // correct bcd.classDef so that they do no longer derive from
3984 // category, but from this class!
3985 BaseClassList scl = bcd.classDef->subClasses();
3986 for (auto &scd : scl)
3987 {
3988 if (scd.classDef==category)
3989 {
3990 scd.classDef=this;
3991 }
3992 }
3993 bcd.classDef->updateSubClasses(scl);
3994 }
3995 }
3996 // make methods private for categories defined in the .m file
3997 //printf("%s::mergeCategory makePrivate=%d\n",qPrint(name()),makePrivate);
3998
3999 const MemberNameInfoLinkedMap &srcMnd = category->memberNameInfoLinkedMap();
4000 MemberNameInfoLinkedMap &dstMnd = m_impl->allMemberNameInfoLinkedMap;
4001
4002 for (auto &srcMni : srcMnd)
4003 {
4004 MemberNameInfo *dstMni=dstMnd.find(srcMni->memberName());
4005 if (dstMni) // method is already defined in the class
4006 {
4007 AUTO_TRACE_ADD("Existing member {}",srcMni->memberName());
4008 const auto &dstMi = dstMni->front();
4009 const auto &srcMi = srcMni->front();
4010 if (srcMi && dstMi)
4011 {
4012 MemberDefMutable *smdm = toMemberDefMutable(srcMi->memberDef());
4013 MemberDefMutable *dmdm = toMemberDefMutable(dstMi->memberDef());
4014 if (smdm && dmdm)
4015 {
4017 dmdm->setCategory(category);
4018 dmdm->setCategoryRelation(smdm);
4019 smdm->setCategoryRelation(dmdm);
4020 }
4021 }
4022 }
4023 else // new method name
4024 {
4025 AUTO_TRACE_ADD("New member {}",srcMni->memberName());
4026 // create a deep copy of the list
4027 MemberNameInfo *newMni = dstMnd.add(srcMni->memberName());
4028
4029 // copy the member(s) from the category to this class
4030 for (auto &mi : *srcMni)
4031 {
4032 //printf("Adding '%s'\n",qPrint(mi->memberDef->name()));
4033 Protection prot = mi->prot();
4034 //if (makePrivate) prot = Private;
4035 auto newMd = mi->memberDef()->deepCopy();
4036 if (newMd)
4037 {
4038 auto mmd = toMemberDefMutable(newMd.get());
4039 AUTO_TRACE_ADD("Copying member {}",mmd->name());
4040 mmd->moveTo(this);
4041
4042 auto newMi=std::make_unique<MemberInfo>(newMd.get(),prot,mi->virt(),mi->inherited(),mi->virtualBaseClass());
4043 newMi->setScopePath(mi->scopePath());
4044 newMi->setAmbigClass(mi->ambigClass());
4045 newMi->setAmbiguityResolutionScope(mi->ambiguityResolutionScope());
4046 newMni->push_back(std::move(newMi));
4047
4048 // also add the newly created member to the global members list
4049
4050 QCString name = newMd->name();
4051 MemberName *mn = Doxygen::memberNameLinkedMap->add(name);
4052
4053 mmd->setCategory(category);
4054 mmd->setCategoryRelation(mi->memberDef());
4055 auto miMmd = toMemberDefMutable(mi->memberDef());
4056 if (miMmd) miMmd->setCategoryRelation(newMd.get());
4057
4058 if (makePrivate || isExtension)
4059 {
4060 mmd->makeImplementationDetail();
4061 }
4062 internalInsertMember(newMd.get(),prot,FALSE);
4063 mn->push_back(std::move(newMd));
4064 }
4065 }
4066 }
4067 }
4068 }
4069}
4070
4071//----------------------------------------------------------------------------
4072
4073void ClassDefImpl::addUsedClass(ClassDef *cd,const QCString &accessName,
4074 Protection prot)
4075{
4076 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4077 bool umlLook = Config_getBool(UML_LOOK);
4078 if (prot==Protection::Private && !extractPrivate) return;
4079 //printf("%s::addUsedClass(%s,%s)\n",qPrint(name()),qPrint(cd->name()),accessName);
4080
4081 auto it = std::find_if(m_impl->usesImplClassList.begin(),
4082 m_impl->usesImplClassList.end(),
4083 [&cd](const auto &ucd) { return ucd.classDef==cd; });
4084 if (it==m_impl->usesImplClassList.end())
4085 {
4086 m_impl->usesImplClassList.emplace_back(cd);
4087 //printf("Adding used class %s to class %s via accessor %s\n",
4088 // qPrint(cd->name()),qPrint(name()),accessName);
4089 it = m_impl->usesImplClassList.end()-1;
4090 }
4091 QCString acc = accessName;
4092 if (umlLook)
4093 {
4094 switch(prot)
4095 {
4096 case Protection::Public: acc.prepend("+"); break;
4097 case Protection::Private: acc.prepend("-"); break;
4098 case Protection::Protected: acc.prepend("#"); break;
4099 case Protection::Package: acc.prepend("~"); break;
4100 }
4101 }
4102 (*it).addAccessor(acc);
4103}
4104
4105void ClassDefImpl::addUsedByClass(ClassDef *cd,const QCString &accessName,
4106 Protection prot)
4107{
4108 bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
4109 bool umlLook = Config_getBool(UML_LOOK);
4110 if (prot==Protection::Private && !extractPrivate) return;
4111 //printf("%s::addUsedByClass(%s,%s)\n",qPrint(name()),qPrint(cd->name()),accessName);
4112 //
4113 auto it = std::find_if(m_impl->usedByImplClassList.begin(),
4114 m_impl->usedByImplClassList.end(),
4115 [&cd](const auto &ucd) { return ucd.classDef==cd; });
4116 if (it==m_impl->usedByImplClassList.end())
4117 {
4118 m_impl->usedByImplClassList.emplace_back(cd);
4119 //printf("Adding used by class %s to class %s\n",
4120 // qPrint(cd->name()),qPrint(name()));
4121 it = m_impl->usedByImplClassList.end()-1;
4122 }
4123 QCString acc = accessName;
4124 if (umlLook)
4125 {
4126 switch(prot)
4127 {
4128 case Protection::Public: acc.prepend("+"); break;
4129 case Protection::Private: acc.prepend("-"); break;
4130 case Protection::Protected: acc.prepend("#"); break;
4131 case Protection::Package: acc.prepend("~"); break;
4132 }
4133 }
4134 (*it).addAccessor(acc);
4135}
4136
4137
4139{
4140 return getCompoundTypeString(getLanguage(),m_impl->compType,isJavaEnum());
4141}
4142
4144{
4145 bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
4146 bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
4148 {
4149 Definition *scope=nullptr;
4150 if (inlineGroupedClasses && !partOfGroups().empty())
4151 {
4152 // point to the group that embeds this class
4153 return partOfGroups().front()->getOutputFileBase();
4154 }
4155 else if (inlineSimpleClasses && m_impl->isSimple && !partOfGroups().empty())
4156 {
4157 // point to simple struct inside a group
4158 return partOfGroups().front()->getOutputFileBase();
4159 }
4160 else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
4161 {
4162 if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
4163 {
4164 return getFileDef()->getOutputFileBase();
4165 }
4166 else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
4167 {
4168 return getOuterScope()->getOutputFileBase();
4169 }
4170 }
4171 }
4172 if (m_impl->templateMaster)
4173 {
4174 // point to the template of which this class is an instance
4175 return m_impl->templateMaster->getOutputFileBase();
4176 }
4177 return m_impl->fileName;
4178}
4179
4181{
4182 return m_impl->fileName;
4183}
4184
4186{
4187 if (m_impl->templateMaster)
4188 {
4189 return m_impl->templateMaster->getSourceFileBase();
4190 }
4191 else
4192 {
4194 }
4195}
4196
4197void ClassDefImpl::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
4198{
4199 gd->addClass(this);
4200 //printf("ClassDefImpl::setGroupDefForAllMembers(%s)\n",qPrint(gd->name()));
4201 for (auto &mni : m_impl->allMemberNameInfoLinkedMap)
4202 {
4203 for (auto &mi : *mni)
4204 {
4205 MemberDefMutable *md = toMemberDefMutable(mi->memberDef());
4206 if (md)
4207 {
4208 md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
4209 gd->insertMember(md,TRUE);
4210 ClassDefMutable *innerClass = toClassDefMutable(md->getClassDefOfAnonymousType());
4211 if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
4212 }
4213 }
4214 }
4215}
4216
4218{
4219 //printf("**** %s::addInnerCompound(%s)\n",qPrint(name()),qPrint(d->name()));
4220 if (d->definitionType()==Definition::TypeClass) // only classes can be
4221 // nested in classes.
4222 {
4223 m_impl->innerClasses.add(d->localName(),toClassDef(d));
4224 }
4225}
4226
4227const Definition *ClassDefImpl::findInnerCompound(const QCString &name) const
4228{
4229 return m_impl->innerClasses.find(name);
4230}
4231
4232ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName,
4233 int startLine, int startColumn, const QCString &templSpec,bool &freshInstance) const
4234{
4235 freshInstance = FALSE;
4236 auto it = std::find_if(m_impl->templateInstances.begin(),
4237 m_impl->templateInstances.end(),
4238 [&templSpec](const auto &ti) { return templSpec==ti.templSpec; });
4239 ClassDefMutable *templateClass=nullptr;
4240 if (it!=m_impl->templateInstances.end())
4241 {
4242 templateClass = toClassDefMutable((*it).classDef);
4243 }
4244 if (templateClass==nullptr)
4245 {
4246 QCString tcname = removeRedundantWhiteSpace(name()+templSpec);
4247 AUTO_TRACE("New template instance class name='{}' templSpec='{}' inside '{}' hidden={}",
4248 name(),templSpec,name(),isHidden());
4249
4250 ClassDef *foundCd = Doxygen::classLinkedMap->find(tcname);
4251 if (foundCd)
4252 {
4253 return foundCd;
4254 }
4255 templateClass =
4257 Doxygen::classLinkedMap->add(tcname,
4258 std::unique_ptr<ClassDef>(
4259 new ClassDefImpl(fileName,startLine,startColumn,tcname,ClassDef::Class))));
4260 if (templateClass)
4261 {
4262 templateClass->setTemplateMaster(this);
4263 templateClass->setOuterScope(getOuterScope());
4264 templateClass->setHidden(isHidden());
4265 templateClass->setArtificial(isArtificial());
4266 templateClass->setImplicitTemplateInstance(true);
4267 m_impl->templateInstances.emplace_back(templSpec,templateClass);
4268
4269 // also add nested classes
4270 for (const auto &innerCd : m_impl->innerClasses)
4271 {
4272 QCString innerName = tcname+"::"+innerCd->localName();
4273 ClassDefMutable *innerClass =
4275 Doxygen::classLinkedMap->add(innerName,
4276 std::unique_ptr<ClassDef>(
4277 new ClassDefImpl(fileName,startLine,startColumn,innerName,ClassDef::Class))));
4278 if (innerClass)
4279 {
4280 templateClass->addInnerCompound(innerClass);
4281 innerClass->setOuterScope(templateClass);
4282 innerClass->setHidden(isHidden());
4283 innerClass->setArtificial(TRUE);
4284 innerClass->setImplicitTemplateInstance(true);
4285 }
4286 }
4287 freshInstance=TRUE;
4288 }
4289 }
4290 return templateClass;
4291}
4292
4293void ClassDefImpl::insertExplicitTemplateInstance(ClassDef *templateClass,const QCString &templSpec)
4294{
4295 m_impl->templateInstances.emplace_back(templSpec,templateClass);
4296}
4297
4299{
4300 m_impl->templBaseClassNames = templateNames;
4301}
4302
4304{
4305 return m_impl->templBaseClassNames;
4306}
4307
4308void ClassDefImpl::addMembersToTemplateInstance(const ClassDef *cd,const ArgumentList &templateArguments,const QCString &templSpec)
4309{
4310 //printf("%s::addMembersToTemplateInstance(%s,%s)\n",qPrint(name()),qPrint(cd->name()),templSpec);
4311 for (const auto &mni : cd->memberNameInfoLinkedMap())
4312 {
4313 for (const auto &mi : *mni)
4314 {
4315 auto actualArguments_p = stringToArgumentList(getLanguage(),templSpec);
4316 MemberDef *md = mi->memberDef();
4317 auto imd = md->createTemplateInstanceMember(templateArguments,actualArguments_p);
4318 //printf("%s->setMemberClass(%p)\n",qPrint(imd->name()),this);
4319 auto mmd = toMemberDefMutable(imd.get());
4320 mmd->setMemberClass(this);
4321 mmd->setTemplateMaster(md);
4322 mmd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
4323 mmd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
4324 mmd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
4325 mmd->setMemberSpecifiers(md->getMemberSpecifiers());
4326 mmd->setMemberGroupId(md->getMemberGroupId());
4327 mmd->setArtificial(true);
4328 insertMember(imd.get());
4329 //printf("Adding member=%s %s%s to class %s templSpec %s\n",
4330 // imd->typeString(),qPrint(imd->name()),imd->argsString(),
4331 // qPrint(imd->getClassDef()->name()),templSpec);
4332 // insert imd in the list of all members
4333 //printf("Adding member=%s class=%s\n",qPrint(imd->name()),qPrint(name()));
4334 MemberName *mn = Doxygen::memberNameLinkedMap->add(imd->name());
4335 mn->push_back(std::move(imd));
4336 }
4337 }
4338 // also instantatie members for nested classes
4339 for (const auto &innerCd : cd->getClasses())
4340 {
4341 ClassDefMutable *ncd = toClassDefMutable(m_impl->innerClasses.find(innerCd->localName()));
4342 if (ncd)
4343 {
4344 ncd->addMembersToTemplateInstance(innerCd,cd->templateArguments(),templSpec);
4345 }
4346 }
4347}
4348
4350{
4351 if (m_impl->templateMaster)
4352 {
4353 return m_impl->templateMaster->getReference();
4354 }
4355 else
4356 {
4358 }
4359}
4360
4362{
4363 if (m_impl->templateMaster)
4364 {
4365 return m_impl->templateMaster->isReference();
4366 }
4367 else
4368 {
4370 }
4371}
4372
4374{
4375 ArgumentLists result;
4376 Definition *d=getOuterScope();
4377 while (d && d->definitionType()==Definition::TypeClass)
4378 {
4379 result.insert(result.begin(),toClassDef(d)->templateArguments());
4380 d = d->getOuterScope();
4381 }
4382 if (!templateArguments().empty())
4383 {
4384 result.push_back(templateArguments());
4385 }
4386 return result;
4387}
4388
4390 const ArgumentLists *actualParams,uint32_t *actualParamIndex) const
4391{
4392 return makeQualifiedNameWithTemplateParameters(this,actualParams,actualParamIndex);
4393}
4394
4396{
4397 if (m_impl->className.isEmpty())
4398 {
4399 return localName();
4400 }
4401 else
4402 {
4403 return m_impl->className;
4404 }
4405}
4406
4408{
4409 m_impl->className = name;
4410}
4411
4413{
4414 SrcLangExt lang = getLanguage();
4415 if (!isLinkableInProject()) return;
4416 //printf("ClassDef(%s)::addListReferences()\n",qPrint(name()));
4417 {
4418 const RefItemVector &xrefItems = xrefListItems();
4419 addRefItem(xrefItems,
4420 qualifiedName(),
4423 displayName(),
4424 QCString(),
4425 this
4426 );
4427 }
4428 for (const auto &mg : m_impl->memberGroups)
4429 {
4430 mg->addListReferences(this);
4431 }
4432 for (auto &ml : m_impl->memberLists)
4433 {
4434 if (ml->listType().isDetailed())
4435 {
4436 ml->addListReferences(this);
4437 }
4438 }
4439}
4440
4441const MemberDef *ClassDefImpl::getMemberByName(const QCString &name) const
4442{
4443 const MemberDef *xmd = nullptr;
4444 MemberNameInfo *mni = m_impl->allMemberNameInfoLinkedMap.find(name);
4445 if (mni)
4446 {
4447 const int maxInheritanceDepth = 100000;
4448 int mdist=maxInheritanceDepth;
4449 for (auto &mi : *mni)
4450 {
4451 const ClassDef *mcd=mi->memberDef()->getClassDef();
4452 int m=minClassDistance(this,mcd);
4453 //printf("found member in %s linkable=%d m=%d\n",
4454 // qPrint(mcd->name()),mcd->isLinkable(),m);
4455 if (m<mdist)
4456 {
4457 mdist=m;
4458 xmd=mi->memberDef();
4459 }
4460 }
4461 }
4462 //printf("getMemberByName(%s)=%p\n",qPrint(name),xmd);
4463 return xmd;
4464}
4465
4466bool ClassDefImpl::isAccessibleMember(const MemberDef *md) const
4467{
4468 return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE,QCString());
4469}
4470
4471MemberList *ClassDefImpl::getMemberList(MemberListType lt) const
4472{
4473 for (auto &ml : m_impl->memberLists)
4474 {
4475 if (ml->listType()==lt)
4476 {
4477 return ml.get();
4478 }
4479 }
4480 return nullptr;
4481}
4482
4483void ClassDefImpl::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief)
4484{
4485 AUTO_TRACE("{} md={} lt={} isBrief={}",name(),md->name(),lt,isBrief);
4486 bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
4487 bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
4488 const auto &ml = m_impl->memberLists.get(lt,MemberListContainer::Class);
4489 ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
4490 ml->push_back(md);
4491
4492 // for members in the declaration lists we set the section, needed for member grouping
4493 if (!ml->listType().isDetailed())
4494 {
4495 MemberDefMutable *mdm = toMemberDefMutable(md);
4496 if (mdm)
4497 {
4498 mdm->setSectionList(this,ml.get());
4499 }
4500 }
4501}
4502
4504{
4505 for (auto &ml : m_impl->memberLists)
4506 {
4507 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
4508 }
4509 std::stable_sort(m_impl->innerClasses.begin(),
4510 m_impl->innerClasses.end(),
4511 [](const auto &c1,const auto &c2)
4512 {
4513 return Config_getBool(SORT_BY_SCOPE_NAME) ?
4514 qstricmp_sort(c1->name(), c2->name() )<0 :
4515 qstricmp_sort(c1->className(), c2->className())<0 ;
4516 });
4517}
4518
4519int ClassDefImpl::countMemberDeclarations(MemberListType lt,const ClassDef *inheritedFrom,
4520 MemberListType lt2,bool invert,bool showAlways,ClassDefSet &visitedClasses) const
4521{
4522 //printf("%s: countMemberDeclarations for %d and %d\n",qPrint(name()),lt.to_int(),lt2.to_int());
4523 int count=0;
4524 MemberList * ml = getMemberList(lt);
4525 MemberList * ml2 = getMemberList(lt2);
4526 if (getLanguage()!=SrcLangExt::VHDL) // use specific declarations function
4527 {
4528 if (ml)
4529 {
4530 count+=ml->numDecMembers();
4531 //printf("-> ml=%d\n",ml->numDecMembers());
4532 }
4533 if (ml2)
4534 {
4535 count+=ml2->numDecMembers();
4536 //printf("-> ml2=%d\n",ml2->numDecMembers());
4537 }
4538 // also include grouped members that have their own section in the class (see bug 722759)
4539 if (inheritedFrom)
4540 {
4541 for (const auto &mg : m_impl->memberGroups)
4542 {
4543 count+=mg->countGroupedInheritedMembers(lt);
4544 if (!lt2.isInvalid()) count+=mg->countGroupedInheritedMembers(lt2);
4545 }
4546 }
4547 bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
4548 if (!inlineInheritedMembers) // show inherited members as separate lists
4549 {
4550 count+=countInheritedDecMembers(lt,inheritedFrom,invert,showAlways,visitedClasses);
4551 }
4552 }
4553 //printf("-> %d\n",count);
4554 return count;
4555}
4556
4558{
4559 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
4560 {
4561 if (lde->kind()==LayoutDocEntry::MemberDecl)
4562 {
4563 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
4564 if (lmd)
4565 {
4566 MemberList * ml = getMemberList(lmd->type);
4567 if (ml)
4568 {
4570 }
4571 }
4572 }
4573 else if (lde->kind()==LayoutDocEntry::MemberGroups)
4574 {
4575 for (const auto &mg : m_impl->memberGroups)
4576 {
4577 mg->setAnonymousEnumType();
4578 }
4579 }
4580 }
4581}
4582
4584{
4585 for (auto &ml : m_impl->memberLists)
4586 {
4587 ml->countDecMembers();
4588 ml->countDocMembers();
4589 }
4590 for (const auto &mg : m_impl->memberGroups)
4591 {
4592 mg->countDecMembers();
4593 mg->countDocMembers();
4594 }
4595}
4596
4598 const ClassDef *inheritedFrom,bool invert,bool showAlways,
4599 ClassDefSet &visitedClasses) const
4600{
4601 int inhCount = 0;
4602 int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4603 bool process = count>0;
4604 //printf("%s: countInheritedDecMembers: lt=%d process=%d count=%d invert=%d\n",
4605 // qPrint(name()),lt.to_int(),process,count,invert);
4606 if ((process^invert) || showAlways)
4607 {
4608 for (const auto &ibcd : m_impl->inherits)
4609 {
4610 ClassDefMutable *icd = toClassDefMutable(ibcd.classDef);
4611 MemberListType lt1 = MemberListType::Invalid();
4612 MemberListType lt2 = MemberListType::Invalid();
4613 if (icd && icd->isLinkable())
4614 {
4615 convertProtectionLevel(lt,ibcd.prot,&lt1,&lt2);
4616 //printf("%s: convert %d->(%d,%d) prot=%d\n",
4617 // qPrint(icd->name()),lt.to_int(),lt1.to_int(),lt2.to_int(),ibcd.prot);
4618 if (visitedClasses.find(icd)==visitedClasses.end())
4619 {
4620 visitedClasses.insert(icd); // guard for multiple virtual inheritance
4621 if (!lt1.isInvalid())
4622 {
4623 inhCount+=icd->countMemberDeclarations(lt1,inheritedFrom,lt2,FALSE,TRUE,visitedClasses);
4624 }
4625 }
4626 }
4627 }
4628 }
4629 return inhCount;
4630}
4631
4633 QCString &title,QCString &subtitle) const
4634{
4635 SrcLangExt lang = getLanguage();
4636 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
4637 {
4638 if (lde->kind()==LayoutDocEntry::MemberDecl)
4639 {
4640 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
4641 if (lmd && lmd->type==type)
4642 {
4643 title = lmd->title(lang);
4644 subtitle = lmd->subtitle(lang);
4645 return;
4646 }
4647 }
4648 }
4649 title="";
4650 subtitle="";
4651}
4652
4654{
4655 int totalCount=0;
4656 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
4657 {
4658 if (lde->kind()==LayoutDocEntry::MemberDecl)
4659 {
4660 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
4661 if (lmd && lmd->type!=MemberListType::Friends()) // friendship is not inherited
4662 {
4663 ClassDefSet visited;
4664 totalCount+=countInheritedDecMembers(lmd->type,this,TRUE,FALSE,visited);
4665 }
4666 }
4667 }
4668 //printf("countAdditionalInheritedMembers()=%d\n",totalCount);
4669 return totalCount;
4670}
4671
4673{
4674 //printf("**** writeAdditionalInheritedMembers()\n");
4675 for (const auto &lde : LayoutDocManager::instance().docEntries(LayoutDocManager::Class))
4676 {
4677 if (lde->kind()==LayoutDocEntry::MemberDecl)
4678 {
4679 const LayoutDocEntryMemberDecl *lmd = dynamic_cast<const LayoutDocEntryMemberDecl*>(lde.get());
4680 if (lmd && lmd->type!=MemberListType::Friends())
4681 {
4682 ClassDefSet visited;
4684 }
4685 }
4686 }
4687}
4688
4690 const ClassDef *inheritedFrom,bool additional) const
4691{
4692 int count=0;
4693 MemberList *ml = getMemberList(lt);
4694 if (ml)
4695 {
4696 count=ml->countInheritableMembers(inheritedFrom);
4697 }
4698 //printf("%s:countMembersIncludingGrouped: count=%d\n",qPrint(name()),count);
4699 for (const auto &mg : m_impl->memberGroups)
4700 {
4701 bool hasOwnSection = !mg->allMembersInSameSection() ||
4702 !m_impl->subGrouping; // group is in its own section
4703 if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
4704 {
4705 count+=mg->countGroupedInheritedMembers(lt);
4706 }
4707 }
4708 //printf("%s:countMembersIncludingGrouped(lt=%s,%s)=%d\n",
4709 // qPrint(name()),qPrint(lt.to_string()),ml?qPrint(ml->listType().toLabel()):"<none>",count);
4710 return count;
4711}
4712
4713
4715 MemberListType lt,MemberListType lt2,const QCString &title,
4716 const ClassDef *inheritedFrom,bool invert,bool showAlways) const
4717{
4718 int count = countMembersIncludingGrouped(lt,inheritedFrom,FALSE);
4719 bool process = count>0;
4720 //printf("%s: writeInheritedMemberDec: lt=%s process=%d invert=%d always=%d\n",
4721 // qPrint(name()),qPrint(lt.to_string()),process,invert,showAlways);
4722 if ((process^invert) || showAlways)
4723 {
4724 for (const auto &ibcd : m_impl->inherits)
4725 {
4726 ClassDefMutable *icd=toClassDefMutable(ibcd.classDef);
4727 if (icd && icd->isLinkable())
4728 {
4729 MemberListType lt1 = MemberListType::Invalid();
4730 MemberListType lt3 = MemberListType::Invalid();
4731 convertProtectionLevel(lt,ibcd.prot,&lt1,&lt3);
4732 if (lt2.isInvalid() && !lt3.isInvalid())
4733 {
4734 lt2=lt3;
4735 }
4736 //printf("%s:convert %s->(%s,%s) prot=%d\n",qPrint(icd->name()),qPrint(lt.to_string()),
4737 // qPrint(lt1.to_string()),qPrint(lt2.to_string()),ibcd.prot);
4738 if (visitedClasses.find(icd)==visitedClasses.end())
4739 {
4740 visitedClasses.insert(icd); // guard for multiple virtual inheritance
4741 if (!lt1.isInvalid())
4742 {
4743 //printf("--> writeMemberDeclarations for type %s\n",qPrint(lt1.to_string()));
4744 icd->writeMemberDeclarations(ol,visitedClasses,lt1,
4745 title,QCString(),FALSE,inheritedFrom,lt2,FALSE,TRUE);
4746 }
4747 }
4748 else
4749 {
4750 //printf("%s: class already visited!\n",qPrint(icd->name()));
4751 }
4752 }
4753 }
4754 }
4755}
4756
4757void ClassDefImpl::writeMemberDeclarations(OutputList &ol,ClassDefSet &visitedClasses,
4758 MemberListType lt,const QCString &title,
4759 const QCString &subTitle,bool showInline,const ClassDef *inheritedFrom,MemberListType lt2,
4760 bool invert,bool showAlways) const
4761{
4762 //printf("%s: ClassDefImpl::writeMemberDeclarations lt=%s lt2=%s\n",qPrint(name()),qPrint(lt.to_string()),qPrint(lt2.to_string()));
4763 MemberList * ml = getMemberList(lt);
4764 MemberList * ml2 = getMemberList(lt2);
4765 if (getLanguage()==SrcLangExt::VHDL) // use specific declarations function
4766 {
4767 static const ClassDef *cdef;
4768 if (cdef!=this)
4769 { // only one inline link
4771 cdef=this;
4772 }
4773 if (ml)
4774 {
4775 VhdlDocGen::writeVhdlDeclarations(ml,ol,nullptr,this,nullptr,nullptr,nullptr);
4776 }
4777 }
4778 else
4779 {
4780 //printf("%s::writeMemberDeclarations(%s) ml=%p ml2=%p\n",qPrint(name()),qPrint(title),ml,ml2);
4781 QCString tt = title, st = subTitle;
4782 if (ml)
4783 {
4784 //printf(" writeDeclarations type=%s count=%d\n",qPrint(lt.to_string()),ml->numDecMembers());
4785 ml->writeDeclarations(ol,this,nullptr,nullptr,nullptr,nullptr,tt,st,FALSE,showInline,inheritedFrom,lt,true);
4786 tt.clear();
4787 st.clear();
4788 }
4789 if (ml2)
4790 {
4791 //printf(" writeDeclarations type=%s count=%d\n",qPrint(lt2.to_string()),ml2->numDecMembers());
4792 ml2->writeDeclarations(ol,this,nullptr,nullptr,nullptr,nullptr,tt,st,FALSE,showInline,inheritedFrom,lt,ml==nullptr);
4793 }
4794 bool inlineInheritedMembers = Config_getBool(INLINE_INHERITED_MEMB);
4795 if (!inlineInheritedMembers) // show inherited members as separate lists
4796 {
4797 writeInheritedMemberDeclarations(ol,visitedClasses,lt,lt2,title,
4798 inheritedFrom ? inheritedFrom : this,
4799 invert,showAlways);
4800 }
4801 }
4802}
4803
4804void ClassDefImpl::addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
4805 const ClassDef *inheritedFrom,const QCString &inheritId) const
4806{
4807 //printf("** %s::addGroupedInheritedMembers() inheritId=%s\n",qPrint(name()),qPrint(inheritId));
4808 for (const auto &mg : m_impl->memberGroups)
4809 {
4810 if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
4811 {
4812 mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
4813 }
4814 }
4815}
4816
4817void ClassDefImpl::writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title,bool showInline) const
4818{
4819 //printf("%s: ClassDefImpl::writeMemberDocumentation()\n",qPrint(name()));
4820 MemberList * ml = getMemberList(lt);
4821 if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline);
4822}
4823
4824void ClassDefImpl::writeSimpleMemberDocumentation(OutputList &ol,MemberListType lt) const
4825{
4826 //printf("%s: ClassDefImpl::writeSimpleMemberDocumentation()\n",qPrint(name()));
4827 MemberList * ml = getMemberList(lt);
4828 if (ml) ml->writeSimpleDocumentation(ol,this);
4829}
4830
4832 MemberListType lt,bool inGroup,
4833 int indentLevel,const ClassDef *inheritedFrom,const QCString &inheritId) const
4834{
4835 //printf("%s: ClassDefImpl::writePlainMemberDeclaration()\n",qPrint(name()));
4836 MemberList * ml = getMemberList(lt);
4837 if (ml)
4838 {
4839 ml->writePlainDeclarations(ol,inGroup,this,nullptr,nullptr,nullptr,nullptr,indentLevel,inheritedFrom,inheritId);
4840 }
4841}
4842
4844{
4845 return m_impl->isLocal;
4846}
4847
4848ClassLinkedRefMap ClassDefImpl::getClasses() const
4849{
4850 return m_impl->innerClasses;
4851}
4852
4854{
4855 return m_impl->compType;
4856}
4857
4859{
4860 return m_impl->inherits;
4861}
4862
4864{
4865 m_impl->inherits = bcd;
4866}
4867
4869{
4870 return m_impl->inheritedBy;
4871}
4872
4874{
4875 m_impl->inheritedBy = bcd;
4876}
4877
4878const MemberNameInfoLinkedMap &ClassDefImpl::memberNameInfoLinkedMap() const
4879{
4880 return m_impl->allMemberNameInfoLinkedMap;
4881}
4882
4884{
4885 std::stable_sort(m_impl->allMemberNameInfoLinkedMap.begin(),
4886 m_impl->allMemberNameInfoLinkedMap.end(),
4887 [](const auto &m1,const auto &m2)
4888 {
4889 return qstricmp_sort(m1->memberName(),m2->memberName())<0;
4890 });
4891}
4892
4894{
4895 return m_impl->prot;
4896}
4897
4898const ArgumentList &ClassDefImpl::templateArguments() const
4899{
4900 return m_impl->tempArgs;
4901}
4902
4904{
4905 return m_impl->fileDef;
4906}
4907
4909{
4910 return m_impl->moduleDef;
4911}
4912
4914{
4915 return m_impl->templateInstances;
4916}
4917
4918const ClassDef *ClassDefImpl::templateMaster() const
4919{
4920 return m_impl->templateMaster;
4921}
4922
4924{
4925 return m_impl->implicitTemplateInstance;
4926}
4927
4929{
4930 m_impl->implicitTemplateInstance = b;
4931}
4932
4934{
4935 return !m_impl->tempArgs.empty();
4936}
4937
4938const IncludeInfo *ClassDefImpl::includeInfo() const
4939{
4940 return m_impl->incInfo.get();
4941}
4942
4944{
4945 return m_impl->usesImplClassList;
4946}
4947
4949{
4950 return m_impl->usedByImplClassList;
4951}
4952
4953const ConstraintClassList &ClassDefImpl::templateTypeConstraints() const
4954{
4955 return m_impl->constraintClassList;
4956}
4957
4959{
4960 return m_impl->isTemplArg;
4961}
4962
4964{
4965 return m_impl->isAbstract || m_impl->spec.isAbstract();
4966}
4967
4969{
4970 return m_impl->spec.isFinal();
4971}
4972
4974{
4975 return m_impl->spec.isSealed();
4976}
4977
4979{
4980 return m_impl->spec.isPublished();
4981}
4982
4984{
4985 return m_impl->spec.isForwardDecl();
4986}
4987
4989{
4990 return m_impl->spec.isInterface();
4991}
4992
4994{
4995 return getLanguage()==SrcLangExt::ObjC;
4996}
4997
4999{
5001}
5002
5004{
5006}
5007
5009{
5010 return m_impl->categoryOf;
5011}
5012
5013const MemberLists &ClassDefImpl::getMemberLists() const
5014{
5015 return m_impl->memberLists;
5016}
5017
5018const MemberGroupList &ClassDefImpl::getMemberGroups() const
5019{
5020 return m_impl->memberGroups;
5021}
5022
5024{
5025 m_impl->fileDef = fd;
5026}
5027
5028void ClassDefImpl::setModuleDef(ModuleDef *mod)
5029{
5030 m_impl->moduleDef = mod;
5031}
5032
5034{
5035 m_impl->subGrouping = enabled;
5036}
5037
5039{
5040 m_impl->prot=p;
5042 {
5043 m_impl->className = name();
5044 }
5045}
5046
5048{
5049 m_impl->isStatic=b;
5050}
5051
5053{
5054 m_impl->compType = t;
5055}
5056
5057void ClassDefImpl::setTemplateMaster(const ClassDef *tm)
5058{
5059 assert(tm!=this);
5060 m_impl->templateMaster=tm;
5061}
5062
5064{
5065 m_impl->isTemplArg = b;
5066}
5067
5069{
5070 m_impl->categoryOf = cd;
5071}
5072
5074{
5075 m_impl->usedOnly = b;
5076}
5077
5079{
5080 return m_impl->usedOnly;
5081}
5082
5084{
5085 return m_impl->isSimple;
5086}
5087
5088const MemberDef *ClassDefImpl::isSmartPointer() const
5089{
5090 return m_impl->arrowOperator;
5091}
5092
5093void ClassDefImpl::reclassifyMember(MemberDefMutable *md,MemberType t)
5094{
5095 md->setMemberType(t);
5096 for (auto &ml : m_impl->memberLists)
5097 {
5098 ml->remove(md);
5099 }
5100 insertMember(md);
5101}
5102
5103QCString ClassDefImpl::anchor() const
5104{
5105 QCString anc;
5107 {
5108 if (m_impl->templateMaster)
5109 {
5110 // point to the template of which this class is an instance
5111 anc = m_impl->templateMaster->getOutputFileBase();
5112 }
5113 else
5114 {
5115 anc = m_impl->fileName;
5116 }
5117 }
5118 return anc;
5119}
5120
5122{
5123 bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
5124 bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
5125
5126 Definition *container = getOuterScope();
5127
5128 bool containerLinkable =
5129 container &&
5130 (
5131 (container==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) || // global class in documented file
5132 container->isLinkableInProject() // class in documented scope
5133 );
5134
5135 // inline because of INLINE_GROUPED_CLASSES=YES ?
5136 bool b1 = (inlineGroupedClasses && !partOfGroups().empty()); // a grouped class
5137 // inline because of INLINE_SIMPLE_STRUCTS=YES ?
5138 bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
5139 (containerLinkable || // in a documented container
5140 !partOfGroups().empty() // or part of a group
5141 )
5142 );
5143 //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
5144 // "inlineSimpleClasses=%d partOfGroups()=%p m_impl->isSimple=%d "
5145 // "getOuterScope()=%s b1=%d b2=%d\n",
5146 // qPrint(name()),inlineGroupedClasses,inlineSimpleClasses,
5147 // partOfGroups().pointer(),m_impl->isSimple,getOuterScope()?qPrint(getOuterScope()->name()):"<none>",b1,b2);
5148 return b1 || b2; // either reason will do
5149}
5150
5151const ClassDef *ClassDefImpl::tagLessReference() const
5152{
5153 return m_impl->tagLessRef;
5154}
5155
5157{
5158 m_impl->tagLessRef = cd;
5159}
5160
5162{
5163 for (auto &ml : m_impl->memberLists)
5164 {
5165 ml->remove(md);
5166 }
5167}
5168
5170{
5171 return m_impl->isJavaEnum;
5172}
5173
5174void ClassDefImpl::setClassSpecifier(TypeSpecifier spec)
5175{
5176 m_impl->spec = spec;
5177}
5178
5180{
5181 for (const auto &sx : qualifiers)
5182 {
5183 bool alreadyAdded = std::find(m_impl->qualifiers.begin(), m_impl->qualifiers.end(), sx) != m_impl->qualifiers.end();
5184 if (!alreadyAdded)
5185 {
5186 m_impl->qualifiers.push_back(sx);
5187 }
5188 }
5189}
5190
5192{
5193 return m_impl->qualifiers;
5194}
5195
5196bool ClassDefImpl::containsOverload(const MemberDef *md) const
5197{
5198 AUTO_TRACE("name={}",md->name());
5199 const auto &mni = m_impl->allMemberNameInfoLinkedMap.find(md->name());
5200 if (mni)
5201 {
5202 for (const auto &mi : *mni)
5203 {
5204 const MemberDef *classMd = mi->memberDef();
5205 const ArgumentList &classAl = classMd->argumentList();
5206 const ArgumentList &al = md->argumentList();
5207 bool found = matchArguments2(
5208 classMd->getOuterScope(),classMd->getFileDef(),&classAl,
5209 md->getOuterScope(),md->getFileDef(),&al,
5210 true,getLanguage()
5211 );
5212 if (found)
5213 {
5214 AUTO_TRACE_EXIT("true");
5215 return true;
5216 }
5217 }
5218 }
5219 AUTO_TRACE_EXIT("false");
5220 return false;
5221}
5222
5224{
5225 QCString n = name();
5226 int si = n.find('(');
5227 int ei = n.find(')');
5228 bool b = ei>si && n.mid(si+1,ei-si-1).stripWhiteSpace().isEmpty();
5229 return b;
5230}
5231
5232const FileList &ClassDefImpl::usedFiles() const
5233{
5234 return m_impl->files;
5235}
5236
5237const ArgumentList &ClassDefImpl::typeConstraints() const
5238{
5239 return m_impl->typeConstraints;
5240}
5241
5242const ExampleList &ClassDefImpl::getExamples() const
5243{
5244 return m_impl->examples;
5245}
5246
5248{
5249 return m_impl->subGrouping;
5250}
5251
5253{
5254 return m_impl->spec.isLocal();
5255}
5256
5257void ClassDefImpl::setMetaData(const QCString &md)
5258{
5259 m_impl->metaData = md;
5260}
5261
5263{
5264 return m_impl->collabFileName;
5265}
5266
5268{
5269 return m_impl->inheritFileName;
5270}
5271
5273{
5274 m_impl->typeInheritanceGraph=e;
5275}
5276
5278{
5279 return m_impl->typeInheritanceGraph;
5280}
5281
5283{
5284 switch (compoundType())
5285 {
5286 case Class: return CodeSymbolType::Class; break;
5287 case Struct: return CodeSymbolType::Struct; break;
5288 case Union: return CodeSymbolType::Union; break;
5289 case Interface: return CodeSymbolType::Interface; break;
5290 case Protocol: return CodeSymbolType::Protocol; break;
5291 case Category: return CodeSymbolType::Category; break;
5292 case Exception: return CodeSymbolType::Exception; break;
5293 case Service: return CodeSymbolType::Service; break;
5294 case Singleton: return CodeSymbolType::Singleton; break;
5295 }
5296 return CodeSymbolType::Class;
5297}
5298
5300{
5301 m_impl->hasCollaborationGraph=e;
5302}
5303
5305{
5306 return m_impl->hasCollaborationGraph;
5307}
5308
5309
5310// --- Cast functions
5311//
5312ClassDef *toClassDef(Definition *d)
5313{
5314 if (d && (typeid(*d)==typeid(ClassDefImpl) || typeid(*d)==typeid(ClassDefAliasImpl)))
5315 {
5316 return static_cast<ClassDef*>(d);
5317 }
5318 else
5319 {
5320 return nullptr;
5321 }
5322}
5323
5324ClassDef *toClassDef(DefinitionMutable *md)
5325{
5326 Definition *d = toDefinition(md);
5327 if (d && typeid(*d)==typeid(ClassDefImpl))
5328 {
5329 return static_cast<ClassDef*>(d);
5330 }
5331 else
5332 {
5333 return nullptr;
5334 }
5335}
5336
5337const ClassDef *toClassDef(const Definition *d)
5338{
5339 if (d && (typeid(*d)==typeid(ClassDefImpl) || typeid(*d)==typeid(ClassDefAliasImpl)))
5340 {
5341 return static_cast<const ClassDef*>(d);
5342 }
5343 else
5344 {
5345 return nullptr;
5346 }
5347}
5348
5349ClassDefMutable *toClassDefMutable(Definition *d)
5350{
5351 if (d && typeid(*d)==typeid(ClassDefImpl))
5352 {
5353 return static_cast<ClassDefMutable*>(d);
5354 }
5355 else
5356 {
5357 return nullptr;
5358 }
5359}
5360
5361// --- Helpers
5362
5363/*! Get a class definition given its name.
5364 * Returns nullptr if the class is not found.
5365 */
5366ClassDef *getClass(const QCString &n)
5367{
5368 if (n.isEmpty()) return nullptr;
5369 return Doxygen::classLinkedMap->find(n);
5370}
5371
5373{
5374 for (const auto &bcd : bcl)
5375 {
5376 const ClassDef *cd=bcd.classDef;
5377 if (cd->isVisibleInHierarchy()) return true;
5378 if (classHasVisibleRoot(cd->baseClasses())) return true;
5379 }
5380 return false;
5381}
5382
5383bool classHasVisibleChildren(const ClassDef *cd)
5384{
5385 BaseClassList bcl;
5386
5387 if (cd->getLanguage()==SrcLangExt::VHDL) // reverse baseClass/subClass relation
5388 {
5389 if (cd->baseClasses().empty()) return FALSE;
5390 bcl=cd->baseClasses();
5391 }
5392 else
5393 {
5394 if (cd->subClasses().empty()) return FALSE;
5395 bcl=cd->subClasses();
5396 }
5397
5398 for (const auto &bcd : bcl)
5399 {
5400 if (bcd.classDef->isVisibleInHierarchy())
5401 {
5402 return TRUE;
5403 }
5404 }
5405 return FALSE;
5406}
5407
5408bool classVisibleInIndex(const ClassDef *cd)
5409{
5410 bool allExternals = Config_getBool(ALLEXTERNALS);
5411 return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
5412}
5413
5414//----------------------------------------------------------------------
5415// recursive function that returns the number of branches in the
5416// inheritance tree that the base class 'bcd' is below the class 'cd'
5417
5418int minClassDistance(const ClassDef *cd,const ClassDef *bcd,int level)
5419{
5420 const int maxInheritanceDepth = 100000;
5421 if (bcd->categoryOf()) // use class that is being extended in case of
5422 // an Objective-C category
5423 {
5424 bcd=bcd->categoryOf();
5425 }
5426 if (cd==bcd) return level;
5427 if (level==256)
5428 {
5429 warn_uncond("class %s seem to have a recursive "
5430 "inheritance relation!\n",qPrint(cd->name()));
5431 return -1;
5432 }
5433 int m=maxInheritanceDepth;
5434 for (const auto &bcdi : cd->baseClasses())
5435 {
5436 int mc=minClassDistance(bcdi.classDef,bcd,level+1);
5437 if (mc<m) m=mc;
5438 if (m<0) break;
5439 }
5440 return m;
5441}
5442
5443Protection classInheritedProtectionLevel(const ClassDef *cd,const ClassDef *bcd,Protection prot,int level)
5444{
5445 if (bcd->categoryOf()) // use class that is being extended in case of
5446 // an Objective-C category
5447 {
5448 bcd=bcd->categoryOf();
5449 }
5450 if (cd==bcd)
5451 {
5452 goto exit;
5453 }
5454 if (level==256)
5455 {
5456 err("Internal inconsistency: found class %s seem to have a recursive "
5457 "inheritance relation! Please send a bug report to doxygen@gmail.com\n",qPrint(cd->name()));
5458 }
5459 else if (prot!=Protection::Private)
5460 {
5461 for (const auto &bcdi : cd->baseClasses())
5462 {
5463 Protection baseProt = classInheritedProtectionLevel(bcdi.classDef,bcd,bcdi.prot,level+1);
5464 if (baseProt==Protection::Private) prot=Protection::Private;
5465 else if (baseProt==Protection::Protected) prot=Protection::Protected;
5466 }
5467 }
5468exit:
5469 //printf("classInheritedProtectionLevel(%s,%s)=%d\n",qPrint(cd->name()),qPrint(bcd->name()),prot);
5470 return prot;
5471}
5472
5473
constexpr auto prefix
Definition anchor.cpp:44
std::vector< ArgumentList > ArgumentLists
Definition arguments.h:138
This class represents an function or template argument list.
Definition arguments.h:60
bool empty() const
Definition arguments.h:92
Argument & at(size_t i)
Definition arguments.h:100
bool isSimple() const override
Definition classdef.cpp:559
bool isFortran() const override
Returns TRUE if this class is implemented in Fortran.
Definition classdef.cpp:525
QCString requiresClause() const override
Definition classdef.cpp:587
void writeTagFile(TextStream &ol) const override
Definition classdef.cpp:626
int countMemberDeclarations(MemberListType lt, const ClassDef *inheritedFrom, MemberListType lt2, bool invert, bool showAlways, ClassDefSet &visitedClasses) const override
Definition classdef.cpp:596
bool isSubClass(ClassDef *bcd, int level=0) const override
Returns TRUE iff bcd is a direct or indirect sub class of this class.
Definition classdef.cpp:494
ClassDef * insertTemplateInstance(const QCString &fileName, int startLine, int startColumn, const QCString &templSpec, bool &freshInstance) const override
Definition classdef.cpp:603
const UsesClassList & usedByImplementationClasses() const override
Definition classdef.cpp:508
bool hasDetailedDescription() const override
returns TRUE if this class has a non-empty detailed description
Definition classdef.cpp:456
ModuleDef * getModuleDef() const override
Returns the C++20 module in which this compound's definition can be found.
Definition classdef.cpp:488
void writeDocumentation(OutputList &ol) const override
Definition classdef.cpp:609
const UsesClassList & usedImplementationClasses() const override
Definition classdef.cpp:506
StringVector getQualifiers() const override
Definition classdef.cpp:589
void writeSummaryLinks(OutputList &ol) const override
Definition classdef.cpp:622
bool isVisibleInHierarchy() const override
the class is visible in a class diagram, or class hierarchy
Definition classdef.cpp:480
QCString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const override
Definition classdef.cpp:518
bool isPublished() const override
Returns TRUE if this class is marked as published.
Definition classdef.cpp:533
const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const override
Returns a dictionary of all members.
Definition classdef.cpp:472
QCString anchor() const override
Definition classdef.cpp:555
QCString title() const override
Definition classdef.cpp:567
bool isImplicitTemplateInstance() const override
Definition classdef.cpp:606
const FileList & usedFiles() const override
Definition classdef.cpp:571
CodeSymbolType codeSymbolType() const override
Definition classdef.cpp:438
bool isFinal() const override
Returns TRUE if this class is marked as final.
Definition classdef.cpp:529
const ExampleList & getExamples() const override
Definition classdef.cpp:575
void moveTo(Definition *) override
Definition classdef.cpp:436
bool isReference() const override
Definition classdef.cpp:448
bool isTemplateArgument() const override
Definition classdef.cpp:512
void updateSubClasses(const BaseClassList &) override
Update the list of sub classes to the one passed.
Definition classdef.cpp:639
bool isForwardDeclared() const override
Returns TRUE if this class represents a forward declaration of a template class.
Definition classdef.cpp:537
const ArgumentList & typeConstraints() const override
Definition classdef.cpp:573
const IncludeInfo * includeInfo() const override
Definition classdef.cpp:504
bool isAccessibleMember(const MemberDef *md) const override
returns TRUE iff md is a member of this class or of the the public/protected members of a base class
Definition classdef.cpp:496
QCString getSourceFileBase() const override
Definition classdef.cpp:444
void writeMemberPages(OutputList &ol) const override
Definition classdef.cpp:613
ClassDefAliasImpl(const Definition *newScope, const ClassDef *cd)
Definition classdef.cpp:425
void writeDeclaration(OutputList &ol, const MemberDef *md, bool inGroup, int indentLevel, const ClassDef *inheritedFrom, const QCString &inheritId) const override
Definition classdef.cpp:617
void writeQuickMemberLinks(OutputList &ol, const MemberDef *md) const override
Definition classdef.cpp:620
void updateBaseClasses(const BaseClassList &) override
Update the list of base classes to the one passed.
Definition classdef.cpp:638
bool containsOverload(const MemberDef *md) const override
Definition classdef.cpp:591
bool subGrouping() const override
Definition classdef.cpp:581
const ArgumentList & templateArguments() const override
Returns the template arguments of this class.
Definition classdef.cpp:484
Protection protection() const override
Return the protection level (Public,Protected,Private) in which this compound was found.
Definition classdef.cpp:474
bool isCSharp() const override
Returns TRUE if this class is implemented in C#.
Definition classdef.cpp:527
const MemberGroupList & getMemberGroups() const override
Returns the member groups defined for this class.
Definition classdef.cpp:549
bool isEmbeddedInOuterScope() const override
Definition classdef.cpp:557
QCString getReference() const override
Definition classdef.cpp:446
int isBaseClass(const ClassDef *bcd, bool followInstances, const QCString &templSpec) const override
Returns TRUE iff bcd is a direct or indirect base class of this class.
Definition classdef.cpp:492
int countMembersIncludingGrouped(MemberListType lt, const ClassDef *inheritedFrom, bool additional) const override
Definition classdef.cpp:594
void addGroupedInheritedMembers(OutputList &ol, MemberListType lt, const ClassDef *inheritedFrom, const QCString &inheritId) const override
Definition classdef.cpp:634
bool isSealed() const override
Returns TRUE if this class is marked as sealed.
Definition classdef.cpp:531
bool hasDocumentation() const override
Definition classdef.cpp:454
FileDef * getFileDef() const override
Returns the namespace this compound is in, or 0 if it has a global scope.
Definition classdef.cpp:486
ArgumentLists getTemplateParameterLists() const override
Returns the template parameter lists that form the template declaration of this class.
Definition classdef.cpp:516
QCString getMemberListFileName() const override
Definition classdef.cpp:579
bool hasNonReferenceSuperClass() const override
Definition classdef.cpp:585
void writeInlineDocumentation(OutputList &ol) const override
Definition classdef.cpp:624
const BaseClassList & subClasses() const override
Returns the list of sub classes that directly derive from this class.
Definition classdef.cpp:470
bool isJavaEnum() const override
Definition classdef.cpp:565
QCString inheritanceGraphFileName() const override
returns the file name to use for the inheritance graph
Definition classdef.cpp:460
~ClassDefAliasImpl() override
Definition classdef.cpp:427
const TemplateInstanceList & getTemplateInstances() const override
Returns a sorted dictionary with all template instances found for this template class.
Definition classdef.cpp:498
QCString compoundTypeString() const override
Returns the type of compound as a string.
Definition classdef.cpp:466
bool isLinkableInProject() const override
Definition classdef.cpp:476
QCString displayName(bool includeScope=TRUE) const override
Definition classdef.cpp:462
QCString className() const override
Returns the name of the class including outer classes, but not including namespaces.
Definition classdef.cpp:543
bool isLocal() const override
Returns TRUE if this is a local class definition, see EXTRACT_LOCAL_CLASSES.
Definition classdef.cpp:450
QCString getInstanceOutputFileBase() const override
Definition classdef.cpp:442
void writeDocumentationForInnerClasses(OutputList &ol) const override
Definition classdef.cpp:611
const MemberLists & getMemberLists() const override
Returns the list containing the list of members sorted per type.
Definition classdef.cpp:547
MemberList * getMemberList(MemberListType lt) const override
Returns the members in the list identified by lt.
Definition classdef.cpp:545
ClassDef * categoryOf() const override
Returns the class of which this is a category (Objective-C only)
Definition classdef.cpp:541
const ClassDef * getCdAlias() const
Definition classdef.cpp:432
QCString collaborationGraphFileName() const override
returns the file name to use for the collaboration graph
Definition classdef.cpp:458
void writeMemberDeclarations(OutputList &ol, ClassDefSet &visitedClasses, MemberListType lt, const QCString &title, const QCString &subTitle=QCString(), bool showInline=FALSE, const ClassDef *inheritedFrom=nullptr, MemberListType lt2=MemberListType::Invalid(), bool invert=FALSE, bool showAlways=FALSE) const override
Definition classdef.cpp:628
QCString getOutputFileBase() const override
Definition classdef.cpp:440
CompoundType compoundType() const override
Returns the type of compound this is, i.e.
Definition classdef.cpp:464
const TemplateNameMap & getTemplateBaseClassNames() const override
Definition classdef.cpp:551
void writeDeclarationLink(OutputList &ol, bool &found, const QCString &header, bool localNames) const override
Definition classdef.cpp:600
const Definition * findInnerCompound(const QCString &name) const override
Definition classdef.cpp:514
DefType definitionType() const override
Definition classdef.cpp:430
QCString generatedFromFiles() const override
Definition classdef.cpp:569
bool isLinkable() const override
Definition classdef.cpp:478
const BaseClassList & baseClasses() const override
Returns the list of base classes from which this class directly inherits.
Definition classdef.cpp:468
const ClassDef * tagLessReference() const override
Definition classdef.cpp:561
bool isExtension() const override
Returns TRUE if this class represents an Objective-C 2.0 extension (nameless category)
Definition classdef.cpp:535
ClassLinkedRefMap getClasses() const override
returns the classes nested into this class
Definition classdef.cpp:452
const ConstraintClassList & templateTypeConstraints() const override
Definition classdef.cpp:510
bool isInterface() const override
Returns TRUE if this class represents an interface.
Definition classdef.cpp:539
std::unique_ptr< ClassDef > deepCopy(const QCString &name) const override
Definition classdef.cpp:433
bool isAbstract() const override
Returns TRUE if there is at least one pure virtual member in this class.
Definition classdef.cpp:521
bool hasExamples() const override
Definition classdef.cpp:577
bool visibleInParentsDeclList() const override
show this class in the declaration section of its parent?
Definition classdef.cpp:482
const MemberDef * getMemberByName(const QCString &s) const override
Returns the member with the given name.
Definition classdef.cpp:490
const ClassDef * templateMaster() const override
Returns the template master of which this class is an instance.
Definition classdef.cpp:500
bool isTemplate() const override
Returns TRUE if this class is a template.
Definition classdef.cpp:502
bool isSliceLocal() const override
Definition classdef.cpp:583
bool isUsedOnly() const override
Definition classdef.cpp:553
const MemberDef * isSmartPointer() const override
Definition classdef.cpp:563
bool isObjectiveC() const override
Returns TRUE if this class is implemented in Objective-C.
Definition classdef.cpp:523
void writeMemberList(OutputList &ol) const override
Definition classdef.cpp:615
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual int countMemberDeclarations(MemberListType lt, const ClassDef *inheritedFrom, MemberListType lt2, bool invert, bool showAlways, ClassDefSet &visitedClasses) const =0
virtual bool isSliceLocal() const =0
virtual ModuleDef * getModuleDef() const =0
Returns the C++20 module in which this compound's definition can be found.
virtual bool isAbstract() const =0
Returns TRUE if there is at least one pure virtual member in this class.
virtual bool isFinal() const =0
Returns TRUE if this class is marked as final.
virtual bool visibleInParentsDeclList() const =0
show this class in the declaration section of its parent?
virtual bool subGrouping() const =0
virtual void writeSummaryLinks(OutputList &ol) const =0
virtual bool hasDetailedDescription() const =0
returns TRUE if this class has a non-empty detailed description
virtual const ArgumentList & templateArguments() const =0
Returns the template arguments of this class.
virtual void writeMemberPages(OutputList &ol) const =0
virtual QCString compoundTypeString() const =0
Returns the type of compound as a string.
virtual bool isFortran() const =0
Returns TRUE if this class is implemented in Fortran.
virtual void writeDocumentation(OutputList &ol) const =0
virtual const MemberLists & getMemberLists() const =0
Returns the list containing the list of members sorted per type.
virtual QCString className() const =0
Returns the name of the class including outer classes, but not including namespaces.
virtual void writeMemberList(OutputList &ol) const =0
virtual bool isVisibleInHierarchy() const =0
the class is visible in a class diagram, or class hierarchy
virtual bool isTemplate() const =0
Returns TRUE if this class is a template.
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual bool isSealed() const =0
Returns TRUE if this class is marked as sealed.
virtual const MemberDef * getMemberByName(const QCString &) const =0
Returns the member with the given name.
virtual const TemplateInstanceList & getTemplateInstances() const =0
Returns a sorted dictionary with all template instances found for this template class.
virtual int isBaseClass(const ClassDef *bcd, bool followInstances, const QCString &templSpec=QCString()) const =0
Returns TRUE iff bcd is a direct or indirect base class of this class.
virtual ArgumentLists getTemplateParameterLists() const =0
Returns the template parameter lists that form the template declaration of this class.
virtual const UsesClassList & usedImplementationClasses() const =0
virtual bool isObjectiveC() const =0
Returns TRUE if this class is implemented in Objective-C.
virtual bool hasExamples() const =0
virtual QCString inheritanceGraphFileName() const =0
returns the file name to use for the inheritance graph
virtual StringVector getQualifiers() const =0
virtual bool isLocal() const =0
Returns TRUE if this is a local class definition, see EXTRACT_LOCAL_CLASSES.
virtual void writeQuickMemberLinks(OutputList &ol, const MemberDef *md) const =0
virtual bool isSimple() const =0
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
virtual const ClassDef * tagLessReference() const =0
virtual MemberList * getMemberList(MemberListType lt) const =0
Returns the members in the list identified by lt.
virtual ClassDef * categoryOf() const =0
Returns the class of which this is a category (Objective-C only)
virtual QCString getInstanceOutputFileBase() const =0
virtual const MemberDef * isSmartPointer() const =0
virtual bool isExtension() const =0
Returns TRUE if this class represents an Objective-C 2.0 extension (nameless category)
virtual bool hasNonReferenceSuperClass() const =0
virtual bool isCSharp() const =0
Returns TRUE if this class is implemented in C#.
virtual bool isForwardDeclared() const =0
Returns TRUE if this class represents a forward declaration of a template class.
virtual QCString generatedFromFiles() const =0
virtual const ExampleList & getExamples() const =0
virtual bool isJavaEnum() const =0
virtual bool isSubClass(ClassDef *bcd, int level=0) const =0
Returns TRUE iff bcd is a direct or indirect sub class of this class.
virtual ClassDef * insertTemplateInstance(const QCString &fileName, int startLine, int startColumn, const QCString &templSpec, bool &freshInstance) const =0
virtual bool isTemplateArgument() const =0
virtual int countMembersIncludingGrouped(MemberListType lt, const ClassDef *inheritedFrom, bool additional) const =0
virtual const ArgumentList & typeConstraints() const =0
virtual bool isAccessibleMember(const MemberDef *md) const =0
returns TRUE iff md is a member of this class or of the the public/protected members of a base class
virtual QCString collaborationGraphFileName() const =0
returns the file name to use for the collaboration graph
virtual const TemplateNameMap & getTemplateBaseClassNames() const =0
virtual bool isPublished() const =0
Returns TRUE if this class is marked as published.
virtual const FileList & usedFiles() const =0
virtual void writeMemberDeclarations(OutputList &ol, ClassDefSet &visitedClasses, MemberListType lt, const QCString &title, const QCString &subTitle=QCString(), bool showInline=FALSE, const ClassDef *inheritedFrom=nullptr, MemberListType lt2=MemberListType::Invalid(), bool invert=FALSE, bool showAlways=FALSE) const =0
virtual QCString getMemberListFileName() const =0
virtual bool isEmbeddedInOuterScope() const =0
virtual void addGroupedInheritedMembers(OutputList &ol, MemberListType lt, const ClassDef *inheritedFrom, const QCString &inheritId) const =0
virtual const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const =0
Returns a dictionary of all members.
virtual void writeDeclarationLink(OutputList &ol, bool &found, const QCString &header, bool localNames) const =0
virtual const ConstraintClassList & templateTypeConstraints() const =0
virtual void writeDeclaration(OutputList &ol, const MemberDef *md, bool inGroup, int indentLevel, const ClassDef *inheritedFrom, const QCString &inheritId) const =0
virtual bool isImplicitTemplateInstance() const =0
virtual QCString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const =0
virtual const MemberGroupList & getMemberGroups() const =0
Returns the member groups defined for this class.
virtual const UsesClassList & usedByImplementationClasses() const =0
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
CompoundType
The various compound types.
Definition classdef.h:109
@ Singleton
Definition classdef.h:117
@ Interface
Definition classdef.h:112
@ Exception
Definition classdef.h:115
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
virtual bool containsOverload(const MemberDef *md) const =0
virtual ClassLinkedRefMap getClasses() const =0
returns the classes nested into this class
virtual bool isInterface() const =0
Returns TRUE if this class represents an interface.
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual const IncludeInfo * includeInfo() const =0
virtual QCString requiresClause() const =0
virtual void writeInlineDocumentation(OutputList &ol) const =0
virtual void writeTagFile(TextStream &) const =0
virtual QCString title() const =0
virtual void writeDocumentationForInnerClasses(OutputList &ol) const =0
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class.
virtual bool isUsedOnly() const =0
Private data associated with a ClassDef object.
Definition classdef.cpp:655
ModuleDef * moduleDef
Definition classdef.cpp:699
const MemberDef * arrowOperator
Does this class overloaded the -> operator?
Definition classdef.cpp:789
QCString collabFileName
Definition classdef.cpp:671
BaseClassList inheritedBy
Definition classdef.cpp:688
void init(const QCString &defFileName, const QCString &name, const QCString &ctStr, const QCString &fName)
Definition classdef.cpp:811
ClassLinkedRefMap innerClasses
Definition classdef.cpp:728
UsesClassList usesImplClassList
Definition classdef.cpp:731
ArgumentList tempArgs
Definition classdef.cpp:705
bool usedOnly
Reason of existence is a "use" relation.
Definition classdef.cpp:780
TemplateInstanceList templateInstances
Definition classdef.cpp:739
TemplateNameMap templBaseClassNames
Definition classdef.cpp:741
ExampleList examples
Definition classdef.cpp:714
QCString requiresClause
C++20 requires clause.
Definition classdef.cpp:801
CLASS_GRAPH_t typeInheritanceGraph
Definition classdef.cpp:806
ConstraintClassList constraintClassList
Definition classdef.cpp:734
ClassDef * categoryOf
Definition classdef.cpp:752
UsesClassList usedByImplClassList
Definition classdef.cpp:732
BaseClassList inherits
Definition classdef.cpp:684
bool isJavaEnum
Does this class represent a Java style enum?
Definition classdef.cpp:794
ArgumentList typeConstraints
Definition classdef.cpp:708
TypeSpecifier spec
Definition classdef.cpp:796
StringSet vhdlSummaryTitles
List of titles to use for the summary.
Definition classdef.cpp:783
std::unique_ptr< IncludeInfo > incInfo
Definition classdef.cpp:679
MemberLists memberLists
Definition classdef.cpp:754
bool implicitTemplateInstance
Definition classdef.cpp:808
ClassDef::CompoundType compType
Definition classdef.cpp:717
MemberGroupList memberGroups
Definition classdef.cpp:757
const ClassDef * tagLessRef
Definition classdef.cpp:791
StringVector qualifiers
Definition classdef.cpp:803
QCString inheritFileName
Definition classdef.cpp:674
MemberNameInfoLinkedMap allMemberNameInfoLinkedMap
Definition classdef.cpp:702
std::unique_ptr< ClassDefImpl::IMPL > deepCopy() const
Definition classdef.cpp:881
const ClassDef * templateMaster
Definition classdef.cpp:744
QCString memberListFileName
Definition classdef.cpp:668
bool isSimple
Is this a simple (non-nested) C structure?
Definition classdef.cpp:786
bool isSubClass(ClassDef *bcd, int level=0) const override
Returns TRUE iff bcd is a direct or indirect sub class of this class.
bool addExample(const QCString &anchor, const QCString &name, const QCString &file) override
QCString getReference() const override
QCString getInstanceOutputFileBase() const override
void writeIncludeFilesForSlice(OutputList &ol) const
void overrideInheritanceGraph(CLASS_GRAPH_t e) override
std::unique_ptr< IMPL > m_impl
Definition classdef.cpp:409
ClassLinkedRefMap getClasses() const override
returns the classes nested into this class
void addMembersToMemberGroup() override
bool subGrouping() const override
void setMetaData(const QCString &md) override
void distributeMemberGroupDocumentation() override
void addMemberToList(MemberListType lt, MemberDef *md, bool isBrief)
bool isObjectiveC() const override
Returns TRUE if this class is implemented in Objective-C.
QCString compoundTypeString() const override
Returns the type of compound as a string.
void setImplicitTemplateInstance(bool b) override
void insertUsedFile(const FileDef *) override
QCString qualifiedNameWithTemplateParameters(const ArgumentLists *actualParams=nullptr, uint32_t *actualParamIndex=nullptr) const override
void writeTemplateSpec(OutputList &ol, const Definition *d, const QCString &type, SrcLangExt lang) const
void addUsedByClass(ClassDef *cd, const QCString &accessName, Protection prot) override
void addClassAttributes(OutputList &ol) const
void updateSubClasses(const BaseClassList &bcd) override
Update the list of sub classes to the one passed.
FileDef * getFileDef() const override
Returns the namespace this compound is in, or 0 if it has a global scope.
bool isTemplateArgument() const override
void writeInheritanceGraph(OutputList &ol) const
QCString className() const override
Returns the name of the class including outer classes, but not including namespaces.
void setAnonymousEnumType() override
void setTagLessReference(const ClassDef *cd) override
bool isLinkableInProject() const override
const TemplateInstanceList & getTemplateInstances() const override
Returns a sorted dictionary with all template instances found for this template class.
const UsesClassList & usedByImplementationClasses() const override
ArgumentLists getTemplateParameterLists() const override
Returns the template parameter lists that form the template declaration of this class.
void writeMemberList(OutputList &ol) const override
void writeMemberDeclarations(OutputList &ol, ClassDefSet &visitedClasses, MemberListType lt, const QCString &title, const QCString &subTitle=QCString(), bool showInline=FALSE, const ClassDef *inheritedFrom=nullptr, MemberListType lt2=MemberListType::Invalid(), bool invert=FALSE, bool showAlways=FALSE) const override
void writeBriefDescription(OutputList &ol, bool exampleFlag) const
void writeInlineClasses(OutputList &ol) const
void moveTo(Definition *) override
Definition classdef.cpp:991
const ExampleList & getExamples() const override
void addListReferences() override
const ArgumentList & templateArguments() const override
Returns the template arguments of this class.
void writeDetailedDocumentationBody(OutputList &ol) const
ClassDefImpl(const QCString &fileName, int startLine, int startColumn, const QCString &name, CompoundType ct, const QCString &ref=QCString(), const QCString &fName=QCString(), bool isSymbol=TRUE, bool isJavaEnum=FALSE)
Definition classdef.cpp:859
QCString generatedFromFiles() const override
ClassDef * insertTemplateInstance(const QCString &fileName, int startLine, int startColumn, const QCString &templSpec, bool &freshInstance) const override
void writeTagFile(TextStream &) const override
void endMemberDeclarations(OutputList &ol) const
const MemberGroupList & getMemberGroups() const override
Returns the member groups defined for this class.
void sortMemberLists() override
const FileList & usedFiles() const override
void insertExplicitTemplateInstance(ClassDef *instance, const QCString &spec) override
void setTemplateArguments(const ArgumentList &al) override
void mergeCategory(ClassDef *category) override
void countMembers() override
void setClassSpecifier(TypeSpecifier spec) override
const MemberDef * getMemberByName(const QCString &) const override
Returns the member with the given name.
void reclassifyMember(MemberDefMutable *md, MemberType t) override
int countAdditionalInheritedMembers() const
void writePlainMemberDeclaration(OutputList &ol, MemberListType lt, bool inGroup, int indentLevel, const ClassDef *inheritedFrom, const QCString &inheritId) const
bool isFinal() const override
Returns TRUE if this class is marked as final.
void insertSubClass(ClassDef *, Protection p, Specifier s, const QCString &t=QCString()) override
void writeDocumentationForInnerClasses(OutputList &ol) const override
bool isUsedOnly() const override
void addQualifiers(const StringVector &qualifiers) override
void setTypeConstraints(const ArgumentList &al) override
bool isInterface() const override
Returns TRUE if this class represents an interface.
void writeSimpleMemberDocumentation(OutputList &ol, MemberListType lt) const
int countMemberDeclarations(MemberListType lt, const ClassDef *inheritedFrom, MemberListType lt2, bool invert, bool showAlways, ClassDefSet &visitedClasses) const override
void writeInlineDocumentation(OutputList &ol) const override
Write class documentation inside another container (i.e.
int countMembersIncludingGrouped(MemberListType lt, const ClassDef *inheritedFrom, bool additional) const override
bool isLocal() const override
Returns TRUE if this is a local class definition, see EXTRACT_LOCAL_CLASSES.
const BaseClassList & baseClasses() const override
Returns the list of base classes from which this class directly inherits.
void writeCollaborationGraph(OutputList &ol) const
void writeDeclarationLink(OutputList &ol, bool &found, const QCString &header, bool localNames) const override
void setRequiresClause(const QCString &req) override
void writeAuthorSection(OutputList &ol) const
void writeDetailedDescription(OutputList &ol, const QCString &pageType, bool exampleFlag, const QCString &title, const QCString &anchor=QCString()) const
const ConstraintClassList & templateTypeConstraints() const override
const UsesClassList & usedImplementationClasses() const override
ClassDef * categoryOf() const override
Returns the class of which this is a category (Objective-C only)
bool isReference() const override
bool isPublished() const override
Returns TRUE if this class is marked as published.
void writeDeclaration(OutputList &ol, const MemberDef *md, bool inGroup, int indentLevel, const ClassDef *inheritedFrom, const QCString &inheritId) const override
void addGroupedInheritedMembers(OutputList &ol, MemberListType lt, const ClassDef *inheritedFrom, const QCString &inheritId) const override
bool isFortran() const override
Returns TRUE if this class is implemented in Fortran.
void writeMemberPages(OutputList &ol) const override
void makeTemplateArgument(bool b=TRUE) override
void endMemberDocumentation(OutputList &ol) const
void writeDocumentation(OutputList &ol) const override
void writeMoreLink(OutputList &ol, const QCString &anchor) const
void setModuleDef(ModuleDef *mod) override
const BaseClassList & subClasses() const override
Returns the list of sub classes that directly derive from this class.
std::unique_ptr< ClassDef > deepCopy(const QCString &name) const override
Definition classdef.cpp:933
bool isSimple() const override
void addUsedInterfaceClasses(MemberDef *md, const QCString &typeStr)
bool hasCollaborationGraph() const override
void writeInheritedMemberDeclarations(OutputList &ol, ClassDefSet &visitedClasses, MemberListType lt, MemberListType lt2, const QCString &title, const ClassDef *inheritedFrom, bool invert, bool showAlways) const
void writeQuickMemberLinks(OutputList &ol, const MemberDef *md) const override
bool containsOverload(const MemberDef *md) const override
void getTitleForMemberListType(MemberListType type, QCString &title, QCString &subtitle) const
bool isJavaEnum() const override
void setCompoundType(CompoundType t) override
void insertMember(MemberDef *) override
int countInheritedDecMembers(MemberListType lt, const ClassDef *inheritedFrom, bool invert, bool showAlways, ClassDefSet &visitedClasses) const
const ClassDef * tagLessReference() const override
bool isForwardDeclared() const override
Returns TRUE if this class represents a forward declaration of a template class.
int countInheritanceNodes() const
void setTemplateBaseClassNames(const TemplateNameMap &templateNames) override
void findSectionsInDocumentation() override
bool isTemplate() const override
Returns TRUE if this class is a template.
int countInheritsNodes() const
void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec) override
void mergeMembersFromBaseClasses(bool mergeVirtualBaseClass)
const MemberNameInfoLinkedMap & memberNameInfoLinkedMap() const override
Returns a dictionary of all members.
const ClassDef * templateMaster() const override
Returns the template master of which this class is an instance.
const TemplateNameMap & getTemplateBaseClassNames() const override
bool isExtension() const override
Returns TRUE if this class represents an Objective-C 2.0 extension (nameless category)
void addTypeConstraint(const QCString &typeConstraint, const QCString &type)
void setIncludeFile(FileDef *fd, const QCString &incName, bool local, bool force) override
bool isAbstract() const override
Returns TRUE if there is at least one pure virtual member in this class.
QCString getOutputFileBase() const override
void setGroupDefForAllMembers(GroupDef *g, Grouping::GroupPri_t pri, const QCString &fileName, int startLine, bool hasDocs) override
const IncludeInfo * includeInfo() const override
void setCategoryOf(ClassDef *cd) override
void addUsedClass(ClassDef *cd, const QCString &accessName, Protection prot) override
void addTypeConstraints() override
void setClassName(const QCString &name) override
QCString title() const override
bool visibleInParentsDeclList() const override
show this class in the declaration section of its parent?
const MemberLists & getMemberLists() const override
Returns the list containing the list of members sorted per type.
void overrideCollaborationGraph(bool e) override
bool isSealed() const override
Returns TRUE if this class is marked as sealed.
bool isSliceLocal() const override
void setIsStatic(bool b) override
int countInheritedByNodes() const
QCString getMemberListFileName() const override
void setFileDef(FileDef *fd) override
void insertBaseClass(ClassDef *, const QCString &name, Protection p, Specifier s, const QCString &t=QCString()) override
DefType definitionType() const override
Definition classdef.cpp:193
CodeSymbolType codeSymbolType() const override
QCString collaborationGraphFileName() const override
returns the file name to use for the collaboration graph
bool isCSharp() const override
Returns TRUE if this class is implemented in C#.
void computeAnchors() override
void writeIncludeFiles(OutputList &ol) const
QCString anchor() const override
void addInnerCompound(Definition *d) override
void setSubGrouping(bool enabled) override
void mergeMembers() override
void writeSummaryLinks(OutputList &ol) const override
void writeMemberGroups(OutputList &ol, bool showInline=FALSE) const
int isBaseClass(const ClassDef *bcd, bool followInstances, const QCString &templSpec) const override
Returns TRUE iff bcd is a direct or indirect base class of this class.
QCString requiresClause() const override
void writeAdditionalInheritedMembers(OutputList &ol) const
void writeNestedClasses(OutputList &ol, const QCString &title) const
void removeMemberFromLists(MemberDef *md) override
QCString displayName(bool includeScope=TRUE) const override
bool isVisibleInHierarchy() const override
void writeMemberDocumentation(OutputList &ol, MemberListType lt, const QCString &title, bool showInline=FALSE) const
bool isLinkable() const override
bool hasDocumentation() const override
ModuleDef * getModuleDef() const override
Returns the C++20 module in which this compound's definition can be found.
void internalInsertMember(MemberDef *md, Protection prot, bool addToAllList)
void startMemberDeclarations(OutputList &ol) const
void writeDocumentationContents(OutputList &ol, const QCString &pageTitle) const
bool hasExamples() const override
StringVector getQualifiers() const override
const MemberDef * isSmartPointer() const override
void updateBaseClasses(const BaseClassList &bcd) override
Update the list of base classes to the one passed.
CLASS_GRAPH_t hasInheritanceGraph() const override
MemberList * getMemberList(MemberListType lt) const override
Returns the members in the list identified by lt.
void setUsedOnly(bool b) override
Protection protection() const override
Return the protection level (Public,Protected,Private) in which this compound was found.
const ArgumentList & typeConstraints() const override
void showUsedFiles(OutputList &ol) const
const Definition * findInnerCompound(const QCString &name) const override
bool isEmbeddedInOuterScope() const override
void sortAllMembersList() override
CompoundType compoundType() const override
Returns the type of compound this is, i.e.
bool isAccessibleMember(const MemberDef *md) const override
returns TRUE iff md is a member of this class or of the the public/protected members of a base class
bool isImplicitTemplateInstance() const override
bool hasNonReferenceSuperClass() const override
void setTemplateMaster(const ClassDef *tm) override
QCString inheritanceGraphFileName() const override
returns the file name to use for the inheritance graph
void startMemberDocumentation(OutputList &ol) const
QCString getSourceFileBase() const override
void setProtection(Protection p) override
bool hasDetailedDescription() const override
returns TRUE if this class has a non-empty detailed description
virtual void setGroupDefForAllMembers(GroupDef *g, Grouping::GroupPri_t pri, const QCString &fileName, int startLine, bool hasDocs)=0
virtual void setTemplateMaster(const ClassDef *tm)=0
virtual void setImplicitTemplateInstance(bool b)=0
virtual void insertUsedFile(const FileDef *)=0
virtual void setUsedOnly(bool b)=0
virtual void setCategoryOf(ClassDef *cd)=0
virtual void addMembersToTemplateInstance(const ClassDef *cd, const ArgumentList &templateArguments, const QCString &templSpec)=0
virtual void mergeMembers()=0
const Definition * getAlias() const
const Definition * getScope() const
DefinitionAliasMixin(const Definition *scope, const Definition *alias)
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual QCString docFile() const =0
virtual const QCString & localName() const =0
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual int docLine() const =0
virtual QCString getDefFileName() const =0
virtual bool isLinkable() const =0
virtual int getDefLine() const =0
virtual DefType definitionType() const =0
virtual QCString anchor() const =0
virtual int inbodyLine() const =0
virtual int briefLine() const =0
virtual bool hasDocumentation() const =0
virtual bool isLinkableInProject() const =0
virtual QCString briefDescription(bool abbreviate=FALSE) const =0
virtual bool isAnonymous() const =0
virtual bool isHidden() const =0
virtual const Definition * findInnerCompound(const QCString &name) const =0
virtual QCString getReference() const =0
virtual QCString getSourceFileBase() const =0
virtual const GroupList & partOfGroups() const =0
virtual QCString documentation() const =0
virtual QCString qualifiedName() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
virtual bool isArtificial() const =0
virtual QCString briefFile() const =0
virtual CodeSymbolType codeSymbolType() const =0
virtual QCString getOutputFileBase() const =0
virtual Definition * getOuterScope() const =0
virtual bool isReference() const =0
virtual QCString inbodyDocumentation() const =0
virtual QCString inbodyFile() const =0
virtual const QCString & name() const =0
bool isReference() const override
const QCString & name() const override
void writeSourceDef(OutputList &ol) const override
QCString getDefFileName() const override
void writeNavigationPath(OutputList &ol) const override
bool hasBriefDescription() const override
QCString docFile() const override
QCString briefFile() const override
QCString qualifiedName() const override
QCString id() const override
void setOuterScope(Definition *def) override
void setReference(const QCString &r) override
QCString getSourceFileBase() const override
const RefItemVector & xrefListItems() const override
QCString briefDescription(bool abbreviate=FALSE) const override
Definition * getOuterScope() const override
QCString getReference() const override
DefinitionMixin(const QCString &defFileName, int defLine, int defColumn, const QCString &name, const char *b=nullptr, const char *d=nullptr, bool isSymbol=TRUE)
const QCString & localName() const override
const GroupList & partOfGroups() const override
const FileDef * getBodyDef() const override
int getStartBodyLine() const override
QCString inbodyDocumentation() const override
QCString documentation() const override
void writeDocAnchorsToTagFile(TextStream &fs) const override
bool hasDocumentation() const override
SrcLangExt getLanguage() const override
virtual void setHidden(bool b)=0
virtual void addInnerCompound(Definition *d)=0
virtual void setLanguage(SrcLangExt lang)=0
virtual void setOuterScope(Definition *d)=0
friend Definition * toDefinition(DefinitionMutable *)
virtual void setArtificial(bool b)=0
bool isTooBig() const
bool isTrivial() const
int numNodes() const
static bool suppressDocWarnings
Definition doxygen.h:132
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:97
static bool generatingXmlOutput
Definition doxygen.h:136
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
bool exists() const
Definition fileinfo.cpp:30
std::string absFilePath() const
Definition fileinfo.cpp:101
virtual bool addClass(ClassDef *def)=0
virtual bool insertMember(MemberDef *def, bool docOnly=FALSE)=0
static LayoutDocManager & instance()
Returns a reference to this singleton.
Definition layout.cpp:1423
T * add(const char *k, Args &&... args)
Adds a new object to the ordered vector if it was not added already.
Definition linkedmap.h:90
const T * find(const std::string &key) const
Find an object given the key.
Definition linkedmap.h:47
virtual QCString typeString() const =0
virtual bool isSignal() const =0
virtual bool isDestructor() const =0
virtual bool isExplicit() const =0
virtual bool isObjCMethod() const =0
virtual bool isMaybeVoid() const =0
virtual bool isConstructor() const =0
virtual bool isFriend() const =0
virtual bool isRelated() const =0
virtual const ClassDef * getClassDef() const =0
virtual bool isOverride() const =0
virtual bool isTypedef() const =0
virtual ClassDef * category() const =0
virtual bool isSlot() const =0
virtual const FileDef * getFileDef() const =0
virtual bool isInline() const =0
virtual const ArgumentList & argumentList() const =0
virtual bool isMaybeAmbiguous() const =0
virtual VhdlSpecifier getVhdlSpecifiers() const =0
virtual bool isFunction() const =0
virtual bool isAttribute() const =0
virtual int getMemberGroupId() const =0
virtual bool isStatic() const =0
virtual bool isMaybeDefault() const =0
virtual bool isRemovable() const =0
virtual bool isConstrained() const =0
virtual bool isReadonly() const =0
virtual bool isBound() const =0
virtual ClassDef * getClassDefOfAnonymousType() const =0
virtual std::unique_ptr< MemberDef > createTemplateInstanceMember(const ArgumentList &formalArgs, const std::unique_ptr< ArgumentList > &actualArgs) const =0
virtual bool isTransient() const =0
virtual Protection protection() const =0
virtual TypeSpecifier getMemberSpecifiers() const =0
virtual bool isOptional() const =0
virtual bool isEnumerate() const =0
virtual MemberType memberType() const =0
virtual std::unique_ptr< MemberDef > deepCopy() const =0
virtual QCString memberTypeName() const =0
virtual bool isVariable() const =0
virtual QCString argsString() const =0
virtual Specifier virtualness(int count=0) const =0
virtual bool isUNOProperty() const =0
virtual bool isFinal() const =0
virtual bool isMutable() const =0
virtual bool isEnumValue() const =0
virtual void setMemberType(MemberType t)=0
virtual void setSectionList(const Definition *container, const MemberList *sl)=0
virtual void setCategory(ClassDef *)=0
virtual void setGroupDef(GroupDef *gd, Grouping::GroupPri_t pri, const QCString &fileName, int startLine, bool hasDocs, MemberDef *member=nullptr)=0
virtual void setCategoryRelation(const MemberDef *)=0
void writeDeclarations(OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, const QCString &title, const QCString &subtitle, bool showEnumValues=FALSE, bool showInline=FALSE, const ClassDef *inheritedFrom=nullptr, MemberListType lt=MemberListType::PubMethods(), bool showSectionTitle=true) const
Writes the list of members to the output.
void writeTagFile(TextStream &, bool useQualifiedName=false, bool showNamespaceMembers=true)
int numDecMembers() const
Definition memberlist.h:116
void writePlainDeclarations(OutputList &ol, bool inGroup, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, int indentLevel, const ClassDef *inheritedFrom, const QCString &inheritId) const
void setAnonymousEnumType()
int countInheritableMembers(const ClassDef *inheritedFrom) const
void writeSimpleDocumentation(OutputList &ol, const Definition *container) const
MemberListType listType() const
Definition memberlist.h:113
void writeDocumentation(OutputList &ol, const QCString &scopeName, const Definition *container, const QCString &title, bool showEnumValues=FALSE, bool showInline=FALSE) const
bool declVisible() const
static MemberListType Invalid()
Definition types.h:209
constexpr const char * toLabel() const
Definition types.h:240
constexpr bool isInvalid() const
Definition types.h:210
void push_back(Ptr &&p)
Definition membername.h:54
void push_back(Ptr &&p)
Definition membername.h:141
void endTextBlock(bool paraBreak=FALSE)
Definition outputlist.h:671
void endIndent()
Definition outputlist.h:585
void writeString(const QCString &text)
Definition outputlist.h:412
void startGroupHeader(int extraLevels=0)
Definition outputlist.h:454
void startMemberDeclaration()
Definition outputlist.h:570
void startMemberDoc(const QCString &clName, const QCString &memName, const QCString &anchor, const QCString &title, int memCount, int memTotal, bool showInline)
Definition outputlist.h:532
void startMemberDocName(bool align)
Definition outputlist.h:679
void startClassDiagram()
Definition outputlist.h:595
void startItemList()
Definition outputlist.h:430
void disable(OutputType o)
void endMemberDocName()
Definition outputlist.h:681
void endMemberDoc(bool hasArgs)
Definition outputlist.h:536
void writeRuler()
Definition outputlist.h:522
void enable(OutputType o)
void endContents()
Definition outputlist.h:619
void endMemberDescription()
Definition outputlist.h:568
void writeObjectLink(const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name)
Definition outputlist.h:440
void writeDoc(const IDocNodeAST *ast, const Definition *ctx, const MemberDef *md)
Definition outputlist.h:384
void startMemberDescription(const QCString &anchor, const QCString &inheritId=QCString(), bool typ=false)
Definition outputlist.h:566
void endCompoundTemplateParams()
Definition outputlist.h:504
void docify(const QCString &s)
Definition outputlist.h:438
void startIndent()
Definition outputlist.h:583
void startParagraph(const QCString &classDef=QCString())
Definition outputlist.h:408
void endDescForItem()
Definition outputlist.h:550
void startTextBlock(bool dense=FALSE)
Definition outputlist.h:669
void endExamples()
Definition outputlist.h:581
void endParagraph()
Definition outputlist.h:410
void addIndexItem(const QCString &s1, const QCString &s2)
Definition outputlist.h:591
void startExamples()
Definition outputlist.h:579
void startMemberSections()
Definition outputlist.h:462
void startMemberList()
Definition outputlist.h:482
void endTextLink()
Definition outputlist.h:445
void startItemListItem()
Definition outputlist.h:458
void endItemListItem()
Definition outputlist.h:460
void startBold()
Definition outputlist.h:562
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:496
void writeSynopsis()
Definition outputlist.h:593
void startTypewriter()
Definition outputlist.h:450
void generateDoc(const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &docStr, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
void pushGeneratorState()
void insertMemberAlign(bool templ=FALSE)
Definition outputlist.h:518
void startDescForItem()
Definition outputlist.h:548
void disableAllBut(OutputType o)
void popGeneratorState()
void writeSummaryLink(const QCString &file, const QCString &anchor, const QCString &title, bool first)
Definition outputlist.h:615
void writeAnchor(const QCString &fileName, const QCString &name)
Definition outputlist.h:524
void endBold()
Definition outputlist.h:564
void endGroupHeader(int extraLevels=0)
Definition outputlist.h:456
void endClassDiagram(const ClassDiagram &d, const QCString &f, const QCString &n)
Definition outputlist.h:597
void endLabels()
Definition outputlist.h:741
void endQuickIndices()
Definition outputlist.h:605
void endDotGraph(DotClassGraph &g)
Definition outputlist.h:649
void endItemList()
Definition outputlist.h:432
void startDotGraph()
Definition outputlist.h:647
void writeLabel(const QCString &l, bool isLast)
Definition outputlist.h:739
void startLabels()
Definition outputlist.h:737
void startContents()
Definition outputlist.h:617
void startCompoundTemplateParams()
Definition outputlist.h:502
void endMemberDeclaration(const QCString &anchor, const QCString &inheritId)
Definition outputlist.h:572
void enableAll()
void endMemberHeader()
Definition outputlist.h:472
void startMemberItem(const QCString &anchor, OutputGenerator::MemberItemType type, const QCString &id=QCString())
Definition outputlist.h:494
void endTypewriter()
Definition outputlist.h:452
void lineBreak(const QCString &style=QCString())
Definition outputlist.h:560
void parseText(const QCString &textStr)
void startTextLink(const QCString &file, const QCString &anchor)
Definition outputlist.h:443
void startMemberHeader(const QCString &anchor, int typ=2)
Definition outputlist.h:470
void endMemberSections()
Definition outputlist.h:464
This is an alternative implementation of QCString.
Definition qcstring.h:101
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString & prepend(const char *s)
Definition qcstring.h:407
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
QCString lower() const
Definition qcstring.h:234
bool endsWith(const char *s) const
Definition qcstring.h:504
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
const std::string & str() const
Definition qcstring.h:526
QCString right(size_t len) const
Definition qcstring.h:219
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
QCString left(size_t len) const
Definition qcstring.h:214
void clear()
Definition qcstring.h:169
ClassDefMutable * resolveClassMutable(const Definition *scope, const QCString &name, bool mayBeUnlinkable=false, bool mayBeHidden=false)
Wrapper around resolveClass that returns a mutable interface to the class object or a nullptr if the ...
virtual QCString trMemberList()=0
virtual QCString trDataTypes()=0
virtual QCString trCollaborationDiagram(const QCString &clName)=0
virtual QCString trIncludingInheritedMembers()=0
virtual QCString trCompoundReference(const QCString &clName, ClassDef::CompoundType compType, bool isTemplate)=0
virtual QCString trServiceGeneratedFromFiles(bool single)=0
virtual QCString trEnumReference(const QCString &name)=0
virtual QCString trGeneratedFromFilesFortran(ClassDef::CompoundType compType, bool single)=0
virtual QCString trMore()=0
virtual QCString trCompoundType(ClassDef::CompoundType compType, SrcLangExt lang)=0
virtual QCString trThisIsTheListOfAllMembers()=0
virtual QCString trSingletonReference(const QCString &sName)=0
virtual QCString trInheritsList(int numEntries)=0
virtual QCString trSingletonGeneratedFromFiles(bool single)=0
virtual QCString trCompounds()=0
virtual QCString trGeneratedAutomatically(const QCString &s)=0
virtual QCString trAdditionalInheritedMembers()=0
virtual QCString trAuthor(bool first_capital, bool singular)=0
virtual QCString trGeneratedFromFiles(ClassDef::CompoundType compType, bool single)=0
virtual QCString trEnumName()=0
virtual QCString trVhdlType(VhdlSpecifier type, bool single)=0
virtual QCString trInheritedByList(int numEntries)=0
virtual QCString trEnumValue()=0
virtual QCString trClassDiagram(const QCString &clName)=0
virtual QCString trDefinedIn()=0
virtual QCString trListOfAllMembers()=0
virtual QCString trServiceReference(const QCString &sName)=0
virtual QCString trCustomReference(const QCString &name)=0
virtual QCString trCompoundReferenceFortran(const QCString &clName, ClassDef::CompoundType compType, bool isTemplate)=0
virtual QCString trEnumGeneratedFromFiles(bool single)=0
virtual QCString trCompoundReferenceSlice(const QCString &clName, ClassDef::CompoundType compType, bool isLocal)=0
@ ARCHITECTURECLASS
Definition vhdldocgen.h:77
static QCString getClassName(const ClassDef *)
static QCString getProtectionName(int prot)
static void writeInlineClassLink(const ClassDef *, OutputList &ol)
static void writeVhdlDeclarations(const MemberList *, OutputList &, const GroupDef *, const ClassDef *, const FileDef *, const NamespaceDef *, const ModuleDef *)
static VhdlClasses convert(Protection prot)
Definition vhdldocgen.h:80
static QCString getClassTitle(const ClassDef *)
static QCString makeQualifiedNameWithTemplateParameters(const ClassDef *cd, const ArgumentLists *actualParams, uint32_t *actualParamIndex)
Definition classdef.cpp:56
static QCString getCompoundTypeString(SrcLangExt lang, ClassDef::CompoundType compType, bool isJavaEnum)
Definition classdef.cpp:147
ClassDefMutable * toClassDefMutable(Definition *d)
static bool hasNonReferenceSuperClassRec(const ClassDef *cd, int level)
static QCString makeDisplayName(const ClassDef *cd, bool includeScope)
Definition classdef.cpp:108
int minClassDistance(const ClassDef *cd, const ClassDef *bcd, int level)
static bool isStandardFunc(const MemberDef *md)
ClassDef * getClass(const QCString &n)
std::unique_ptr< ClassDef > createClassDefAlias(const Definition *newScope, const ClassDef *cd)
Definition classdef.cpp:642
static void writeInheritanceSpecifier(OutputList &ol, const BaseClassDef &bcd)
bool classHasVisibleRoot(const BaseClassList &bcl)
std::unique_ptr< ClassDef > createClassDef(const QCString &fileName, int startLine, int startColumn, const QCString &name, ClassDef::CompoundType ct, const QCString &ref, const QCString &fName, bool isSymbol, bool isJavaEnum)
Factory method to create a new ClassDef object.
Definition classdef.cpp:412
static void searchTemplateSpecs(const Definition *d, ArgumentLists &result, QCString &name, SrcLangExt lang)
bool classVisibleInIndex(const ClassDef *cd)
ClassDef * toClassDef(Definition *d)
Protection classInheritedProtectionLevel(const ClassDef *cd, const ClassDef *bcd, Protection prot, int level)
bool classHasVisibleChildren(const ClassDef *cd)
std::vector< BaseClassDef > BaseClassList
Definition classdef.h:81
std::unordered_set< const ClassDef * > ClassDefSet
Definition classdef.h:95
std::map< std::string, int > TemplateNameMap
Definition classdef.h:93
std::vector< TemplateInstanceDef > TemplateInstanceList
Definition classdef.h:91
#define Config_getInt(name)
Definition config.h:34
#define Config_getList(name)
Definition config.h:38
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
#define NON_COPYABLE(cls)
Macro to help implementing the rule of 5 for a non-copyable & movable class.
Definition construct.h:37
std::set< std::string > StringSet
Definition containers.h:31
std::vector< std::string > StringVector
Definition containers.h:33
std::unique_ptr< ArgumentList > stringToArgumentList(SrcLangExt lang, const QCString &argsString, QCString *extraTypeChars=nullptr)
Definition defargs.l:814
#define AUTO_TRACE_ADD(...)
Definition docnode.cpp:47
#define AUTO_TRACE(...)
Definition docnode.cpp:46
#define AUTO_TRACE_EXIT(...)
Definition docnode.cpp:48
void docFindSections(const QCString &input, const Definition *d, const QCString &fileName)
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:54
IDocNodeASTPtr validatingParseDoc(IDocParser &parserIntf, const QCString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const QCString &input, bool indexWords, bool isExample, const QCString &exampleName, bool singleLine, bool linkFromIndex, bool markdownSupport)
@ Collaboration
Definition dotgraph.h:31
@ Inheritance
Definition dotgraph.h:31
static bool isSpecialization(const ArgumentLists &srcTempArgLists, const ArgumentLists &dstTempArgLists)
Definition doxygen.cpp:5791
static void writeTagFile()
QCString includeClose(SrcLangExt lang, IncludeKind kind)
Definition filedef.cpp:86
QCString includeStatement(SrcLangExt lang, IncludeKind kind)
Definition filedef.cpp:56
FileDef * toFileDef(Definition *d)
Definition filedef.cpp:1892
QCString includeOpen(SrcLangExt lang, IncludeKind kind)
Definition filedef.cpp:73
@ IncludeLocal
Definition filedef.h:50
@ IncludeSystem
Definition filedef.h:49
void startTitle(OutputList &ol, const QCString &fileName, const DefinitionMutable *def)
Definition index.cpp:386
void endFile(OutputList &ol, bool skipNavIndex, bool skipEndContents, const QCString &navPath)
Definition index.cpp:421
void endTitle(OutputList &ol, const QCString &fileName, const QCString &name)
Definition index.cpp:395
void startFile(OutputList &ol, const QCString &name, const QCString &manName, const QCString &title, HighlightedItem hli, bool additionalIndices, const QCString &altSidebarName, int hierarchyLevel)
Definition index.cpp:402
void endFileWithNavPath(OutputList &ol, const Definition *d)
Definition index.cpp:441
HighlightedItem
Definition index.h:59
@ InterfaceVisible
Definition index.h:89
@ ExceptionVisible
Definition index.h:91
Translator * theTranslator
Definition language.cpp:71
MemberDefMutable * toMemberDefMutable(Definition *d)
void combineDeclarationAndDefinition(MemberDefMutable *mdec, MemberDefMutable *mdef)
void msg(const char *fmt,...)
Definition message.cpp:98
#define warn_uncond(fmt,...)
Definition message.h:79
#define warn(file, line, fmt,...)
Definition message.h:59
#define err(fmt,...)
Definition message.h:84
ModuleDef * toModuleDef(Definition *d)
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:442
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
const char * qPrint(const char *s)
Definition qcstring.h:661
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
std::vector< RefItem * > RefItemVector
Definition reflist.h:133
Web server based search engine.
QCString type
Definition arguments.h:37
QCString name
Definition arguments.h:39
QCString defval
Definition arguments.h:41
QCString typeConstraint
Definition arguments.h:43
ClassDef * classDef
Class definition that this relation inherits from.
Definition classdef.h:60
QCString templSpecifiers
Template arguments used for the base class.
Definition classdef.h:78
Specifier virt
Virtualness of the inheritance relation: Normal, or Virtual.
Definition classdef.h:75
Protection prot
Protection level of the inheritance relation: Public, Protected, or Private.
Definition classdef.h:70
GroupPri_t
Grouping priority.
Definition types.h:68
QCString title(SrcLangExt lang) const
Definition layout.cpp:1533
MemberListType type
Definition layout.h:115
QCString subtitle(SrcLangExt lang) const
Definition layout.cpp:1538
MemberListType type
Definition layout.h:130
QCString title(SrcLangExt lang) const
Definition layout.cpp:1545
QCString title(SrcLangExt lang) const
Definition layout.cpp:1526
This file contains a number of basic enums and types.
CodeSymbolType
Definition types.h:319
MemberType
Definition types.h:390
@ Enumeration
Definition types.h:395
@ EnumValue
Definition types.h:396
@ Interface
Definition types.h:403
@ Variable
Definition types.h:393
@ Property
Definition types.h:401
@ Typedef
Definition types.h:394
@ Function
Definition types.h:392
@ Service
Definition types.h:404
Protection
Protection level of members.
Definition types.h:26
@ Package
Definition types.h:26
@ Public
Definition types.h:26
@ Private
Definition types.h:26
@ Protected
Definition types.h:26
SrcLangExt
Language as given by extension.
Definition types.h:42
@ CSharp
Definition types.h:46
@ Fortran
Definition types.h:53
@ Python
Definition types.h:52
@ Slice
Definition types.h:59
Specifier
Virtualness of a member.
Definition types.h:29
@ Virtual
Definition types.h:29
@ Normal
Definition types.h:29
@ Pure
Definition types.h:29
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
SrcLangExt getLanguageFromFileName(const QCString &fileName, SrcLangExt defLang)
Definition util.cpp:5549
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
Definition util.cpp:4100
bool protectionLevelVisible(Protection prot)
Definition util.cpp:6269
const int maxInheritanceDepth
Definition util.cpp:156
QCString convertToHtml(const QCString &s, bool keepEntities)
Definition util.cpp:4317
void writeTypeConstraints(OutputList &ol, const Definition *d, const ArgumentList &al)
Definition util.cpp:5755
QCString tempArgListToString(const ArgumentList &al, SrcLangExt lang, bool includeDefault)
Definition util.cpp:1219
void addRefItem(const RefItemVector &sli, const QCString &key, const QCString &prefix, const QCString &name, const QCString &title, const QCString &args, const Definition *scope)
Definition util.cpp:5146
void addGroupListToTitle(OutputList &ol, const Definition *d)
Definition util.cpp:5233
bool found
Definition util.cpp:984
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:172
void createSubDirs(const Dir &d)
Definition util.cpp:3994
bool matchArguments2(const Definition *srcScope, const FileDef *srcFileScope, const ArgumentList *srcAl, const Definition *dstScope, const FileDef *dstFileScope, const ArgumentList *dstAl, bool checkCV, SrcLangExt lang)
Definition util.cpp:1931
QCString stripScope(const QCString &name)
Definition util.cpp:4133
QCString stripExtension(const QCString &fName)
Definition util.cpp:5265
static QCString stripFromPath(const QCString &p, const StringVector &l)
Definition util.cpp:309
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3858
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:4266
EntryType guessSection(const QCString &name)
Definition util.cpp:349
void convertProtectionLevel(MemberListType inListType, Protection inProt, MemberListType *outListType1, MemberListType *outListType2)
Computes for a given list type inListType, which are the the corresponding list type(s) in the base c...
Definition util.cpp:6556
QCString getLanguageSpecificSeparator(SrcLangExt lang, bool classScope)
Returns the scope separator to use given the programming language lang.
Definition util.cpp:6229
void writeMarkerList(OutputList &ol, const std::string &markerText, size_t numMarkers, std::function< void(size_t)> replaceFunc)
Definition util.cpp:1103
void linkifyText(const TextGeneratorIntf &out, const Definition *scope, const FileDef *fileScope, const Definition *self, const QCString &text, bool autoBreak, bool external, bool keepSpaces, int indentLevel)
Definition util.cpp:904
QCString convertToId(const QCString &s)
Definition util.cpp:4226
void writeExamples(OutputList &ol, const ExampleList &list)
Definition util.cpp:1127
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5243
A bunch of utility functions.