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

memberdef.cpp
Go to the documentation of this file.
1 
16 #include <stdio.h>
17 #include <qglobal.h>
18 #include <qregexp.h>
19 #include <assert.h>
20 #include "md5.h"
21 #include "memberdef.h"
22 #include "membername.h"
23 #include "doxygen.h"
24 #include "util.h"
25 #include "code.h"
26 #include "message.h"
27 #include "htmlhelp.h"
28 #include "language.h"
29 #include "outputlist.h"
30 #include "example.h"
31 #include "membergroup.h"
32 #include "groupdef.h"
33 #include "defargs.h"
34 #include "docparser.h"
35 #include "dot.h"
36 #include "dotcallgraph.h"
37 #include "searchindex.h"
38 #include "parserintf.h"
39 
40 #include "vhdldocgen.h"
41 #include "arguments.h"
42 #include "memberlist.h"
43 #include "namespacedef.h"
44 #include "filedef.h"
45 #include "config.h"
46 #include "definitionimpl.h"
47 
48 //-----------------------------------------------------------------------------
49 
50 class MemberDefImpl : public DefinitionImpl, public MemberDef
51 {
52  public:
53  MemberDefImpl(const char *defFileName,int defLine,int defColumn,
54  const char *type,const char *name,const char *args,
55  const char *excp,Protection prot,Specifier virt,bool stat,
56  Relationship related,MemberType t,const ArgumentList &tal,
57  const ArgumentList &al,const char *metaData);
58  virtual ~MemberDefImpl();
59 
60  virtual DefType definitionType() const { return TypeMember; }
61  virtual MemberDef *resolveAlias() { return this; }
62  virtual const MemberDef *resolveAlias() const { return this; }
63  virtual MemberDef *deepCopy() const;
64  virtual void moveTo(Definition *);
65  virtual QCString getOutputFileBase() const;
66  virtual QCString getReference() const;
67  virtual QCString anchor() const;
68  virtual const char *declaration() const;
69  virtual const char *definition() const;
70  virtual const char *typeString() const;
71  virtual const char *argsString() const;
72  virtual const char *excpString() const;
73  virtual const char *bitfieldString() const;
74  virtual const char *extraTypeChars() const;
75  virtual const QCString &initializer() const;
76  virtual int initializerLines() const;
77  virtual uint64 getMemberSpecifiers() const;
78  virtual const MemberList *getSectionList() const;
79  virtual QCString displayDefinition() const;
80  virtual const ClassDef *getClassDef() const;
81  virtual ClassDef *getClassDef();
82  virtual const FileDef *getFileDef() const;
83  virtual FileDef *getFileDef();
84  virtual const NamespaceDef* getNamespaceDef() const;
85  virtual NamespaceDef* getNamespaceDef();
86  virtual const GroupDef *getGroupDef() const;
87  virtual GroupDef *getGroupDef();
88  virtual ClassDef *accessorClass() const;
89  virtual const char *getReadAccessor() const;
90  virtual const char *getWriteAccessor() const;
91  virtual Grouping::GroupPri_t getGroupPri() const;
92  virtual const char *getGroupFileName() const;
93  virtual int getGroupStartLine() const;
94  virtual bool getGroupHasDocs() const;
95  virtual QCString qualifiedName() const;
96  virtual QCString objCMethodName(bool localLink,bool showStatic) const;
97  virtual Protection protection() const;
98  virtual Specifier virtualness(int count=0) const;
99  virtual MemberType memberType() const;
100  virtual QCString memberTypeName() const;
101  virtual bool isSignal() const;
102  virtual bool isSlot() const;
103  virtual bool isVariable() const;
104  virtual bool isEnumerate() const;
105  virtual bool isEnumValue() const;
106  virtual bool isTypedef() const;
107  virtual bool isSequence() const;
108  virtual bool isDictionary() const;
109  virtual bool isFunction() const;
110  virtual bool isFunctionPtr() const;
111  virtual bool isDefine() const;
112  virtual bool isFriend() const;
113  virtual bool isDCOP() const;
114  virtual bool isProperty() const;
115  virtual bool isEvent() const;
116  virtual bool isRelated() const;
117  virtual bool isForeign() const;
118  virtual bool isStatic() const;
119  virtual bool isInline() const;
120  virtual bool isExplicit() const;
121  virtual bool isMutable() const;
122  virtual bool isGettable() const;
123  virtual bool isPrivateGettable() const;
124  virtual bool isProtectedGettable() const;
125  virtual bool isSettable() const;
126  virtual bool isPrivateSettable() const;
127  virtual bool isProtectedSettable() const;
128  virtual bool isReadable() const;
129  virtual bool isWritable() const;
130  virtual bool isAddable() const;
131  virtual bool isRemovable() const;
132  virtual bool isRaisable() const;
133  virtual bool isFinal() const;
134  virtual bool isAbstract() const;
135  virtual bool isOverride() const;
136  virtual bool isInitonly() const;
137  virtual bool isOptional() const;
138  virtual bool isRequired() const;
139  virtual bool isNonAtomic() const;
140  virtual bool isCopy() const;
141  virtual bool isAssign() const;
142  virtual bool isRetain() const;
143  virtual bool isWeak() const;
144  virtual bool isStrong() const;
145  virtual bool isUnretained() const;
146  virtual bool isNew() const;
147  virtual bool isSealed() const;
148  virtual bool isImplementation() const;
149  virtual bool isExternal() const;
150  virtual bool isTypeAlias() const;
151  virtual bool isDefault() const;
152  virtual bool isDelete() const;
153  virtual bool isNoExcept() const;
154  virtual bool isAttribute() const;
155  virtual bool isUNOProperty() const;
156  virtual bool isReadonly() const;
157  virtual bool isBound() const;
158  virtual bool isConstrained() const;
159  virtual bool isTransient() const;
160  virtual bool isMaybeVoid() const;
161  virtual bool isMaybeDefault() const;
162  virtual bool isMaybeAmbiguous() const;
163  virtual bool isPublished() const;
164  virtual bool isTemplateSpecialization() const;
165  virtual bool isObjCMethod() const;
166  virtual bool isObjCProperty() const;
167  virtual bool isConstructor() const;
168  virtual bool isDestructor() const;
169  virtual bool hasOneLineInitializer() const;
170  virtual bool hasMultiLineInitializer() const;
171  virtual bool showInCallGraph() const;
172  virtual bool isStrongEnumValue() const;
173  virtual bool livesInsideEnum() const;
174  virtual bool isSliceLocal() const;
175  virtual bool isConstExpr() const;
176  virtual int numberOfFlowKeyWords() const;
177  virtual bool isFriendToHide() const;
178  virtual bool isNotFriend() const;
179  virtual bool isFunctionOrSignalSlot() const;
180  virtual bool isRelatedOrFriend() const;
181  virtual bool isLinkableInProject() const;
182  virtual bool isLinkable() const;
183  virtual bool hasDocumentation() const;
184  virtual bool isDeleted() const;
185  virtual bool isBriefSectionVisible() const;
186  virtual bool isDetailedSectionVisible(bool inGroup,bool inFile) const;
187  virtual bool isDetailedSectionLinkable() const;
188  virtual bool isFriendClass() const;
189  virtual bool isDocumentedFriendClass() const;
190  virtual MemberDef *reimplements() const;
191  virtual MemberList *reimplementedBy() const;
192  virtual bool isReimplementedBy(const ClassDef *cd) const;
193  virtual ClassDef *relatedAlso() const;
194  virtual bool hasDocumentedEnumValues() const;
195  virtual const MemberDef *getAnonymousEnumType() const;
196  virtual bool isDocsForDefinition() const;
197  virtual const MemberDef *getEnumScope() const;
198  virtual const MemberList *enumFieldList() const;
199  virtual void setEnumBaseType(const QCString &type);
200  virtual QCString enumBaseType() const;
201  virtual bool hasExamples() const;
202  virtual ExampleSDict *getExamples() const;
203  virtual bool isPrototype() const;
204  virtual const ArgumentList &argumentList() const;
205  virtual ArgumentList &argumentList();
206  virtual const ArgumentList &declArgumentList() const;
207  virtual const ArgumentList &templateArguments() const;
208  virtual const std::vector<ArgumentList> &definitionTemplateParameterLists() const;
209  virtual int getMemberGroupId() const;
210  virtual MemberGroup *getMemberGroup() const;
211  virtual bool fromAnonymousScope() const;
212  virtual bool anonymousDeclShown() const;
213  virtual MemberDef *fromAnonymousMember() const;
214  virtual bool hasCallGraph() const;
215  virtual bool hasCallerGraph() const;
216  virtual bool visibleMemberGroup(bool hideNoHeader) const;
217  virtual bool hasReferencesRelation() const;
218  virtual bool hasReferencedByRelation() const;
219  virtual MemberDef *templateMaster() const;
220  virtual QCString getScopeString() const;
221  virtual ClassDef *getClassDefOfAnonymousType() const;
222  virtual bool isTypedefValCached() const;
223  virtual const ClassDef *getCachedTypedefVal() const;
224  virtual QCString getCachedTypedefTemplSpec() const;
225  virtual QCString getCachedResolvedTypedef() const;
226  virtual MemberDef *memberDefinition() const;
227  virtual MemberDef *memberDeclaration() const;
228  virtual MemberDef *inheritsDocsFrom() const;
229  virtual const MemberDef *getGroupAlias() const;
230  virtual ClassDef *category() const;
231  virtual MemberDef *categoryRelation() const;
232  virtual QCString displayName(bool=TRUE) const;
233  virtual QCString getDeclType() const;
234  virtual void getLabels(QStrList &sl,const Definition *container) const;
235  virtual const ArgumentList &typeConstraints() const;
236  virtual QCString documentation() const;
237  virtual QCString briefDescription(bool abbr=FALSE) const;
238  virtual QCString fieldType() const;
239  virtual bool isReference() const;
240  virtual QCString getDeclFileName() const;
241  virtual int getDeclLine() const;
242  virtual int getDeclColumn() const;
243  virtual void setMemberType(MemberType t);
244  virtual void setDefinition(const char *d);
245  virtual void setFileDef(FileDef *fd);
246  virtual void setAnchor();
247  virtual void setProtection(Protection p);
248  virtual void setMemberSpecifiers(uint64 s);
249  virtual void mergeMemberSpecifiers(uint64 s);
250  virtual void setInitializer(const char *i);
251  virtual void setBitfields(const char *s);
252  virtual void setMaxInitLines(int lines);
253  virtual void setMemberClass(ClassDef *cd);
254  virtual void setSectionList(MemberList *sl);
255  virtual void setGroupDef(GroupDef *gd,Grouping::GroupPri_t pri,
256  const QCString &fileName,int startLine,bool hasDocs,
257  MemberDef *member=0);
258  virtual void setReadAccessor(const char *r);
259  virtual void setWriteAccessor(const char *w);
260  virtual void setTemplateSpecialization(bool b);
261  virtual void makeRelated();
262  virtual void makeForeign();
263  virtual void setInheritsDocsFrom(MemberDef *md);
264  virtual void setTagInfo(const TagInfo *i);
265  virtual void setArgsString(const char *as);
266  virtual void setReimplements(MemberDef *md);
267  virtual void insertReimplementedBy(MemberDef *md);
268  virtual void setRelatedAlso(ClassDef *cd);
269  virtual void insertEnumField(MemberDef *md);
270  virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE);
271  virtual void setEnumClassScope(ClassDef *cd);
272  virtual void setDocumentedEnumValues(bool value);
273  virtual void setAnonymousEnumType(const MemberDef *md);
274  virtual bool addExample(const char *anchor,const char *name,const char *file);
275  virtual void setPrototype(bool p,const QCString &df,int line, int column);
276  virtual void setExplicitExternal(bool b,const QCString &df,int line,int column);
277  virtual void setDeclFile(const QCString &df,int line,int column);
278  virtual void setArgumentList(const ArgumentList &al);
279  virtual void setDeclArgumentList(const ArgumentList &al);
280  virtual void setDefinitionTemplateParameterLists(const std::vector<ArgumentList> &lists);
281  virtual void setTypeConstraints(const ArgumentList &al);
282  virtual void setType(const char *t);
283  virtual void setAccessorType(ClassDef *cd,const char *t);
284  virtual void setNamespace(NamespaceDef *nd);
285  virtual void setMemberGroup(MemberGroup *grp);
286  virtual void setMemberGroupId(int id);
287  virtual void makeImplementationDetail();
288  virtual void setFromAnonymousScope(bool b) const;
289  virtual void setFromAnonymousMember(MemberDef *m);
290  virtual void enableCallGraph(bool e);
291  virtual void enableCallerGraph(bool e);
292  virtual void enableReferencedByRelation(bool e);
293  virtual void enableReferencesRelation(bool e);
294  virtual void setTemplateMaster(MemberDef *mt);
295  virtual void addListReference(Definition *d);
296  virtual void setDocsForDefinition(bool b);
297  virtual void setGroupAlias(const MemberDef *md);
298  virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType);
299  virtual void invalidateTypedefValCache();
300  virtual void invalidateCachedArgumentTypes();
301  virtual void setMemberDefinition(MemberDef *md);
302  virtual void setMemberDeclaration(MemberDef *md);
303  virtual void setAnonymousUsed() const;
304  virtual void copyArgumentNames(MemberDef *bmd);
305  virtual void setCategory(ClassDef *);
306  virtual void setCategoryRelation(MemberDef *);
307  virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE);
308  virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine);
309  virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine);
310  virtual void setHidden(bool b);
311  virtual void incrementFlowKeyWordCount();
312  virtual void writeDeclaration(OutputList &ol,
313  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
314  bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const;
315  virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol,
316  const char *scopeName,const Definition *container,
317  bool inGroup,bool showEnumValues=FALSE,bool
318  showInline=FALSE) const;
319  virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const;
320  virtual void writeEnumDeclaration(OutputList &typeDecl,
321  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const;
322  virtual void writeTagFile(FTextStream &) const;
323  virtual void warnIfUndocumented() const;
324  virtual void warnIfUndocumentedParams() const;
325  virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const;
326  virtual MemberDef *createTemplateInstanceMember(const ArgumentList &formalArgs,
327  const ArgumentList &actualArgs) const;
328  virtual void findSectionsInDocumentation();
329  virtual void writeLink(OutputList &ol,
330  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
331  bool onlyText=FALSE) const;
332  virtual void addToSearchIndex() const;
333 
334  private:
336  void _computeIsConstructor();
337  void _computeIsDestructor();
338  void _writeGroupInclude(OutputList &ol,bool inGroup) const;
339  void _writeCallGraph(OutputList &ol) const;
340  void _writeCallerGraph(OutputList &ol) const;
341  void _writeReimplements(OutputList &ol) const;
342  void _writeReimplementedBy(OutputList &ol) const;
343  void _writeExamples(OutputList &ol) const;
344  void _writeTypeConstraints(OutputList &ol) const;
345  void _writeEnumValues(OutputList &ol,const Definition *container,
346  const QCString &cfname,const QCString &ciname,
347  const QCString &cname) const;
348  void _writeCategoryRelation(OutputList &ol) const;
349  void _writeTagData(const DefType) const;
350 
351  static int s_indentLevel;
352 
353  // disable copying of member defs
354  MemberDefImpl(const MemberDefImpl &);
356 
357 
358  // PIMPL idiom
359  class IMPL;
361  uchar m_isLinkableCached; // 0 = not cached, 1=FALSE, 2=TRUE
362  uchar m_isConstructorCached; // 0 = not cached, 1=FALSE, 2=TRUE
363  uchar m_isDestructorCached; // 0 = not cached, 1=FALSE, 2=TRUE
364 };
365 
366 MemberDef *createMemberDef(const char *defFileName,int defLine,int defColumn,
367  const char *type,const char *name,const char *args,
368  const char *excp,Protection prot,Specifier virt,bool stat,
369  Relationship related,MemberType t,const ArgumentList &tal,
370  const ArgumentList &al,const char *metaData)
371 {
372  return new MemberDefImpl(defFileName,defLine,defColumn,type,name,args,excp,prot,virt,
373  stat,related,t,tal,al,metaData);
374 }
375 
376 //-----------------------------------------------------------------------------
377 
379 {
380  public:
381  MemberDefAliasImpl(const Definition *newScope,const MemberDef *md)
382  : DefinitionAliasImpl(newScope,md), m_memberGroup(0) {}
383  virtual ~MemberDefAliasImpl() {}
384  virtual DefType definitionType() const { return TypeMember; }
385 
386  const MemberDef *getMdAlias() const { return dynamic_cast<const MemberDef*>(getAlias()); }
387  virtual MemberDef *resolveAlias() { return const_cast<MemberDef*>(getMdAlias()); }
388  virtual const MemberDef *resolveAlias() const { return getMdAlias(); }
389 
390  virtual MemberDef *deepCopy() const {
392  }
393  virtual void moveTo(Definition *) {}
394 
395  virtual QCString getOutputFileBase() const
396  { return getMdAlias()->getOutputFileBase(); }
397  virtual QCString getReference() const
398  { return getMdAlias()->getReference(); }
399  virtual QCString anchor() const
400  { return getMdAlias()->anchor(); }
401  virtual const char *declaration() const
402  { return getMdAlias()->declaration(); }
403  virtual const char *definition() const
404  { return getMdAlias()->definition(); }
405  virtual const char *typeString() const
406  { return getMdAlias()->typeString(); }
407  virtual const char *argsString() const
408  { return getMdAlias()->argsString(); }
409  virtual const char *excpString() const
410  { return getMdAlias()->excpString(); }
411  virtual const char *bitfieldString() const
412  { return getMdAlias()->bitfieldString(); }
413  virtual const char *extraTypeChars() const
414  { return getMdAlias()->extraTypeChars(); }
415  virtual const QCString &initializer() const
416  { return getMdAlias()->initializer(); }
417  virtual int initializerLines() const
418  { return getMdAlias()->initializerLines(); }
419  virtual uint64 getMemberSpecifiers() const
420  { return getMdAlias()->getMemberSpecifiers(); }
421  virtual const MemberList *getSectionList() const
422  { return getMdAlias()->getSectionList(); }
423  virtual QCString displayDefinition() const
424  { return getMdAlias()->displayDefinition(); }
425  virtual const ClassDef *getClassDef() const
426  { return getMdAlias()->getClassDef(); }
427  virtual const FileDef *getFileDef() const
428  { return getMdAlias()->getFileDef(); }
429  virtual const NamespaceDef* getNamespaceDef() const
430  { return getMdAlias()->getNamespaceDef(); }
431  virtual ClassDef *accessorClass() const
432  { return getMdAlias()->accessorClass(); }
433  virtual const char *getReadAccessor() const
434  { return getMdAlias()->getReadAccessor(); }
435  virtual const char *getWriteAccessor() const
436  { return getMdAlias()->getWriteAccessor(); }
437  virtual const GroupDef *getGroupDef() const
438  { return getMdAlias()->getGroupDef(); }
440  { return getMdAlias()->getGroupPri(); }
441  virtual const char *getGroupFileName() const
442  { return getMdAlias()->getGroupFileName(); }
443  virtual int getGroupStartLine() const
444  { return getMdAlias()->getGroupStartLine(); }
445  virtual bool getGroupHasDocs() const
446  { return getMdAlias()->getGroupHasDocs(); }
447  virtual QCString qualifiedName() const
448  { return getMdAlias()->qualifiedName(); }
449  virtual QCString objCMethodName(bool localLink,bool showStatic) const
450  { return getMdAlias()->objCMethodName(localLink,showStatic); }
451  virtual Protection protection() const
452  { return getMdAlias()->protection(); }
453  virtual Specifier virtualness(int count) const
454  { return getMdAlias()->virtualness(); }
455  virtual MemberType memberType() const
456  { return getMdAlias()->memberType(); }
457  virtual QCString memberTypeName() const
458  { return getMdAlias()->memberTypeName(); }
459  virtual bool isSignal() const
460  { return getMdAlias()->isSignal(); }
461  virtual bool isSlot() const
462  { return getMdAlias()->isSlot(); }
463  virtual bool isVariable() const
464  { return getMdAlias()->isVariable(); }
465  virtual bool isEnumerate() const
466  { return getMdAlias()->isEnumerate(); }
467  virtual bool isEnumValue() const
468  { return getMdAlias()->isEnumValue(); }
469  virtual bool isTypedef() const
470  { return getMdAlias()->isTypedef(); }
471  virtual bool isSequence() const
472  { return getMdAlias()->isSequence(); }
473  virtual bool isDictionary() const
474  { return getMdAlias()->isDictionary(); }
475  virtual bool isFunction() const
476  { return getMdAlias()->isFunction(); }
477  virtual bool isFunctionPtr() const
478  { return getMdAlias()->isFunctionPtr(); }
479  virtual bool isDefine() const
480  { return getMdAlias()->isDefine(); }
481  virtual bool isFriend() const
482  { return getMdAlias()->isFriend(); }
483  virtual bool isDCOP() const
484  { return getMdAlias()->isDCOP(); }
485  virtual bool isProperty() const
486  { return getMdAlias()->isProperty(); }
487  virtual bool isEvent() const
488  { return getMdAlias()->isEvent(); }
489  virtual bool isRelated() const
490  { return getMdAlias()->isRelated(); }
491  virtual bool isForeign() const
492  { return getMdAlias()->isForeign(); }
493  virtual bool isStatic() const
494  { return getMdAlias()->isStatic(); }
495  virtual bool isInline() const
496  { return getMdAlias()->isInline(); }
497  virtual bool isExplicit() const
498  { return getMdAlias()->isExplicit(); }
499  virtual bool isMutable() const
500  { return getMdAlias()->isMutable(); }
501  virtual bool isGettable() const
502  { return getMdAlias()->isGettable(); }
503  virtual bool isPrivateGettable() const
504  { return getMdAlias()->isPrivateGettable(); }
505  virtual bool isProtectedGettable() const
506  { return getMdAlias()->isProtectedGettable(); }
507  virtual bool isSettable() const
508  { return getMdAlias()->isSettable(); }
509  virtual bool isPrivateSettable() const
510  { return getMdAlias()->isPrivateSettable(); }
511  virtual bool isProtectedSettable() const
512  { return getMdAlias()->isProtectedSettable(); }
513  virtual bool isReadable() const
514  { return getMdAlias()->isReadable(); }
515  virtual bool isWritable() const
516  { return getMdAlias()->isWritable(); }
517  virtual bool isAddable() const
518  { return getMdAlias()->isAddable(); }
519  virtual bool isRemovable() const
520  { return getMdAlias()->isRemovable(); }
521  virtual bool isRaisable() const
522  { return getMdAlias()->isRaisable(); }
523  virtual bool isFinal() const
524  { return getMdAlias()->isFinal(); }
525  virtual bool isAbstract() const
526  { return getMdAlias()->isAbstract(); }
527  virtual bool isOverride() const
528  { return getMdAlias()->isOverride(); }
529  virtual bool isInitonly() const
530  { return getMdAlias()->isInitonly(); }
531  virtual bool isOptional() const
532  { return getMdAlias()->isOptional(); }
533  virtual bool isRequired() const
534  { return getMdAlias()->isRequired(); }
535  virtual bool isNonAtomic() const
536  { return getMdAlias()->isNonAtomic(); }
537  virtual bool isCopy() const
538  { return getMdAlias()->isCopy(); }
539  virtual bool isAssign() const
540  { return getMdAlias()->isAssign(); }
541  virtual bool isRetain() const
542  { return getMdAlias()->isRetain(); }
543  virtual bool isWeak() const
544  { return getMdAlias()->isWeak(); }
545  virtual bool isStrong() const
546  { return getMdAlias()->isStrong(); }
547  virtual bool isUnretained() const
548  { return getMdAlias()->isUnretained(); }
549  virtual bool isNew() const
550  { return getMdAlias()->isNew(); }
551  virtual bool isSealed() const
552  { return getMdAlias()->isSealed(); }
553  virtual bool isImplementation() const
554  { return getMdAlias()->isImplementation(); }
555  virtual bool isExternal() const
556  { return getMdAlias()->isExternal(); }
557  virtual bool isTypeAlias() const
558  { return getMdAlias()->isTypeAlias(); }
559  virtual bool isDefault() const
560  { return getMdAlias()->isDefault(); }
561  virtual bool isDelete() const
562  { return getMdAlias()->isDelete(); }
563  virtual bool isNoExcept() const
564  { return getMdAlias()->isNoExcept(); }
565  virtual bool isAttribute() const
566  { return getMdAlias()->isAttribute(); }
567  virtual bool isUNOProperty() const
568  { return getMdAlias()->isUNOProperty(); }
569  virtual bool isReadonly() const
570  { return getMdAlias()->isReadable(); }
571  virtual bool isBound() const
572  { return getMdAlias()->isBound(); }
573  virtual bool isConstrained() const
574  { return getMdAlias()->isConstrained(); }
575  virtual bool isTransient() const
576  { return getMdAlias()->isTransient(); }
577  virtual bool isMaybeVoid() const
578  { return getMdAlias()->isMaybeVoid(); }
579  virtual bool isMaybeDefault() const
580  { return getMdAlias()->isMaybeDefault(); }
581  virtual bool isMaybeAmbiguous() const
582  { return getMdAlias()->isMaybeAmbiguous(); }
583  virtual bool isPublished() const
584  { return getMdAlias()->isPublished(); }
585  virtual bool isTemplateSpecialization() const
586  { return getMdAlias()->isTemplateSpecialization(); }
587  virtual bool isObjCMethod() const
588  { return getMdAlias()->isObjCMethod(); }
589  virtual bool isObjCProperty() const
590  { return getMdAlias()->isObjCProperty(); }
591  virtual bool isConstructor() const
592  { return getMdAlias()->isConstructor(); }
593  virtual bool isDestructor() const
594  { return getMdAlias()->isDestructor(); }
595  virtual bool hasOneLineInitializer() const
596  { return getMdAlias()->hasOneLineInitializer(); }
597  virtual bool hasMultiLineInitializer() const
598  { return getMdAlias()->hasMultiLineInitializer(); }
599  virtual bool showInCallGraph() const
600  { return getMdAlias()->showInCallGraph(); }
601  virtual bool isStrongEnumValue() const
602  { return getMdAlias()->isStrongEnumValue(); }
603  virtual bool livesInsideEnum() const
604  { return getMdAlias()->livesInsideEnum(); }
605  virtual bool isSliceLocal() const
606  { return getMdAlias()->isSliceLocal(); }
607  virtual bool isConstExpr() const
608  { return getMdAlias()->isConstExpr(); }
609  virtual int numberOfFlowKeyWords() const
610  { return getMdAlias()->numberOfFlowKeyWords(); }
611  virtual bool isFriendToHide() const
612  { return getMdAlias()->isFriendToHide(); }
613  virtual bool isNotFriend() const
614  { return getMdAlias()->isNotFriend(); }
615  virtual bool isFunctionOrSignalSlot() const
616  { return getMdAlias()->isFunctionOrSignalSlot(); }
617  virtual bool isRelatedOrFriend() const
618  { return getMdAlias()->isRelatedOrFriend(); }
619  virtual bool isLinkableInProject() const
620  { return getMdAlias()->isLinkableInProject(); }
621  virtual bool isLinkable() const
622  { return getMdAlias()->isLinkable(); }
623  virtual bool hasDocumentation() const
624  { return getMdAlias()->hasDocumentation(); }
625  virtual bool isDeleted() const
626  { return getMdAlias()->isDeleted(); }
627  virtual bool isBriefSectionVisible() const
628  { return getMdAlias()->isBriefSectionVisible(); }
629  virtual bool isDetailedSectionVisible(bool inGroup,bool inFile) const
630  { return getMdAlias()->isDetailedSectionVisible(inGroup,inFile); }
631  virtual bool isDetailedSectionLinkable() const
632  { return getMdAlias()->isDetailedSectionLinkable(); }
633  virtual bool isFriendClass() const
634  { return getMdAlias()->isFriendClass(); }
635  virtual bool isDocumentedFriendClass() const
636  { return getMdAlias()->isDocumentedFriendClass(); }
637  virtual MemberDef *reimplements() const
638  { return getMdAlias()->reimplements(); }
639  virtual MemberList *reimplementedBy() const
640  { return getMdAlias()->reimplementedBy(); }
641  virtual bool isReimplementedBy(const ClassDef *cd) const
642  { return getMdAlias()->isReimplementedBy(cd); }
643  virtual ClassDef *relatedAlso() const
644  { return getMdAlias()->relatedAlso(); }
645  virtual bool hasDocumentedEnumValues() const
646  { return getMdAlias()->hasDocumentedEnumValues(); }
647  virtual const MemberDef *getAnonymousEnumType() const
648  { return getMdAlias()->getAnonymousEnumType(); }
649  virtual bool isDocsForDefinition() const
650  { return getMdAlias()->isDocsForDefinition(); }
651  virtual const MemberDef *getEnumScope() const
652  { return getMdAlias()->getEnumScope(); }
653  virtual const MemberList *enumFieldList() const
654  { return getMdAlias()->enumFieldList(); }
655  virtual QCString enumBaseType() const
656  { return getMdAlias()->enumBaseType(); }
657  virtual bool hasExamples() const
658  { return getMdAlias()->hasExamples(); }
659  virtual ExampleSDict *getExamples() const
660  { return getMdAlias()->getExamples(); }
661  virtual bool isPrototype() const
662  { return getMdAlias()->isPrototype(); }
663  virtual const ArgumentList &argumentList() const
664  { return getMdAlias()->argumentList(); }
665  virtual const ArgumentList &declArgumentList() const
666  { return getMdAlias()->declArgumentList(); }
667  virtual const ArgumentList &templateArguments() const
668  { return getMdAlias()->templateArguments(); }
669  virtual const std::vector<ArgumentList> &definitionTemplateParameterLists() const
671  virtual int getMemberGroupId() const
672  { return getMdAlias()->getMemberGroupId(); }
673  virtual MemberGroup *getMemberGroup() const
674  { return m_memberGroup; }
675  virtual bool fromAnonymousScope() const
676  { return getMdAlias()->fromAnonymousScope(); }
677  virtual bool anonymousDeclShown() const
678  { return getMdAlias()->anonymousDeclShown(); }
680  { return getMdAlias()->fromAnonymousMember(); }
681  virtual bool hasCallGraph() const
682  { return getMdAlias()->hasCallGraph(); }
683  virtual bool hasCallerGraph() const
684  { return getMdAlias()->hasCallerGraph(); }
685  virtual bool visibleMemberGroup(bool hideNoHeader) const
686  { return getMdAlias()->visibleMemberGroup(hideNoHeader); }
687  virtual bool hasReferencesRelation() const
688  { return getMdAlias()->hasReferencesRelation(); }
689  virtual bool hasReferencedByRelation() const
690  { return getMdAlias()->hasReferencedByRelation(); }
691  virtual MemberDef *templateMaster() const
692  { return getMdAlias()->templateMaster(); }
693  virtual QCString getScopeString() const
694  { return getMdAlias()->getScopeString(); }
696  { return getMdAlias()->getClassDefOfAnonymousType(); }
697  virtual bool isTypedefValCached() const
698  { return getMdAlias()->isTypedefValCached(); }
699  virtual const ClassDef *getCachedTypedefVal() const
700  { return getMdAlias()->getCachedTypedefVal(); }
702  { return getMdAlias()->getCachedTypedefTemplSpec(); }
704  { return getMdAlias()->getCachedResolvedTypedef(); }
705  virtual MemberDef *memberDefinition() const
706  { return getMdAlias()->memberDefinition(); }
707  virtual MemberDef *memberDeclaration() const
708  { return getMdAlias()->memberDeclaration(); }
709  virtual MemberDef *inheritsDocsFrom() const
710  { return getMdAlias()->inheritsDocsFrom(); }
711  virtual const MemberDef *getGroupAlias() const
712  { return getMdAlias()->getGroupAlias(); }
713  virtual ClassDef *category() const
714  { return getMdAlias()->category(); }
715  virtual MemberDef *categoryRelation() const
716  { return getMdAlias()->categoryRelation(); }
717  virtual QCString displayName(bool b=TRUE) const
718  { return getMdAlias()->displayName(b); }
719  virtual QCString getDeclType() const
720  { return getMdAlias()->getDeclType(); }
721  virtual void getLabels(QStrList &sl,const Definition *container) const
722  { return getMdAlias()->getLabels(sl,container); }
723  virtual const ArgumentList &typeConstraints() const
724  { return getMdAlias()->typeConstraints(); }
725  virtual QCString documentation() const
726  { return getMdAlias()->documentation(); }
727  virtual QCString briefDescription(bool abbr=FALSE) const
728  { return getMdAlias()->briefDescription(); }
729  virtual QCString fieldType() const
730  { return getMdAlias()->fieldType(); }
731  virtual bool isReference() const
732  { return getMdAlias()->isReference(); }
733  virtual QCString getDeclFileName() const
734  { return getMdAlias()->getDeclFileName(); }
735  virtual int getDeclLine() const
736  { return getMdAlias()->getDeclLine(); }
737  virtual int getDeclColumn() const
738  { return getMdAlias()->getDeclColumn(); }
739 
740  // non-const getters should not be called
742  { err("non-const getClassDef() called on aliased member. Please report as a bug.\n"); return 0; }
743  virtual FileDef *getFileDef()
744  { err("non-const getFileDef() called on aliased member. Please report as a bug.\n"); return 0; }
746  { err("non-const getNamespaceDef() called on aliased member. Please report as a bug.\n"); return 0; }
748  { err("non-const getGroupDef() called on aliased member. Please report as a bug.\n"); return 0; }
750  { err("non-const argumentList() called on aliased member. Please report as bug.\n");
751  static ArgumentList dummy; return dummy;
752  }
753 
754  virtual void setEnumBaseType(const QCString &type) {}
755  virtual void setMemberType(MemberType t) {}
756  virtual void setDefinition(const char *d) {}
757  virtual void setFileDef(FileDef *fd) {}
758  virtual void setAnchor() {}
759  virtual void setProtection(Protection p) {}
760  virtual void setMemberSpecifiers(uint64 s) {}
761  virtual void mergeMemberSpecifiers(uint64 s) {}
762  virtual void setInitializer(const char *i) {}
763  virtual void setBitfields(const char *s) {}
764  virtual void setMaxInitLines(int lines) {}
765  virtual void setMemberClass(ClassDef *cd) {}
766  virtual void setSectionList(MemberList *sl) {}
768  const QCString &fileName,int startLine,bool hasDocs,
769  MemberDef *member=0) {}
770  virtual void setReadAccessor(const char *r) {}
771  virtual void setWriteAccessor(const char *w) {}
772  virtual void setTemplateSpecialization(bool b) {}
773  virtual void makeRelated() {}
774  virtual void makeForeign() {}
775  virtual void setInheritsDocsFrom(MemberDef *md) {}
776  virtual void setTagInfo(const TagInfo *i) {}
777  virtual void setArgsString(const char *as) {}
778  virtual void setReimplements(MemberDef *md) {}
779  virtual void insertReimplementedBy(MemberDef *md) {}
780  virtual void setRelatedAlso(ClassDef *cd) {}
781  virtual void insertEnumField(MemberDef *md) {}
782  virtual void setEnumScope(MemberDef *md,bool livesInsideEnum=FALSE) {}
783  virtual void setEnumClassScope(ClassDef *cd) {}
784  virtual void setDocumentedEnumValues(bool value) {}
785  virtual void setAnonymousEnumType(const MemberDef *md) {}
786  virtual bool addExample(const char *anchor,const char *name,const char *file) { return FALSE; }
787  virtual void setPrototype(bool p,const QCString &df,int line, int column) {}
788  virtual void setExplicitExternal(bool b,const QCString &df,int line,int column) {}
789  virtual void setDeclFile(const QCString &df,int line,int column) {}
790  virtual void setArgumentList(const ArgumentList &al) {}
791  virtual void setDeclArgumentList(const ArgumentList &al) {}
792  virtual void setDefinitionTemplateParameterLists(const std::vector<ArgumentList> &lists) {}
793  virtual void setTypeConstraints(const ArgumentList &al) {}
794  virtual void setType(const char *t) {}
795  virtual void setAccessorType(ClassDef *cd,const char *t) {}
796  virtual void setNamespace(NamespaceDef *nd) {}
797  virtual void setMemberGroup(MemberGroup *grp) { m_memberGroup = grp; }
798  virtual void setMemberGroupId(int id) {}
799  virtual void makeImplementationDetail() {}
800  virtual void setFromAnonymousScope(bool b) const {}
801  virtual void setFromAnonymousMember(MemberDef *m) {}
802  virtual void enableCallGraph(bool e) {}
803  virtual void enableCallerGraph(bool e) {}
804  virtual void enableReferencedByRelation(bool e) {}
805  virtual void enableReferencesRelation(bool e) {}
806  virtual void setTemplateMaster(MemberDef *mt) {}
807  virtual void addListReference(Definition *d) {}
808  virtual void setDocsForDefinition(bool b) {}
809  virtual void setGroupAlias(const MemberDef *md) {}
810  virtual void cacheTypedefVal(const ClassDef *val,const QCString &templSpec,const QCString &resolvedType) {}
811  virtual void invalidateTypedefValCache() {}
813  virtual void setMemberDefinition(MemberDef *md) {}
814  virtual void setMemberDeclaration(MemberDef *md) {}
815  virtual void setAnonymousUsed() const {}
816  virtual void copyArgumentNames(MemberDef *bmd) {}
817  virtual void setCategory(ClassDef *) {}
818  virtual void setCategoryRelation(MemberDef *) {}
819  virtual void setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace=TRUE) {}
820  virtual void setBriefDescription(const char *b,const char *briefFile,int briefLine) {}
821  virtual void setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine) {}
822  virtual void setHidden(bool b) {}
823  virtual void addToSearchIndex() const {}
824  virtual void findSectionsInDocumentation() {}
826  const ArgumentList &actualArgs) const
827  { return getMdAlias()->createTemplateInstanceMember(formalArgs,actualArgs); }
828  virtual void incrementFlowKeyWordCount() {}
829 
830  virtual void writeDeclaration(OutputList &ol,
831  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
832  bool inGroup, const ClassDef *inheritFrom=0,const char *inheritId=0) const
833  {
834  getMdAlias()->writeDeclaration(ol,cd,nd,fd,gd,inGroup,inheritFrom,inheritId);
835  }
836  virtual void writeEnumDeclaration(OutputList &typeDecl,
837  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd) const
838  {
839  getMdAlias()->writeEnumDeclaration(typeDecl,cd,nd,fd,gd);
840  }
841  virtual void writeDocumentation(const MemberList *ml,int memCount,int memTotal,OutputList &ol,
842  const char *scopeName,const Definition *container,
843  bool inGroup,bool showEnumValues=FALSE,bool
844  showInline=FALSE) const {}
845  virtual void writeMemberDocSimple(OutputList &ol,const Definition *container) const {}
846  virtual void writeLink(OutputList &ol,
847  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
848  bool onlyText=FALSE) const {}
849  virtual void writeTagFile(FTextStream &) const {}
850  virtual void warnIfUndocumented() const {}
851  virtual void warnIfUndocumentedParams() const {}
852  virtual void detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const {}
853  private:
854  MemberGroup *m_memberGroup; // group's member definition
855 };
856 
857 
858 MemberDef *createMemberDefAlias(const Definition *newScope,const MemberDef *aliasMd)
859 {
860  return new MemberDefAliasImpl(newScope,aliasMd);
861 }
862 
863 //-----------------------------------------------------------------------------
864 
866 
867 //-----------------------------------------------------------------------------
868 
869 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
870 {
871  QCString result;
872  QCString clRealName=n;
873  int p=0,i;
874  if ((i=clRealName.find('<'))!=-1)
875  {
876  clRealName=clRealName.left(i); // strip template specialization
877  }
878  if ((i=clRealName.findRev("::"))!=-1)
879  {
880  clRealName=clRealName.right(clRealName.length()-i-2);
881  }
882  while ((i=s.find(clRealName,p))!=-1)
883  {
884  result+=s.mid(p,i-p);
885  uint j=clRealName.length()+i;
886  if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
887  { // add template names
888  //printf("Adding %s+%s\n",clRealName.data(),t.data());
889  result+=clRealName+t;
890  }
891  else
892  { // template names already present
893  //printf("Adding %s\n",clRealName.data());
894  result+=clRealName;
895  }
896  p=i+clRealName.length();
897  }
898  result+=s.right(s.length()-p);
899  //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
900  return result;
901 }
902 
903 // ol.startMemberDocName has already been done before this is called.
904 // when this function returns TRUE, ol.endParameterList will be called.
905 //
906 // typical sequence:
907 // ol.startMemberDoc
908 // ol.startMemberDocName
909 // --- enter writeDefArgumentList
910 // ol.endMemberDocName
911 // ol.startParameterList
912 // ...
913 // ol.startParameterType(first=TRUE)
914 // ol.endParameterType
915 // ol.startParameterName
916 // ol.endParameterName(last==FALSE)
917 // ...
918 // ol.startParameterType(first=FALSE)
919 // ol.endParameterType
920 // ol.startParameterName
921 // ol.endParameterName(last==TRUE)
922 // ...
923 // --- leave writeDefArgumentList with return value TRUE
924 // ol.endParameterList
925 // ol.endMemberDoc(hasArgs=TRUE)
926 //
927 // For an empty list the function should return FALSE, the sequence is
928 // ol.startMemberDoc
929 // ol.startMemberDocName
930 // --- enter writeDefArgumentList
931 // --- leave writeDefArgumentList with return value FALSE
932 // ol.endMemberDocName
933 // ol.endMemberDoc(hasArgs=FALSE);
934 //
935 
936 static bool writeDefArgumentList(OutputList &ol,const Definition *scope,const MemberDef *md)
937 {
938  const ArgumentList &defArgList=(md->isDocsForDefinition()) ?
939  md->argumentList() : md->declArgumentList();
940  //printf("writeDefArgumentList '%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
941  if (!defArgList.hasParameters() || md->isProperty())
942  {
943  return FALSE; // member has no function like argument list
944  }
945 
946  if (!md->isDefine()) ol.docify(" ");
947 
948  //printf("writeDefArgList(%d)\n",defArgList->count());
949  ol.pushGeneratorState();
950  //ol.disableAllBut(OutputGenerator::Html);
951  bool htmlOn = ol.isEnabled(OutputGenerator::Html);
952  bool latexOn = ol.isEnabled(OutputGenerator::Latex);
953  bool docbookOn = ol.isEnabled(OutputGenerator::Docbook);
954  {
955  // html and latex
956  if (htmlOn) ol.enable(OutputGenerator::Html);
957  if (latexOn) ol.enable(OutputGenerator::Latex);
958  if (docbookOn) ol.enable(OutputGenerator::Docbook);
959 
960  ol.endMemberDocName();
961  ol.startParameterList(!md->isObjCMethod());
962  }
963  ol.enableAll();
967  {
968  // other formats
969  if (!md->isObjCMethod()) ol.docify("("); // start argument list
970  ol.endMemberDocName();
971  }
972  ol.popGeneratorState();
973  //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
974 
975  QCString cName;
976  if (scope)
977  {
978  cName=scope->name();
979  int il=cName.find('<');
980  int ir=cName.findRev('>');
981  if (il!=-1 && ir!=-1 && ir>il)
982  {
983  cName=cName.mid(il,ir-il+1);
984  //printf("1. cName=%s\n",cName.data());
985  }
986  else if (scope->definitionType()==Definition::TypeClass)
987  {
988  cName=tempArgListToString((dynamic_cast<const ClassDef*>(scope))->templateArguments(),
989  scope->getLanguage());
990  //printf("2. cName=%s\n",cName.data());
991  }
992  else // no template specifier
993  {
994  cName.resize(0);
995  }
996  }
997  //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
998 
999  bool first=TRUE;
1000  bool paramTypeStarted=FALSE;
1001  bool isDefine = md->isDefine();
1002  auto alIt = defArgList.begin();
1003  while (alIt!=defArgList.end())
1004  {
1005  Argument a = *alIt;
1006  if (isDefine || first)
1007  {
1008  ol.startParameterType(first,0);
1009  paramTypeStarted=TRUE;
1010  if (isDefine)
1011  {
1012  ol.endParameterType();
1014  }
1015  }
1016  QRegExp re(")("),res("(.*\\*");
1017  int vp=a.type.find(re);
1018  int wp=a.type.find(res);
1019 
1020  // use the following to put the function pointer type before the name
1021  bool hasFuncPtrType=FALSE;
1022 
1023  if (!a.attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
1024  {
1025  ol.docify(a.attrib+" ");
1026  }
1027  if (hasFuncPtrType) // argument type is a function pointer
1028  {
1029  //printf("a.type='%s' a.name='%s'\n",a.type.data(),a.name.data());
1030  QCString n=a.type.left(vp);
1031  if (hasFuncPtrType) n=a.type.left(wp);
1032  if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
1033  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
1034  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
1035  }
1036  else // non-function pointer type
1037  {
1038  QCString n=a.type;
1039  if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
1040  if (a.type!="...")
1041  {
1042  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
1043  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
1044  }
1045  }
1046  if (!isDefine)
1047  {
1048  if (paramTypeStarted)
1049  {
1050  ol.endParameterType();
1051  paramTypeStarted=FALSE;
1052  }
1053  ol.startParameterName(defArgList.size()<2);
1054  }
1055  if (hasFuncPtrType)
1056  {
1057  ol.docify(a.type.mid(wp,vp-wp));
1058  }
1059  if (!a.name.isEmpty() || a.type=="...") // argument has a name
1060  {
1061  //if (!hasFuncPtrType)
1062  //{
1063  // ol.docify(" ");
1064  //}
1068  ol.docify(" "); /* man page */
1069  if (htmlOn) ol.enable(OutputGenerator::Html);
1071  ol.startEmphasis();
1073  if (latexOn) ol.enable(OutputGenerator::Latex);
1074  if (docbookOn) ol.enable(OutputGenerator::Docbook);
1075  if (a.name.isEmpty()) ol.docify(a.type); else ol.docify(a.name);
1079  ol.endEmphasis();
1081  if (latexOn) ol.enable(OutputGenerator::Latex);
1082  if (docbookOn) ol.enable(OutputGenerator::Docbook);
1083  }
1084  if (!a.array.isEmpty())
1085  {
1086  ol.docify(a.array);
1087  }
1088  if (hasFuncPtrType) // write the part of the argument type
1089  // that comes after the name
1090  {
1091  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),
1092  md,a.type.right(a.type.length()-vp));
1093  }
1094  if (!a.defval.isEmpty()) // write the default value
1095  {
1096  QCString n=a.defval;
1097  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
1098  ol.docify(" = ");
1099 
1100  ol.startTypewriter();
1101  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
1102  ol.endTypewriter();
1103 
1104  }
1105  ++alIt;
1106  if (alIt!=defArgList.end())
1107  {
1108  a = *alIt;
1109  if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
1110  if (!isDefine)
1111  {
1112  QCString key;
1113  if (md->isObjCMethod() && a.attrib.length()>=2)
1114  {
1115  //printf("Found parameter keyword %s\n",a.attrib.data());
1116  // strip [ and ]
1117  key=a.attrib.mid(1,a.attrib.length()-2);
1118  if (key!=",") key+=":"; // for normal keywords add colon
1119  }
1121  if (paramTypeStarted)
1122  {
1123  ol.endParameterType();
1124  }
1125  ol.startParameterType(FALSE,key);
1126  paramTypeStarted=TRUE;
1127  }
1128  else // isDefine
1129  {
1131  }
1132  }
1133  first=FALSE;
1134  }
1135  ol.pushGeneratorState();
1139  if (!md->isObjCMethod()) ol.docify(")"); // end argument list
1140  ol.enableAll();
1141  if (htmlOn) ol.enable(OutputGenerator::Html);
1142  if (latexOn) ol.enable(OutputGenerator::Latex);
1143  if (docbookOn) ol.enable(OutputGenerator::Docbook);
1144  if (first) ol.startParameterName(defArgList.size()<2);
1145  ol.endParameterName(TRUE,defArgList.size()<2,!md->isObjCMethod());
1146  ol.popGeneratorState();
1147  if (md->extraTypeChars())
1148  {
1149  ol.docify(md->extraTypeChars());
1150  }
1151  if (defArgList.constSpecifier)
1152  {
1153  ol.docify(" const");
1154  }
1155  if (defArgList.volatileSpecifier)
1156  {
1157  ol.docify(" volatile");
1158  }
1159  if (defArgList.refQualifier==RefQualifierLValue)
1160  {
1161  ol.docify(" &");
1162  }
1163  else if (defArgList.refQualifier==RefQualifierRValue)
1164  {
1165  ol.docify(" &&");
1166  }
1167  if (!defArgList.trailingReturnType.isEmpty())
1168  {
1169  linkifyText(TextGeneratorOLImpl(ol), // out
1170  scope, // scope
1171  md->getBodyDef(), // fileScope
1172  md, // self
1173  defArgList.trailingReturnType, // text
1174  FALSE // autoBreak
1175  );
1176 
1177  }
1178  return TRUE;
1179 }
1180 
1182  OutputList &ol, const ClassDef *cd, const MemberDef *md, QCString const& exception)
1183 {
1184  // this is ordinary exception spec - there must be a '('
1185  //printf("exception='%s'\n",exception.data());
1186  int index = exception.find('(');
1187  if (index!=-1)
1188  {
1189  ol.exceptionEntry(exception.left(index),false);
1190  ++index; // paren in second column so skip it here
1191  for (int comma = exception.find(',', index); comma!=-1; )
1192  {
1193  ++comma; // include comma
1194  linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,
1195  exception.mid(index,comma-index));
1196  ol.exceptionEntry(0,false);
1197  index=comma;
1198  comma = exception.find(',', index);
1199  }
1200  int close = exception.find(')', index);
1201  if (close!=-1)
1202  {
1203  QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
1204  linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,type);
1205  ol.exceptionEntry(0,true);
1206  }
1207  else
1208  {
1209  warn(md->getDefFileName(),md->getDefLine(),
1210  "missing ) in exception list on member %s",qPrint(md->name()));
1211  }
1212  }
1213  else // Java Exception
1214  {
1215  ol.docify(" ");
1216  linkifyText(TextGeneratorOLImpl(ol),cd,md->getBodyDef(),md,exception);
1217  }
1218 }
1219 
1220 static void writeExceptionList(OutputList &ol, const ClassDef *cd, const MemberDef *md)
1221 {
1222  QCString exception(QCString(md->excpString()).stripWhiteSpace());
1223  if ('{'==exception.at(0))
1224  {
1225  // this is an UNO IDL attribute - need special handling
1226  int index = exception.find(';');
1227  int oldIndex = 1;
1228  while (-1 != index) // there should be no more than 2 (set / get)
1229  {
1230  // omit '{' and ';' -> "set raises (...)"
1231  writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
1232  oldIndex=index+1;
1233  index = exception.find(';',oldIndex);
1234  }
1235  // the rest is now just '}' - omit that
1236  }
1237  else
1238  {
1239  writeExceptionListImpl(ol,cd,md,exception);
1240  }
1241 }
1242 
1243 static void writeTemplatePrefix(OutputList &ol,const ArgumentList &al)
1244 {
1245  ol.docify("template<");
1246  for (auto it = al.begin(); it!=al.end();)
1247  {
1248  Argument a = *it;
1249  ol.docify(a.type);
1250  ol.docify(" ");
1251  ol.docify(a.name);
1252  if (a.defval.length()!=0)
1253  {
1254  ol.docify(" = ");
1255  ol.docify(a.defval);
1256  }
1257  ++it;
1258  if (it!=al.end()) ol.docify(", ");
1259  }
1260  ol.docify("> ");
1261 }
1262 
1263 //-----------------------------------------------------------------------------
1264 //-----------------------------------------------------------------------------
1265 //-----------------------------------------------------------------------------
1266 
1268 {
1269  public:
1270  IMPL();
1271  ~IMPL();
1272  void init(Definition *def,const char *t,const char *a,const char *e,
1273  Protection p,Specifier v,bool s,Relationship r,
1274  MemberType mt,const ArgumentList &tal,
1275  const ArgumentList &al,const char *meta
1276  );
1277 
1278  ClassDef *classDef = 0; // member of or related to
1279  FileDef *fileDef = 0; // member of file definition
1280  NamespaceDef *nspace = 0; // the namespace this member is in.
1281 
1282  MemberDef *enumScope = 0; // the enclosing scope, if this is an enum field
1283  bool livesInsideEnum = false;
1284  const MemberDef *annEnumType = 0; // the anonymous enum that is the type of this member
1285  MemberList *enumFields = 0; // enumeration fields
1286 
1287  MemberDef *redefines = 0; // the members that this member redefines
1288  MemberList *redefinedBy = 0; // the list of members that redefine this one
1289 
1290  MemberDef *memDef = 0; // member definition for this declaration
1291  MemberDef *memDec = 0; // member declaration for this definition
1292  ClassDef *relatedAlso = 0; // points to class marked by relatedAlso
1293 
1294  ExampleSDict *exampleSDict = 0; // a dictionary of all examples for quick access
1295 
1296  QCString type; // return actual type
1297  QCString accessorType; // return type that tell how to get to this member
1298  ClassDef *accessorClass = 0; // class that this member accesses (for anonymous types)
1299  QCString args; // function arguments/variable array specifiers
1300  QCString def; // member definition in code (fully qualified name)
1301  QCString anc; // HTML anchor name
1302  Specifier virt = Normal; // normal/virtual/pure virtual
1303  Protection prot = Public; // protection type [Public/Protected/Private]
1304  QCString decl; // member declaration in class
1305 
1306  QCString bitfields; // struct member bitfields
1307  QCString read; // property read accessor
1308  QCString write; // property write accessor
1309  QCString exception; // exceptions that can be thrown
1310  QCString initializer; // initializer
1311  QCString extraTypeChars; // extra type info found after the argument list
1312  QCString enumBaseType; // base type of the enum (C++11)
1313  int initLines = 0; // number of lines in the initializer
1314 
1315  uint64 memSpec = 0; // The specifiers present for this member
1316  MemberType mtype = MemberType_Define; // returns the kind of member
1317  int maxInitLines = 0; // when the initializer will be displayed
1318  int userInitLines = 0; // result of explicit \hideinitializer or \showinitializer
1320 
1321  ArgumentList defArgList; // argument list of this member definition
1322  ArgumentList declArgList; // argument list of this member declaration
1323 
1324  ArgumentList tArgList; // template argument list of function template
1325  ArgumentList typeConstraints; // type constraints for template parameters
1327  std::vector<ArgumentList> defTmpArgLists; // lists of template argument lists
1328  // (for template functions in nested template classes)
1329 
1330  QCString metaData; // Slice metadata.
1331 
1332  ClassDef *cachedAnonymousType; // if the member has an anonymous compound
1333  // as its type then this is computed by
1334  // getClassDefOfAnonymousType() and
1335  // cached here.
1336  SDict<MemberList> *classSectionSDict = 0; // not accessible
1337 
1338  const MemberDef *groupAlias = 0; // Member containing the definition
1339  int grpId = 0; // group id
1340  MemberGroup *memberGroup = 0; // group's member definition
1341  GroupDef *group = 0; // group in which this member is in
1342  Grouping::GroupPri_t grouppri; // priority of this definition
1343  QCString groupFileName; // file where this grouping was defined
1344  int groupStartLine = 0; // line " " " " "
1346 
1347  bool isTypedefValCached = false;
1351 
1352  // inbody documentation
1353  //int inbodyLine;
1354  //QCString inbodyFile;
1355  //QCString inbodyDocs;
1356 
1357  // documentation inheritance
1359 
1360  // to store the output file base from tag files
1362 
1363  // objective-c
1364  bool implOnly = false; // function found in implementation but not
1365  // in the interface
1366  mutable bool hasDocumentedParams = false;
1367  mutable bool hasDocumentedReturnType = false;
1368  bool isDMember = false;
1369  Relationship related = Member; // relationship of this to the class
1370  bool stat = false; // is it a static function?
1371  bool proto = false; // is it a prototype?
1372  bool docEnumValues = false; // is an enum with documented enum values.
1373 
1374  mutable bool annScope = false; // member is part of an anonymous scope
1375  mutable bool annUsed = false; // ugly: needs to be mutable to allow setAnonymousUsed to act as a
1376  // const member.
1377  bool hasCallGraph = false;
1378  bool hasCallerGraph = false;
1381  bool explExt = false; // member was explicitly declared external
1382  bool tspec = false; // member is a template specialization
1383  bool groupHasDocs = false; // true if the entry that caused the grouping was documented
1384  bool docsForDefinition = false; // TRUE => documentation block is put before
1385  // definition.
1386  // FALSE => block is put before declaration.
1390  int declLine = 0;
1391  int declColumn = 0;
1393 };
1394 
1396  enumFields(0),
1397  redefinedBy(0),
1398  exampleSDict(0),
1399  classSectionSDict(0),
1400  category(0),
1401  categoryRelation(0),
1402  declLine(-1),
1403  declColumn(-1),
1404  numberOfFlowKW(0)
1405 {
1406 }
1407 
1409 {
1410  delete redefinedBy;
1411  delete exampleSDict;
1412  delete enumFields;
1413  delete classSectionSDict;
1414 }
1415 
1417  const char *t,const char *a,const char *e,
1418  Protection p,Specifier v,bool s,Relationship r,
1419  MemberType mt,const ArgumentList &tal,
1420  const ArgumentList &al,const char *meta
1421  )
1422 {
1423  classDef=0;
1424  fileDef=0;
1425  redefines=0;
1426  relatedAlso=0;
1427  redefinedBy=0;
1428  accessorClass=0;
1429  nspace=0;
1430  memDef=0;
1431  memDec=0;
1432  group=0;
1433  grpId=-1;
1434  exampleSDict=0;
1435  enumFields=0;
1436  enumScope=0;
1438  hasCallGraph = FALSE;
1442  initLines=0;
1443  type=t;
1444  if (mt==MemberType_Typedef) type.stripPrefix("typedef ");
1445  // type.stripPrefix("struct ");
1446  // type.stripPrefix("class " );
1447  // type.stripPrefix("union " );
1448  type=removeRedundantWhiteSpace(type);
1449  args=a;
1450  args=removeRedundantWhiteSpace(args);
1451  if (type.isEmpty()) decl=d->name()+args; else decl=type+" "+d->name()+args;
1452 
1453  memberGroup=0;
1454  virt=v;
1455  prot=p;
1456  related=r;
1457  stat=s;
1458  mtype=mt;
1459  exception=e;
1460  proto=FALSE;
1461  annScope=FALSE;
1462  memSpec=0;
1463  annMemb=0;
1464  annUsed=FALSE;
1465  annEnumType=0;
1466  groupAlias=0;
1467  explExt=FALSE;
1468  tspec=FALSE;
1469  cachedAnonymousType=0;
1470  maxInitLines=Config_getInt(MAX_INITIALIZER_LINES);
1471  userInitLines=-1;
1472  docEnumValues=FALSE;
1473  // copy function template arguments (if any)
1474  tArgList = tal;
1475  //printf("new member al=%p\n",al);
1476  // copy function definition arguments (if any)
1477  defArgList = al;
1478  // convert function declaration arguments (if any)
1479  if (!args.isEmpty())
1480  {
1481  stringToArgumentList(d->getLanguage(),args,declArgList,&extraTypeChars);
1482  //printf("setDeclArgList %s to %s const=%d\n",args.data(),
1483  // argListToString(declArgList).data(),declArgList->constSpecifier);
1484  }
1485  metaData = meta;
1486  templateMaster = 0;
1487  classSectionSDict = 0;
1488  docsForDefinition = TRUE;
1490  cachedTypedefValue = 0;
1491  //inbodyLine = -1;
1492  implOnly=FALSE;
1493  groupMember = 0;
1494  hasDocumentedParams = FALSE;
1495  hasDocumentedReturnType = FALSE;
1496  docProvider = 0;
1497  isDMember = d->getDefFileName().right(2).lower()==".d";
1498 }
1499 
1500 
1501 //-----------------------------------------------------------------------------
1502 //-----------------------------------------------------------------------------
1503 //-----------------------------------------------------------------------------
1504 
1528 MemberDefImpl::MemberDefImpl(const char *df,int dl,int dc,
1529  const char *t,const char *na,const char *a,const char *e,
1530  Protection p,Specifier v,bool s,Relationship r,MemberType mt,
1531  const ArgumentList &tal,const ArgumentList &al,const char *meta
1532  ) : DefinitionImpl(df,dl,dc,removeRedundantWhiteSpace(na))
1533 {
1534  //printf("MemberDefImpl::MemberDef(%s)\n",na);
1536  m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al,meta);
1537  m_isLinkableCached = 0;
1540 }
1541 
1543 {
1545  m_isLinkableCached = 0;
1548 }
1549 
1551 {
1552  //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
1553  MemberDefImpl *result = new MemberDefImpl(*this);
1554  // first copy everything by reference
1555  *result->m_impl = *m_impl;
1556  // clear pointers owned by object
1557  result->m_impl->redefinedBy= 0;
1558  result->m_impl->exampleSDict=0;
1559  result->m_impl->enumFields=0;
1560  result->m_impl->classSectionSDict=0;
1561  // replace pointers owned by the object by deep copies
1562  if (m_impl->redefinedBy)
1563  {
1565  MemberDef *md;
1566  for (mli.toFirst();(md=mli.current());++mli)
1567  {
1568  result->insertReimplementedBy(md);
1569  }
1570  }
1571  if (m_impl->exampleSDict)
1572  {
1574  Example *e;
1575  for (it.toFirst();(e=it.current());++it)
1576  {
1577  result->addExample(e->anchor,e->name,e->file);
1578  }
1579  }
1580  if (m_impl->enumFields)
1581  {
1583  MemberDef *md;
1584  for (mli.toFirst();(md=mli.current());++mli)
1585  {
1586  result->insertEnumField(md);
1587  }
1588  }
1589  result->m_impl->defArgList = m_impl->defArgList;
1590  result->m_impl->tArgList = m_impl->tArgList;
1594  {
1595  result->m_impl->classSectionSDict = new SDict<MemberList>(7);
1597  MemberList *ml;
1598  for (it.toFirst();(ml=it.current());++it)
1599  {
1600  result->m_impl->classSectionSDict->append(it.currentKey(),ml);
1601  }
1602  }
1603  result->m_impl->declArgList = m_impl->declArgList;
1604  return result;
1605 }
1606 
1608 {
1609  setOuterScope(scope);
1610  if (scope->definitionType()==Definition::TypeClass)
1611  {
1612  m_impl->classDef = dynamic_cast<ClassDef*>(scope);
1613  }
1614  else if (scope->definitionType()==Definition::TypeFile)
1615  {
1616  m_impl->fileDef = dynamic_cast<FileDef*>(scope);
1617  }
1618  else if (scope->definitionType()==Definition::TypeNamespace)
1619  {
1620  m_impl->nspace = dynamic_cast<NamespaceDef*>(scope);
1621  }
1622  m_isLinkableCached = 0;
1624 }
1625 
1626 
1629 {
1630  delete m_impl;
1631  //printf("%p: ~MemberDef()\n",this);
1632  m_impl=0;
1633 }
1634 
1636 {
1637  m_impl->redefines = md;
1638 }
1639 
1641 {
1642  if (m_impl->templateMaster)
1643  {
1645  }
1647  if (m_impl->redefinedBy->findRef(md)==-1)
1648  {
1649  m_impl->redefinedBy->inSort(md);
1650  }
1651 }
1652 
1654 {
1655  return m_impl->redefines;
1656 }
1657 
1659 {
1660  return m_impl->redefinedBy;
1661 }
1662 
1664 {
1665  if (cd && m_impl->redefinedBy)
1666  {
1668  MemberDef *md;
1669  for (mi.toFirst();(md=mi.current());++mi)
1670  {
1671  const ClassDef *mcd = md->getClassDef();
1672  if (mcd)
1673  {
1674  if (cd==mcd || cd->isBaseClass(mcd,TRUE))
1675  {
1676  return TRUE;
1677  }
1678  }
1679  }
1680  }
1681  return FALSE;
1682 }
1683 
1685 {
1687  m_impl->enumFields->append(md);
1688 }
1689 
1690 bool MemberDefImpl::addExample(const char *anchor,const char *nameStr,
1691  const char *file)
1692 {
1693  //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
1695  if (m_impl->exampleSDict->find(nameStr)==0)
1696  {
1697  //printf("Add reference to example %s to member %s\n",nameStr,name.data());
1698  Example *e=new Example;
1699  e->anchor=anchor;
1700  e->name=nameStr;
1701  e->file=file;
1702  m_impl->exampleSDict->inSort(nameStr,e);
1703  return TRUE;
1704  }
1705  return FALSE;
1706 }
1707 
1709 {
1710  if (m_impl->exampleSDict==0)
1711  return FALSE;
1712  else
1713  return m_impl->exampleSDict->count()>0;
1714 }
1715 
1717 {
1718  static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1719  static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
1720  QCString baseName;
1721 
1722  //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
1723  // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
1724  // m_impl->nspace,m_impl->fileDef);
1725  const NamespaceDef *nspace = getNamespaceDef();
1726  const FileDef *fileDef = getFileDef();
1727  const ClassDef *classDef = getClassDef();
1728  const GroupDef *groupDef = getGroupDef();
1730  {
1732  }
1733  else if (templateMaster())
1734  {
1735  return templateMaster()->getOutputFileBase();
1736  }
1737  else if (groupDef)
1738  {
1739  baseName=groupDef->getOutputFileBase();
1740  }
1741  else if (classDef)
1742  {
1743  baseName=classDef->getOutputFileBase();
1744  if (inlineSimpleClasses && classDef->isSimple())
1745  {
1746  return baseName;
1747  }
1748  }
1749  else if (nspace && (nspace->isLinkable() || nspace->isAnonymous()))
1750  {
1751  baseName=nspace->getOutputFileBase();
1752  }
1753  else if (fileDef)
1754  {
1755  baseName=fileDef->getOutputFileBase();
1756  }
1757 
1758  if (baseName.isEmpty())
1759  {
1761  "Internal inconsistency: member %s does not belong to any"
1762  " container!",qPrint(name())
1763  );
1764  return "dummy";
1765  }
1766  else if (separateMemberPages && isDetailedSectionLinkable())
1767  {
1768  if (getEnumScope()) // enum value, which is part of enum's documentation
1769  {
1770  baseName+="_"+getEnumScope()->anchor();
1771  }
1772  else
1773  {
1774  baseName+="_"+anchor();
1775  }
1776  }
1777  return baseName;
1778 }
1779 
1781 {
1783  if (!ref.isEmpty())
1784  {
1785  return ref;
1786  }
1787  const NamespaceDef *nspace = getNamespaceDef();
1788  const FileDef *fileDef = getFileDef();
1789  const ClassDef *classDef = getClassDef();
1790  const GroupDef *groupDef = getGroupDef();
1791  if (templateMaster())
1792  {
1793  return templateMaster()->getReference();
1794  }
1795  else if (groupDef)
1796  {
1797  return groupDef->getReference();
1798  }
1799  else if (classDef)
1800  {
1801  return classDef->getReference();
1802  }
1803  else if (nspace)
1804  {
1805  return nspace->getReference();
1806  }
1807  else if (fileDef)
1808  {
1809  return fileDef->getReference();
1810  }
1811  return "";
1812 }
1813 
1815 {
1816  QCString result=m_impl->anc;
1817  if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
1819  if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
1820  {
1821  result.prepend(m_impl->enumScope->anchor());
1822  }
1823  if (getGroupDef())
1824  {
1825  if (m_impl->groupMember)
1826  {
1827  result=m_impl->groupMember->anchor();
1828  }
1829  else if (getReference().isEmpty())
1830  {
1831  result.prepend("g");
1832  }
1833  }
1834  return result;
1835 }
1836 
1838 {
1839  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1840  static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL);
1841  m_isLinkableCached = 2; // linkable
1842  //printf("MemberDefImpl::isLinkableInProject(name=%s)\n",name().data());
1843  if (isHidden())
1844  {
1845  //printf("is hidden\n");
1846  m_isLinkableCached = 1;
1847  return;
1848  }
1849  if (templateMaster())
1850  {
1851  //printf("has template master\n");
1853  return;
1854  }
1855  if (isAnonymous())
1856  {
1857  //printf("name invalid\n");
1858  m_isLinkableCached = 1; // not a valid or a dummy name
1859  return;
1860  }
1861  if (!hasDocumentation() || isReference())
1862  {
1863  //printf("no docs or reference\n");
1864  m_isLinkableCached = 1; // no documentation
1865  return;
1866  }
1867  const GroupDef *groupDef = getGroupDef();
1868  const ClassDef *classDef = getClassDef();
1869  if (groupDef && !groupDef->isLinkableInProject())
1870  {
1871  //printf("group but group not linkable!\n");
1872  m_isLinkableCached = 1; // group but group not linkable
1873  return;
1874  }
1875  if (!groupDef && classDef && !classDef->isLinkableInProject())
1876  {
1877  //printf("in a class but class not linkable!\n");
1878  m_isLinkableCached = 1; // in class but class not linkable
1879  return;
1880  }
1881  const NamespaceDef *nspace = getNamespaceDef();
1882  const FileDef *fileDef = getFileDef();
1883  if (!groupDef && nspace && !m_impl->related && !nspace->isLinkableInProject()
1884  && (fileDef==0 || !fileDef->isLinkableInProject()))
1885  {
1886  //printf("in a namespace but namespace not linkable!\n");
1887  m_isLinkableCached = 1; // in namespace but namespace not linkable
1888  return;
1889  }
1890  if (!groupDef && !nspace &&
1891  !m_impl->related && !classDef &&
1892  fileDef && !fileDef->isLinkableInProject())
1893  {
1894  //printf("in a file but file not linkable!\n");
1895  m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
1896  return;
1897  }
1899  !(m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual))
1900  {
1901  //printf("private and invisible!\n");
1902  m_isLinkableCached = 1; // hidden due to protection
1903  return;
1904  }
1905  if (m_impl->stat && classDef==0 && !extractStatic)
1906  {
1907  //printf("static and invisible!\n");
1908  m_isLinkableCached = 1; // hidden due to staticness
1909  return;
1910  }
1911  //printf("linkable!\n");
1912  return; // linkable!
1913 }
1914 
1915 void MemberDefImpl::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
1916 {
1918  m_isLinkableCached = 0;
1919 }
1920 
1921 void MemberDefImpl::setBriefDescription(const char *b,const char *briefFile,int briefLine)
1922 {
1924  m_isLinkableCached = 0;
1925 }
1926 
1927 void MemberDefImpl::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
1928 {
1930  m_isLinkableCached = 0;
1931 }
1932 
1934 {
1936  m_isLinkableCached = 0;
1937 }
1938 
1940 {
1941  if (m_isLinkableCached==0)
1942  {
1943  MemberDefImpl *that = (MemberDefImpl*)this;
1944  that->_computeLinkableInProject();
1945  }
1947  return m_isLinkableCached==2;
1948 }
1949 
1951 {
1952  if (m_impl->templateMaster)
1953  {
1954  return m_impl->templateMaster->isLinkable();
1955  }
1956  else
1957  {
1958  return isLinkableInProject() || isReference();
1959  }
1960 }
1961 
1962 
1963 void MemberDefImpl::setDefinitionTemplateParameterLists(const std::vector<ArgumentList> &lists)
1964 {
1965  m_impl->defTmpArgLists = lists;
1966 }
1967 
1969  const ClassDef *,const NamespaceDef *,const FileDef *fd,const GroupDef *gd,
1970  bool onlyText) const
1971 {
1972  SrcLangExt lang = getLanguage();
1973  static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
1975  QCString n = name();
1976  const ClassDef *classDef = getClassDef();
1977  const NamespaceDef *nspace = getNamespaceDef();
1978  if (!hideScopeNames)
1979  {
1981  {
1982  n.prepend(m_impl->enumScope->displayName()+sep);
1983  }
1984  if (classDef && gd && !isRelated())
1985  {
1986  n.prepend(classDef->displayName()+sep);
1987  }
1988  else if (nspace && (gd || fd))
1989  {
1990  n.prepend(nspace->displayName()+sep);
1991  }
1992  }
1993 
1994  if (isObjCMethod())
1995  {
1996  if (isStatic()) ol.docify("+ "); else ol.docify("- ");
1997  }
1998  if (!onlyText && isLinkable()) // write link
1999  {
2000  if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped
2001  getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
2002  {
2003  const GroupDef *enumValGroup = getEnumScope()->getGroupDef();
2004  ol.writeObjectLink(enumValGroup->getReference(),
2005  enumValGroup->getOutputFileBase(),
2006  anchor(),n);
2007  }
2008  else
2009  {
2011  }
2012  }
2013  else // write only text
2014  {
2015  ol.startBold();
2016  ol.docify(n);
2017  ol.endBold();
2018  }
2019 }
2020 
2025 {
2027 
2028  QCString cname;
2029  if (getClassDef()!=0)
2030  {
2031  cname=getClassDef()->name();
2032  }
2033  else if (getNamespaceDef()!=0)
2034  {
2035  cname=getNamespaceDef()->name();
2036  }
2037  QCString ltype(m_impl->type);
2038  // strip 'static' keyword from ltype
2039  //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
2040  // strip 'friend' keyword from ltype
2041  ltype.stripPrefix("friend ");
2042  static QRegExp r("@[0-9]+");
2043  int l,i=r.match(ltype,0,&l);
2044  //printf("ltype='%s' i=%d\n",ltype.data(),i);
2045  // search for the last anonymous scope in the member type
2046  ClassDef *annoClassDef=0;
2047  if (i!=-1) // found anonymous scope in type
2048  {
2049  int il=i-1,ir=i+l;
2050  // extract anonymous scope
2051  while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
2052  if (il>0) il++; else if (il<0) il=0;
2053  while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
2054 
2055  QCString annName = ltype.mid(il,ir-il);
2056 
2057  // if inside a class or namespace try to prepend the scope name
2058  if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
2059  {
2060  QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
2061  annoClassDef=getClass(ts);
2062  }
2063  // if not found yet, try without scope name
2064  if (annoClassDef==0)
2065  {
2067  annoClassDef=getClass(ts);
2068  }
2069  }
2070  m_impl->cachedAnonymousType = annoClassDef;
2071  return annoClassDef;
2072 }
2073 
2078 {
2079  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
2080  static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL);
2081  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
2082  static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
2083  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
2084  static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
2085 
2086  //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
2087  // name().data(),
2088  // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
2089  // "", //getFileDef()->name().data(),
2090  // argsString());
2091 
2093  //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
2094  //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
2095  bool hasDocs = hasDocumentation() ||
2096  // part of a documented member group
2097  (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
2098 
2099  // only include static members with file/namespace scope if
2100  // explicitly enabled in the config file
2101  bool visibleIfStatic = !(getClassDef()==0 &&
2102  isStatic() &&
2103  !extractStatic
2104  );
2105 
2106  // only include members is the are documented or
2107  // HIDE_UNDOC_MEMBERS is NO in the config file
2108  bool visibleIfDocumented = (!hideUndocMembers ||
2109  hasDocs ||
2111  );
2112 
2113  // hide members with no detailed description and brief descriptions
2114  // explicitly disabled.
2115  bool visibleIfEnabled = !(hideUndocMembers &&
2116  documentation().isEmpty() &&
2117  !briefMemberDesc &&
2118  !repeatBrief
2119  );
2120 
2121  // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
2122  bool visibleIfFriendCompound = !(hideFriendCompounds &&
2123  isFriend() /*&&
2124  (m_impl->type=="friend class" ||
2125  m_impl->type=="friend struct" ||
2126  m_impl->type=="friend union"
2127  )*/
2128  );
2129 
2130  // only include members that are non-private unless EXTRACT_PRIVATE is
2131  // set to YES or the member is part of a group. And as a special case,
2132  // private *documented* virtual members are shown if EXTRACT_PRIV_VIRTUAL
2133  // is set to YES
2134  bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
2136  (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual && hasDocs)
2137  );
2138 
2139  // hide member if it overrides a member in a superclass and has no
2140  // documentation of its own
2141  //bool visibleIfDocVirtual = !reimplements() ||
2142  // !Config_getBool(INHERIT_DOCS) ||
2143  // hasDocs;
2144 
2145  // true if this member is a constructor or destructor
2146  bool cOrDTor = isConstructor() || isDestructor();
2147 
2148  // hide default constructors or destructors (no args) without
2149  // documentation
2150  bool visibleIfNotDefaultCDTor = !(cOrDTor &&
2151  (m_impl->defArgList.empty() ||
2152  m_impl->defArgList.front().type == "void"
2153  ) &&
2154  !hasDocs
2155  );
2156 
2157 
2158  //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
2159  // "visibleIfPrivate=%d visibleIfNotDefaultCDTor=%d "
2160  // "visibleIfFriendCompound=%d !annScope=%d\n",
2161  // visibleIfStatic,visibleIfDocumented,
2162  // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
2163  // visibleIfFriendCompound,!m_impl->annScope);
2164 
2165  bool visible = visibleIfStatic && visibleIfDocumented &&
2166  visibleIfEnabled && visibleIfPrivate &&
2167  /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
2168  visibleIfFriendCompound &&
2169  !m_impl->annScope && !isHidden();
2170  //printf("MemberDefImpl::isBriefSectionVisible() %d\n",visible);
2171  return visible;
2172 }
2173 
2175 {
2176  QCString ltype(m_impl->type);
2177  if (isTypedef() && getLanguage() != SrcLangExt_Slice)
2178  {
2179  ltype.prepend("typedef ");
2180  }
2181  if (isTypeAlias())
2182  {
2183  ltype="using";
2184  }
2185  // strip 'friend' keyword from ltype
2186  ltype.stripPrefix("friend ");
2187  if (ltype=="@") // rename type from enum values
2188  {
2189  ltype="";
2190  }
2191  else
2192  {
2193  if (isObjCMethod())
2194  {
2195  ltype.prepend("(");
2196  ltype.append(")");
2197  }
2198  }
2199  return ltype;
2200 }
2201 
2203  const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,
2204  bool inGroup, const ClassDef *inheritedFrom,const char *inheritId) const
2205 {
2206  //printf("%s MemberDefImpl::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup);
2207 
2208  // hide enum value, since they appear already as part of the enum, unless they
2209  // are explicitly grouped.
2210  if (!inGroup && m_impl->mtype==MemberType_EnumValue) return;
2211 
2212 
2213  const Definition *d=0;
2214  ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
2215  if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
2216  if (d==gd) // see bug 753608
2217  {
2218  if (getClassDef()) d = getClassDef();
2219  else if (getNamespaceDef()) d = getNamespaceDef();
2220  else if (getFileDef()) d = getFileDef();
2221  }
2222 
2223  addToSearchIndex();
2224 
2225  QCString cname = d->name();
2226  QCString cdname = d->displayName();
2227  QCString cfname = getOutputFileBase();
2228 
2229  // search for the last anonymous scope in the member type
2230  ClassDef *annoClassDef=getClassDefOfAnonymousType();
2231 
2233 
2234  // start a new member declaration
2235  bool isAnonType = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
2237  ol.startMemberItem(anchor(),
2238  isAnonType ? 1 : !m_impl->tArgList.empty() ? 3 : 0,
2239  inheritId
2240  );
2241 
2242  // If there is no detailed description we need to write the anchor here.
2243  bool detailsVisible = isDetailedSectionLinkable();
2244  bool writeAnchor = (inGroup || getGroupDef()==0) && // only write anchors for member that have no details and are
2245  !detailsVisible && !m_impl->annMemb; // rendered inside the group page or are not grouped at all
2246  if (writeAnchor)
2247  {
2248  QCString doxyArgs=argsString();
2249  QCString doxyName=name();
2250  if (!cname.isEmpty())
2251  {
2252  doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
2253  }
2254  ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
2255  }
2256 
2257  if (!detailsVisible)
2258  {
2259  ol.pushGeneratorState();
2263  ol.docify("\n");
2264  ol.popGeneratorState();
2265  }
2266 
2267  if (annoClassDef || m_impl->annMemb)
2268  {
2269  int j;
2270  for (j=0;j<s_indentLevel;j++)
2271  {
2272  ol.writeNonBreakableSpace(3);
2273  }
2274  }
2275 
2276  // *** write template lists
2278  {
2279  if (!isAnonType) ol.startMemberTemplateParams();
2281  if (!isAnonType) ol.endMemberTemplateParams(anchor(),inheritId);
2282  }
2283 
2284  // *** write type
2285  QCString ltype(m_impl->type);
2286  if (isTypedef() && getLanguage() != SrcLangExt_Slice)
2287  {
2288  ltype.prepend("typedef ");
2289  }
2290  if (isTypeAlias())
2291  {
2292  ltype="using";
2293  }
2294  // strip 'friend' keyword from ltype
2295  ltype.stripPrefix("friend ");
2296  static QRegExp r("@[0-9]+");
2297 
2298  bool endAnonScopeNeeded=FALSE;
2299  int l,i=r.match(ltype,0,&l);
2300  if (i!=-1) // member has an anonymous type
2301  {
2302  //printf("annoClassDef=%p annMemb=%p scopeName='%s' anonymous='%s'\n",
2303  // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
2304 
2305  if (annoClassDef) // type is an anonymous compound
2306  {
2307  int ir=i+l;
2308  //printf("<<<<<<<<<<<<<<\n");
2310  annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
2311  //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
2312  ol.startMemberItem(anchor(),2,inheritId);
2313  int j;
2314  for (j=0;j< s_indentLevel-1;j++)
2315  {
2316  ol.writeNonBreakableSpace(3);
2317  }
2318  QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
2319  //printf(">>>>>> ltype='%s' varName='%s'\n",ltype.data(),varName.data());
2320  ol.docify("}");
2321  if (varName.isEmpty() && isAnonymous())
2322  {
2323  ol.docify(";");
2324  }
2325  else if (!varName.isEmpty() && (varName.at(0)=='*' || varName.at(0)=='&'))
2326  {
2327  ol.docify(" ");
2328  ol.docify(varName);
2329  }
2330  endAnonScopeNeeded=TRUE;
2331  }
2332  else
2333  {
2334  if (getAnonymousEnumType()) // type is an anonymous enum
2335  {
2336  linkifyText(TextGeneratorOLImpl(ol), // out
2337  d, // scope
2338  getBodyDef(), // fileScope
2339  this, // self
2340  ltype.left(i), // text
2341  FALSE // autoBreak
2342  );
2343  getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
2344  //ol+=*getAnonymousEnumType()->enumDecl();
2345  linkifyText(TextGeneratorOLImpl(ol),d,getFileDef(),this,ltype.right(ltype.length()-i-l),TRUE);
2346  }
2347  else
2348  {
2349  ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
2350  linkifyText(TextGeneratorOLImpl(ol), // out
2351  d, // scope
2352  getBodyDef(), // fileScope
2353  this, // self
2354  ltype, // text
2355  FALSE // autoBreak
2356  );
2357  }
2358  }
2359  }
2360  else if (ltype=="@") // rename type from enum values
2361  {
2362  ltype="";
2363  }
2364  else
2365  {
2366  if (isObjCMethod())
2367  {
2368  ltype.prepend("(");
2369  ltype.append(")");
2370  }
2371  linkifyText(TextGeneratorOLImpl(ol), // out
2372  d, // scope
2373  getBodyDef(), // fileScope
2374  this, // self
2375  ltype, // text
2376  FALSE // autoBreak
2377  );
2378  }
2379  bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2380  if (htmlOn && !ltype.isEmpty())
2381  {
2383  }
2384  if (!ltype.isEmpty()) ol.docify(" ");
2385  if (htmlOn)
2386  {
2388  }
2389 
2390  if (m_impl->annMemb)
2391  {
2392  ol.pushGeneratorState();
2394  ol.writeNonBreakableSpace(3);
2395  ol.popGeneratorState();
2396  }
2397  else
2398  {
2400  }
2401 
2402  // *** write name
2403  if (!isAnonymous()) // hide anonymous stuff
2404  {
2405  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2406  static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL);
2407  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
2408  //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation());
2409  if (!name().isEmpty() && // name valid
2410  (hasDocumentation() || isReference()) && // has docs
2411  !(m_impl->prot==Private && !extractPrivate && (m_impl->virt==Normal || !extractPrivateVirtual) && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
2412  !(isStatic() && getClassDef()==0 && !extractStatic) // hidden due to static-ness
2413  )
2414  {
2415  if (m_impl->annMemb)
2416  {
2417  //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
2418  m_impl->annMemb->writeLink(ol,
2423  );
2425  setAnonymousUsed();
2426  }
2427  else
2428  {
2429  //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
2430  const ClassDef *rcd = cd;
2431  if (isReference() && getClassDef()) rcd = getClassDef();
2432  writeLink(ol,rcd,nd,fd,gd);
2433  }
2434  }
2435  else if (isDocumentedFriendClass())
2436  // if the member is an undocumented friend declaration for some class,
2437  // then maybe we can link to the class
2438  {
2439  writeLink(ol,getClass(name()),0,0,0);
2440  }
2441  else
2442  // there is a brief member description and brief member
2443  // descriptions are enabled or there is no detailed description.
2444  {
2445  if (m_impl->annMemb)
2446  {
2448  setAnonymousUsed();
2449  }
2450  const ClassDef *rcd = cd;
2451  if (isReference() && getClassDef()) rcd = getClassDef();
2452  writeLink(ol,rcd,nd,fd,gd,TRUE);
2453  }
2454  }
2455 
2456  // add to index
2457  if (isEnumerate() && isAnonymous())
2458  {
2459  // don't add to index
2460  }
2461  else // index member
2462  {
2463  //static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
2464  //QCString cfname = getOutputFileBase();
2465  //QCString cfiname = d->getOutputFileBase();
2466  //Doxygen::indexList->addIndexItem(
2467  // cname, // level1
2468  // name(), // level2
2469  // separateMemPages ? cfname : cfiname, // contRef
2470  // cfname, // memRef
2471  // anchor(), // anchor
2472  // this); // memberdef
2474  }
2475 
2476  // *** write arguments
2477  if (argsString() && !isObjCMethod())
2478  {
2479  if (!isDefine() && !isTypedef()) ol.writeString(" ");
2480  linkifyText(TextGeneratorOLImpl(ol), // out
2481  d, // scope
2482  getBodyDef(), // fileScope
2483  this, // self
2484  isDefine() ?
2485  (const char*)substitute(argsString(),",",", ") :
2486  isTypedef() ?
2487  (const char*)substitute(argsString(),")(",") (") :
2488  argsString(), // text
2489  m_impl->annMemb, // autoBreak
2490  TRUE, // external
2491  FALSE, // keepSpaces
2493  );
2494  }
2495  // *** write exceptions
2496  if (excpString())
2497  {
2498  ol.writeString(" ");
2499  ol.docify(excpString());
2500  }
2501 
2502  // *** write bitfields
2503  if (!m_impl->bitfields.isEmpty()) // add bitfields
2504  {
2506  }
2507  else if (hasOneLineInitializer()
2509  //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
2510  ) // add initializer
2511  {
2512  if (!isDefine())
2513  {
2514  //ol.writeString(" = ");
2515  ol.writeString(" ");
2517  }
2518  else
2519  {
2520  ol.writeNonBreakableSpace(3);
2522  }
2523  }
2524  else if (isTypeAlias()) // using template alias
2525  {
2526  ol.writeString(" = ");
2528  }
2529 
2530 
2531  if ((isObjCMethod() || isObjCProperty()) && isImplementation())
2532  {
2533  ol.startTypewriter();
2534  ol.docify(" [implementation]");
2535  ol.endTypewriter();
2536  }
2537 
2538  bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2539 
2540  if (isProperty() && (isSettable() || isGettable() ||
2543  {
2544  ol.writeLatexSpacing();
2545  ol.startTypewriter();
2546  ol.docify(" [");
2547  QStrList sl;
2548 
2549  if (isGettable()) sl.append("get");
2550  if (isProtectedGettable()) sl.append("protected get");
2551  if (isSettable()) sl.append("set");
2552  if (isProtectedSettable()) sl.append("protected set");
2553  if (extractPrivate)
2554  {
2555  if (isPrivateGettable()) sl.append("private get");
2556  if (isPrivateSettable()) sl.append("private set");
2557  }
2558  const char *s=sl.first();
2559  while (s)
2560  {
2561  ol.docify(s);
2562  s=sl.next();
2563  if (s) ol.docify(", ");
2564  }
2565  ol.docify("]");
2566  ol.endTypewriter();
2567  }
2568 
2569  if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
2570  {
2571  ol.writeLatexSpacing();
2572  ol.startTypewriter();
2573  ol.docify(" [");
2574  QStrList sl;
2575  if (isAddable()) sl.append("add");
2576  if (isRemovable()) sl.append("remove");
2577  if (isRaisable()) sl.append("raise");
2578  const char *s=sl.first();
2579  while (s)
2580  {
2581  ol.docify(s);
2582  s=sl.next();
2583  if (s) ol.docify(", ");
2584  }
2585  ol.docify("]");
2586  ol.endTypewriter();
2587  }
2588 
2589  if (writeAnchor)
2590  {
2591  ol.endDoxyAnchor(cfname,anchor());
2592  }
2593 
2594  //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
2595  // name().data(),annoClassDef,annEnumType);
2596  ol.endMemberItem();
2597  if (endAnonScopeNeeded)
2598  {
2600  }
2601 
2602  // write brief description
2603  if (!briefDescription().isEmpty() &&
2604  Config_getBool(BRIEF_MEMBER_DESC)
2605  /* && !annMemb */
2606  )
2607  {
2610  TRUE,FALSE,0,TRUE,FALSE);
2611 
2612  if (rootNode && !rootNode->isEmpty())
2613  {
2614  ol.startMemberDescription(anchor(),inheritId);
2615  ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this);
2616  if (detailsVisible)
2617  {
2618  ol.pushGeneratorState();
2620  //ol.endEmphasis();
2621  ol.docify(" ");
2624  ol.endTextLink();
2625  //ol.startEmphasis();
2626  ol.popGeneratorState();
2627  }
2628  // for RTF we need to add an extra empty paragraph
2629  ol.pushGeneratorState();
2631  ol.startParagraph();
2632  ol.endParagraph();
2633  ol.popGeneratorState();
2634  ol.endMemberDescription();
2635  }
2636  delete rootNode;
2637  }
2638 
2639  ol.endMemberDeclaration(anchor(),inheritId);
2640 
2642 }
2643 
2645 {
2646  static bool extractAll = Config_getBool(EXTRACT_ALL);
2647  static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC);
2648  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
2649  static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
2650  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
2651  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
2652  static bool extractPrivateVirtual = Config_getBool(EXTRACT_PRIV_VIRTUAL);
2653 
2654  // the member has details documentation for any of the following reasons
2655  bool docFilter =
2656  // treat everything as documented
2657  extractAll ||
2658  // has detailed docs
2659  !documentation().isEmpty() ||
2660  // has inbody docs
2662  // is an enum with values that are documented
2664  // is documented enum value
2666  // has brief description that is part of the detailed description
2667  (!briefDescription().isEmpty() && // has brief docs
2668  (alwaysDetailedSec && // they are visible in
2669  (repeatBrief || // detailed section or
2670  !briefMemberDesc // they are explicitly not
2671  ) // shown in brief section
2672  )
2673  ) ||
2674  // has a multi-line initialization block
2675  //(initLines>0 && initLines<maxInitLines) ||
2676  (hasMultiLineInitializer() && !hideUndocMembers) ||
2677  // has one or more documented arguments
2679  // is an attribute or property - need to display that tag
2681  // has user comments
2683  ;
2684 
2685  // this is not a global static or global statics should be extracted
2686  bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
2687 
2688  // only include members that are non-private unless EXTRACT_PRIVATE is
2689  // set to YES or the member is part of a group
2690  bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend ||
2691  (m_impl->prot==Private && m_impl->virt!=Normal && extractPrivateVirtual);
2692 
2693  // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
2694  // is true
2695  bool friendCompoundFilter = !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
2696  isFriend() /*&&
2697  (m_impl->type=="friend class" ||
2698  m_impl->type=="friend struct" ||
2699  m_impl->type=="friend union"
2700  )*/
2701  );
2702 
2703 
2704  bool result = (docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden());
2705  return result;
2706 }
2707 
2708 bool MemberDefImpl::isDetailedSectionVisible(bool inGroup,bool inFile) const
2709 {
2710  static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
2711  static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
2712  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
2713  bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
2714  bool fileFilter = getNamespaceDef()==0 || !getNamespaceDef()->isLinkable() || !inFile;
2715  bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs &&
2716  getClassDef()!=0 && getClassDef()->isSimple();
2717 
2718  bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
2719  !isReference();
2720  bool result = visible || simpleFilter;
2721  //printf("%s::isDetailedSectionVisible: %d groupFilter=%d fileFilter=%d\n",
2722  // name().data(),result,groupFilter,fileFilter);
2723  return result;
2724 }
2725 
2726 void MemberDefImpl::getLabels(QStrList &sl,const Definition *container) const
2727 {
2728  static bool inlineInfo = Config_getBool(INLINE_INFO);
2729 
2730  Specifier lvirt=virtualness();
2731  if ((!isObjCMethod() || isOptional() || isRequired()) &&
2732  (protection()!=Public || lvirt!=Normal ||
2733  isFriend() || isRelated() ||
2734  (isInline() && inlineInfo) ||
2735  isSignal() || isSlot() ||
2736  isStatic() ||
2737  (getClassDef() && getClassDef()!=container && container->definitionType()==TypeClass) ||
2738  (m_impl->memSpec & ~Entry::Inline)!=0
2739  )
2740  )
2741  {
2742  // write the member specifier list
2743  //ol.writeLatexSpacing();
2744  //ol.startTypewriter();
2745  //ol.docify(" [");
2746  SrcLangExt lang = getLanguage();
2747  bool optVhdl = lang==SrcLangExt_VHDL;
2748  bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
2749  if (optVhdl)
2750  {
2752  }
2753  else
2754  {
2755  if (isFriend()) sl.append("friend");
2756  else if (isRelated()) sl.append("related");
2757  else
2758  {
2759  if (Config_getBool(INLINE_INFO) && isInline()) sl.append("inline");
2760  if (isExplicit()) sl.append("explicit");
2761  if (isMutable()) sl.append("mutable");
2762  if (isStatic()) sl.append("static");
2763  if (isGettable()) sl.append("get");
2764  if (isProtectedGettable()) sl.append("protected get");
2765  if (isSettable()) sl.append("set");
2766  if (isProtectedSettable()) sl.append("protected set");
2767  if (extractPrivate)
2768  {
2769  if (isPrivateGettable()) sl.append("private get");
2770  if (isPrivateSettable()) sl.append("private set");
2771  }
2772  if (isConstExpr()) sl.append("constexpr");
2773  if (isAddable()) sl.append("add");
2774  if (!isUNOProperty() && isRemovable()) sl.append("remove");
2775  if (isRaisable()) sl.append("raise");
2776  if (isReadable()) sl.append("read");
2777  if (isWritable()) sl.append("write");
2778  if (isFinal()) sl.append("final");
2779  if (isAbstract()) sl.append("abstract");
2780  if (isOverride()) sl.append("override");
2781  if (isInitonly()) sl.append("initonly");
2782  if (isSealed()) sl.append("sealed");
2783  if (isNew()) sl.append("new");
2784  if (isOptional()) sl.append("optional");
2785  if (isRequired()) sl.append("required");
2786 
2787  if (isNonAtomic()) sl.append("nonatomic");
2788  else if (isObjCProperty()) sl.append("atomic");
2789 
2790  // mutual exclusive Objective 2.0 property attributes
2791  if (isAssign()) sl.append("assign");
2792  else if (isCopy()) sl.append("copy");
2793  else if (isRetain()) sl.append("retain");
2794  else if (isWeak()) sl.append("weak");
2795  else if (isStrong()) sl.append("strong");
2796  else if (isUnretained()) sl.append("unsafe_unretained");
2797 
2798  if (!isObjCMethod())
2799  {
2800  if (protection()==Protected) sl.append("protected");
2801  else if (protection()==Private) sl.append("private");
2802  else if (protection()==Package) sl.append("package");
2803 
2804  if (lvirt==Virtual) sl.append("virtual");
2805  else if (lvirt==Pure) sl.append("pure virtual");
2806  if (isSignal()) sl.append("signal");
2807  if (isSlot()) sl.append("slot");
2808  if (isDefault()) sl.append("default");
2809  if (isDelete()) sl.append("delete");
2810  if (isNoExcept()) sl.append("noexcept");
2811  if (isAttribute()) sl.append("attribute");
2812  if (isUNOProperty()) sl.append("property");
2813  if (isReadonly()) sl.append("readonly");
2814  if (isBound()) sl.append("bound");
2815  if (isUNOProperty() && isRemovable()) sl.append("removable");
2816  if (isConstrained()) sl.append("constrained");
2817  if (isTransient()) sl.append("transient");
2818  if (isMaybeVoid()) sl.append("maybevoid");
2819  if (isMaybeDefault()) sl.append("maybedefault");
2820  if (isMaybeAmbiguous()) sl.append("maybeambiguous");
2821  if (isPublished()) sl.append("published"); // enum
2822  }
2823  if (isObjCProperty() && isImplementation())
2824  {
2825  sl.append("implementation");
2826  }
2827  }
2828  if (getClassDef() &&
2829  container->definitionType()==TypeClass &&
2830  getClassDef()!=container &&
2831  !isRelated()
2832  )
2833  {
2834  sl.append("inherited");
2835  }
2836  }
2837  }
2838  else if (isObjCMethod() && isImplementation())
2839  {
2840  sl.append("implementation");
2841  }
2842 }
2843 
2845 {
2846  // write call graph
2847  if (m_impl->hasCallGraph
2848  && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2849  )
2850  {
2851  DotCallGraph callGraph(this,FALSE);
2852  if (callGraph.isTooBig())
2853  {
2854  warn_uncond("Call graph for '%s' not generated, too many nodes (%d), threshold is %d. Consider increasing DOT_GRAPH_MAX_NODES.\n",
2856  }
2857  else if (!callGraph.isTrivial())
2858  {
2859  msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
2861  ol.startCallGraph();
2863  ol.endCallGraph(callGraph);
2864  ol.enableAll();
2865  }
2866  }
2867 }
2868 
2870 {
2871  if (m_impl->hasCallerGraph
2872  && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2873  )
2874  {
2875  DotCallGraph callerGraph(this, TRUE);
2876  if (callerGraph.isTooBig())
2877  {
2878  warn_uncond("Caller graph for '%s' not generated, too many nodes (%d), threshold is %d. Consider increasing DOT_GRAPH_MAX_NODES.\n",
2880  }
2881  else if (!callerGraph.isTrivial())
2882  {
2883  msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
2885  ol.startCallGraph();
2887  ol.endCallGraph(callerGraph);
2888  ol.enableAll();
2889  }
2890  }
2891 }
2892 
2894 {
2895  MemberDef *bmd=reimplements();
2896  const ClassDef *bcd=0;
2897  if (bmd && (bcd=bmd->getClassDef()))
2898  {
2899  // write class that contains a member that is reimplemented by this one
2900  if (bcd->isLinkable())
2901  {
2902  ol.startParagraph();
2903  QCString reimplFromLine;
2904  if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
2905  {
2906  reimplFromLine = theTranslator->trReimplementedFromList(1);
2907  }
2908  else
2909  {
2910  reimplFromLine = theTranslator->trImplementedFromList(1);
2911  }
2912  int markerPos = reimplFromLine.find("@0");
2913  if (markerPos!=-1) // should always pass this.
2914  {
2915  ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
2916  if (bmd->isLinkable()) // replace marker with link
2917  {
2918  //Definition *bd=bmd->group;
2919  //if (bd==0) bd=bcd;
2921  bmd->anchor(),bcd->displayName());
2922 
2923  //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2924  // bmd->anchor(),bcd->name());
2925  if ( bmd->isLinkableInProject() )
2926  {
2927  writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2928  }
2929  }
2930  else
2931  {
2933  0,bcd->displayName());
2934  if (bcd->isLinkableInProject()/* && !Config_getBool(PDF_HYPERLINKS)*/ )
2935  {
2936  writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
2937  }
2938  }
2939  ol.parseText(reimplFromLine.right(
2940  reimplFromLine.length()-markerPos-2)); // text right from marker
2941 
2942  }
2943  else
2944  {
2945  err("translation error: no marker in trReimplementsFromList()\n");
2946  }
2947  ol.endParagraph();
2948  }
2949  }
2950 }
2951 
2953 {
2954  MemberList *bml=reimplementedBy();
2955  if (bml)
2956  {
2957  MemberListIterator mli(*bml);
2958  MemberDef *bmd=0;
2959  uint count=0;
2960  const ClassDef *bcd=0;
2961  for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
2962  {
2963  // count the members that directly inherit from md and for
2964  // which the member and class are visible in the docs.
2965  if ( bmd->isLinkable() && bcd->isLinkable() )
2966  {
2967  count++;
2968  }
2969  }
2970  if (count>0)
2971  {
2972  mli.toFirst();
2973  // write the list of classes that overwrite this member
2974  ol.startParagraph();
2975 
2976  QCString reimplInLine;
2977  if (m_impl->virt==Pure || (getClassDef() && getClassDef()->compoundType()==ClassDef::Interface))
2978  {
2979  reimplInLine = theTranslator->trImplementedInList(count);
2980  }
2981  else
2982  {
2983  reimplInLine = theTranslator->trReimplementedInList(count);
2984  }
2985  static QRegExp marker("@[0-9]+");
2986  int index=0,newIndex,matchLen;
2987  // now replace all markers in reimplInLine with links to the classes
2988  while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
2989  {
2990  ol.parseText(reimplInLine.mid(index,newIndex-index));
2991  bool ok;
2992  uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2993  //bmd=bml->at(entryIndex);
2994 
2995  count=0;
2996  // find the entryIndex-th documented entry in the inheritance list.
2997  for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
2998  {
2999  if ( bmd->isLinkable() && bcd->isLinkable())
3000  {
3001  if (count==entryIndex) break;
3002  count++;
3003  }
3004  }
3005 
3006  if (ok && bcd && bmd) // write link for marker
3007  {
3008  //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
3009  // bmd->anchor(),bcd->name());
3011  bmd->anchor(),bcd->displayName());
3012 
3013  if (bmd->isLinkableInProject() )
3014  {
3015  writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
3016  }
3017  }
3018  ++mli;
3019  index=newIndex+matchLen;
3020  }
3021  ol.parseText(reimplInLine.right(reimplInLine.length()-index));
3022  ol.endParagraph();
3023  }
3024  }
3025 }
3026 
3028 {
3029  if (getClassDef()) // this should be a member of a class/category
3030  {
3031  //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
3032  // name().data(),
3033  // m_impl->category ? m_impl->category->name().data() : "<none>",
3034  // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
3035  // m_impl->classDef->name().data(),
3036  // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
3037  // );
3038  QCString text;
3039  QCString ref;
3040  QCString file;
3041  QCString anc;
3042  QCString name;
3043  int i=-1;
3045  {
3046  if (m_impl->category)
3047  {
3048  // this member is in a normal class and implements method categoryRelation from category
3049  // so link to method 'categoryRelation' with 'provided by category 'category' text.
3052  }
3053  else if (getClassDef()->categoryOf())
3054  {
3055  // this member is part of a category so link to the corresponding class member of the class we extend
3056  // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
3057  text = theTranslator->trExtendsClass();
3059  }
3060  i=text.find("@0");
3061  if (i!=-1)
3062  {
3064  ref = md->getReference();
3065  file = md->getOutputFileBase();
3066  anc = md->anchor();
3067  }
3068  }
3069  if (i!=-1 && !name.isEmpty())
3070  {
3071  ol.startParagraph();
3072  ol.parseText(text.left(i));
3073  ol.writeObjectLink(ref,file,anc,name);
3074  ol.parseText(text.mid(i+2));
3075  ol.endParagraph();
3076  }
3077  }
3078 }
3079 
3081 {
3082  // write the list of examples that use this member
3083  if (hasExamples())
3084  {
3085  ol.startExamples();
3086  ol.startDescForItem();
3088  ol.endDescForItem();
3089  ol.endExamples();
3090  }
3091 }
3092 
3094 {
3096  {
3098  }
3099 }
3100 
3102  const QCString &cfname,const QCString &ciname,
3103  const QCString &cname) const
3104 {
3105  // For enum, we also write the documented enum values
3106  if (isEnumerate())
3107  {
3108  bool first=TRUE;
3109  const MemberList *fmdl=enumFieldList();
3110  //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
3111  if (fmdl)
3112  {
3113  MemberListIterator it(*fmdl);
3114  MemberDef *fmd;
3115  for (;(fmd=it.current());++it)
3116  {
3117  //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
3118  if (fmd->isLinkable())
3119  {
3120  if (first)
3121  {
3123  }
3124 
3125  ol.startDescTableRow();
3126  ol.addIndexItem(fmd->name(),ciname);
3127  ol.addIndexItem(ciname,fmd->name());
3128 
3129  Doxygen::indexList->addIndexItem(container,fmd);
3130 
3131  ol.startDescTableTitle();
3132  ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
3133  first=FALSE;
3134  ol.docify(fmd->name());
3136  ol.writeString(" ");
3137  ol.enableAll();
3138  ol.endDoxyAnchor(cfname,fmd->anchor());
3139  ol.endDescTableTitle();
3140  ol.startDescTableData();
3141 
3142  bool hasBrief = !fmd->briefDescription().isEmpty();
3143  bool hasDetails = !fmd->documentation().isEmpty();
3144 
3145  if (hasBrief)
3146  {
3147  ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
3148  getOuterScope()?getOuterScope():container,
3149  fmd,fmd->briefDescription(),TRUE,FALSE);
3150  }
3151  // FIXME:PARA
3152  //if (!fmd->briefDescription().isEmpty() &&
3153  // !fmd->documentation().isEmpty())
3154  //{
3155  // ol.newParagraph();
3156  //}
3157  if (hasDetails)
3158  {
3159  ol.generateDoc(fmd->docFile(),fmd->docLine(),
3160  getOuterScope()?getOuterScope():container,
3161  fmd,fmd->documentation()+"\n",TRUE,FALSE);
3162  }
3163  ol.endDescTableData();
3164  ol.endDescTableRow();
3165  }
3166  }
3167  }
3168  if (!first)
3169  {
3170  ol.endDescTable();
3171  }
3172  }
3173 }
3174 
3176 {
3177  QCString ldef = definition();
3178  QCString title = name();
3179  if (isEnumerate())
3180  {
3181  if (isAnonymous())
3182  {
3183  ldef = title = "anonymous enum";
3184  if (!m_impl->enumBaseType.isEmpty())
3185  {
3186  ldef+=" : "+m_impl->enumBaseType;
3187  }
3188  }
3189  else
3190  {
3191  ldef.prepend("enum ");
3192  if (isSliceLocal())
3193  {
3194  ldef.prepend("local ");
3195  }
3196  }
3197  }
3198  else if (isEnumValue())
3199  {
3200  if (isAnonymous())
3201  {
3202  ldef=ldef.mid(2);
3203  }
3204  }
3205  static QRegExp r("@[0-9]+");
3206  int l,i=r.match(ldef,0,&l);
3207  if (i!=-1) // replace anonymous parts with { ... }
3208  {
3209  int si=ldef.find(' '),pi,ei=i+l;
3210  if (si==-1) si=0;
3211  while ((pi=r.match(ldef,i+l,&l))!=-1)
3212  {
3213  i=pi;
3214  ei=i+l;
3215  }
3216  int ni=ldef.find("::",si);
3217  if (ni>=ei) ei=ni+2;
3218  ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei);
3219  }
3220  const ClassDef *cd=getClassDef();
3221  if (cd && cd->isObjectiveC())
3222  {
3223  // strip scope name
3224  int ep = ldef.find("::");
3225  if (ep!=-1)
3226  {
3227  int sp=ldef.findRev(' ',ep);
3228  if (sp!=-1)
3229  {
3230  ldef=ldef.left(sp+1)+ldef.mid(ep+2);
3231  }
3232  }
3233  // strip keywords
3234  int dp = ldef.find(':');
3235  if (dp!=-1)
3236  {
3237  ldef=ldef.left(dp+1);
3238  }
3239  l=ldef.length();
3240  //printf("start >%s<\n",ldef.data());
3241  i=l-1;
3242  while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
3243  while (i>=0 && isspace((uchar)ldef.at(i))) i--;
3244  if (i>0)
3245  {
3246  // insert braches around the type
3247  QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
3248  ldef=tmp;
3249  }
3250  //printf("end >%s< i=%d\n",ldef.data(),i);
3251  if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
3252  }
3253  SrcLangExt lang = getLanguage();
3255  return substitute(ldef,"::",sep);
3256 }
3257 
3258 void MemberDefImpl::_writeGroupInclude(OutputList &ol,bool inGroup) const
3259 {
3260  // only write out the include file if this is not part of a class or file
3261  // definition
3262  static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC);
3263  const FileDef *fd = getFileDef();
3264  QCString nm;
3265  if (fd) nm = getFileDef()->docName();
3266  if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
3267  {
3268  ol.startParagraph();
3269  ol.startTypewriter();
3270  SrcLangExt lang = getLanguage();
3271  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
3272  if (isIDLorJava)
3273  {
3274  ol.docify("import ");
3275  }
3276  else
3277  {
3278  ol.docify("#include ");
3279  }
3280 
3281  if (isIDLorJava) ol.docify("\""); else ol.docify("<");
3282 
3283  if (fd->isLinkable())
3284  {
3285  ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
3286  }
3287  else
3288  {
3289  ol.docify(nm);
3290  }
3291 
3292  if (isIDLorJava) ol.docify("\""); else ol.docify(">");
3293 
3294  ol.endTypewriter();
3295  ol.endParagraph();
3296  }
3297 }
3298 
3303  int memCount,int memTotal,
3304  OutputList &ol,
3305  const char *scName,
3306  const Definition *container,
3307  bool inGroup,
3308  bool showEnumValues,
3309  bool showInline
3310  ) const
3311 {
3312  // if this member is in a group find the real scope name.
3313  bool hasParameterList = FALSE;
3314 
3315  //printf("MemberDefImpl::writeDocumentation(): name='%s' hasDocs='%d' containerType=%d inGroup=%d sectionLinkable=%d\n",
3316  // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable());
3317 
3318  //if ( !hasDocs ) return;
3319  //if (isEnumValue() && !showEnumValues) return;
3320 
3321  SrcLangExt lang = getLanguage();
3322  //printf("member=%s lang=%d\n",name().data(),lang);
3323  bool optVhdl = lang==SrcLangExt_VHDL;
3325 
3326  QCString scopeName = scName;
3327  QCString memAnchor = anchor();
3328  QCString ciname = container->displayName();
3329  const Definition *scopedContainer = container; // see bug 753608
3330  if (container->definitionType()==TypeGroup)
3331  {
3332  if (getClassDef()) { scopeName=getClassDef()->displayName(); scopedContainer=getClassDef(); }
3333  else if (getNamespaceDef()) { scopeName=getNamespaceDef()->displayName(); scopedContainer=getNamespaceDef(); }
3334  else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); }
3335  ciname = (dynamic_cast<const GroupDef *>(container))->groupTitle();
3336  }
3337  else if (container->definitionType()==TypeFile && getNamespaceDef() && getNamespaceDef()->isLinkable())
3338  { // member is in a namespace, but is written as part of the file documentation
3339  // as well, so we need to make sure its anchor is unique (it is not really used).
3340  memAnchor.prepend("file_");
3341  }
3342 
3343  QCString cname = container->name();
3344  QCString cfname = getOutputFileBase();
3345 
3346  // get member name
3347  QCString doxyName=name();
3348  // prepend scope if there is any. TODO: make this optional for C only docs
3349  if (!scopeName.isEmpty())
3350  {
3351  doxyName.prepend(scopeName+sep);
3352  }
3353  QCString doxyArgs=argsString();
3354 
3355  QCString ldef = definition();
3356  QCString title = name();
3357  //printf("member '%s' def='%s'\n",name().data(),ldef.data());
3358  if (isEnumerate())
3359  {
3360  if (title.at(0)=='@')
3361  {
3362  ldef = title = "anonymous enum";
3363  if (!m_impl->enumBaseType.isEmpty())
3364  {
3365  ldef+=" : "+m_impl->enumBaseType;
3366  }
3367  }
3368  else
3369  {
3370  ldef.prepend("enum ");
3371  if (isSliceLocal())
3372  {
3373  ldef.prepend("local ");
3374  }
3375  }
3376  }
3377  else if (isEnumValue())
3378  {
3379  if (ldef.at(0)=='@')
3380  {
3381  ldef=ldef.mid(2);
3382  }
3383  }
3384  else if (isFunction() && !isObjCMethod())
3385  {
3386  title += "()";
3387  }
3388  int i=0,l;
3389  static QRegExp r("@[0-9]+");
3390 
3391  if (lang == SrcLangExt_Slice)
3392  {
3393  // Remove the container scope from the member name.
3394  QCString prefix = scName + sep;
3395  int pos = ldef.findRev(prefix.data());
3396  if(pos != -1)
3397  {
3398  ldef.remove(pos, prefix.length());
3399  }
3400  }
3401 
3402  //----------------------------------------
3403 
3404  ol.pushGeneratorState();
3405 
3406  bool htmlEndLabelTable=FALSE;
3407  QStrList sl;
3408  getLabels(sl,scopedContainer);
3409 
3410  if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
3411  {
3412  // find enum type and insert it in the definition
3413  MemberListIterator vmli(*ml);
3414  MemberDef *vmd;
3415  bool found=FALSE;
3416  for ( ; (vmd=vmli.current()) && !found ; ++vmli)
3417  {
3418  if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
3419  {
3420  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3421  ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
3422  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.left(i));
3424  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-i-l));
3425 
3426  found=TRUE;
3427  }
3428  }
3429  if (!found) // anonymous compound
3430  {
3431  //printf("Anonymous compound '%s'\n",cname.data());
3432  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3433  ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
3434  // search for the last anonymous compound name in the definition
3435  int si=ldef.find(' '),pi,ei=i+l;
3436  if (si==-1) si=0;
3437  while ((pi=r.match(ldef,i+l,&l))!=-1)
3438  {
3439  i=pi;
3440  ei=i+l;
3441  }
3442  // first si characters of ldef contain compound type name
3444  ol.docify(ldef.left(si));
3445  ol.docify(" { ... } ");
3446  // last ei characters of ldef contain pointer/reference specifiers
3447  int ni=ldef.find("::",si);
3448  if (ni>=ei) ei=ni+2;
3449  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-ei));
3450  }
3451  }
3452  else // not an enum value or anonymous compound
3453  {
3454  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3455  ol.startMemberDoc(ciname,name(),memAnchor,title,memCount,memTotal,showInline);
3456 
3458  {
3460  ol.docify(m_impl->metaData);
3462  }
3463 
3464  const ClassDef *cd=getClassDef();
3465  const NamespaceDef *nd=getNamespaceDef();
3467  {
3468  bool first=TRUE;
3469  if (!m_impl->defTmpArgLists.empty() && lang==SrcLangExt_Cpp)
3470  // definition has explicit template parameter declarations
3471  {
3472  for (const ArgumentList &tal : m_impl->defTmpArgLists)
3473  {
3474  if (!tal.empty())
3475  {
3476  if (!first) ol.docify(" ");
3478  writeTemplatePrefix(ol,tal);
3480  }
3481  }
3482  }
3483  else // definition gets it template parameters from its class
3484  // (since no definition was found)
3485  {
3486  if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
3487  {
3488  for (const ArgumentList &tal : cd->getTemplateParameterLists())
3489  {
3490  if (!tal.empty())
3491  {
3492  if (!first) ol.docify(" ");
3494  writeTemplatePrefix(ol,tal);
3496  }
3497  }
3498  }
3499  if (m_impl->tArgList.hasParameters() && lang==SrcLangExt_Cpp) // function template prefix
3500  {
3504  }
3505  }
3506  }
3507 
3508  if (sl.count()>0)
3509  {
3510  ol.pushGeneratorState();
3511  ol.disableAll();
3513  ol.writeString("<table class=\"mlabels\">\n");
3514  ol.writeString(" <tr>\n");
3515  ol.writeString(" <td class=\"mlabels-left\">\n");
3516  ol.popGeneratorState();
3517  htmlEndLabelTable=TRUE;
3518  }
3519 
3521  if (cd && cd->isObjectiveC())
3522  {
3523  // strip scope name
3524  int ep = ldef.find("::");
3525  if (ep!=-1)
3526  {
3527  int sp=ldef.findRev(' ',ep);
3528  if (sp!=-1)
3529  {
3530  ldef=ldef.left(sp+1)+ldef.mid(ep+2);
3531  } else {
3532  ldef=ldef.mid(ep+2);
3533  }
3534  }
3535  // strip keywords
3536  int dp = ldef.find(':');
3537  if (dp!=-1)
3538  {
3539  ldef=ldef.left(dp+1);
3540  }
3541  int dl=ldef.length();
3542  //printf("start >%s<\n",ldef.data());
3543  i=dl-1;
3544  while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
3545  while (i>=0 && isspace((uchar)ldef.at(i))) i--;
3546  if (i>0)
3547  {
3548  // insert braches around the type
3549  QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
3550  ldef=tmp;
3551  }
3552  //printf("end >%s< i=%d\n",ldef.data(),i);
3553  if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
3554  }
3555 
3556  if (optVhdl)
3557  {
3558  hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,scopedContainer,ol);
3559  }
3560  else if (lang==SrcLangExt_Slice)
3561  {
3562  // Eliminate the self-reference.
3563  int pos = ldef.findRev(' ');
3565  scopedContainer,
3566  getBodyDef(),
3567  this,
3568  ldef.left(pos)
3569  );
3570  ol.docify(ldef.mid(pos));
3571  const Definition *scope = cd;
3572  if (scope==0) scope = nd;
3573  hasParameterList=writeDefArgumentList(ol,scope,this);
3574  }
3575  else
3576  {
3578  scopedContainer,
3579  getBodyDef(),
3580  this,
3581  substitute(ldef,"::",sep)
3582  );
3583  const Definition *scope = cd;
3584  if (scope==0) scope = nd;
3585  hasParameterList=writeDefArgumentList(ol,scope,this);
3586  }
3587 
3588  if (hasOneLineInitializer()) // add initializer
3589  {
3590  if (!isDefine())
3591  {
3592  //ol.docify(" = ");
3593  ol.docify(" ");
3595  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,init);
3596  }
3597  else
3598  {
3599  ol.writeNonBreakableSpace(3);
3600  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,m_impl->initializer);
3601  }
3602  }
3603  if (excpString()) // add exception list
3604  {
3605  writeExceptionList(ol,cd,this);
3606  hasParameterList=true; // call endParameterList below
3607  }
3608  }
3609 
3610  ol.pushGeneratorState();
3612  if (sl.count()>0)
3613  {
3614  ol.startLabels();
3615  const char *s=sl.first();
3616  while (s)
3617  {
3618  const char *ns = sl.next();
3619  ol.writeLabel(s,ns==0);
3620  s=ns;
3621  }
3622  ol.endLabels();
3623  }
3624  ol.popGeneratorState();
3625 
3626  if (hasParameterList)
3627  {
3628  ol.endParameterList();
3629  ol.endMemberDoc(TRUE);
3630  }
3631  else
3632  {
3633  ol.endMemberDocName();
3634  ol.endMemberDoc(FALSE);
3635  }
3636 
3637  // for HTML write the labels here
3638  ol.pushGeneratorState();
3639  ol.disableAll();
3641  if (htmlEndLabelTable)
3642  {
3643  ol.writeString(" </td>\n");
3644  ol.writeString(" <td class=\"mlabels-right\">\n");
3645  ol.startLabels();
3646  const char *s=sl.first();
3647  while (s)
3648  {
3649  const char *ns = sl.next();
3650  ol.writeLabel(s,ns==0);
3651  s=ns;
3652  }
3653  ol.endLabels();
3654  ol.writeString(" </td>\n");
3655  ol.writeString(" </tr>\n");
3656  ol.writeString("</table>\n");
3657  }
3658  ol.writeString("</div>");
3659  ol.popGeneratorState();
3660 
3661 
3662  ol.endDoxyAnchor(cfname,memAnchor);
3663  ol.startIndent();
3664 
3665  _writeGroupInclude(ol,inGroup);
3666 
3667  /* write multi-line initializer (if any) */
3669  //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
3670  // || initLines<userInitLines // explicitly enabled
3671  // )
3672  )
3673  {
3674  //printf("md=%s initLines=%d init='%s'\n",name().data(),initLines,init.data());
3675  ol.startBold();
3678  else
3680  ol.endBold();
3682  intf.resetCodeParserState();
3683  ol.startCodeFragment();
3684  intf.parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()),
3685  -1,-1,TRUE,this,FALSE,this);
3686  ol.endCodeFragment();
3687  }
3688 
3689  QCString brief = briefDescription();
3690  QCString detailed = documentation();
3691  ArgumentList &docArgList = m_impl->defArgList;
3692  if (m_impl->templateMaster)
3693  {
3695  detailed = m_impl->templateMaster->documentation();
3696  docArgList = m_impl->templateMaster->argumentList();
3697  }
3698 
3699  /* write brief description */
3700  if (!brief.isEmpty() &&
3701  (Config_getBool(REPEAT_BRIEF) ||
3702  !Config_getBool(BRIEF_MEMBER_DESC)
3703  )
3704  )
3705  {
3706  ol.startParagraph();
3708  scopedContainer,this,
3709  brief,FALSE,FALSE,0,TRUE,FALSE);
3710  ol.endParagraph();
3711  }
3712 
3713  /* write detailed description */
3714  if (!detailed.isEmpty() ||
3715  !inbodyDocumentation().isEmpty())
3716  {
3717  // write vhdl inline code with or without option INLINE_SOURCE
3718  if (optVhdl && VhdlDocGen::isMisc(this))
3719  {
3720  VhdlDocGen::writeSource(this,ol,cname);
3721  return;
3722  }
3723  else
3724  {
3725  ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE);
3726  }
3727 
3728  if (!inbodyDocumentation().isEmpty())
3729  {
3731  scopedContainer,this,
3732  inbodyDocumentation()+"\n",TRUE,FALSE);
3733  }
3734  }
3735  else if (!brief.isEmpty() && (Config_getBool(REPEAT_BRIEF) ||
3736  !Config_getBool(BRIEF_MEMBER_DESC)))
3737  {
3738  if (!inbodyDocumentation().isEmpty())
3739  {
3740  ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE);
3741  }
3742  }
3743 
3744 
3745  //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
3746  // defArgList,
3747  // defArgList?defArgList->hasDocumentation():-1);
3748  if (docArgList.hasDocumentation())
3749  {
3750  QCString paramDocs;
3751  for (const Argument &a : docArgList)
3752  {
3753  if (a.hasDocumentation())
3754  {
3755  QCString docsWithoutDir = a.docs;
3756  QCString direction = extractDirection(docsWithoutDir);
3757  paramDocs+="@param"+direction+" "+a.name+" "+a.docs;
3758  }
3759  }
3760  // feed the result to the documentation parser
3761  ol.generateDoc(
3762  docFile(),docLine(),
3763  scopedContainer,
3764  this, // memberDef
3765  paramDocs, // docStr
3766  TRUE, // indexWords
3767  FALSE // isExample
3768  );
3769 
3770  }
3771 
3772  _writeEnumValues(ol,scopedContainer,cfname,ciname,cname);
3773  _writeReimplements(ol);
3776  _writeExamples(ol);
3778  writeSourceDef(ol,cname);
3779  writeInlineCode(ol,cname);
3780  if (hasReferencesRelation()) writeSourceRefs(ol,cname);
3782  _writeCallGraph(ol);
3783  _writeCallerGraph(ol);
3784 
3786  {
3787  ol.pushGeneratorState();
3789  QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
3790  "passthru(\"$root/doxynotes --lookup "+
3791  getOutputFileBase()+":"+anchor()+"\") ?>";
3792  ol.writeString(cmd);
3793  ol.popGeneratorState();
3794  }
3795 
3796  ol.endIndent();
3797 
3798  // enable LaTeX again
3799  //if (Config_getBool(EXTRACT_ALL) && !hasDocs) ol.enable(OutputGenerator::Latex);
3800  ol.popGeneratorState();
3801 
3803 }
3804 
3805 // strip scope and field name from the type
3806 // example: "struct N::S.v.c" will become "struct v"
3808 {
3810  if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
3811  static QRegExp re("[A-Z_a-z0-9]+::");
3812  int i,l;
3813  while ((i=re.match(ts,0,&l))!=-1)
3814  {
3815  ts=ts.left(i)+ts.mid(i+l);
3816  }
3817  i=ts.findRev('.');
3818  if (i!=-1) ts = ts.left(i);
3819  i=ts.findRev('.');
3820  if (i!=-1) ts = ts.right(ts.length()-i-1);
3821  //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
3822  return ts;
3823 }
3824 
3825 #if 0
3826 
3833 static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
3834 {
3835  int pos=0;
3836  int i;
3837  QCString name;
3838  QCString templSpec;
3839  while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
3840  {
3841  ClassDef *cd=0;
3842  MemberDef *md=0;
3843  int l = name.length()+templSpec.length();
3844  if (!templSpec.isEmpty())
3845  {
3846  cd = getResolvedClass(scope,0,name+templSpec,&md);
3847  }
3848  cd = getResolvedClass(scope,0,name);
3849  if (cd)
3850  {
3851  start=i;
3852  length=l;
3853  printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3854  return cd;
3855  }
3856  else if (md)
3857  {
3858  start=i;
3859  length=l;
3860  printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3861  return md;
3862  }
3863  pos=i+l;
3864  }
3865  return 0;
3866 }
3867 #endif
3868 
3870 {
3871  QCString type = m_impl->accessorType;
3872  if (type.isEmpty())
3873  {
3874  type = m_impl->type;
3875  }
3876 
3877  if (isTypedef() && getLanguage() != SrcLangExt_Slice) type.prepend("typedef ");
3878  return simplifyTypeForTable(type);
3879 }
3880 
3882 {
3883  Definition *scope = getOuterScope();
3884  QCString doxyName = name();
3885  QCString doxyArgs = argsString();
3886  QCString memAnchor = anchor();
3887  QCString cfname = getOutputFileBase();
3888  QCString cname;
3889  if (scope) cname = scope->name();
3890  if (doxyName.at(0)=='@')
3891  {
3892  doxyName="__unnamed__";
3893  }
3894 
3895  ClassDef *cd = m_impl->accessorClass;
3896  //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
3897 
3898  if (container && container->definitionType()==Definition::TypeClass &&
3899  !(dynamic_cast<const ClassDef*>(container))->isJavaEnum())
3900  {
3901  ol.startInlineMemberType();
3902  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3903 
3904  QCString ts = fieldType();
3905 
3906  if (cd) // cd points to an anonymous struct pointed to by this member
3907  // so we add a link to it from the type column.
3908  {
3909  int i=0;
3910  const char *prefixes[] = { "struct ","union ","class ", 0 };
3911  const char **p = prefixes;
3912  while (*p)
3913  {
3914  int l=qstrlen(*p);
3915  if (ts.left(l)==*p)
3916  {
3917  ol.writeString(*p);
3918  i=l;
3919  }
3920  p++;
3921  }
3922  ol.writeObjectLink(cd->getReference(),
3923  cd->getOutputFileBase(),
3924  cd->anchor(),ts.mid(i));
3925  }
3926  else // use standard auto linking
3927  {
3928  linkifyText(TextGeneratorOLImpl(ol), // out
3929  scope, // scope
3930  getBodyDef(), // fileScope
3931  this, // self
3932  ts // text
3933  );
3934  }
3935  ol.endDoxyAnchor(cfname,memAnchor);
3936  ol.endInlineMemberType();
3937  }
3938 
3939  ol.startInlineMemberName();
3940  ol.docify(doxyName);
3941  if (isVariable() && argsString() && !isObjCMethod())
3942  {
3944  }
3945  if (!m_impl->bitfields.isEmpty()) // add bitfields
3946  {
3948  }
3949  ol.endInlineMemberName();
3950 
3951  ol.startInlineMemberDoc();
3952 
3953  QCString brief = briefDescription();
3954  QCString detailed = documentation();
3955 
3956  /* write brief description */
3957  if (!brief.isEmpty())
3958  {
3960  getOuterScope()?getOuterScope():container,this,
3961  brief,FALSE,FALSE,0,TRUE,FALSE);
3962  }
3963 
3964  /* write detailed description */
3965  if (!detailed.isEmpty())
3966  {
3967  ol.generateDoc(docFile(),docLine(),
3968  getOuterScope()?getOuterScope():container,this,
3969  detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
3970 
3971  }
3972 
3973  ol.endInlineMemberDoc();
3974 }
3975 
3977 {
3978  switch (m_impl->mtype)
3979  {
3980  case MemberType_Define: return "macro definition";
3981  case MemberType_Function: return "function";
3982  case MemberType_Variable: return "variable";
3983  case MemberType_Typedef: return "typedef";
3984  case MemberType_Enumeration: return "enumeration";
3985  case MemberType_EnumValue: return "enumvalue";
3986  case MemberType_Signal: return "signal";
3987  case MemberType_Slot: return "slot";
3988  case MemberType_Friend: return "friend";
3989  case MemberType_DCOP: return "dcop";
3990  case MemberType_Property: return "property";
3991  case MemberType_Event: return "event";
3992  case MemberType_Interface: return "interface";
3993  case MemberType_Service: return "service";
3994  case MemberType_Sequence: return "sequence";
3995  case MemberType_Dictionary: return "dictionary";
3996  default: return "unknown";
3997  }
3998 }
3999 
4001 {
4002  /*
4003  * Removed bug_303020:
4004  * if (m_impl->memberGroup) return;
4005  */
4006  const ClassDef *cd = getClassDef();
4007  const NamespaceDef *nd = getNamespaceDef();
4008  const FileDef *fd = getFileDef();
4009  const GroupDef *gd = getGroupDef();
4010  const Definition *d=0;
4011  const char *t=0;
4012  if (cd)
4013  t="class", d=cd;
4014  else if (nd)
4015  {
4016  d=nd;
4017  if (d->getLanguage() == SrcLangExt_Fortran)
4018  t="module";
4019  else
4020  t="namespace";
4021  }
4022  else if (gd)
4023  t="group", d=gd;
4024  else
4025  t="file", d=fd;
4026  static bool extractAll = Config_getBool(EXTRACT_ALL);
4027 
4028  //printf("%s:warnIfUndoc: hasUserDocs=%d isFriendClass=%d protection=%d isRef=%d isDel=%d\n",
4029  // name().data(),
4030  // hasUserDocumentation(),isFriendClass(),protectionLevelVisible(m_impl->prot),isReference(),isDeleted());
4031  if ((!hasUserDocumentation() && !extractAll) &&
4032  !isFriendClass() &&
4033  name().find('@')==-1 && d && d->name().find('@')==-1 &&
4035  !isReference() && !isDeleted()
4036  )
4037  {
4038  warn_undoc(getDefFileName(),getDefLine(),"Member %s%s (%s) of %s %s is not documented.",
4040  }
4041  else if (!isDetailedSectionLinkable())
4042  {
4044  }
4045 }
4046 
4048 {
4049  QCString result = s;
4050  bool done;
4051  do
4052  {
4053  done=true;
4054  if (result.stripPrefix("constexpr ") ||
4055  result.stripPrefix("consteval ") ||
4056  result.stripPrefix("virtual ") ||
4057  result.stripPrefix("static ") ||
4058  result.stripPrefix("volatile "))
4059  {
4060  done=false;
4061  }
4062  }
4063  while (!done);
4064  return result;
4065 }
4066 
4067 void MemberDefImpl::detectUndocumentedParams(bool hasParamCommand,bool hasReturnCommand) const
4068 {
4069  if (!Config_getBool(WARN_NO_PARAMDOC)) return;
4071  bool isPython = getLanguage()==SrcLangExt_Python;
4072  bool isFortran = getLanguage()==SrcLangExt_Fortran;
4073  bool isFortranSubroutine = isFortran && returnType.find("subroutine")!=-1;
4074  bool isVoidReturn = returnType=="void";
4075 
4076  if (!m_impl->hasDocumentedParams && hasParamCommand)
4077  {
4078  //printf("%s:hasDocumentedParams=TRUE;\n",name().data());
4080  }
4081  else if (!m_impl->hasDocumentedParams)
4082  {
4083  const ArgumentList &al = argumentList();
4084  const ArgumentList &declAl = declArgumentList();
4085  bool allDoc=TRUE; // no parameter => all parameters are documented
4086  if ( // member has parameters
4087  al.hasParameters() // with at least one parameter (that is not void)
4088  )
4089  {
4090  // see if all parameters have documentation
4091  for (auto it = al.begin(); it!=al.end() && allDoc; ++it)
4092  {
4093  Argument a = *it;
4094  if (!a.name.isEmpty() && a.type!="void" &&
4095  !(isPython && (a.name=="self" || a.name=="cls"))
4096  )
4097  {
4098  allDoc = !a.docs.isEmpty();
4099  }
4100  //printf("a->type=%s a->name=%s doc=%s\n",
4101  // a->type.data(),a->name.data(),a->docs.data());
4102  }
4103  if (!allDoc && declAl.empty()) // try declaration arguments as well
4104  {
4105  allDoc=TRUE;
4106  for (auto it = al.begin(); it!=al.end() && allDoc; ++it)
4107  {
4108  Argument a = *it;
4109  if (!a.name.isEmpty() && a.type!="void" &&
4110  !(isPython && (a.name=="self" || a.name=="cls"))
4111  )
4112  {
4113  allDoc = !a.docs.isEmpty();
4114  }
4115  //printf("a->name=%s doc=%s\n",a->name.data(),a->docs.data());
4116  }
4117  }
4118  }
4119  if (allDoc)
4120  {
4121  //printf("%s:hasDocumentedParams=TRUE;\n",name().data());
4123  }
4124  }
4125 
4126  //printf("Member %s hasDocumentedReturnType=%d hasReturnCommand=%d\n",
4127  // name().data(),m_impl->hasDocumentedReturnType,hasReturnCommand);
4128  if (!m_impl->hasDocumentedReturnType && // docs not yet found
4129  hasReturnCommand)
4130  {
4132  }
4133  else if ( // see if return type is documented in a function w/o return type
4134  hasReturnCommand &&
4135  (
4136  isVoidReturn || // void return type
4137  isFortranSubroutine || // fortran subroutine
4138  isConstructor() || // a constructor
4139  isDestructor() // or destructor
4140  )
4141  )
4142  {
4143  warn_doc_error(getDefFileName(),getDefLine(),"documented empty return type of %s",
4144  qualifiedName().data());
4145  }
4146  else if ( // see if return needs to documented
4148  isVoidReturn || // void return type
4149  isFortranSubroutine || // fortran subroutine
4150  isConstructor() || // a constructor
4151  isDestructor() // or destructor
4152  )
4153  {
4155  }
4156 }
4157 
4159 {
4160  if (!Config_getBool(EXTRACT_ALL) &&
4161  Config_getBool(WARN_IF_UNDOCUMENTED) &&
4162  Config_getBool(WARN_NO_PARAMDOC) &&
4163  !isDeleted() &&
4164  !isReference() &&
4166  {
4167  QCString returnType = typeString();
4169  {
4171  "parameters of member %s are not (all) documented",
4172  qPrint(qualifiedName()));
4173  }
4175  isFunction() && hasDocumentation() && !returnType.isEmpty())
4176  {
4178  "return type of member %s is not documented",
4179  qPrint(qualifiedName()));
4180  }
4181  }
4182 }
4183 
4185 {
4186  ClassDef *fcd=0;
4187  QCString baseName=name();
4188  int i=baseName.find('<');
4189  if (i!=-1) baseName=baseName.left(i);
4190  return (isFriendClass() &&
4191  (fcd=getClass(baseName)) && fcd->isLinkable());
4192 }
4193 
4195 {
4196  return m_impl->defArgList.isDeleted;
4197 }
4198 
4200 {
4202  (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values
4203  (m_impl->defArgList.hasDocumentation()); // has doc arguments
4204 }
4205 
4206 #if 0
4208 {
4209  bool hasDocs = DefinitionImpl::hasUserDocumentation();
4210  return hasDocs;
4211 }
4212 #endif
4213 
4214 
4216 {
4217  m_impl->memberGroup = grp;
4218 }
4219 
4220 bool MemberDefImpl::visibleMemberGroup(bool hideNoHeader) const
4221 {
4222  return m_impl->memberGroup!=0 &&
4223  (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
4224 }
4225 
4227 {
4228  QCString result;
4229  if (getClassDef()) result=getClassDef()->displayName();
4230  else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
4231  return result;
4232 }
4233 
4234 #if 0
4235 static QCString escapeAnchor(const QCString &anchor)
4236 {
4237  QCString result;
4238  int l = anchor.length(),i;
4239  for (i=0;i<l;i++)
4240  {
4241  char c = anchor.at(i);
4242  if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
4243  {
4244  result+=c;
4245  }
4246  else
4247  {
4248  static char hexStr[]="0123456789ABCDEF";
4249  char escChar[]={ '_', 0, 0, 0 };
4250  escChar[1]=hexStr[c>>4];
4251  escChar[2]=hexStr[c&0xf];
4252  result+=escChar;
4253  }
4254  }
4255  return result;
4256 }
4257 #endif
4258 
4260 {
4261  QCString memAnchor = name();
4262  if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
4263 
4264  memAnchor.prepend(definition()); // actually the method name is now included
4265  // twice, which is silly, but we keep it this way for backward
4266  // compatibility.
4267 
4268  // include number of template arguments as well,
4269  // to distinguish between two template
4270  // specializations that only differ in the template parameters.
4271  if (m_impl->tArgList.hasParameters())
4272  {
4273  char buf[20];
4274  qsnprintf(buf,20,"%d:",(int)m_impl->tArgList.size());
4275  buf[19]='\0';
4276  memAnchor.prepend(buf);
4277  }
4278 
4279  // convert to md5 hash
4280  uchar md5_sig[16];
4281  QCString sigStr(33);
4282  MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
4283  MD5SigToString(md5_sig,sigStr.rawData(),33);
4284  m_impl->anc = "a"+sigStr;
4285 }
4286 
4288  const QCString &fileName,int startLine,
4289  bool hasDocs,MemberDef *member)
4290 {
4291  //printf("%s MemberDefImpl::setGroupDef(%s)\n",name().data(),gd->name().data());
4292  m_impl->group=gd;
4293  m_impl->grouppri=pri;
4294  m_impl->groupFileName=fileName;
4295  m_impl->groupStartLine=startLine;
4296  m_impl->groupHasDocs=hasDocs;
4297  m_impl->groupMember=member;
4298  m_isLinkableCached = 0;
4299 }
4300 
4301 void MemberDefImpl::setEnumScope(MemberDef *md,bool livesInsideEnum)
4302 {
4303  m_impl->enumScope=md;
4305  if (md->getGroupDef())
4306  {
4307  m_impl->group=md->getGroupDef();
4308  m_impl->grouppri=md->getGroupPri();
4312  m_isLinkableCached = 0;
4313  }
4314 }
4315 
4317 {
4318  m_impl->classDef=cd;
4319  m_isLinkableCached = 0;
4321  setOuterScope(cd);
4322 }
4323 
4325 {
4326  m_impl->nspace=nd;
4327  setOuterScope(nd);
4328 }
4329 
4331  const ArgumentList &formalArgs,const ArgumentList &actualArgs) const
4332 {
4333  //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
4334  ArgumentList actualArgList;
4335  if (!m_impl->defArgList.empty())
4336  {
4337  actualArgList = m_impl->defArgList;
4338 
4339  // replace formal arguments with actuals
4340  for (Argument &arg : actualArgList)
4341  {
4342  arg.type = substituteTemplateArgumentsInString(arg.type,formalArgs,actualArgs);
4343  }
4344  actualArgList.trailingReturnType =
4345  substituteTemplateArgumentsInString(actualArgList.trailingReturnType,formalArgs,actualArgs);
4346  }
4347 
4348  QCString methodName=name();
4349  if (methodName.left(9)=="operator ") // conversion operator
4350  {
4351  methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
4352  }
4353 
4354  MemberDef *imd = createMemberDef(
4356  substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
4357  methodName,
4358  substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
4361  ArgumentList(), ArgumentList(), ""
4362  );
4363  imd->setArgumentList(actualArgList);
4364  imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
4365  imd->setBodyDef(getBodyDef());
4367  //imd->setBodyMember(this);
4368 
4369  // TODO: init other member variables (if needed).
4370  // TODO: reimplemented info
4371  return imd;
4372 }
4373 
4375 {
4376  //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
4377  // name().data(),m_impl->initializer.data(),m_impl->initLines,
4378  // m_impl->maxInitLines,m_impl->userInitLines);
4379  return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
4380  ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
4381 }
4382 
4384 {
4385  //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
4386  // initLines,userInitLines,maxInitLines);
4387  return m_impl->initLines>0 &&
4388  ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
4389  || m_impl->initLines<m_impl->userInitLines // explicitly enabled
4390  );
4391 }
4392 
4393 void MemberDefImpl::setInitializer(const char *initializer)
4394 {
4396  int l=m_impl->initializer.length();
4397  int p=l-1;
4398  while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
4401  //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
4402 }
4403 
4405 {
4406  static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
4407  //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
4408  //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
4409  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
4410  SrcLangExt lang = getLanguage();
4411  if (!isLinkableInProject()) return;
4412  QCString memLabel;