My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
memberdef.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <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 "searchindex.h"
37 #include "parserintf.h"
38 #include "marshal.h"
39 #include "objcache.h"
40 
41 #include "vhdldocgen.h"
42 #include "arguments.h"
43 #include "memberlist.h"
44 #include "namespacedef.h"
45 #include "filedef.h"
46 #include "config.h"
47 
48 //-----------------------------------------------------------------------------
49 
51 
52 //-----------------------------------------------------------------------------
53 
54 static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
55 {
56  QCString result;
57  QCString clRealName=n;
58  int p=0,i;
59  if ((i=clRealName.find('<'))!=-1)
60  {
61  clRealName=clRealName.left(i); // strip template specialization
62  }
63  if ((i=clRealName.findRev("::"))!=-1)
64  {
65  clRealName=clRealName.right(clRealName.length()-i-2);
66  }
67  while ((i=s.find(clRealName,p))!=-1)
68  {
69  result+=s.mid(p,i-p);
70  uint j=clRealName.length()+i;
71  if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
72  { // add template names
73  //printf("Adding %s+%s\n",clRealName.data(),t.data());
74  result+=clRealName+t;
75  }
76  else
77  { // template names already present
78  //printf("Adding %s\n",clRealName.data());
79  result+=clRealName;
80  }
81  p=i+clRealName.length();
82  }
83  result+=s.right(s.length()-p);
84  //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
85  return result;
86 }
87 
88 // ol.startMemberDocName has already been done before this is called.
89 // when this function returns TRUE, ol.endParameterList will be called.
90 //
91 // typical sequence:
92 // ol.startMemberDoc
93 // ol.startMemberDocName
94 // --- enter writeDefArgumentList
95 // ol.endMemberDocName
96 // ol.startParameterList
97 // ...
98 // ol.startParameterType(first=TRUE)
99 // ol.endParameterType
100 // ol.startParameterName
101 // ol.endParameterName(last==FALSE)
102 // ...
103 // ol.startParameterType(first=FALSE)
104 // ol.endParamtereType
105 // ol.startParameterName
106 // ol.endParameterName(last==TRUE)
107 // ...
108 // --- leave writeDefArgumentList with return value TRUE
109 // ol.endParameterList
110 // ol.endMemberDoc(hasArgs=TRUE)
111 //
112 // For an empty list the function should return FALSE, the sequence is
113 // ol.startMemberDoc
114 // ol.startMemberDocName
115 // --- enter writeDefArgumentList
116 // --- leave writeDefArgumentList with return value FALSE
117 // ol.endMemberDocName
118 // ol.endMemberDoc(hasArgs=FALSE);
119 //
120 
122 {
123  ArgumentList *defArgList=(md->isDocsForDefinition()) ?
124  md->argumentList() : md->declArgumentList();
125  //printf("writeDefArgumentList `%s' isDocsForDefinition()=%d\n",md->name().data(),md->isDocsForDefinition());
126  if (defArgList==0 || md->isProperty())
127  {
128  return FALSE; // member has no function like argument list
129  }
130 
131  // simple argument list for tcl
132  if (md->getLanguage()==SrcLangExt_Tcl)
133  {
134  if (defArgList->count()==0) return FALSE;
135  ArgumentListIterator ali(*defArgList);
136  Argument *a;
137  ol.endMemberDocName();
138  ol.startParameterList(FALSE);
139  ol.startParameterType(TRUE,0);
140  ol.endParameterType();
141  ol.startParameterName(FALSE);
142  for (;(a=ali.current());++ali)
143  {
144  if (a->defval.isEmpty())
145  {
146  ol.docify(a->name+" ");
147  }
148  else
149  {
150  ol.docify("?"+a->name+"? ");
151  }
152  }
153  ol.endParameterName(TRUE,FALSE,FALSE);
154  return TRUE;
155  }
156 
157  if (!md->isDefine()) ol.docify(" ");
158 
159  //printf("writeDefArgList(%d)\n",defArgList->count());
160  ol.pushGeneratorState();
161  //ol.disableAllBut(OutputGenerator::Html);
162  bool htmlOn = ol.isEnabled(OutputGenerator::Html);
163  bool latexOn = ol.isEnabled(OutputGenerator::Latex);
164  {
165  // html and latex
166  if (htmlOn) ol.enable(OutputGenerator::Html);
167  if (latexOn) ol.enable(OutputGenerator::Latex);
168 
169  ol.endMemberDocName();
170  ol.startParameterList(!md->isObjCMethod());
171  }
172  ol.enableAll();
175  {
176  // other formats
177  if (!md->isObjCMethod()) ol.docify("("); // start argument list
178  ol.endMemberDocName();
179  }
180  ol.popGeneratorState();
181  //printf("===> name=%s isDefine=%d\n",md->name().data(),md->isDefine());
182 
183  QCString cName;
184  if (scope)
185  {
186  cName=scope->name();
187  int il=cName.find('<');
188  int ir=cName.findRev('>');
189  if (il!=-1 && ir!=-1 && ir>il)
190  {
191  cName=cName.mid(il,ir-il+1);
192  //printf("1. cName=%s\n",cName.data());
193  }
194  else if (scope->definitionType()==Definition::TypeClass && ((ClassDef*)scope)->templateArguments())
195  {
196  cName=tempArgListToString(((ClassDef*)scope)->templateArguments(),scope->getLanguage());
197  //printf("2. cName=%s\n",cName.data());
198  }
199  else // no template specifier
200  {
201  cName.resize(0);
202  }
203  }
204  //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());
205 
206  bool first=TRUE;
207  bool paramTypeStarted=FALSE;
208  bool isDefine = md->isDefine();
209  ArgumentListIterator ali(*defArgList);
210  Argument *a=ali.current();
211  while (a)
212  {
213  if (isDefine || first)
214  {
215  ol.startParameterType(first,0);
216  paramTypeStarted=TRUE;
217  if (isDefine)
218  {
219  ol.endParameterType();
220  ol.startParameterName(TRUE);
221  }
222  }
223  QRegExp re(")("),res("(.*\\*");
224  int vp=a->type.find(re);
225  int wp=a->type.find(res);
226 
227  // use the following to put the function pointer type before the name
228  bool hasFuncPtrType=FALSE;
229 
230  if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
231  {
232  ol.docify(a->attrib+" ");
233  }
234  if (hasFuncPtrType) // argument type is a function pointer
235  {
236  //printf("a->type=`%s' a->name=`%s'\n",a->type.data(),a->name.data());
237  QCString n=a->type.left(vp);
238  if (hasFuncPtrType) n=a->type.left(wp);
239  if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
240  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
241  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
242  }
243  else // non-function pointer type
244  {
245  QCString n=a->type;
246  if (md->isObjCMethod()) { n.prepend("("); n.append(")"); }
247  if (a->type!="...")
248  {
249  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
250  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n);
251  }
252  }
253  if (!isDefine)
254  {
255  if (paramTypeStarted)
256  {
257  ol.endParameterType();
258  paramTypeStarted=FALSE;
259  }
260  ol.startParameterName(defArgList->count()<2);
261  }
262  if (hasFuncPtrType)
263  {
264  ol.docify(a->type.mid(wp,vp-wp));
265  }
266  if (!a->name.isEmpty() || a->type=="...") // argument has a name
267  {
268  //if (!hasFuncPtrType)
269  //{
270  // ol.docify(" ");
271  //}
274  ol.docify(" "); /* man page */
275  if (htmlOn) ol.enable(OutputGenerator::Html);
277  ol.startEmphasis();
279  if (latexOn) ol.enable(OutputGenerator::Latex);
280  if (a->name.isEmpty()) ol.docify(a->type); else ol.docify(a->name);
283  ol.endEmphasis();
285  if (latexOn) ol.enable(OutputGenerator::Latex);
286  }
287  if (!a->array.isEmpty())
288  {
289  ol.docify(a->array);
290  }
291  if (hasFuncPtrType) // write the part of the argument type
292  // that comes after the name
293  {
295  md,a->type.right(a->type.length()-vp));
296  }
297  if (!a->defval.isEmpty()) // write the default value
298  {
299  QCString n=a->defval;
300  if (!cName.isEmpty()) n=addTemplateNames(n,scope->name(),cName);
301  ol.docify(" = ");
302 
303  ol.startTypewriter();
304  linkifyText(TextGeneratorOLImpl(ol),scope,md->getBodyDef(),md,n,FALSE,TRUE,TRUE);
305  ol.endTypewriter();
306 
307  }
308  ++ali;
309  a=ali.current();
310  if (a)
311  {
312  if (!md->isObjCMethod()) ol.docify(", "); // there are more arguments
313  if (!isDefine)
314  {
315  QCString key;
316  if (md->isObjCMethod() && a->attrib.length()>=2)
317  {
318  //printf("Found parameter keyword %s\n",a->attrib.data());
319  // strip [ and ]
320  key=a->attrib.mid(1,a->attrib.length()-2);
321  if (key!=",") key+=":"; // for normal keywords add colon
322  }
323  ol.endParameterName(FALSE,FALSE,!md->isObjCMethod());
324  if (paramTypeStarted)
325  {
326  ol.endParameterType();
327  }
328  ol.startParameterType(FALSE,key);
329  paramTypeStarted=TRUE;
330  }
331  else // isDefine
332  {
333  ol.endParameterName(FALSE,FALSE,TRUE);
334  }
335  }
336  first=FALSE;
337  }
338  ol.pushGeneratorState();
341  if (!md->isObjCMethod()) ol.docify(")"); // end argument list
342  ol.enableAll();
343  if (htmlOn) ol.enable(OutputGenerator::Html);
344  if (latexOn) ol.enable(OutputGenerator::Latex);
345  if (first) ol.startParameterName(defArgList->count()<2);
346  ol.endParameterName(TRUE,defArgList->count()<2,!md->isObjCMethod());
347  ol.popGeneratorState();
348  if (md->extraTypeChars())
349  {
350  ol.docify(md->extraTypeChars());
351  }
352  if (defArgList->constSpecifier)
353  {
354  ol.docify(" const");
355  }
356  if (defArgList->volatileSpecifier)
357  {
358  ol.docify(" volatile");
359  }
360  if (!defArgList->trailingReturnType.isEmpty())
361  {
362  linkifyText(TextGeneratorOLImpl(ol), // out
363  scope, // scope
364  md->getBodyDef(), // fileScope
365  md, // self
366  defArgList->trailingReturnType, // text
367  FALSE // autoBreak
368  );
369 
370  }
371  return TRUE;
372 }
373 
375  OutputList &ol, ClassDef *cd, MemberDef *md, QCString const& exception)
376 {
377  // this is ordinary exception spec - there must be a '('
378  //printf("exception='%s'\n",exception.data());
379  int index = exception.find('(');
380  if (index!=-1)
381  {
382  ol.exceptionEntry(exception.left(index),false);
383  ++index; // paren in second column so skip it here
384  for (int comma = exception.find(',', index); comma!=-1; )
385  {
386  ++comma; // include comma
388  exception.mid(index,comma-index));
389  ol.exceptionEntry(0,false);
390  index=comma;
391  comma = exception.find(',', index);
392  }
393  int close = exception.find(')', index);
394  if (close!=-1)
395  {
396  QCString type=removeRedundantWhiteSpace(exception.mid(index,close-index));
398  ol.exceptionEntry(0,true);
399  }
400  else
401  {
402  warn(md->getDefFileName(),md->getDefLine(),
403  "missing ) in exception list on member %s",qPrint(md->name()));
404  }
405  }
406  else // Java Exception
407  {
408  ol.docify(" ");
410  }
411 }
412 
414 {
415  QCString exception(QCString(md->excpString()).stripWhiteSpace());
416  if ('{'==exception.at(0))
417  {
418  // this is an UNO IDL attribute - need special handling
419  int index = exception.find(';');
420  int oldIndex = 1;
421  while (-1 != index) // there should be no more than 2 (set / get)
422  {
423  // omit '{' and ';' -> "set raises (...)"
424  writeExceptionListImpl(ol,cd,md,exception.mid(oldIndex,index-oldIndex));
425  oldIndex=index+1;
426  index = exception.find(';',oldIndex);
427  }
428  // the rest is now just '}' - omit that
429  }
430  else
431  {
433  }
434 }
435 
437 {
438  ol.docify("template<");
439  ArgumentListIterator ali(*al);
440  Argument *a = ali.current();
441  while (a)
442  {
443  ol.docify(a->type);
444  ol.docify(" ");
445  ol.docify(a->name);
446  if (a->defval.length()!=0)
447  {
448  ol.docify(" = ");
449  ol.docify(a->defval);
450  }
451  ++ali;
452  a=ali.current();
453  if (a) ol.docify(", ");
454  }
455  ol.docify("> ");
456 }
457 
458 //-----------------------------------------------------------------------------
459 //-----------------------------------------------------------------------------
460 //-----------------------------------------------------------------------------
461 
463 {
464  public:
465  MemberDefImpl();
466  ~MemberDefImpl();
467  void init(Definition *def,const char *t,const char *a,const char *e,
468  Protection p,Specifier v,bool s,Relationship r,
469  MemberType mt,const ArgumentList *tal,
470  const ArgumentList *al
471  );
472 
473  ClassDef *classDef; // member of or related to
474  FileDef *fileDef; // member of file definition
475  NamespaceDef *nspace; // the namespace this member is in.
476 
477  MemberDef *enumScope; // the enclosing scope, if this is an enum field
479  MemberDef *annEnumType; // the anonymous enum that is the type of this member
480  MemberList *enumFields; // enumeration fields
481 
482  MemberDef *redefines; // the members that this member redefines
483  MemberList *redefinedBy; // the list of members that redefine this one
484 
485  MemberDef *memDef; // member definition for this declaration
486  MemberDef *memDec; // member declaration for this definition
487  ClassDef *relatedAlso; // points to class marked by relatedAlso
488 
489  ExampleSDict *exampleSDict; // a dictionary of all examples for quick access
490 
491  QCString type; // return actual type
492  QCString accessorType; // return type that tell how to get to this member
493  ClassDef *accessorClass; // class that this member accesses (for anonymous types)
494  QCString args; // function arguments/variable array specifiers
495  QCString def; // member definition in code (fully qualified name)
496  QCString anc; // HTML anchor name
497  Specifier virt; // normal/virtual/pure virtual
498  Protection prot; // protection type [Public/Protected/Private]
499  QCString decl; // member declaration in class
500 
501  QCString bitfields; // struct member bitfields
502  QCString read; // property read accessor
503  QCString write; // property write accessor
504  QCString exception; // exceptions that can be thrown
505  QCString initializer; // initializer
506  QCString extraTypeChars; // extra type info found after the argument list
507  QCString enumBaseType; // base type of the enum (C++11)
508  int initLines; // number of lines in the initializer
509 
510  uint64 memSpec; // The specifiers present for this member
511  MemberType mtype; // returns the kind of member
512  int maxInitLines; // when the initializer will be displayed
513  int userInitLines; // result of explicit \hideinitializer or \showinitializer
515 
516  ArgumentList *defArgList; // argument list of this member definition
517  ArgumentList *declArgList; // argument list of this member declaration
518 
519  ArgumentList *tArgList; // template argument list of function template
520  ArgumentList *typeConstraints; // type constraints for template parameters
522  QList<ArgumentList> *defTmpArgLists; // lists of template argument lists
523  // (for template functions in nested template classes)
524 
525  ClassDef *cachedAnonymousType; // if the member has an anonymous compound
526  // as its type then this is computed by
527  // getClassDefOfAnonymousType() and
528  // cached here.
530 
531  MemberDef *groupAlias; // Member containing the definition
532  int grpId; // group id
533  MemberGroup *memberGroup; // group's member definition
534  GroupDef *group; // group in which this member is in
535  Grouping::GroupPri_t grouppri; // priority of this definition
536  QCString groupFileName; // file where this grouping was defined
537  int groupStartLine; // line " " " " "
539 
544 
545  // inbody documentation
546  //int inbodyLine;
547  //QCString inbodyFile;
548  //QCString inbodyDocs;
549 
550  // documentation inheritance
552 
553  // to store the output file base from tag files
555 
556  // objective-c
557  bool implOnly; // function found in implementation but not
558  // in the interface
561  bool isDMember;
562  Relationship related; // relationship of this to the class
563  bool stat; // is it a static function?
564  bool proto; // is it a prototype;
565  bool docEnumValues; // is an enum with documented enum values.
566  bool annScope; // member is part of an annoymous scope
567  bool annUsed;
570  bool explExt; // member was explicitly declared external
571  bool tspec; // member is a template specialization
572  bool groupHasDocs; // true if the entry that caused the grouping was documented
573  bool docsForDefinition; // TRUE => documentation block is put before
574  // definition.
575  // FALSE => block is put before declaration.
578 };
579 
581  enumFields(0),
582  redefinedBy(0),
583  exampleSDict(0),
584  defArgList(0),
585  declArgList(0),
586  tArgList(0),
587  typeConstraints(0),
588  defTmpArgLists(0),
589  classSectionSDict(0),
590  category(0),
591  categoryRelation(0)
592 {
593 }
594 
596 {
597  delete redefinedBy;
598  delete exampleSDict;
599  delete enumFields;
600  delete defArgList;
601  delete tArgList;
602  delete typeConstraints;
603  delete defTmpArgLists;
604  delete classSectionSDict;
605  delete declArgList;
606 }
607 
609  const char *t,const char *a,const char *e,
610  Protection p,Specifier v,bool s,Relationship r,
611  MemberType mt,const ArgumentList *tal,
612  const ArgumentList *al
613  )
614 {
615  classDef=0;
616  fileDef=0;
617  redefines=0;
618  relatedAlso=0;
619  redefinedBy=0;
620  accessorClass=0;
621  nspace=0;
622  memDef=0;
623  memDec=0;
624  group=0;
625  grpId=-1;
626  exampleSDict=0;
627  enumFields=0;
628  enumScope=0;
629  livesInsideEnum=FALSE;
630  defTmpArgLists=0;
631  hasCallGraph = FALSE;
632  hasCallerGraph = FALSE;
633  initLines=0;
634  type=t;
635  if (mt==MemberType_Typedef) type.stripPrefix("typedef ");
636  // type.stripPrefix("struct ");
637  // type.stripPrefix("class " );
638  // type.stripPrefix("union " );
640  args=a;
642  if (type.isEmpty()) decl=def->name()+args; else decl=type+" "+def->name()+args;
643 
644  memberGroup=0;
645  virt=v;
646  prot=p;
647  related=r;
648  stat=s;
649  mtype=mt;
650  exception=e;
651  proto=FALSE;
652  annScope=FALSE;
653  memSpec=0;
654  annMemb=0;
655  annUsed=FALSE;
656  annEnumType=0;
657  groupAlias=0;
658  explExt=FALSE;
659  tspec=FALSE;
661  maxInitLines=Config_getInt(MAX_INITIALIZER_LINES);
662  userInitLines=-1;
663  docEnumValues=FALSE;
664  // copy function template arguments (if any)
665  if (tal)
666  {
667  tArgList = tal->deepCopy();
668  }
669  else
670  {
671  tArgList=0;
672  }
673  //printf("new member al=%p\n",al);
674  // copy function definition arguments (if any)
675  if (al)
676  {
677  defArgList = al->deepCopy();
678  }
679  else
680  {
681  defArgList=0;
682  }
683  // convert function declaration arguments (if any)
684  if (!args.isEmpty())
685  {
688  //printf("setDeclArgList %s to %s const=%d\n",args.data(),
689  // argListToString(declArgList).data(),declArgList->constSpecifier);
690  }
691  else
692  {
693  declArgList = 0;
694  }
695  templateMaster = 0;
696  classSectionSDict = 0;
697  docsForDefinition = TRUE;
698  isTypedefValCached = FALSE;
699  cachedTypedefValue = 0;
700  //inbodyLine = -1;
701  implOnly=FALSE;
702  groupMember = 0;
703  hasDocumentedParams = FALSE;
704  hasDocumentedReturnType = FALSE;
705  docProvider = 0;
706  isDMember = def->getDefFileName().right(2).lower()==".d";
707 }
708 
709 
710 //-----------------------------------------------------------------------------
711 //-----------------------------------------------------------------------------
712 //-----------------------------------------------------------------------------
713 
736 MemberDef::MemberDef(const char *df,int dl,int dc,
737  const char *t,const char *na,const char *a,const char *e,
739  const ArgumentList *tal,const ArgumentList *al
740  ) : Definition(df,dl,dc,removeRedundantWhiteSpace(na)), visited(FALSE)
741 {
742  //printf("MemberDef::MemberDef(%s)\n",na);
743  m_impl = new MemberDefImpl;
744  m_impl->init(this,t,a,e,p,v,s,r,mt,tal,al);
745  m_isLinkableCached = 0;
748 }
749 
750 MemberDef::MemberDef(const MemberDef &md) : Definition(md), visited(FALSE)
751 {
752  m_impl = new MemberDefImpl;
753  m_isLinkableCached = 0;
756 }
757 
759 {
760  //MemberDef *result = new MemberDef(getDefFileName(),getDefLine(),name());
761  MemberDef *result = new MemberDef(*this);
762  // first copy everything by reference
763  *result->m_impl = *m_impl;
764  // clear pointers owned by object
765  result->m_impl->redefinedBy= 0;
766  result->m_impl->exampleSDict=0;
767  result->m_impl->enumFields=0;
768  result->m_impl->defArgList=0;
769  result->m_impl->tArgList=0;
770  result->m_impl->typeConstraints=0;
771  result->m_impl->defTmpArgLists=0;
772  result->m_impl->classSectionSDict=0;
773  result->m_impl->declArgList=0;
774  // replace pointers owned by the object by deep copies
775  if (m_impl->redefinedBy)
776  {
778  MemberDef *md;
779  for (mli.toFirst();(md=mli.current());++mli)
780  {
781  result->insertReimplementedBy(md);
782  }
783  }
784  if (m_impl->exampleSDict)
785  {
787  Example *e;
788  for (it.toFirst();(e=it.current());++it)
789  {
790  result->addExample(e->anchor,e->name,e->file);
791  }
792  }
793  if (m_impl->enumFields)
794  {
796  MemberDef *md;
797  for (mli.toFirst();(md=mli.current());++mli)
798  {
799  result->insertEnumField(md);
800  }
801  }
802  if (m_impl->defArgList)
803  {
804  result->m_impl->defArgList = m_impl->defArgList->deepCopy();
805  }
806  if (m_impl->tArgList)
807  {
808  result->m_impl->tArgList = m_impl->tArgList->deepCopy();
809  }
810  if (m_impl->typeConstraints)
811  {
813  }
816  {
817  result->m_impl->classSectionSDict = new SDict<MemberList>(7);
819  MemberList *ml;
820  for (it.toFirst();(ml=it.current());++it)
821  {
822  result->m_impl->classSectionSDict->append(it.currentKey(),ml);
823  }
824  }
825  if (m_impl->declArgList)
826  {
828  }
829  return result;
830 }
831 
833 {
834  setOuterScope(scope);
836  {
837  m_impl->classDef = (ClassDef*)scope;
838  }
839  else if (scope->definitionType()==Definition::TypeFile)
840  {
841  m_impl->fileDef = (FileDef*)scope;
842  }
843  else if (scope->definitionType()==Definition::TypeNamespace)
844  {
845  m_impl->nspace = (NamespaceDef*)scope;
846  }
847  m_isLinkableCached = 0;
849 }
850 
851 
854 {
855  delete m_impl;
856  //printf("%p: ~MemberDef()\n",this);
857  m_impl=0;
858 }
859 
861 {
862  m_impl->redefines = md;
863 }
864 
866 {
867  if (m_impl->templateMaster)
868  {
870  }
872  if (m_impl->redefinedBy->findRef(md)==-1)
873  {
874  m_impl->redefinedBy->inSort(md);
875  }
876 }
877 
879 {
880  return m_impl->redefines;
881 }
882 
884 {
885  return m_impl->redefinedBy;
886 }
887 
889 {
890  if (cd && m_impl->redefinedBy)
891  {
893  MemberDef *md;
894  for (mi.toFirst();(md=mi.current());++mi)
895  {
896  ClassDef *mcd = md->getClassDef();
897  if (mcd)
898  {
899  if (cd==mcd || cd->isBaseClass(mcd,TRUE))
900  {
901  return TRUE;
902  }
903  }
904  }
905  }
906  return FALSE;
907 }
908 
910 {
912  m_impl->enumFields->append(md);
913 }
914 
915 bool MemberDef::addExample(const char *anchor,const char *nameStr,
916  const char *file)
917 {
918  //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
920  if (m_impl->exampleSDict->find(nameStr)==0)
921  {
922  //printf("Add reference to example %s to member %s\n",nameStr,name.data());
923  Example *e=new Example;
924  e->anchor=anchor;
925  e->name=nameStr;
926  e->file=file;
927  m_impl->exampleSDict->inSort(nameStr,e);
928  return TRUE;
929  }
930  return FALSE;
931 }
932 
934 {
935  if (m_impl->exampleSDict==0)
936  return FALSE;
937  else
938  return m_impl->exampleSDict->count()>0;
939 }
940 
942 {
943  static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
944  static bool inlineSimpleClasses = Config_getBool(INLINE_SIMPLE_STRUCTS);
945  QCString baseName;
946 
947  //printf("Member: %s: templateMaster=%p group=%p classDef=%p nspace=%p fileDef=%p\n",
948  // name().data(),m_impl->templateMaster,m_impl->group,m_impl->classDef,
949  // m_impl->nspace,m_impl->fileDef);
950  if (!m_impl->explicitOutputFileBase.isEmpty())
951  {
953  }
954  else if (m_impl->templateMaster)
955  {
957  }
958  else if (m_impl->group)
959  {
960  baseName=m_impl->group->getOutputFileBase();
961  }
962  else if (m_impl->classDef)
963  {
964  baseName=m_impl->classDef->getOutputFileBase();
965  if (inlineSimpleClasses && m_impl->classDef->isSimple())
966  {
967  return baseName;
968  }
969  }
970  else if (m_impl->nspace && m_impl->nspace->isLinkableInProject())
971  {
972  baseName=m_impl->nspace->getOutputFileBase();
973  }
974  else if (m_impl->fileDef)
975  {
976  baseName=m_impl->fileDef->getOutputFileBase();
977  }
978 
979  if (baseName.isEmpty())
980  {
982  "Internal inconsistency: member %s does not belong to any"
983  " container!",qPrint(name())
984  );
985  return "dummy";
986  }
987  else if (separateMemberPages && isDetailedSectionLinkable())
988  {
989  if (getEnumScope()) // enum value, which is part of enum's documentation
990  {
991  baseName+="_"+getEnumScope()->anchor();
992  }
993  else
994  {
995  baseName+="_"+anchor();
996  }
997  }
998  return baseName;
999 }
1000 
1001 QCString MemberDef::getReference() const
1002 {
1003  QCString ref = Definition::getReference();
1004  if (!ref.isEmpty())
1005  {
1006  return ref;
1007  }
1008  if (m_impl->templateMaster)
1009  {
1010  return m_impl->templateMaster->getReference();
1011  }
1012  else if (m_impl->group)
1013  {
1014  return m_impl->group->getReference();
1015  }
1016  else if (m_impl->classDef)
1017  {
1018  return m_impl->classDef->getReference();
1019  }
1020  else if (m_impl->nspace)
1021  {
1022  return m_impl->nspace->getReference();
1023  }
1024  else if (m_impl->fileDef)
1025  {
1026  return m_impl->fileDef->getReference();
1027  }
1028  return "";
1029 }
1030 
1031 QCString MemberDef::anchor() const
1032 {
1033  QCString result=m_impl->anc;
1034  if (m_impl->groupAlias) return m_impl->groupAlias->anchor();
1036  if (m_impl->enumScope && m_impl->enumScope!=this) // avoid recursion for C#'s public enum E { E, F }
1037  {
1038  result.prepend(m_impl->enumScope->anchor());
1039  }
1040  if (m_impl->group)
1041  {
1042  if (m_impl->groupMember)
1043  {
1044  result=m_impl->groupMember->anchor();
1045  }
1046  else if (getReference().isEmpty())
1047  {
1048  result.prepend("g");
1049  }
1050  }
1051  return result;
1052 }
1053 
1055 {
1056  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1057  m_isLinkableCached = 2; // linkable
1058  //printf("MemberDef::isLinkableInProject(name=%s)\n",name().data());
1059  if (isHidden())
1060  {
1061  //printf("is hidden\n");
1062  m_isLinkableCached = 1;
1063  return;
1064  }
1065  if (m_impl->templateMaster)
1066  {
1067  //printf("has template master\n");
1069  return;
1070  }
1071  if (name().isEmpty() || name().at(0)=='@')
1072  {
1073  //printf("name invalid\n");
1074  m_isLinkableCached = 1; // not a valid or a dummy name
1075  return;
1076  }
1077  if (!hasDocumentation() && !isReference())
1078  {
1079  //printf("no docs or reference\n");
1080  m_isLinkableCached = 1; // no documentation
1081  return;
1082  }
1084  {
1085  //printf("group but group not linkable!\n");
1086  m_isLinkableCached = 1; // group but group not linkable
1087  return;
1088  }
1090  {
1091  //printf("in a class but class not linkable!\n");
1092  m_isLinkableCached = 1; // in class but class not linkable
1093  return;
1094  }
1096  && (m_impl->fileDef==0 || !m_impl->fileDef->isLinkableInProject()))
1097  {
1098  //printf("in a namespace but namespace not linkable!\n");
1099  m_isLinkableCached = 1; // in namespace but namespace not linkable
1100  return;
1101  }
1102  if (!m_impl->group && !m_impl->nspace &&
1103  !m_impl->related && !m_impl->classDef &&
1105  {
1106  //printf("in a file but file not linkable!\n");
1107  m_isLinkableCached = 1; // in file (and not in namespace) but file not linkable
1108  return;
1109  }
1111  {
1112  //printf("private and invisible!\n");
1113  m_isLinkableCached = 1; // hidden due to protection
1114  return;
1115  }
1116  if (m_impl->stat && m_impl->classDef==0 && !extractStatic)
1117  {
1118  //printf("static and invisible!\n");
1119  m_isLinkableCached = 1; // hidden due to staticness
1120  return;
1121  }
1122  //printf("linkable!\n");
1123  return; // linkable!
1124 }
1125 
1126 void MemberDef::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
1127 {
1128  Definition::setDocumentation(d,docFile,docLine,stripWhiteSpace);
1129  m_isLinkableCached = 0;
1130 }
1131 
1132 void MemberDef::setBriefDescription(const char *b,const char *briefFile,int briefLine)
1133 {
1134  Definition::setBriefDescription(b,briefFile,briefLine);
1135  m_isLinkableCached = 0;
1136 }
1137 
1138 void MemberDef::setInbodyDocumentation(const char *d,const char *inbodyFile,int inbodyLine)
1139 {
1140  Definition::setInbodyDocumentation(d,inbodyFile,inbodyLine);
1141  m_isLinkableCached = 0;
1142 }
1143 
1145 {
1147  m_isLinkableCached = 0;
1148 }
1149 
1151 {
1152  if (m_isLinkableCached==0)
1153  {
1154  MemberDef *that = (MemberDef*)this;
1155  that->_computeLinkableInProject();
1156  }
1157  ASSERT(m_isLinkableCached>0);
1158  return m_isLinkableCached==2;
1159 }
1160 
1162 {
1163  if (m_impl->templateMaster)
1164  {
1165  return m_impl->templateMaster->isLinkable();
1166  }
1167  else
1168  {
1169  return isLinkableInProject() || isReference();
1170  }
1171 }
1172 
1173 
1174 void MemberDef::setDefinitionTemplateParameterLists(QList<ArgumentList> *lists)
1175 {
1176  if (lists)
1177  {
1180  }
1181 }
1182 
1184  FileDef *fd,GroupDef *gd,bool onlyText)
1185 {
1186  SrcLangExt lang = getLanguage();
1187  static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
1188  QCString sep = getLanguageSpecificSeparator(lang,TRUE);
1189  QCString n = name();
1190  if (!hideScopeNames)
1191  {
1193  {
1194  n.prepend(m_impl->enumScope->displayName()+sep);
1195  }
1196  if (m_impl->classDef && gd && !isRelated())
1197  {
1198  n.prepend(m_impl->classDef->displayName()+sep);
1199  }
1200  else if (m_impl->nspace && (gd || fd))
1201  {
1202  n.prepend(m_impl->nspace->displayName()+sep);
1203  }
1204  }
1205 
1206  if (isObjCMethod())
1207  {
1208  if (isStatic()) ol.docify("+ "); else ol.docify("- ");
1209  }
1210  if (!onlyText && isLinkable()) // write link
1211  {
1212  if (m_impl->mtype==MemberType_EnumValue && getGroupDef()==0 && // enum value is not grouped
1213  getEnumScope() && getEnumScope()->getGroupDef()) // but its container is
1214  {
1215  GroupDef *enumValGroup = getEnumScope()->getGroupDef();
1216  ol.writeObjectLink(enumValGroup->getReference(),
1217  enumValGroup->getOutputFileBase(),
1218  anchor(),n);
1219  }
1220  else
1221  {
1223  }
1224  }
1225  else // write only text
1226  {
1227  ol.startBold();
1228  ol.docify(n);
1229  ol.endBold();
1230  }
1231 }
1232 
1237 {
1239 
1240  QCString cname;
1241  if (getClassDef()!=0)
1242  {
1243  cname=getClassDef()->name().copy();
1244  }
1245  else if (getNamespaceDef()!=0)
1246  {
1247  cname=getNamespaceDef()->name().copy();
1248  }
1249  QCString ltype(m_impl->type);
1250  // strip `static' keyword from ltype
1251  //if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
1252  // strip `friend' keyword from ltype
1253  ltype.stripPrefix("friend ");
1254  static QRegExp r("@[0-9]+");
1255  int l,i=r.match(ltype,0,&l);
1256  //printf("ltype=`%s' i=%d\n",ltype.data(),i);
1257  // search for the last anonymous scope in the member type
1258  ClassDef *annoClassDef=0;
1259  if (i!=-1) // found anonymous scope in type
1260  {
1261  int il=i-1,ir=i+l;
1262  // extract anonymous scope
1263  while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
1264  if (il>0) il++; else if (il<0) il=0;
1265  while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;
1266 
1267  QCString annName = ltype.mid(il,ir-il);
1268 
1269  // if inside a class or namespace try to prepend the scope name
1270  if (!cname.isEmpty() && annName.left(cname.length()+2)!=cname+"::")
1271  {
1272  QCString ts=stripAnonymousNamespaceScope(cname+"::"+annName);
1273  annoClassDef=getClass(ts);
1274  }
1275  // if not found yet, try without scope name
1276  if (annoClassDef==0)
1277  {
1278  QCString ts=stripAnonymousNamespaceScope(annName);
1279  annoClassDef=getClass(ts);
1280  }
1281  }
1282  m_impl->cachedAnonymousType = annoClassDef;
1283  return annoClassDef;
1284 }
1285 
1290 {
1291  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1292  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1293  static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1294  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1295  static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
1296 
1297  //printf("Member %s grpId=%d docs=%s file=%s args=%s\n",
1298  // name().data(),
1299  // 0,"", //grpId,grpId==-1?"<none>":Doxygen::memberDocDict[grpId]->data(),
1300  // "", //getFileDef()->name().data(),
1301  // argsString());
1302 
1304  //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
1305  //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
1306  bool hasDocs = hasDocumentation() ||
1307  // part of a documented member group
1308  (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
1309 
1310  // only include static members with file/namespace scope if
1311  // explicitly enabled in the config file
1312  bool visibleIfStatic = !(getClassDef()==0 &&
1313  isStatic() &&
1314  !extractStatic
1315  );
1316 
1317  // only include members is the are documented or
1318  // HIDE_UNDOC_MEMBERS is NO in the config file
1319  bool visibleIfDocumented = (!hideUndocMembers ||
1320  hasDocs ||
1322  );
1323 
1324  // hide members with no detailed description and brief descriptions
1325  // explicitly disabled.
1326  bool visibleIfEnabled = !(hideUndocMembers &&
1327  documentation().isEmpty() &&
1328  !briefMemberDesc &&
1329  !repeatBrief
1330  );
1331 
1332  // Hide friend (class|struct|union) declarations if HIDE_FRIEND_COMPOUNDS is true
1333  bool visibleIfFriendCompound = !(hideFriendCompounds &&
1334  isFriend() &&
1335  (m_impl->type=="friend class" ||
1336  m_impl->type=="friend struct" ||
1337  m_impl->type=="friend union"
1338  )
1339  );
1340 
1341  // only include members that are non-private unless EXTRACT_PRIVATE is
1342  // set to YES or the member is part of a group
1343  bool visibleIfPrivate = (protectionLevelVisible(protection()) ||
1345  );
1346 
1347  // hide member if it overrides a member in a superclass and has no
1348  // documentation of its own
1349  //bool visibleIfDocVirtual = !reimplements() ||
1350  // !Config_getBool(INHERIT_DOCS) ||
1351  // hasDocs;
1352 
1353  // true if this member is a constructor or destructor
1354  bool cOrDTor = isConstructor() || isDestructor();
1355 
1356  // hide default constructors or destructors (no args) without
1357  // documentation
1358  bool visibleIfNotDefaultCDTor = !(cOrDTor &&
1359  m_impl->defArgList &&
1360  (m_impl->defArgList->isEmpty() ||
1361  m_impl->defArgList->getFirst()->type == "void"
1362  ) &&
1363  !hasDocs
1364  );
1365 
1366 
1367  //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d "
1368  // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
1369  // "visibleIfFriendCompound=%d !annScope=%d\n",
1370  // visibleIfStatic,visibleIfDocumented,
1371  // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
1372  // visibleIfFriendCompound,!m_impl->annScope);
1373 
1374  bool visible = visibleIfStatic && visibleIfDocumented &&
1375  visibleIfEnabled && visibleIfPrivate &&
1376  /*visibleIfDocVirtual &&*/ visibleIfNotDefaultCDTor &&
1377  visibleIfFriendCompound &&
1378  !m_impl->annScope && !isHidden();
1379  //printf("MemberDef::isBriefSectionVisible() %d\n",visible);
1380  return visible;
1381 }
1382 
1383 QCString MemberDef::getDeclType() const
1384 {
1385  QCString ltype(m_impl->type);
1387  {
1388  ltype.prepend("typedef ");
1389  }
1390  if (isAlias())
1391  {
1392  ltype="using";
1393  }
1394  // strip `friend' keyword from ltype
1395  ltype.stripPrefix("friend ");
1396  if (ltype=="@") // rename type from enum values
1397  {
1398  ltype="";
1399  }
1400  else
1401  {
1402  if (isObjCMethod())
1403  {
1404  ltype.prepend("(");
1405  ltype.append(")");
1406  }
1407  }
1408  return ltype;
1409 }
1410 
1412  ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1413  bool inGroup, ClassDef *inheritedFrom,const char *inheritId)
1414 {
1415  //printf("%s MemberDef::writeDeclaration() inGroup=%d\n",qualifiedName().data(),inGroup);
1416 
1417  // hide enum value, since they appear already as part of the enum, unless they
1418  // are explicitly grouped.
1419  if (!inGroup && m_impl->mtype==MemberType_EnumValue) return;
1420 
1421 
1422  Definition *d=0;
1423  ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
1424  if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
1425  if (d==gd) // see bug 753608
1426  {
1427  if (getClassDef()) d = getClassDef();
1428  else if (getNamespaceDef()) d = getNamespaceDef();
1429  else if (getFileDef()) d = getFileDef();
1430  }
1431 
1432  //_writeTagData(compoundType);
1434 
1435  QCString cname = d->name();
1436  QCString cdname = d->displayName();
1437  QCString cfname = getOutputFileBase();
1438 
1439  // search for the last anonymous scope in the member type
1440  ClassDef *annoClassDef=getClassDefOfAnonymousType();
1441 
1443 
1444  // start a new member declaration
1445  bool isAnonymous = annoClassDef || m_impl->annMemb || m_impl->annEnumType;
1447  ol.startMemberItem(anchor(),
1448  isAnonymous ? 1 : m_impl->tArgList ? 3 : 0,
1449  inheritId
1450  );
1451 
1452  // If there is no detailed description we need to write the anchor here.
1453  bool detailsVisible = isDetailedSectionLinkable();
1454  bool writeAnchor = (inGroup || m_impl->group==0) && // only write anchors for member that have no details and are
1455  !detailsVisible && !m_impl->annMemb; // rendered inside the group page or are not grouped at all
1456  if (writeAnchor)
1457  {
1458  QCString doxyArgs=argsString();
1459  QCString doxyName=name();
1460  if (!cname.isEmpty())
1461  {
1462  doxyName.prepend(cdname+getLanguageSpecificSeparator(getLanguage()));
1463  }
1464  ol.startDoxyAnchor(cfname,cname,anchor(),doxyName,doxyArgs);
1465  }
1466 
1467  if (!detailsVisible)
1468  {
1469  ol.pushGeneratorState();
1472  ol.docify("\n");
1473  ol.popGeneratorState();
1474  }
1475 
1476  if (annoClassDef || m_impl->annMemb)
1477  {
1478  int j;
1479  for (j=0;j<s_indentLevel;j++)
1480  {
1481  ol.writeNonBreakableSpace(3);
1482  }
1483  }
1484 
1485  // *** write template lists
1487  {
1488  if (!isAnonymous) ol.startMemberTemplateParams();
1490  if (!isAnonymous) ol.endMemberTemplateParams(anchor(),inheritId);
1491  }
1492 
1493  // *** write type
1494  QCString ltype(m_impl->type);
1495  if (m_impl->mtype==MemberType_Typedef) ltype.prepend("typedef ");
1496  if (isAlias())
1497  {
1498  ltype="using";
1499  }
1500  // strip `friend' keyword from ltype
1501  ltype.stripPrefix("friend ");
1502  static QRegExp r("@[0-9]+");
1503 
1504  bool endAnonScopeNeeded=FALSE;
1505  int l,i=r.match(ltype,0,&l);
1506  if (i!=-1) // member has an anonymous type
1507  {
1508  //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
1509  // annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());
1510 
1511  if (annoClassDef) // type is an anonymous compound
1512  {
1513  int ir=i+l;
1514  //printf("<<<<<<<<<<<<<<\n");
1516  annoClassDef->writeDeclaration(ol,m_impl->annMemb,inGroup,inheritedFrom,inheritId);
1517  //printf(">>>>>>>>>>>>>> startMemberItem(2)\n");
1518  ol.startMemberItem(anchor(),2,inheritId);
1519  int j;
1520  for (j=0;j< s_indentLevel-1;j++)
1521  {
1522  ol.writeNonBreakableSpace(3);
1523  }
1524  QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
1525  //printf(">>>>>> ltype=`%s' varName=`%s'\n",ltype.data(),varName.data());
1526  ol.docify("}");
1527  if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@'))
1528  {
1529  ol.docify(";");
1530  }
1531  else if (!varName.isEmpty() && (varName.at(0)=='*' || varName.at(0)=='&'))
1532  {
1533  ol.docify(" ");
1534  ol.docify(varName);
1535  }
1536  endAnonScopeNeeded=TRUE;
1537  }
1538  else
1539  {
1540  if (getAnonymousEnumType()) // type is an anonymous enum
1541  {
1542  linkifyText(TextGeneratorOLImpl(ol), // out
1543  d, // scope
1544  getBodyDef(), // fileScope
1545  this, // self
1546  ltype.left(i), // text
1547  FALSE // autoBreak
1548  );
1549  getAnonymousEnumType()->writeEnumDeclaration(ol,cd,nd,fd,gd);
1550  //ol+=*getAnonymousEnumType()->enumDecl();
1551  linkifyText(TextGeneratorOLImpl(ol),d,m_impl->fileDef,this,ltype.right(ltype.length()-i-l),TRUE);
1552  }
1553  else
1554  {
1555  ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
1556  linkifyText(TextGeneratorOLImpl(ol), // out
1557  d, // scope
1558  getBodyDef(), // fileScope
1559  this, // self
1560  ltype, // text
1561  FALSE // autoBreak
1562  );
1563  }
1564  }
1565  }
1566  else if (ltype=="@") // rename type from enum values
1567  {
1568  ltype="";
1569  }
1570  else
1571  {
1572  if (isObjCMethod())
1573  {
1574  ltype.prepend("(");
1575  ltype.append(")");
1576  }
1577  linkifyText(TextGeneratorOLImpl(ol), // out
1578  d, // scope
1579  getBodyDef(), // fileScope
1580  this, // self
1581  ltype, // text
1582  FALSE // autoBreak
1583  );
1584  }
1585  bool htmlOn = ol.isEnabled(OutputGenerator::Html);
1586  if (htmlOn && !ltype.isEmpty())
1587  {
1589  }
1590  if (!ltype.isEmpty()) ol.docify(" ");
1591  if (htmlOn)
1592  {
1594  }
1595 
1596  if (m_impl->annMemb)
1597  {
1598  ol.pushGeneratorState();
1600  ol.writeNonBreakableSpace(3);
1601  ol.popGeneratorState();
1602  }
1603  else
1604  {
1606  }
1607 
1608  // *** write name
1609  if (!name().isEmpty() && name().at(0)!='@') // hide anonymous stuff
1610  {
1611  static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1612  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1613  //printf("Member name=`%s gd=%p md->groupDef=%p inGroup=%d isLinkable()=%d hasDocumentation=%d\n",name().data(),gd,getGroupDef(),inGroup,isLinkable(),hasDocumentation());
1614  if (!(name().isEmpty() || name().at(0)=='@') && // name valid
1615  (hasDocumentation() || isReference()) && // has docs
1616  !(m_impl->prot==Private && !extractPrivate && m_impl->mtype!=MemberType_Friend) && // hidden due to protection
1617  !(isStatic() && m_impl->classDef==0 && !extractStatic) // hidden due to static-ness
1618  )
1619  {
1620  if (m_impl->annMemb)
1621  {
1622  //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
1623  m_impl->annMemb->writeLink(ol,
1628  );
1630  setAnonymousUsed();
1631  }
1632  else
1633  {
1634  //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
1635  ClassDef *rcd = cd;
1636  if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1637  writeLink(ol,rcd,nd,fd,gd);
1638  }
1639  }
1640  else if (isDocumentedFriendClass())
1641  // if the member is an undocumented friend declaration for some class,
1642  // then maybe we can link to the class
1643  {
1644  writeLink(ol,getClass(name()),0,0,0);
1645  }
1646  else
1647  // there is a brief member description and brief member
1648  // descriptions are enabled or there is no detailed description.
1649  {
1650  if (m_impl->annMemb)
1651  {
1653  setAnonymousUsed();
1654  }
1655  ClassDef *rcd = cd;
1656  if (isReference() && m_impl->classDef) rcd = m_impl->classDef;
1657  writeLink(ol,rcd,nd,fd,gd,TRUE);
1658  }
1659  }
1660 
1661  // add to index
1662  if (isEnumerate() && name().at(0)=='@')
1663  {
1664  // don't add to index
1665  }
1666  else // index member
1667  {
1668  //static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1669  //QCString cfname = getOutputFileBase();
1670  //QCString cfiname = d->getOutputFileBase();
1671  //Doxygen::indexList->addIndexItem(
1672  // cname, // level1
1673  // name(), // level2
1674  // separateMemPages ? cfname : cfiname, // contRef
1675  // cfname, // memRef
1676  // anchor(), // anchor
1677  // this); // memberdef
1679  }
1680 
1681  // *** write arguments
1682  if (argsString() && !isObjCMethod())
1683  {
1684  if (!isDefine() && !isTypedef()) ol.writeString(" ");
1685  linkifyText(TextGeneratorOLImpl(ol), // out
1686  d, // scope
1687  getBodyDef(), // fileScope
1688  this, // self
1689  isDefine() ?
1690  (const char*)substitute(argsString(),",",", ") :
1691  isTypedef() ?
1692  (const char*)substitute(argsString(),")(",") (") :
1693  argsString(), // text
1694  m_impl->annMemb, // autoBreak
1695  TRUE, // external
1696  FALSE, // keepSpaces
1698  );
1699  }
1700  // *** write exceptions
1701  if (excpString())
1702  {
1703  ol.writeString(" ");
1704  ol.docify(excpString());
1705  }
1706 
1707  // *** write bitfields
1708  if (!m_impl->bitfields.isEmpty()) // add bitfields
1709  {
1711  }
1712  else if (hasOneLineInitializer()
1714  //((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
1715  ) // add initializer
1716  {
1717  if (!isDefine())
1718  {
1719  //ol.writeString(" = ");
1720  ol.writeString(" ");
1721  linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->initializer.simplifyWhiteSpace());
1722  }
1723  else
1724  {
1725  ol.writeNonBreakableSpace(3);
1727  }
1728  }
1729  else if (isAlias()) // using template alias
1730  {
1731  ol.writeString(" = ");
1733  }
1734 
1735 
1736  if ((isObjCMethod() || isObjCProperty()) && isImplementation())
1737  {
1738  ol.startTypewriter();
1739  ol.docify(" [implementation]");
1740  ol.endTypewriter();
1741  }
1742 
1743  bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1744 
1745  if (isProperty() && (isSettable() || isGettable() ||
1748  {
1749  ol.writeLatexSpacing();
1750  ol.startTypewriter();
1751  ol.docify(" [");
1752  QStrList sl;
1753 
1754  if (isGettable()) sl.append("get");
1755  if (isProtectedGettable()) sl.append("protected get");
1756  if (isSettable()) sl.append("set");
1757  if (isProtectedSettable()) sl.append("protected set");
1758  if (extractPrivate)
1759  {
1760  if (isPrivateGettable()) sl.append("private get");
1761  if (isPrivateSettable()) sl.append("private set");
1762  }
1763  const char *s=sl.first();
1764  while (s)
1765  {
1766  ol.docify(s);
1767  s=sl.next();
1768  if (s) ol.docify(", ");
1769  }
1770  ol.docify("]");
1771  ol.endTypewriter();
1772  }
1773 
1774  if (isEvent() && (isAddable() || isRemovable() || isRaisable()))
1775  {
1776  ol.writeLatexSpacing();
1777  ol.startTypewriter();
1778  ol.docify(" [");
1779  QStrList sl;
1780  if (isAddable()) sl.append("add");
1781  if (isRemovable()) sl.append("remove");
1782  if (isRaisable()) sl.append("raise");
1783  const char *s=sl.first();
1784  while (s)
1785  {
1786  ol.docify(s);
1787  s=sl.next();
1788  if (s) ol.docify(", ");
1789  }
1790  ol.docify("]");
1791  ol.endTypewriter();
1792  }
1793 
1794  if (writeAnchor)
1795  {
1796  ol.endDoxyAnchor(cfname,anchor());
1797  }
1798 
1799  //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
1800  // name().data(),annoClassDef,annEnumType);
1801  ol.endMemberItem();
1802  if (endAnonScopeNeeded)
1803  {
1805  }
1806 
1807  // write brief description
1808  if (!briefDescription().isEmpty() &&
1809  Config_getBool(BRIEF_MEMBER_DESC)
1810  /* && !annMemb */
1811  )
1812  {
1815  TRUE,FALSE,0,TRUE,FALSE);
1816 
1817  if (rootNode && !rootNode->isEmpty())
1818  {
1819  ol.startMemberDescription(anchor(),inheritId);
1820  ol.writeDoc(rootNode,getOuterScope()?getOuterScope():d,this);
1821  if (detailsVisible)
1822  {
1823  static bool separateMemberPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1824  ol.pushGeneratorState();
1826  //ol.endEmphasis();
1827  ol.docify(" ");
1828  if (inheritedFrom ||
1829  separateMemberPages ||
1830  (m_impl->group!=0 && gd==0) ||
1831  (m_impl->nspace!=0 && nd==0)
1832  ) // forward link to the page or group or namespace
1833  {
1835  }
1836  else // local link
1837  {
1838  ol.startTextLink(0,anchor());
1839  }
1841  ol.endTextLink();
1842  //ol.startEmphasis();
1843  ol.popGeneratorState();
1844  }
1845  // for RTF we need to add an extra empty paragraph
1846  ol.pushGeneratorState();
1848  ol.startParagraph();
1849  ol.endParagraph();
1850  ol.popGeneratorState();
1851  ol.endMemberDescription();
1852  }
1853  delete rootNode;
1854  }
1855 
1856  ol.endMemberDeclaration(anchor(),inheritId);
1857 
1859 }
1860 
1862 {
1863  static bool extractAll = Config_getBool(EXTRACT_ALL);
1864  static bool alwaysDetailedSec = Config_getBool(ALWAYS_DETAILED_SEC);
1865  static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
1866  static bool briefMemberDesc = Config_getBool(BRIEF_MEMBER_DESC);
1867  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1868  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
1869 
1870  // the member has details documentation for any of the following reasons
1871  bool docFilter =
1872  // treat everything as documented
1873  extractAll ||
1874  // has detailed docs
1875  !documentation().isEmpty() ||
1876  // has inbody docs
1877  !inbodyDocumentation().isEmpty() ||
1878  // is an enum with values that are documented
1880  // is documented enum value
1881  (m_impl->mtype==MemberType_EnumValue && !briefDescription().isEmpty()) ||
1882  // has brief description that is part of the detailed description
1883  (!briefDescription().isEmpty() && // has brief docs
1884  (alwaysDetailedSec && // they are visible in
1885  (repeatBrief || // detailed section or
1886  !briefMemberDesc // they are explicitly not
1887  ) // shown in brief section
1888  )
1889  ) ||
1890  // has a multi-line initialization block
1891  //(initLines>0 && initLines<maxInitLines) ||
1892  (hasMultiLineInitializer() && !hideUndocMembers) ||
1893  // has one or more documented arguments
1895  // is an attribute or property - need to display that tag
1897  // has user comments
1899  ;
1900 
1901  // this is not a global static or global statics should be extracted
1902  bool staticFilter = getClassDef()!=0 || !isStatic() || extractStatic;
1903 
1904  // only include members that are non-private unless EXTRACT_PRIVATE is
1905  // set to YES or the member is part of a group
1906  bool privateFilter = protectionLevelVisible(protection()) || m_impl->mtype==MemberType_Friend;
1907 
1908  // member is part of an anonymous scope that is the type of
1909  // another member in the list.
1910  //
1911  //bool inAnonymousScope = !briefDescription().isEmpty() && annUsed;
1912 
1913  // hide friend (class|struct|union) member if HIDE_FRIEND_COMPOUNDS
1914  // is true
1915  bool friendCompoundFilter = !(Config_getBool(HIDE_FRIEND_COMPOUNDS) &&
1916  isFriend() &&
1917  (m_impl->type=="friend class" ||
1918  m_impl->type=="friend struct" ||
1919  m_impl->type=="friend union"
1920  )
1921  );
1922 
1923 
1924  bool result = ((docFilter && staticFilter && privateFilter && friendCompoundFilter && !isHidden()));
1925  //printf("%s::isDetailedSectionLinkable: %d\n",name().data(),result);
1926  return result;
1927 }
1928 
1929 bool MemberDef::isDetailedSectionVisible(bool inGroup,bool inFile) const
1930 {
1931  static bool separateMemPages = Config_getBool(SEPARATE_MEMBER_PAGES);
1932  static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
1933  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
1934  bool groupFilter = getGroupDef()==0 || inGroup || separateMemPages;
1935  bool fileFilter = getNamespaceDef()==0 || !getNamespaceDef()->isLinkable() || !inFile;
1936  bool simpleFilter = (hasBriefDescription() || !hideUndocMembers) && inlineSimpleStructs &&
1937  getClassDef()!=0 && getClassDef()->isSimple();
1938 
1939  bool visible = isDetailedSectionLinkable() && groupFilter && fileFilter &&
1940  !isReference();
1941  bool result = visible || simpleFilter;
1942  //printf("%s::isDetailedSectionVisble: %d groupFilter=%d fileFilter=%d\n",
1943  // name().data(),result,groupFilter,fileFilter);
1944  return result;
1945 }
1946 
1947 void MemberDef::getLabels(QStrList &sl,Definition *container) const
1948 {
1949  static bool inlineInfo = Config_getBool(INLINE_INFO);
1950 
1951  Specifier lvirt=virtualness();
1952  if ((!isObjCMethod() || isOptional() || isRequired()) &&
1953  (protection()!=Public || lvirt!=Normal ||
1954  isFriend() || isRelated() ||
1955  (isInline() && inlineInfo) ||
1956  isSignal() || isSlot() ||
1957  isStatic() ||
1958  (m_impl->classDef && m_impl->classDef!=container && container->definitionType()==TypeClass) ||
1959  (m_impl->memSpec & ~Entry::Inline)!=0
1960  )
1961  )
1962  {
1963  // write the member specifier list
1964  //ol.writeLatexSpacing();
1965  //ol.startTypewriter();
1966  //ol.docify(" [");
1967  SrcLangExt lang = getLanguage();
1968  bool optVhdl = lang==SrcLangExt_VHDL;
1969  bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
1970  if (optVhdl)
1971  {
1973  }
1974  else
1975  {
1976  if (isFriend()) sl.append("friend");
1977  else if (isRelated()) sl.append("related");
1978  else
1979  {
1980  if (Config_getBool(INLINE_INFO) && isInline()) sl.append("inline");
1981  if (isExplicit()) sl.append("explicit");
1982  if (isMutable()) sl.append("mutable");
1983  if (isStatic()) sl.append("static");
1984  if (isGettable()) sl.append("get");
1985  if (isProtectedGettable()) sl.append("protected get");
1986  if (isSettable()) sl.append("set");
1987  if (isProtectedSettable()) sl.append("protected set");
1988  if (extractPrivate)
1989  {
1990  if (isPrivateGettable()) sl.append("private get");
1991  if (isPrivateSettable()) sl.append("private set");
1992  }
1993  if (isAddable()) sl.append("add");
1994  if (!isUNOProperty() && isRemovable()) sl.append("remove");
1995  if (isRaisable()) sl.append("raise");
1996  if (isReadable()) sl.append("read");
1997  if (isWritable()) sl.append("write");
1998  if (isFinal()) sl.append("final");
1999  if (isAbstract()) sl.append("abstract");
2000  if (isOverride()) sl.append("override");
2001  if (isInitonly()) sl.append("initonly");
2002  if (isSealed()) sl.append("sealed");
2003  if (isNew()) sl.append("new");
2004  if (isOptional()) sl.append("optional");
2005  if (isRequired()) sl.append("required");
2006 
2007  if (isNonAtomic()) sl.append("nonatomic");
2008  else if (isObjCProperty()) sl.append("atomic");
2009 
2010  // mutual exclusive Objective 2.0 property attributes
2011  if (isAssign()) sl.append("assign");
2012  else if (isCopy()) sl.append("copy");
2013  else if (isRetain()) sl.append("retain");
2014  else if (isWeak()) sl.append("weak");
2015  else if (isStrong()) sl.append("strong");
2016  else if (isUnretained()) sl.append("unsafe_unretained");
2017 
2018  if (!isObjCMethod())
2019  {
2020  if (protection()==Protected) sl.append("protected");
2021  else if (protection()==Private) sl.append("private");
2022  else if (protection()==Package) sl.append("package");
2023 
2024  if (lvirt==Virtual) sl.append("virtual");
2025  else if (lvirt==Pure) sl.append("pure virtual");
2026  if (isSignal()) sl.append("signal");
2027  if (isSlot()) sl.append("slot");
2028  if (isDefault()) sl.append("default");
2029  if (isDelete()) sl.append("delete");
2030  if (isNoExcept()) sl.append("noexcept");
2031  if (isAttribute()) sl.append("attribute");
2032  if (isUNOProperty()) sl.append("property");
2033  if (isReadonly()) sl.append("readonly");
2034  if (isBound()) sl.append("bound");
2035  if (isUNOProperty() && isRemovable()) sl.append("removable");
2036  if (isConstrained()) sl.append("constrained");
2037  if (isTransient()) sl.append("transient");
2038  if (isMaybeVoid()) sl.append("maybevoid");
2039  if (isMaybeDefault()) sl.append("maybedefault");
2040  if (isMaybeAmbiguous()) sl.append("maybeambiguous");
2041  if (isPublished()) sl.append("published"); // enum
2042  }
2043  if (isObjCProperty() && isImplementation())
2044  {
2045  sl.append("implementation");
2046  }
2047  }
2048  if (m_impl->classDef &&
2049  container->definitionType()==TypeClass &&
2050  m_impl->classDef!=container &&
2051  !isRelated()
2052  )
2053  {
2054  sl.append("inherited");
2055  }
2056  }
2057  }
2058  else if (isObjCMethod() && isImplementation())
2059  {
2060  sl.append("implementation");
2061  }
2062 }
2063 
2065 {
2066  // write call graph
2067  if (m_impl->hasCallGraph
2068  && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2069  )
2070  {
2071  DotCallGraph callGraph(this,FALSE);
2072  if (callGraph.isTooBig())
2073  {
2074  warn_uncond("Call graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2075  }
2076  else if (!callGraph.isTrivial())
2077  {
2078  msg("Generating call graph for function %s\n",qPrint(qualifiedName()));
2080  ol.startCallGraph();
2082  ol.endCallGraph(callGraph);
2083  ol.enableAll();
2084  }
2085  }
2086 }
2087 
2089 {
2090  if (m_impl->hasCallerGraph
2091  && (isFunction() || isSlot() || isSignal()) && Config_getBool(HAVE_DOT)
2092  )
2093  {
2094  DotCallGraph callerGraph(this, TRUE);
2095  if (callerGraph.isTooBig())
2096  {
2097  warn_uncond("Caller graph for '%s' not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES.\n",qPrint(qualifiedName()));
2098  }
2099  else if (!callerGraph.isTrivial() && !callerGraph.isTooBig())
2100  {
2101  msg("Generating caller graph for function %s\n",qPrint(qualifiedName()));
2103  ol.startCallGraph();
2105  ol.endCallGraph(callerGraph);
2106  ol.enableAll();
2107  }
2108  }
2109 }
2110 
2112 {
2113  MemberDef *bmd=reimplements();
2114  ClassDef *bcd=0;
2115  if (bmd && (bcd=bmd->getClassDef()))
2116  {
2117  // write class that contains a member that is reimplemented by this one
2118  if (bcd->isLinkable())
2119  {
2120  ol.startParagraph();
2121  QCString reimplFromLine;
2122  if (bmd->virtualness()!=Pure && bcd->compoundType()!=ClassDef::Interface)
2123  {
2124  reimplFromLine = theTranslator->trReimplementedFromList(1);
2125  }
2126  else
2127  {
2128  reimplFromLine = theTranslator->trImplementedFromList(1);
2129  }
2130  int markerPos = reimplFromLine.find("@0");
2131  if (markerPos!=-1) // should always pass this.
2132  {
2133  ol.parseText(reimplFromLine.left(markerPos)); //text left from marker
2134  if (bmd->isLinkable()) // replace marker with link
2135  {
2136  //Definition *bd=bmd->group;
2137  //if (bd==0) bd=bcd;
2139  bmd->anchor(),bcd->displayName());
2140 
2141  //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2142  // bmd->anchor(),bcd->name());
2143  if ( bmd->isLinkableInProject() )
2144  {
2145  writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2146  }
2147  }
2148  else
2149  {
2151  0,bcd->displayName());
2152  if (bcd->isLinkableInProject()/* && !Config_getBool(PDF_HYPERLINKS)*/ )
2153  {
2154  writePageRef(ol,bcd->getOutputFileBase(),bcd->anchor());
2155  }
2156  }
2157  ol.parseText(reimplFromLine.right(
2158  reimplFromLine.length()-markerPos-2)); // text right from marker
2159 
2160  }
2161  else
2162  {
2163  err("translation error: no marker in trReimplementsFromList()\n");
2164  }
2165  ol.endParagraph();
2166  }
2167  }
2168 }
2169 
2171 {
2172  MemberList *bml=reimplementedBy();
2173  if (bml)
2174  {
2175  MemberListIterator mli(*bml);
2176  MemberDef *bmd=0;
2177  uint count=0;
2178  ClassDef *bcd=0;
2179  for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
2180  {
2181  // count the members that directly inherit from md and for
2182  // which the member and class are visible in the docs.
2183  if ( bmd->isLinkable() && bcd->isLinkable() )
2184  {
2185  count++;
2186  }
2187  }
2188  if (count>0)
2189  {
2190  mli.toFirst();
2191  // write the list of classes that overwrite this member
2192  ol.startParagraph();
2193 
2194  QCString reimplInLine;
2196  {
2197  reimplInLine = theTranslator->trImplementedInList(count);
2198  }
2199  else
2200  {
2201  reimplInLine = theTranslator->trReimplementedInList(count);
2202  }
2203  static QRegExp marker("@[0-9]+");
2204  int index=0,newIndex,matchLen;
2205  // now replace all markers in reimplInLine with links to the classes
2206  while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
2207  {
2208  ol.parseText(reimplInLine.mid(index,newIndex-index));
2209  bool ok;
2210  uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
2211  //bmd=bml->at(entryIndex);
2212 
2213  count=0;
2214  // find the entryIndex-th documented entry in the inheritance list.
2215  for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
2216  {
2217  if ( bmd->isLinkable() && bcd->isLinkable())
2218  {
2219  if (count==entryIndex) break;
2220  count++;
2221  }
2222  }
2223 
2224  if (ok && bcd && bmd) // write link for marker
2225  {
2226  //ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
2227  // bmd->anchor(),bcd->name());
2229  bmd->anchor(),bcd->displayName());
2230 
2231  if (bmd->isLinkableInProject() )
2232  {
2233  writePageRef(ol,bmd->getOutputFileBase(),bmd->anchor());
2234  }
2235  }
2236  ++mli;
2237  index=newIndex+matchLen;
2238  }
2239  ol.parseText(reimplInLine.right(reimplInLine.length()-index));
2240  ol.endParagraph();
2241  }
2242  }
2243 }
2244 
2246 {
2247  if (m_impl->classDef) // this should be a member of a class/category
2248  {
2249  //printf("%s: category %s relation %s class=%s categoryOf=%s\n",
2250  // name().data(),
2251  // m_impl->category ? m_impl->category->name().data() : "<none>",
2252  // m_impl->categoryRelation ? m_impl->categoryRelation->name().data() : "<none>",
2253  // m_impl->classDef->name().data(),
2254  // m_impl->classDef->categoryOf() ? m_impl->classDef->categoryOf()->name().data() : "<none>"
2255  // );
2256  QCString text;
2257  QCString ref;
2258  QCString file;
2259  QCString anc;
2260  QCString name;
2261  int i=-1;
2263  {
2264  if (m_impl->category)
2265  {
2266  // this member is in a normal class and implements method categoryRelation from category
2267  // so link to method 'categoryRelation' with 'provided by category 'category' text.
2269  name = m_impl->category->displayName();
2270  }
2271  else if (m_impl->classDef->categoryOf())
2272  {
2273  // this member is part of a category so link to the corresponding class member of the class we extend
2274  // so link to method 'categoryRelation' with 'extends class 'classDef->categoryOf()'
2275  text = theTranslator->trExtendsClass();
2276  name = m_impl->classDef->categoryOf()->displayName();
2277  }
2278  i=text.find("@0");
2279  if (i!=-1)
2280  {
2282  ref = md->getReference();
2283  file = md->getOutputFileBase();
2284  anc = md->anchor();
2285  }
2286  }
2287  if (i!=-1 && !name.isEmpty())
2288  {
2289  ol.startParagraph();
2290  ol.parseText(text.left(i));
2291  ol.writeObjectLink(ref,file,anc,name);
2292  ol.parseText(text.mid(i+2));
2293  ol.endParagraph();
2294  }
2295  }
2296 }
2297 
2299 {
2300  // write the list of examples that use this member
2301  if (hasExamples())
2302  {
2304  ol.startDescForItem();
2306  ol.endDescForItem();
2307  ol.endSimpleSect();
2308  }
2309 }
2310 
2312 {
2313  if (m_impl->typeConstraints)
2314  {
2316  }
2317 }
2318 
2320  const QCString &cfname,const QCString &ciname,
2321  const QCString &cname)
2322 {
2323  // For enum, we also write the documented enum values
2324  if (isEnumerate())
2325  {
2326  bool first=TRUE;
2327  MemberList *fmdl=enumFieldList();
2328  //printf("** %s: enum values=%d\n",name().data(),fmdl!=0 ? fmdl->count() : 0);
2329  if (fmdl)
2330  {
2331  MemberListIterator it(*fmdl);
2332  MemberDef *fmd;
2333  for (;(fmd=it.current());++it)
2334  {
2335  //printf("Enum %p: isLinkable()=%d\n",fmd,fmd->isLinkable());
2336  if (fmd->isLinkable())
2337  {
2338  if (first)
2339  {
2340  //ol.startSimpleSect(BaseOutputDocInterface::EnumValues,0,0,theTranslator->trEnumerationValues()+": ");
2341  //ol.startDescForItem();
2343  }
2344 
2345  ol.startDescTableRow();
2346  ol.addIndexItem(fmd->name(),ciname);
2347  ol.addIndexItem(ciname,fmd->name());
2348 
2349  //Doxygen::indexList->addIndexItem(
2350  // ciname, // level1
2351  // fmd->name(), // level2
2352  // separateMemPages ? cfname : cfiname, // contRef
2353  // cfname, // memRef
2354  // fmd->anchor(), // anchor
2355  // fmd); // memberdef
2356  Doxygen::indexList->addIndexItem(container,fmd);
2357 
2358  //ol.writeListItem();
2359  ol.startDescTableTitle();
2360  ol.startDoxyAnchor(cfname,cname,fmd->anchor(),fmd->name(),fmd->argsString());
2361  first=FALSE;
2362  //ol.startEmphasis();
2363  ol.docify(fmd->name());
2364  //ol.endEmphasis();
2366  ol.writeString(" ");
2367  ol.enableAll();
2368  ol.endDoxyAnchor(cfname,fmd->anchor());
2369  ol.endDescTableTitle();
2370  //ol.newParagraph();
2371  ol.startDescTableData();
2372 
2373  bool hasBrief = !fmd->briefDescription().isEmpty();
2374  bool hasDetails = !fmd->documentation().isEmpty();
2375 
2376  if (hasBrief)
2377  {
2378  ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
2379  getOuterScope()?getOuterScope():container,
2380  fmd,fmd->briefDescription(),TRUE,FALSE);
2381  }
2382  // FIXME:PARA
2383  //if (!fmd->briefDescription().isEmpty() &&
2384  // !fmd->documentation().isEmpty())
2385  //{
2386  // ol.newParagraph();
2387  //}
2388  if (hasDetails)
2389  {
2390  ol.generateDoc(fmd->docFile(),fmd->docLine(),
2391  getOuterScope()?getOuterScope():container,
2392  fmd,fmd->documentation()+"\n",TRUE,FALSE);
2393  }
2394  ol.endDescTableData();
2395  ol.endDescTableRow();
2396  }
2397  }
2398  }
2399  if (!first)
2400  {
2401  //ol.endItemList();
2402  ol.endDescTable();
2403  //ol.endDescForItem();
2404  //ol.endSimpleSect();
2405  //ol.writeChar('\n');
2406  }
2407  }
2408 }
2409 
2411 {
2412  QCString ldef = definition();
2413  QCString title = name();
2414  if (isEnumerate())
2415  {
2416  if (title.at(0)=='@')
2417  {
2418  ldef = title = "anonymous enum";
2419  if (!m_impl->enumBaseType.isEmpty())
2420  {
2421  ldef+=" : "+m_impl->enumBaseType;
2422  }
2423  }
2424  else
2425  {
2426  ldef.prepend("enum ");
2427  }
2428  }
2429  else if (isEnumValue())
2430  {
2431  if (ldef.at(0)=='@')
2432  {
2433  ldef=ldef.mid(2);
2434  }
2435  }
2436  static QRegExp r("@[0-9]+");
2437  int l,i=r.match(ldef,0,&l);
2438  if (i!=-1) // replace anonymous parts with { ... }
2439  {
2440  int si=ldef.find(' '),pi,ei=i+l;
2441  if (si==-1) si=0;
2442  while ((pi=r.match(ldef,i+l,&l))!=-1)
2443  {
2444  i=pi;
2445  ei=i+l;
2446  }
2447  int ni=ldef.find("::",si);
2448  if (ni>=ei) ei=ni+2;
2449  ldef = ldef.left(si) + " { ... } " + ldef.right(ldef.length()-ei);
2450  }
2451  ClassDef *cd=getClassDef();
2452  if (cd && cd->isObjectiveC())
2453  {
2454  // strip scope name
2455  int ep = ldef.find("::");
2456  if (ep!=-1)
2457  {
2458  int sp=ldef.findRev(' ',ep);
2459  if (sp!=-1)
2460  {
2461  ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2462  }
2463  }
2464  // strip keywords
2465  int dp = ldef.find(':');
2466  if (dp!=-1)
2467  {
2468  ldef=ldef.left(dp+1);
2469  }
2470  l=ldef.length();
2471  //printf("start >%s<\n",ldef.data());
2472  i=l-1;
2473  while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2474  while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2475  if (i>0)
2476  {
2477  // insert braches around the type
2478  QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2479  ldef=tmp;
2480  }
2481  //printf("end >%s< i=%d\n",ldef.data(),i);
2482  if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2483  }
2484  SrcLangExt lang = getLanguage();
2485  QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2486  return substitute(ldef,"::",sep);
2487 }
2488 
2490 {
2491  // only write out the include file if this is not part of a class or file
2492  // definition
2493  static bool showGroupedMembInc = Config_getBool(SHOW_GROUPED_MEMB_INC);
2494  FileDef *fd = getFileDef();
2495  QCString nm;
2496  if (fd) nm = getFileDef()->docName();
2497  if (inGroup && fd && showGroupedMembInc && !nm.isEmpty())
2498  {
2499  ol.startParagraph();
2500  ol.startTypewriter();
2501  SrcLangExt lang = getLanguage();
2502  bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
2503  if (isIDLorJava)
2504  {
2505  ol.docify("import ");
2506  }
2507  else
2508  {
2509  ol.docify("#include ");
2510  }
2511 
2512  if (isIDLorJava) ol.docify("\""); else ol.docify("<");
2513 
2514  if (fd->isLinkable())
2515  {
2516  ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),fd->anchor(),nm);
2517  }
2518  else
2519  {
2520  ol.docify(nm);
2521  }
2522 
2523  if (isIDLorJava) ol.docify("\""); else ol.docify(">");
2524 
2525  ol.endTypewriter();
2526  ol.endParagraph();
2527  }
2528 }
2529 
2534  int memCount,int memTotal,
2535  OutputList &ol,
2536  const char *scName,
2537  Definition *container,
2538  bool inGroup,
2539  bool showEnumValues,
2540  bool showInline
2541  )
2542 {
2543  // if this member is in a group find the real scope name.
2544  bool hasParameterList = FALSE;
2545  bool inFile = container->definitionType()==Definition::TypeFile;
2546  bool hasDocs = isDetailedSectionVisible(inGroup,inFile);
2547 
2548  //printf("MemberDef::writeDocumentation(): name=`%s' hasDocs=`%d' containerType=%d inGroup=%d sectionLinkable=%d\n",
2549  // name().data(),hasDocs,container->definitionType(),inGroup,isDetailedSectionLinkable());
2550 
2551  //if ( !hasDocs ) return;
2552  //if (isEnumValue() && !showEnumValues) return;
2553 
2554  SrcLangExt lang = getLanguage();
2555  //printf("member=%s lang=%d\n",name().data(),lang);
2556  bool optVhdl = lang==SrcLangExt_VHDL;
2557  QCString sep = getLanguageSpecificSeparator(lang,TRUE);
2558 
2559  QCString scopeName = scName;
2560  QCString memAnchor = anchor();
2561  QCString ciname = container->name();
2562  Definition *scopedContainer = container; // see bug 753608
2563  if (container->definitionType()==TypeGroup)
2564  {
2565  if (getClassDef()) { scopeName=getClassDef()->displayName(); scopedContainer=getClassDef(); }
2566  else if (getNamespaceDef()) { scopeName=getNamespaceDef()->displayName(); scopedContainer=getNamespaceDef(); }
2567  else if (getFileDef()) { scopeName=getFileDef()->displayName(); scopedContainer=getFileDef(); }
2568  ciname = ((GroupDef *)container)->groupTitle();
2569  }
2570  else if (container->definitionType()==TypeFile && getNamespaceDef())
2571  { // member is in a namespace, but is written as part of the file documentation
2572  // as well, so we need to make sure its label is unique.
2573  memAnchor.prepend("file_");
2574  }
2575 
2576  QCString cname = container->name();
2577  QCString cfname = getOutputFileBase();
2578 
2579  // get member name
2580  QCString doxyName=name();
2581  // prepend scope if there is any. TODO: make this optional for C only docs
2582  if (!scopeName.isEmpty())
2583  {
2584  doxyName.prepend(scopeName+sep);
2585  }
2586  QCString doxyArgs=argsString();
2587 
2588  QCString ldef = definition();
2589  QCString title = name();
2590  //printf("member `%s' def=`%s'\n",name().data(),ldef.data());
2591  if (isEnumerate())
2592  {
2593  if (title.at(0)=='@')
2594  {
2595  ldef = title = "anonymous enum";
2596  if (!m_impl->enumBaseType.isEmpty())
2597  {
2598  ldef+=" : "+m_impl->enumBaseType;
2599  }
2600  }
2601  else
2602  {
2603  ldef.prepend("enum ");
2604  }
2605  }
2606  else if (isEnumValue())
2607  {
2608  if (ldef.at(0)=='@')
2609  {
2610  ldef=ldef.mid(2);
2611  }
2612  }
2613  else if (isFunction())
2614  {
2615  title += "()";
2616  }
2617  int i=0,l;
2618  static QRegExp r("@[0-9]+");
2619 
2620  //----------------------------------------
2621 
2622  ol.pushGeneratorState();
2623 
2624  bool htmlEndLabelTable=FALSE;
2625  QStrList sl;
2626  getLabels(sl,scopedContainer);
2627 
2628  if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
2629  {
2630  // find enum type and insert it in the definition
2631  MemberListIterator vmli(*ml);
2632  MemberDef *vmd;
2633  bool found=FALSE;
2634  for ( ; (vmd=vmli.current()) && !found ; ++vmli)
2635  {
2636  if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
2637  {
2638  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2639  ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2640  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.left(i));
2642  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-i-l));
2643 
2644  found=TRUE;
2645  }
2646  }
2647  if (!found) // anonymous compound
2648  {
2649  //printf("Anonymous compound `%s'\n",cname.data());
2650  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2651  ol.startMemberDoc(ciname,name(),memAnchor,name(),memCount,memTotal,showInline);
2652  // search for the last anonymous compound name in the definition
2653  int si=ldef.find(' '),pi,ei=i+l;
2654  if (si==-1) si=0;
2655  while ((pi=r.match(ldef,i+l,&l))!=-1)
2656  {
2657  i=pi;
2658  ei=i+l;
2659  }
2660  // first si characters of ldef contain compound type name
2662  ol.docify(ldef.left(si));
2663  ol.docify(" { ... } ");
2664  // last ei characters of ldef contain pointer/reference specifiers
2665  int ni=ldef.find("::",si);
2666  if (ni>=ei) ei=ni+2;
2667  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,ldef.right(ldef.length()-ei));
2668  }
2669  }
2670  else // not an enum value or anonymous compound
2671  {
2672  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
2673  ol.startMemberDoc(ciname,name(),memAnchor,title,memCount,memTotal,showInline);
2674 
2675  ClassDef *cd=getClassDef();
2677  if (!Config_getBool(HIDE_SCOPE_NAMES))
2678  {
2679  bool first=TRUE;
2680  SrcLangExt lang = getLanguage();
2681  if (m_impl->defTmpArgLists && lang==SrcLangExt_Cpp)
2682  // definition has explicit template parameter declarations
2683  {
2684  QListIterator<ArgumentList> ali(*m_impl->defTmpArgLists);
2685  ArgumentList *tal;
2686  for (ali.toFirst();(tal=ali.current());++ali)
2687  {
2688  if (tal->count()>0)
2689  {
2690  if (!first) ol.docify(" ");
2692  writeTemplatePrefix(ol,tal);
2694  }
2695  }
2696  }
2697  else // definition gets it template parameters from its class
2698  // (since no definition was found)
2699  {
2700  if (cd && lang==SrcLangExt_Cpp && !isTemplateSpecialization())
2701  {
2702  QList<ArgumentList> tempParamLists;
2703  cd->getTemplateParameterLists(tempParamLists);
2704  //printf("#tempParamLists=%d\n",tempParamLists.count());
2705  QListIterator<ArgumentList> ali(tempParamLists);
2706  ArgumentList *tal;
2707  for (ali.toFirst();(tal=ali.current());++ali)
2708  {
2709  if (tal->count()>0)
2710  {
2711  if (!first) ol.docify(" ");
2713  writeTemplatePrefix(ol,tal);
2715  }
2716  }
2717  }
2718  if (m_impl->tArgList && lang==SrcLangExt_Cpp) // function template prefix
2719  {
2723  }
2724  }
2725  }
2726 
2727  if (sl.count()>0)
2728  {
2729  ol.pushGeneratorState();
2730  ol.disableAll();
2732  ol.writeString("<table class=\"mlabels\">\n");
2733  ol.writeString(" <tr>\n");
2734  ol.writeString(" <td class=\"mlabels-left\">\n");
2735  ol.popGeneratorState();
2736  htmlEndLabelTable=TRUE;
2737  }
2738 
2740  if (cd && cd->isObjectiveC())
2741  {
2742  // strip scope name
2743  int ep = ldef.find("::");
2744  if (ep!=-1)
2745  {
2746  int sp=ldef.findRev(' ',ep);
2747  if (sp!=-1)
2748  {
2749  ldef=ldef.left(sp+1)+ldef.mid(ep+2);
2750  } else {
2751  ldef=ldef.mid(ep+2);
2752  }
2753  }
2754  // strip keywords
2755  int dp = ldef.find(':');
2756  if (dp!=-1)
2757  {
2758  ldef=ldef.left(dp+1);
2759  }
2760  int l=ldef.length();
2761  //printf("start >%s<\n",ldef.data());
2762  int i=l-1;
2763  while (i>=0 && (isId(ldef.at(i)) || ldef.at(i)==':')) i--;
2764  while (i>=0 && isspace((uchar)ldef.at(i))) i--;
2765  if (i>0)
2766  {
2767  // insert braches around the type
2768  QCString tmp("("+ldef.left(i+1)+")"+ldef.mid(i+1));
2769  ldef=tmp;
2770  }
2771  //printf("end >%s< i=%d\n",ldef.data(),i);
2772  if (isStatic()) ldef.prepend("+ "); else ldef.prepend("- ");
2773  }
2774 
2775  if (optVhdl)
2776  {
2777  hasParameterList=VhdlDocGen::writeVHDLTypeDocumentation(this,scopedContainer,ol);
2778  }
2779  else
2780  {
2782  scopedContainer,
2783  getBodyDef(),
2784  this,
2785  substitute(ldef,"::",sep)
2786  );
2787  Definition *scope = cd;
2788  if (scope==0) scope = nd;
2789  hasParameterList=writeDefArgumentList(ol,scope,this);
2790  }
2791 
2792  if (hasOneLineInitializer()) // add initializer
2793  {
2794  if (!isDefine())
2795  {
2796  //ol.docify(" = ");
2797  ol.docify(" ");
2798  QCString init = m_impl->initializer.simplifyWhiteSpace();
2799  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,init);
2800  }
2801  else
2802  {
2803  ol.writeNonBreakableSpace(3);
2804  linkifyText(TextGeneratorOLImpl(ol),scopedContainer,getBodyDef(),this,m_impl->initializer);
2805  }
2806  }
2807  if (excpString()) // add exception list
2808  {
2809  writeExceptionList(ol,cd,this);
2810  hasParameterList=true; // call endParameterList below
2811  }
2812  }
2813 
2814  ol.pushGeneratorState();
2816  if (sl.count()>0)
2817  {
2818  ol.startLabels();
2819  const char *s=sl.first();
2820  while (s)
2821  {
2822  const char *ns = sl.next();
2823  ol.writeLabel(s,ns==0);
2824  s=ns;
2825  }
2826  ol.endLabels();
2827  }
2828  ol.popGeneratorState();
2829 
2830  if (hasParameterList)
2831  {
2832  ol.endParameterList();
2833  ol.endMemberDoc(TRUE);
2834  }
2835  else
2836  {
2837  ol.endMemberDocName();
2838  ol.endMemberDoc(FALSE);
2839  }
2840 
2841  // for HTML write the labels here
2842  ol.pushGeneratorState();
2843  ol.disableAll();
2845  if (htmlEndLabelTable)
2846  {
2847  ol.writeString(" </td>\n");
2848  ol.writeString(" <td class=\"mlabels-right\">\n");
2849  ol.startLabels();
2850  const char *s=sl.first();
2851  while (s)
2852  {
2853  const char *ns = sl.next();
2854  ol.writeLabel(s,ns==0);
2855  s=ns;
2856  }
2857  ol.endLabels();
2858  ol.writeString(" </td>\n");
2859  ol.writeString(" </tr>\n");
2860  ol.writeString("</table>\n");
2861  }
2862  ol.writeString("</div>");
2863  ol.popGeneratorState();
2864 
2865 
2866  ol.endDoxyAnchor(cfname,memAnchor);
2867  ol.startIndent();
2868 
2869  _writeGroupInclude(ol,inGroup);
2870 
2871  /* write multi-line initializer (if any) */
2873  //initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
2874  // || initLines<userInitLines // explicitly enabled
2875  // )
2876  )
2877  {
2878  //printf("md=%s initLines=%d init=`%s'\n",name().data(),initLines,init.data());
2879  ol.startBold();
2882  else
2884  ol.endBold();
2886  pIntf->resetCodeParserState();
2887  ol.startCodeFragment();
2888  pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,getFileDef(),
2889  -1,-1,TRUE,this,FALSE,this);
2890  ol.endCodeFragment();
2891  }
2892 
2893  QCString brief = briefDescription();
2894  QCString detailed = documentation();
2895  ArgumentList *docArgList = m_impl->defArgList;
2896  if (m_impl->templateMaster)
2897  {
2899  detailed = m_impl->templateMaster->documentation();
2900  docArgList = m_impl->templateMaster->argumentList();
2901  }
2902 
2903  /* write brief description */
2904  if (!brief.isEmpty() &&
2905  (Config_getBool(REPEAT_BRIEF) ||
2906  !Config_getBool(BRIEF_MEMBER_DESC)
2907  )
2908  )
2909  {
2910  ol.startParagraph();
2912  scopedContainer,this,
2913  brief,FALSE,FALSE,0,TRUE,FALSE);
2914  ol.endParagraph();
2915  }
2916 
2917  /* write detailed description */
2918  if (!detailed.isEmpty() ||
2919  !inbodyDocumentation().isEmpty())
2920  {
2921  // write vhdl inline code with or without option INLINE_SOURCE
2922  if (optVhdl && VhdlDocGen::isMisc(this))
2923  {
2924  VhdlDocGen::writeSource(this,ol,cname);
2925  return;
2926  }
2927  else
2928  {
2929  ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE);
2930  }
2931 
2932  if (!inbodyDocumentation().isEmpty())
2933  {
2935  scopedContainer,this,
2936  inbodyDocumentation()+"\n",TRUE,FALSE);
2937  }
2938  }
2939  else if (!brief.isEmpty() && (Config_getBool(REPEAT_BRIEF) ||
2940  !Config_getBool(BRIEF_MEMBER_DESC)))
2941  {
2942  if (!inbodyDocumentation().isEmpty())
2943  {
2944  ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE);
2945  }
2946  }
2947 
2948 
2949  //printf("***** defArgList=%p name=%s docs=%s hasDocs=%d\n",
2950  // defArgList,
2951  // defArgList?defArgList->hasDocumentation():-1);
2952  if (docArgList!=0 && docArgList->hasDocumentation())
2953  {
2954  QCString paramDocs;
2955  ArgumentListIterator ali(*docArgList);
2956  Argument *a;
2957  // convert the parameter documentation into a list of @param commands
2958  for (ali.toFirst();(a=ali.current());++ali)
2959  {
2960  if (a->hasDocumentation())
2961  {
2962  QCString direction = extractDirection(a->docs);
2963  paramDocs+="@param"+direction+" "+a->name+" "+a->docs;
2964  }
2965  }
2966  // feed the result to the documentation parser
2967  ol.generateDoc(
2968  docFile(),docLine(),
2969  scopedContainer,
2970  this, // memberDef
2971  paramDocs, // docStr
2972  TRUE, // indexWords
2973  FALSE // isExample
2974  );
2975 
2976  }
2977 
2978  _writeEnumValues(ol,scopedContainer,cfname,ciname,cname);
2979  _writeReimplements(ol);
2982  _writeExamples(ol);
2984  writeSourceDef(ol,cname);
2985  writeSourceRefs(ol,cname);
2986  writeSourceReffedBy(ol,cname);
2987  writeInlineCode(ol,cname);
2988  _writeCallGraph(ol);
2989  _writeCallerGraph(ol);
2990 
2992  {
2993  ol.pushGeneratorState();
2995  QCString cmd = "<? $root=$_SERVER['DOCUMENT_ROOT']; "
2996  "passthru(\"$root/doxynotes --lookup "+
2997  getOutputFileBase()+":"+anchor()+"\") ?>";
2998  ol.writeString(cmd);
2999  ol.popGeneratorState();
3000  }
3001 
3002  ol.endIndent();
3003 
3004  // enable LaTeX again
3005  //if (Config_getBool(EXTRACT_ALL) && !hasDocs) ol.enable(OutputGenerator::Latex);
3006  ol.popGeneratorState();
3007 
3008  //------------------------------------------------
3009 
3010  if (!Config_getBool(EXTRACT_ALL) &&
3011  Config_getBool(WARN_IF_UNDOCUMENTED) &&
3012  Config_getBool(WARN_NO_PARAMDOC) &&
3014  {
3015  if (!hasDocumentedParams())
3016  {
3018  "parameters of member %s are not (all) documented",
3019  qPrint(qualifiedName()));
3020  }
3022  {
3024  "return type of member %s is not documented",
3025  qPrint(qualifiedName()));
3026  }
3027  }
3028 }
3029 
3030 // strip scope and field name from the type
3031 // example: "struct N::S.v.c" will become "struct v"
3032 static QCString simplifyTypeForTable(const QCString &s)
3033 {
3034  QCString ts=removeAnonymousScopes(s);
3035  if (ts.right(2)=="::") ts = ts.left(ts.length()-2);
3036  static QRegExp re("[A-Z_a-z0-9]+::");
3037  int i,l;
3038  while ((i=re.match(ts,0,&l))!=-1)
3039  {
3040  ts=ts.left(i)+ts.mid(i+l);
3041  }
3042  i=ts.findRev('.');
3043  if (i!=-1) ts = ts.left(i);
3044  i=ts.findRev('.');
3045  if (i!=-1) ts = ts.right(ts.length()-i-1);
3046  //printf("simplifyTypeForTable(%s)->%s\n",s.data(),ts.data());
3047  return ts;
3048 }
3049 
3050 #if 0
3051 
3058 static Definition *getClassFromType(Definition *scope,const QCString &type,SrcLangExt lang,int &start,int &length)
3059 {
3060  int pos=0;
3061  int i;
3062  QCString name;
3063  QCString templSpec;
3064  while ((i=extractClassNameFromType(type,pos,name,templSpec,lang))!=-1)
3065  {
3066  ClassDef *cd=0;
3067  MemberDef *md=0;
3068  int l = name.length()+templSpec.length();
3069  if (!templSpec.isEmpty())
3070  {
3071  cd = getResolvedClass(scope,0,name+templSpec,&md);
3072  }
3073  cd = getResolvedClass(scope,0,name);
3074  if (cd)
3075  {
3076  start=i;
3077  length=l;
3078  printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3079  return cd;
3080  }
3081  else if (md)
3082  {
3083  start=i;
3084  length=l;
3085  printf("getClassFromType: type=%s name=%s start=%d length=%d\n",type.data(),name.data(),start,length);
3086  return md;
3087  }
3088  pos=i+l;
3089  }
3090  return 0;
3091 }
3092 #endif
3093 
3094 QCString MemberDef::fieldType() const
3095 {
3096  QCString type = m_impl->accessorType;
3097  if (type.isEmpty())
3098  {
3099  type = m_impl->type;
3100  }
3101 
3102  if (isTypedef()) type.prepend("typedef ");
3103  return simplifyTypeForTable(type);
3104 }
3105 
3107 {
3108  Definition *scope = getOuterScope();
3109  QCString doxyName = name();
3110  QCString doxyArgs = argsString();
3111  QCString memAnchor = anchor();
3112  QCString cfname = getOutputFileBase();
3113  QCString cname;
3114  if (scope) cname = scope->name();
3115  if (doxyName.at(0)=='@')
3116  {
3117  doxyName="__unnamed__";
3118  }
3119 
3120  ClassDef *cd = m_impl->accessorClass;
3121  //printf("===> %s::anonymous: %s\n",name().data(),cd?cd->name().data():"<none>");
3122 
3123  if (container && container->definitionType()==Definition::TypeClass &&
3124  !((ClassDef*)container)->isJavaEnum())
3125  {
3126  ol.startInlineMemberType();
3127  ol.startDoxyAnchor(cfname,cname,memAnchor,doxyName,doxyArgs);
3128 
3129  QCString ts = fieldType();
3130 
3131  if (cd) // cd points to an anonymous struct pointed to by this member
3132  // so we add a link to it from the type column.
3133  {
3134  int i=0;
3135  const char *prefixes[] = { "struct ","union ","class ", 0 };
3136  const char **p = prefixes;
3137  while (*p)
3138  {
3139  int l=qstrlen(*p);
3140  if (ts.left(l)==*p)
3141  {
3142  ol.writeString(*p);
3143  i=l;
3144  }
3145  p++;
3146  }
3147  ol.writeObjectLink(cd->getReference(),
3148  cd->getOutputFileBase(),
3149  cd->anchor(),ts.mid(i));
3150  }
3151  else // use standard auto linking
3152  {
3153  linkifyText(TextGeneratorOLImpl(ol), // out
3154  scope, // scope
3155  getBodyDef(), // fileScope
3156  this, // self
3157  ts, // text
3158  TRUE // autoBreak
3159  );
3160  }
3161  ol.endDoxyAnchor(cfname,memAnchor);
3162  ol.endInlineMemberType();
3163  }
3164 
3165  ol.startInlineMemberName();
3166  ol.docify(doxyName);
3167  if (isVariable() && argsString() && !isObjCMethod())
3168  {
3170  }
3171  if (!m_impl->bitfields.isEmpty()) // add bitfields
3172  {
3174  }
3175  ol.endInlineMemberName();
3176 
3177  ol.startInlineMemberDoc();
3178 
3179  QCString brief = briefDescription();
3180  QCString detailed = documentation();
3181 
3182  /* write brief description */
3183  if (!brief.isEmpty())
3184  {
3186  getOuterScope()?getOuterScope():container,this,
3187  brief,FALSE,FALSE,0,TRUE,FALSE);
3188  }
3189 
3190  /* write detailed description */
3191  if (!detailed.isEmpty())
3192  {
3193  ol.generateDoc(docFile(),docLine(),
3194  getOuterScope()?getOuterScope():container,this,
3195  detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
3196 
3197  }
3198 
3199  ol.endInlineMemberDoc();
3200 }
3201 
3203 {
3204  switch (m_impl->mtype)
3205  {
3206  case MemberType_Define: return "macro definition";
3207  case MemberType_Function: return "function";
3208  case MemberType_Variable: return "variable";
3209  case MemberType_Typedef: return "typedef";
3210  case MemberType_Enumeration: return "enumeration";
3211  case MemberType_EnumValue: return "enumvalue";
3212  case MemberType_Signal: return "signal";
3213  case MemberType_Slot: return "slot";
3214  case MemberType_Friend: return "friend";
3215  case MemberType_DCOP: return "dcop";
3216  case MemberType_Property: return "property";
3217  case MemberType_Event: return "event";
3218  case MemberType_Interface: return "interface";
3219  case MemberType_Service: return "service";
3220  default: return "unknown";
3221  }
3222 }
3223 
3225 {
3226  if (m_impl->memberGroup) return;
3227  ClassDef *cd = getClassDef();
3228  NamespaceDef *nd = getNamespaceDef();
3229  FileDef *fd = getFileDef();
3230  GroupDef *gd = getGroupDef();
3231  Definition *d=0;
3232  const char *t=0;
3233  if (cd)
3234  t="class", d=cd;
3235  else if (nd)
3236  {
3237  d=nd;
3238  if (d->getLanguage() == SrcLangExt_Fortran)
3239  t="module";
3240  else
3241  t="namespace";
3242  }
3243  else if (gd)
3244  t="group", d=gd;
3245  else
3246  t="file", d=fd;
3247  static bool extractAll = Config_getBool(EXTRACT_ALL);
3248 
3249  //printf("%s:warnIfUndoc: hasUserDocs=%d isFriendClass=%d protection=%d isRef=%d isDel=%d\n",
3250  // name().data(),
3251  // hasUserDocumentation(),isFriendClass(),protectionLevelVisible(m_impl->prot),isReference(),isDeleted());
3252  if ((!hasUserDocumentation() && !extractAll) &&
3253  !isFriendClass() &&
3254  name().find('@')==-1 && d && d->name().find('@')==-1 &&
3256  !isReference() && !isDeleted()
3257  )
3258  {
3259  warn_undoc(getDefFileName(),getDefLine(),"Member %s%s (%s) of %s %s is not documented.",
3260  qPrint(name()),qPrint(argsString()),qPrint(memberTypeName()),t,qPrint(d->name()));
3261  }
3262 }
3263 
3264 
3265 
3267 {
3268  return (isFriend() &&
3269  (m_impl->type=="friend class" || m_impl->type=="friend struct" ||
3270  m_impl->type=="friend union"));
3271 }
3272 
3274 {
3275  ClassDef *fcd=0;
3276  QCString baseName=name();
3277  int i=baseName.find('<');
3278  if (i!=-1) baseName=baseName.left(i);
3279  return (isFriendClass() &&
3280  (fcd=getClass(baseName)) && fcd->isLinkable());
3281 }
3282 
3284 {
3286 }
3287 
3289 {
3290  return Definition::hasDocumentation() ||
3291  (m_impl->mtype==MemberType_Enumeration && m_impl->docEnumValues) || // has enum values
3292  (m_impl->defArgList!=0 && m_impl->defArgList->hasDocumentation()); // has doc arguments
3293 }
3294 
3295 #if 0
3297 {
3298  bool hasDocs = Definition::hasUserDocumentation();
3299  return hasDocs;
3300 }
3301 #endif
3302 
3303 
3305 {
3306  m_impl->memberGroup = grp;
3307 }
3308 
3309 bool MemberDef::visibleMemberGroup(bool hideNoHeader)
3310 {
3311  return m_impl->memberGroup!=0 &&
3312  (!hideNoHeader || m_impl->memberGroup->header()!="[NOHEADER]");
3313 }
3314 
3316 {
3317  QCString result;
3318  if (getClassDef()) result=getClassDef()->displayName();
3319  else if (getNamespaceDef()) result=getNamespaceDef()->displayName();
3320  return result;
3321 }
3322 
3323 #if 0
3324 static QCString escapeAnchor(const QCString &anchor)
3325 {
3326  QCString result;
3327  int l = anchor.length(),i;
3328  for (i=0;i<l;i++)
3329  {
3330  char c = anchor.at(i);
3331  if ((c>='a' && c<='z') || (c>='A' && c<='Z'))
3332  {
3333  result+=c;
3334  }
3335  else
3336  {
3337  static char hexStr[]="0123456789ABCDEF";
3338  char escChar[]={ '_', 0, 0, 0 };
3339  escChar[1]=hexStr[c>>4];
3340  escChar[2]=hexStr[c&0xf];
3341  result+=escChar;
3342  }
3343  }
3344  return result;
3345 }
3346 #endif
3347 
3349 {
3350  QCString memAnchor = name();
3351  if (!m_impl->args.isEmpty()) memAnchor+=m_impl->args;
3352 
3353  memAnchor.prepend(definition()); // actually the method name is now included
3354  // twice, which is silly, but we keep it this way for backward
3355  // compatibility.
3356 
3357  // include number of template arguments as well,
3358  // to distinguish between two template
3359  // specializations that only differ in the template parameters.
3360  if (m_impl->tArgList)
3361  {
3362  char buf[20];
3363  qsnprintf(buf,20,"%d:",m_impl->tArgList->count());
3364  buf[19]='\0';
3365  memAnchor.prepend(buf);
3366  }
3367 
3368  // convert to md5 hash
3369  uchar md5_sig[16];
3370  QCString sigStr(33);
3371  MD5Buffer((const unsigned char *)memAnchor.data(),memAnchor.length(),md5_sig);
3372  //printf("memAnchor=%s\n",memAnchor.data());
3373  MD5SigToString(md5_sig,sigStr.rawData(),33);
3374  m_impl->anc = "a"+sigStr;
3375 }
3376 
3378  const QCString &fileName,int startLine,
3379  bool hasDocs,MemberDef *member)
3380 {
3381  //printf("%s MemberDef::setGroupDef(%s)\n",name().data(),gd->name().data());
3382  m_impl->group=gd;
3383  m_impl->grouppri=pri;
3384  m_impl->groupFileName=fileName;
3385  m_impl->groupStartLine=startLine;
3386  m_impl->groupHasDocs=hasDocs;
3387  m_impl->groupMember=member;
3388  m_isLinkableCached = 0;
3389 }
3390 
3391 void MemberDef::setEnumScope(MemberDef *md,bool livesInsideEnum)
3392 {
3393  m_impl->enumScope=md;
3395  if (md->getGroupDef())
3396  {
3397  m_impl->group=md->getGroupDef();
3398  m_impl->grouppri=md->getGroupPri();
3402  m_isLinkableCached = 0;
3403  }
3404 }
3405 
3407 {
3408  m_impl->classDef=cd;
3409  m_isLinkableCached = 0;
3411  setOuterScope(cd);
3412 }
3413 
3415 {
3416  m_impl->nspace=nd;
3417  setOuterScope(nd);
3418 }
3419 
3421  ArgumentList *formalArgs,ArgumentList *actualArgs)
3422 {
3423  //printf(" Member %s %s %s\n",typeString(),name().data(),argsString());
3424  ArgumentList *actualArgList = 0;
3425  if (m_impl->defArgList)
3426  {
3427  actualArgList = m_impl->defArgList->deepCopy();
3428 
3429  // replace formal arguments with actuals
3430  ArgumentListIterator ali(*actualArgList);
3431  Argument *arg;
3432  for (;(arg=ali.current());++ali)
3433  {
3434  arg->type = substituteTemplateArgumentsInString(arg->type,formalArgs,actualArgs);
3435  }
3436  actualArgList->trailingReturnType =
3437  substituteTemplateArgumentsInString(actualArgList->trailingReturnType,formalArgs,actualArgs);
3438  }
3439 
3440  QCString methodName=name();
3441  if (methodName.left(9)=="operator ") // conversion operator
3442  {
3443  methodName=substituteTemplateArgumentsInString(methodName,formalArgs,actualArgs);
3444  }
3445 
3446  MemberDef *imd = new MemberDef(
3448  substituteTemplateArgumentsInString(m_impl->type,formalArgs,actualArgs),
3449  methodName,
3450  substituteTemplateArgumentsInString(m_impl->args,formalArgs,actualArgs),
3453  );
3454  imd->setArgumentList(actualArgList);
3455  imd->setDefinition(substituteTemplateArgumentsInString(m_impl->def,formalArgs,actualArgs));
3456  imd->setBodyDef(getBodyDef());
3458  //imd->setBodyMember(this);
3459 
3460  // TODO: init other member variables (if needed).
3461  // TODO: reimplemented info
3462  return imd;
3463 }
3464 
3466 {
3467  //printf("%s: init=%s, initLines=%d maxInitLines=%d userInitLines=%d\n",
3468  // name().data(),m_impl->initializer.data(),m_impl->initLines,
3469  // m_impl->maxInitLines,m_impl->userInitLines);
3470  return !m_impl->initializer.isEmpty() && m_impl->initLines==0 && // one line initializer
3471  ((m_impl->maxInitLines>0 && m_impl->userInitLines==-1) || m_impl->userInitLines>0); // enabled by default or explicitly
3472 }
3473 
3475 {
3476  //printf("initLines=%d userInitLines=%d maxInitLines=%d\n",
3477  // initLines,userInitLines,maxInitLines);
3478  return m_impl->initLines>0 &&
3479  ((m_impl->initLines<m_impl->maxInitLines && m_impl->userInitLines==-1) // implicitly enabled
3480  || m_impl->initLines<m_impl->userInitLines // explicitly enabled
3481  );
3482 }
3483 
3484 void MemberDef::setInitializer(const char *initializer)
3485 {
3487  int l=m_impl->initializer.length();
3488  int p=l-1;
3489  while (p>=0 && isspace((uchar)m_impl->initializer.at(p))) p--;
3490  m_impl->initializer=m_impl->initializer.left(p+1);
3491  m_impl->initLines=m_impl->initializer.contains('\n');
3492  //printf("%s::setInitializer(%s)\n",name().data(),m_impl->initializer.data());
3493 }
3494 
3496 {
3497  static bool optimizeOutputForC = Config_getBool(OPTIMIZE_OUTPUT_FOR_C);
3498  //static bool hideScopeNames = Config_getBool(HIDE_SCOPE_NAMES);
3499  //static bool optimizeOutputJava = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
3500  //static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
3501  SrcLangExt lang = getLanguage();
3502  visited=TRUE;
3503  if (!isLinkableInProject()) return;
3504  QCString memLabel;
3505  if (optimizeOutputForC)
3506  {
3507  memLabel=theTranslator->trGlobal(TRUE,TRUE);
3508  }
3509  else if (lang==SrcLangExt_Fortran)
3510  {
3511  memLabel=theTranslator->trSubprogram(TRUE,TRUE);
3512  }
3513  else
3514  {
3515  memLabel=theTranslator->trMember(TRUE,TRUE);
3516  }
3517  QCString memName = name();
3518  Definition *pd=getOuterScope();
3519  QCString pdName = pd->definitionType()==Definition::TypeClass ?
3520  ((ClassDef*)pd)->displayName() : pd->name();
3521  QCString sep = getLanguageSpecificSeparator(lang,TRUE);
3522  QCString memArgs;
3523  if (!isRelated()
3524  /* && commented out as a result of bug 597016
3525  (
3526  (!hideScopeNames && // there is a scope
3527  pd && pd!=Doxygen::globalScope) // and we can show it
3528  ||
3529  (pd=getClassDef()) // it's a class so we
3530  // show the scope anyway
3531  )
3532  */
3533  )
3534  {
3535  if (isObjCMethod())
3536  {
3537  memName = "[" + pd->name() + " " + name() + "]";
3538  }
3539  else
3540  {
3541  if (pd!=Doxygen::globalScope) memName.prepend(pdName+sep);
3542  memArgs = argsString();
3543  }
3544  }
3545  QList<ListItemInfo> *xrefItems = xrefListItems();
3546  if (xrefItems)
3547  {
3548  addRefItem(xrefItems,
3549  qualifiedName()+argsString(), // argsString is needed for overloaded functions (see bug 609624)
3550  memLabel,
3551  getOutputFileBase()+"#"+anchor(),memName,memArgs,pd);
3552  }
3553 }
3554 
3556 {
3557  char key[20];
3558  sprintf(key,"%p",d);
3559  return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
3560 }
3561 
3563 {
3564  //printf("MemberDef::setSectionList(%p,%p) name=%s\n",d,sl,name().data());
3565  char key[20];
3566  sprintf(key,"%p",d);
3567  if (m_impl->classSectionSDict==0)
3568  {
3570  }
3571  m_impl->classSectionSDict->append(key,sl);
3572 }
3573 
3575 {
3576  if (count>25)
3577  {
3579  "Internal inconsistency: recursion detected in overload relation for member %s!"
3580  ,qPrint(name())
3581  );
3582  return Normal;
3583  }
3584  Specifier v = m_impl->virt;
3585  MemberDef *rmd = reimplements();
3586  while (rmd && v==Normal)
3587  {
3588  v = rmd->virtualness(count+1)==Normal ? Normal : Virtual;
3589  rmd = rmd->reimplements();
3590  }
3591  return v;
3592 }
3593 
3595 {
3596  if (!isLinkableInProject()) return;
3597  tagFile << " <member kind=\"";
3598  switch (m_impl->mtype)
3599  {
3600  case MemberType_Define: tagFile << "define"; break;
3601  case MemberType_EnumValue: tagFile << "enumvalue"; break;
3602  case MemberType_Property: tagFile << "property"; break;
3603  case MemberType_Event: tagFile << "event"; break;
3604  case MemberType_Variable: tagFile << "variable"; break;
3605  case MemberType_Typedef: tagFile << "typedef"; break;
3606  case MemberType_Enumeration: tagFile << "enumeration"; break;
3607  case MemberType_Function: tagFile << "function"; break;
3608  case MemberType_Signal: tagFile << "signal"; break;
3609  case MemberType_Friend: tagFile << "friend"; break;
3610  case MemberType_DCOP: tagFile << "dcop"; break;
3611  case MemberType_Slot: tagFile << "slot"; break;
3612  case MemberType_Interface: tagFile << "interface"; break;
3613  case MemberType_Service: tagFile << "service"; break;
3614  }
3615  if (m_impl->prot!=Public)
3616  {
3617  tagFile << "\" protection=\"";
3618  if (m_impl->prot==Protected) tagFile << "protected";
3619  else if (m_impl->prot==Package) tagFile << "package";
3620  else /* Private */ tagFile << "private";
3621  }
3622  if (m_impl->virt!=Normal)
3623  {
3624  tagFile << "\" virtualness=\"";
3625  if (m_impl->virt==Virtual) tagFile << "virtual";
3626  else /* Pure */ tagFile << "pure";
3627  }
3628  if (isStatic())
3629  {
3630  tagFile << "\" static=\"yes";
3631  }
3632  tagFile << "\">" << endl;
3633  if (typeString()!=QCString("@"))
3634  {
3635  tagFile << " <type>" << convertToXML(typeString()) << "</type>" << endl;
3636  }
3637  tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
3638  tagFile << " <anchorfile>" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
3639  tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
3640  QCString idStr = id();
3641  if (!idStr.isEmpty())
3642  {
3643  tagFile << " <clangid>" << convertToXML(idStr) << "</clangid>" << endl;
3644  }
3645  tagFile << " <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
3646  if (isStrong())
3647  {
3648  MemberList *fmdl=m_impl->enumFields;
3649  if (fmdl)
3650  {
3651  MemberListIterator mli(*fmdl);
3652  MemberDef *fmd;
3653  for (mli.toFirst();(fmd=mli.current());++mli)
3654  {
3655  if (!fmd->isReference())
3656  {
3657  tagFile << " <enumvalue file=\"" << convertToXML(getOutputFileBase()+Doxygen::htmlFileExtension);
3658  tagFile << "\" anchor=\"" << convertToXML(fmd->anchor());
3659  QCString idStr = fmd->id();
3660  if (!idStr.isEmpty())
3661  {
3662  tagFile << "\" clangid=\"" << convertToXML(idStr);
3663  }
3664  tagFile << "\">" << convertToXML(fmd->name()) << "</enumvalue>" << endl;
3665  }
3666  }
3667  }
3668  }
3669  writeDocAnchorsToTagFile(tagFile);
3670  tagFile << " </member>" << endl;
3671 }
3672 
3674 {
3675  m_isConstructorCached=1; // FALSE
3676  if (m_impl->classDef)
3677  {
3678  if (m_impl->isDMember) // for D
3679  {
3680  m_isConstructorCached = name()=="this" ? 2 : 1;
3681  return;
3682  }
3683  else if (getLanguage()==SrcLangExt_PHP) // for PHP
3684  {
3685  m_isConstructorCached = name()=="__construct" ? 2 : 1;
3686  return;
3687  }
3688  else if (name()=="__init__" &&
3689  getLanguage()==SrcLangExt_Python) // for Python
3690  {
3691  m_isConstructorCached = 2; // TRUE
3692  return;
3693  }
3694  else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3695  {
3696  m_isConstructorCached = name()=="constructor" ? 2 : 1;
3697  return;
3698  }
3699  else // for other languages
3700  {
3701  QCString locName = m_impl->classDef->localName();
3702  int i=locName.find('<');
3703  if (i==-1) // not a template class
3704  {
3705  m_isConstructorCached = name()==locName ? 2 : 1;
3706  }
3707  else
3708  {
3709  m_isConstructorCached = name()==locName.left(i) ? 2 : 1;
3710  }
3711  return;
3712  }
3713  }
3714 }
3715 
3717 {
3718  if (m_isConstructorCached==0)
3719  {
3720  MemberDef *that = (MemberDef*)this;
3721  that->_computeIsConstructor();
3722  }
3723  ASSERT(m_isConstructorCached>0);
3724  return m_isConstructorCached==2;
3725 
3726 }
3727 
3729 {
3730  bool isDestructor;
3731  if (m_impl->isDMember) // for D
3732  {
3733  isDestructor = name()=="~this";
3734  }
3735  else if (getLanguage()==SrcLangExt_PHP) // for PHP
3736  {
3737  isDestructor = name()=="__destruct";
3738  }
3739  else if (getLanguage()==SrcLangExt_Tcl) // for Tcl
3740  {
3741  isDestructor = name()=="destructor";
3742  }
3743  else if (name()=="__del__" &&
3744  getLanguage()==SrcLangExt_Python) // for Python
3745  {
3746  isDestructor=TRUE;
3747  }
3748  else // other languages
3749  {
3750  isDestructor =
3751  (name().find('~')!=-1 || name().find('!')!=-1) // The ! is for C++/CLI
3752  && name().find("operator")==-1;
3753  }
3754  m_isDestructorCached = isDestructor ? 2 : 1;
3755 }
3756 
3758 {
3759  if (m_isDestructorCached==0)
3760  {
3761  MemberDef *that=(MemberDef*)this;
3762  that->_computeIsDestructor();
3763  }
3764  ASSERT(m_isDestructorCached>0);
3765  return m_isDestructorCached==2;
3766 }
3767 
3769  ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd)
3770 {
3771  int enumMemCount=0;
3772 
3773  MemberList *fmdl=m_impl->enumFields;
3774  uint numVisibleEnumValues=0;
3775  if (fmdl)
3776  {
3777  MemberListIterator mli(*fmdl);
3778  MemberDef *fmd;
3779  for (mli.toFirst();(fmd=mli.current());++mli)
3780  {
3781  if (fmd->isBriefSectionVisible()) numVisibleEnumValues++;
3782  }
3783  }
3784  if (numVisibleEnumValues==0 && !isBriefSectionVisible())
3785  {
3786  return;
3787  }
3788 
3789  QCString n = name();
3790  int i=n.findRev("::");
3791  if (i!=-1) n=n.right(n.length()-i-2); // strip scope (TODO: is this needed?)
3792  if (n[0]!='@') // not an anonymous enum
3793  {
3795  {
3796  //_writeTagData(compoundType);
3798  writeLink(typeDecl,cd,nd,fd,gd);
3799  }
3800  else
3801  {
3802  typeDecl.startBold();
3803  typeDecl.docify(n);
3804  typeDecl.endBold();
3805  }
3806  typeDecl.writeChar(' ');
3807  }
3808  if (!m_impl->enumBaseType.isEmpty())
3809  {
3810  typeDecl.writeChar(':');
3811  typeDecl.writeChar(' ');
3812  typeDecl.docify(m_impl->enumBaseType);
3813  typeDecl.writeChar(' ');
3814  }
3815 
3816  uint enumValuesPerLine = (uint)Config_getInt(ENUM_VALUES_PER_LINE);
3817  if (numVisibleEnumValues>0 && enumValuesPerLine>0)
3818  {
3819  typeDecl.docify("{ ");
3820  if (fmdl)
3821  {
3822  MemberListIterator mli(*fmdl);
3823  MemberDef *fmd=mli.current();
3824  bool fmdVisible = fmd ? fmd->isBriefSectionVisible() : TRUE;
3825  while (fmd)
3826  {
3827  if (fmdVisible)
3828  {
3829  /* in html we start a new line after a number of items */
3830  if (numVisibleEnumValues>enumValuesPerLine
3831  && (enumMemCount%enumValuesPerLine)==0
3832  )
3833  {
3834  typeDecl.pushGeneratorState();
3836  typeDecl.enable(OutputGenerator::Latex);
3837  typeDecl.lineBreak();
3838  typeDecl.disable(OutputGenerator::Latex);
3839  typeDecl.writeString("&#160;&#160;");
3840  typeDecl.popGeneratorState();
3841  }
3842 
3843  if (fmd->hasDocumentation()) // enum value has docs
3844  {
3845  //fmd->_writeTagData(compoundType);
3846  fmd->_addToSearchIndex();
3847  fmd->writeLink(typeDecl,cd,nd,fd,gd);
3848  }
3849  else // no docs for this enum value
3850  {
3851  typeDecl.startBold();
3852  typeDecl.docify(fmd->name());
3853  typeDecl.endBold();
3854  }
3855  if (fmd->hasOneLineInitializer()) // enum value has initializer
3856  {
3857  //typeDecl.writeString(" = ");
3858  typeDecl.writeString(" ");
3859  typeDecl.parseText(fmd->initializer());
3860  }
3861  }
3862 
3863  bool prevVisible = fmdVisible;
3864  ++mli;
3865  fmd=mli.current();
3866  if (fmd && (fmdVisible=fmd->isBriefSectionVisible()))
3867  {
3868  typeDecl.writeString(", ");
3869  }
3870  if (prevVisible)
3871  {
3872  typeDecl.disable(OutputGenerator::Man);
3873  typeDecl.writeString("\n"); // to prevent too long lines in LaTeX
3874  typeDecl.enable(OutputGenerator::Man);
3875  enumMemCount++;
3876  }
3877  }
3878  if (numVisibleEnumValues>enumValuesPerLine)
3879  {
3880  typeDecl.pushGeneratorState();
3882  typeDecl.lineBreak();
3883  typeDecl.popGeneratorState();
3884  }
3885  }
3886  typeDecl.docify(" }");
3887  }
3888 }
3889 
3891 {
3892  if (m_impl->defArgList) delete m_impl->defArgList;
3893  m_impl->defArgList = al;
3894 }
3895 
3897 {
3898  if (m_impl->declArgList) delete m_impl->declArgList;
3899  m_impl->declArgList = al;
3900 }
3901 
3903 {
3904  if (al==0) return;
3907  m_impl->typeConstraints->setAutoDelete(TRUE);
3908  ArgumentListIterator ali(*al);
3909  Argument *a;
3910  for (;(a=ali.current());++ali)
3911  {
3912  m_impl->typeConstraints->append(new Argument(*a));
3913  }
3914 }
3915 
3916 void MemberDef::setType(const char *t)
3917 {
3918  m_impl->type = t;
3919 }
3920 
3921 void MemberDef::setAccessorType(ClassDef *cd,const char *t)
3922 {
3923  m_impl->accessorClass = cd;
3924  m_impl->accessorType = t;
3925 }
3926 
3928 {
3929  return m_impl->accessorClass;
3930 }
3931 
3933 {
3935 }
3936 
3938 {
3939  m_impl->hasCallGraph=e;
3940  if (e) Doxygen::parseSourcesNeeded = TRUE;
3941 }
3942 
3944 {
3946  if (e) Doxygen::parseSourcesNeeded = TRUE;
3947 }
3948 
3949 #if 0
3950 bool MemberDef::protectionVisible() const
3951 {
3952  return m_impl->prot==Public ||
3953  (m_impl->prot==Private && Config_getBool(EXTRACT_PRIVATE)) ||
3954  (m_impl->prot==Protected && Config_getBool(EXTRACT_PROTECTED)) ||
3955  (m_impl->prot==Package && Config_getBool(EXTRACT_PACKAGE));
3956 }
3957 #endif
3958 
3959 #if 0
3960 void MemberDef::setInbodyDocumentation(const char *docs,
3961  const char *docFile,int docLine)
3962 {
3963  m_impl->inbodyDocs = docs;
3964  m_impl->inbodyDocs = m_impl->inbodyDocs.stripWhiteSpace();
3965  m_impl->inbodyLine = docLine;
3966  m_impl->inbodyFile = docFile;
3967 }
3968 #endif
3969 
3971 {
3972  if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isFunction()) return TRUE;
3973  return FALSE;
3974 }
3975 
3977 {
3978  if (m_impl->classDef && m_impl->classDef->isObjectiveC() && isProperty()) return TRUE;
3979  return FALSE;
3980 }
3981 
3983 {
3984  if (isObjCMethod())
3985  {
3986  QCString qm;
3987  if (isStatic()) qm="+"; else qm="-";
3988  qm+="[";
3989  qm+=m_impl->classDef->name()+" ";
3990  qm+=name();
3991  qm+="]";
3992  return qm;
3993  }
3994  else if (m_impl->enumScope && m_impl->enumScope->isStrong())
3995  {
3996  return m_impl->enumScope->qualifiedName()+
3998  localName();
3999  }
4000  else
4001  {
4002  return Definition::qualifiedName();
4003  }
4004 }
4005 
4007 {
4008  if (ti)
4009  {
4010  //printf("%s: Setting tag name=%s anchor=%s\n",name().data(),ti->tagName.data(),ti->anchor.data());
4011  m_impl->anc=ti->anchor;
4012  setReference(ti->tagName);
4014  }
4015 }
4016 
4017 QCString MemberDef::objCMethodName(bool localLink,bool showStatic) const
4018 {
4019  QCString qm;
4020  if (showStatic)
4021  {
4022  if (isStatic()) qm="+ "; else qm="- ";
4023  }
4024  qm+=name();
4025  if (!localLink) // link to method of same class
4026  {
4027  qm+=" (";
4028  qm+=m_impl->classDef->name();
4029  qm+=")";
4030  }
4031  return qm;
4032 }
4033 
4034 const char *MemberDef::declaration() const
4035 {
4036  return m_impl->decl;
4037 }
4038 
4039 const char *MemberDef::definition() const
4040 {
4041  return m_impl->def;
4042 }
4043 
4044 const char *MemberDef::extraTypeChars() const
4045 {
4046  return m_impl->extraTypeChars;
4047 }
4048 
4049 const char *MemberDef::typeString() const
4050 {
4051  return m_impl->type;
4052 }
4053 
4054 const char *MemberDef::argsString() const
4055 {
4056  return m_impl->args;
4057 }
4058 
4059 const char *MemberDef::excpString() const
4060 {
4061  return m_impl->exception;
4062 }
4063 
4064 const char *MemberDef::bitfieldString() const
4065 {
4066  return m_impl->bitfields;
4067 }
4068 
4069 const QCString &MemberDef::initializer() const
4070 {
4071  return m_impl->initializer;
4072 }
4073 
4075 {
4076  return m_impl->initLines;
4077 }
4078 
4080 {
4081  return m_impl->memSpec;
4082 }
4083 
4085 {
4086  return m_impl->classDef;
4087 }
4088 
4090 {
4091  return m_impl->fileDef;
4092 }
4093 
4095 {
4096  return m_impl->nspace;
4097 }
4098 
4099 const char *MemberDef::getReadAccessor() const
4100 {
4101  return m_impl->read;
4102 }
4103 
4104 const char *MemberDef::getWriteAccessor() const
4105 {
4106  return m_impl->write;
4107 }
4108 
4110 {
4111  return m_impl->group;
4112 }
4113 
4115 {
4116  return m_impl->grouppri;
4117 }
4118 
4119 const char *MemberDef::getGroupFileName() const
4120 {
4121  return m_impl->groupFileName;
4122 }
4123 
4125 {
4126  return m_impl->groupStartLine;
4127 }
4128 
4130 {
4131  return m_impl->groupHasDocs;
4132 }
4133 
4135 {
4136  return m_impl->prot;
4137 }
4138 
4140 {
4141  return m_impl->mtype;
4142 }
4143 
4145 {
4146  return m_impl->mtype==MemberType_Signal;
4147 }
4148 
4149 bool MemberDef::isSlot() const
4150 {
4151  return m_impl->mtype==MemberType_Slot;
4152 }
4153 
4155 {
4156  return m_impl->mtype==MemberType_Variable;
4157 }
4158 
4160 {
4162 }
4163 
4165 {
4167 }
4168 
4170 {
4171  return m_impl->mtype==MemberType_Typedef;
4172 }
4173 
4175 {
4176  return m_impl->mtype==MemberType_Function;
4177 }
4178 
4180 {
4181  return m_impl->mtype==MemberType_Variable && QCString(argsString()).find(")(")!=-1;
4182 }
4183 
4185 {
4186  return m_impl->mtype==MemberType_Define;
4187 }
4188 
4190 {
4191  return m_impl->mtype==MemberType_Friend;
4192 }
4193 
4194 bool MemberDef::isDCOP() const
4195 {
4196  return m_impl->mtype==MemberType_DCOP;
4197 }
4198 
4200 {
4201  return m_impl->mtype==MemberType_Property;
4202 }
4203 
4205 {
4206  return m_impl->mtype==MemberType_Event;
4207 }
4208 
4210 {
4211  return m_impl->related == Related;
4212 }
4213 
4215 {
4216  return m_impl->related == Foreign;
4217 }
4218 
4220 {
4221  return m_impl->stat;
4222 }
4223 
4225 {
4226  return (m_impl->memSpec&Entry::Inline)!=0;
4227 }
4228 
4230 {
4231  return (m_impl->memSpec&Entry::Explicit)!=0;
4232 }
4233 
4235 {
4236  return (m_impl->memSpec&Entry::Mutable)!=0;
4237 }
4238 
4240 {
4241  return (m_impl->memSpec&Entry::Gettable)!=0;
4242 }
4243 
4245 {
4246  return (m_impl->memSpec&Entry::PrivateGettable)!=0;
4247 }
4248 
4250 {
4252 }
4253 
4255 {
4256  return (m_impl->memSpec&Entry::Settable)!=0;
4257 }
4258 
4260 {
4261  return (m_impl->memSpec&Entry::PrivateSettable)!=0;
4262 }
4263 
4265 {
4267 }
4268 
4270 {
4271  return (m_impl->memSpec&Entry::Addable)!=0;
4272 }
4273 
4275 {
4276  return (m_impl->memSpec&Entry::Removable)!=0;
4277 }
4278 
4280 {
4281  return (m_impl->memSpec&Entry::Raisable)!=0;
4282 }
4283 
4285 {
4286  return (m_impl->memSpec&Entry::Readable)!=0;
4287 }
4288 
4290 {
4291  return (m_impl->memSpec&Entry::Writable)!=0;
4292 }
4293 
4295 {
4296  return (m_impl->memSpec&Entry::Final)!=0;
4297 }
4298 
4299 bool MemberDef::isNew() const
4300 {
4301  return (m_impl->memSpec&Entry::New)!=0;
4302 }
4303 
4305 {
4306  return (m_impl->memSpec&Entry::Sealed)!=0;
4307 }
4308 
4310 {
4311  return (m_impl->memSpec&Entry::Override)!=0;
4312 }
4313 
4315 {
4316  return (m_impl->memSpec&Entry::Initonly)!=0;
4317 }
4318 
4320 {
4321  return (m_impl->memSpec&Entry::Abstract)!=0;
4322 }
4323 
4325 {
4326  return (m_impl->memSpec&Entry::Optional)!=0;
4327 }
4328 
4330 {
4331  return (m_impl->memSpec&Entry::Required)!=0;
4332 }
4333 
4335 {
4336  return (m_impl->memSpec&Entry::NonAtomic)!=0;
4337 }
4338 
4339 bool MemberDef::isCopy() const
4340 {
4341  return (m_impl->memSpec&Entry::Copy)!=0;
4342 }
4343 
4345 {
4346  return (m_impl->memSpec&Entry::Assign)!=0;
4347 }
4348 
4350 {
4351  return (m_impl->memSpec&Entry::Retain)!=0;
4352 }
4353 
4354 bool MemberDef::isWeak() const
4355 {
4356  return (m_impl->memSpec&Entry::Weak)!=0;
4357 }
4358 
4360 {
4361  return (m_impl->memSpec&Entry::Strong)!=0;
4362 }
4363 
4365 {
4366  return m_impl->mtype==MemberType_EnumValue &&
4367  m_impl->enumScope &&
4369 }
4370 
4372 {
4373  return (m_impl->memSpec&Entry::Unretained)!=0;
4374 }
4375 
4377 {
4378  return (m_impl->memSpec&Entry::Alias)!=0;
4379 }
4380 
4382 {
4383  return (m_impl->memSpec&Entry::Default)!=0;
4384 }
4385 
4387 {
4388  return (m_impl->memSpec&Entry::Delete)!=0;
4389 }
4390 
4392 {
4393  return (m_impl->memSpec&Entry::NoExcept)!=0;
4394 }
4395 
4397 {
4398  return (m_impl->memSpec&Entry::Attribute)!=0;
4399 }
4400 
4402 {
4403  return (m_impl->memSpec&Entry::Property)!=0;
4404 }
4405 
4407 {
4408  return (m_impl->memSpec&Entry::Readonly)!=0;
4409 }
4410 
4412 {
4413  return (m_impl->memSpec&Entry::Bound)!=0;
4414 }
4415 
4417 {
4418  return (m_impl->memSpec&Entry::Constrained)!=0;
4419 }
4420 
4422 {
4423  return (m_impl->memSpec&Entry::Transient)!=0;
4424 }
4425 
4427 {
4428  return (m_impl->memSpec&Entry::MaybeVoid)!=0;
4429 }
4430 
4432 {
4433  return (m_impl->memSpec&Entry::MaybeDefault)!=0;
4434 }
4435 
4437 {
4438  return (m_impl->memSpec&Entry::MaybeAmbiguous)!=0;
4439 }
4440 
4442 {
4443  return (m_impl->memSpec&Entry::Published)!=0;
4444 }
4445 
4446 
4448 {
4449  return m_impl->implOnly;
4450 }
4451 
4453 {
4454  return m_impl->explExt;
4455 }
4456 
4458 {
4459  return m_impl->tspec;
4460 }
4461 
4463 {
4464  return m_impl->hasDocumentedParams;
4465 }
4466 
4468 {
4470 }
4471 
4473 {
4474  return isFunction() ||
4475  isSlot() ||
4476  isConstructor() ||
4477  isDestructor() ||
4478  isObjCMethod();
4479 }
4480 
4482 {
4483  return m_impl->relatedAlso;
4484 }
4485 
4487 {
4488  return m_impl->docEnumValues;
4489 }
4490 
4492 {
4493  return m_impl->annEnumType;
4494 }
4495 
4497 {
4498  return m_impl->docsForDefinition;
4499 }
4500 
4502 {
4503  return m_impl->enumScope;
4504 }
4505 
4507 {
4508  return m_impl->livesInsideEnum;
4509 }
4510 
4512 {
4513  return m_impl->enumFields;
4514 }
4515 
4517 {
4518  return m_impl->exampleSDict;
4519 }
4520 
4522 {
4523  return m_impl->proto;
4524 }
4525 
4527 {
4528  return m_impl->defArgList;
4529 }
4530 
4532 {
4533  return m_impl->declArgList;
4534 }
4535 
4537 {
4538  return m_impl->tArgList;
4539 }
4540 
4542 {
4543  return m_impl->defTmpArgLists;
4544 }
4545 
4547 {
4548  return m_impl->grpId;
4549 }
4550 
4552 {
4553  return m_impl->memberGroup;
4554 }
4555 
4557 {
4558  return m_impl->annScope;
4559 }
4560 
4562 {
4563  return m_impl->annUsed;
4564 }
4565 
4567 {
4568  m_impl->annUsed = TRUE;
4569 }
4570 
4572 {
4573  return m_impl->hasCallGraph;
4574 }
4575 
4577 {
4578  return m_impl->hasCallerGraph;
4579 }
4580 
4582 {
4583  return m_impl->templateMaster;
4584 }
4585 
4587 {
4588  return m_impl->isTypedefValCached;
4589 }
4590 
4592 {
4593  return m_impl->cachedTypedefValue;
4594 }
4595 
4597 {
4599 }
4600 
4602 {
4603  //printf("MemberDef::getCachedResolvedTypedef()=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4604  return m_impl->cachedResolvedType;
4605 }
4606 
4608 {
4609  return m_impl->memDef;
4610 }
4611 
4613 {
4614  return m_impl->memDec;
4615 }
4616 
4618 {
4619  return m_impl->docProvider;
4620 }
4621 
4623 {
4624  return m_impl->groupAlias;
4625 }
4626 
4628 {
4629  m_impl->mtype=t;
4630  m_isLinkableCached = 0;
4631 }
4632 
4633 void MemberDef::setDefinition(const char *d)
4634 {
4635  m_impl->def=d;
4636 }
4637 
4639 {
4640  m_impl->fileDef=fd;
4641  m_isLinkableCached = 0;
4644 }
4645 
4647 {
4648  m_impl->prot=p;
4649  m_isLinkableCached = 0;
4650 }
4651 
4653 {
4654  m_impl->memSpec=s;
4655 }
4656 
4658 {
4659  m_impl->memSpec|=s;
4660 }
4661 
4662 void MemberDef::setBitfields(const char *s)
4663 {
4664  m_impl->bitfields = QCString(s).simplifyWhiteSpace();
4665 }
4666 
4668 {
4669  if (lines!=-1)
4670  {
4671  m_impl->userInitLines=lines;
4672  }
4673 }
4674 
4676 {
4677  m_impl->explExt=b;
4678 }
4679 
4680 void MemberDef::setReadAccessor(const char *r)
4681 {
4682  m_impl->read=r;
4683 }
4684 
4685 void MemberDef::setWriteAccessor(const char *w)
4686 {
4687  m_impl->write=w;
4688 }
4689 
4691 {
4692  m_impl->tspec=b;
4693 }
4694 
4696 {
4697  m_impl->related = Related;
4698  m_isLinkableCached = 0;
4699 }
4700 
4702 {
4703  m_impl->related = Foreign;
4704  m_isLinkableCached = 0;
4705 }
4706 
4708 {
4710 }
4711 
4713 {
4715 }
4716 
4718 {
4719  m_impl->docProvider = md;
4720 }
4721 
4722 void MemberDef::setArgsString(const char *as)
4723 {
4724  m_impl->args = as;
4725 }
4726 
4728 {
4729  m_impl->relatedAlso=cd;
4730 }
4731 
4733 {
4734  m_impl->classDef = cd;
4735  m_isLinkableCached = 0;
4737 }
4738 
4740 {
4741  m_impl->docEnumValues=value;
4742 }
4743 
4745 {
4746  m_impl->annEnumType = md;
4747 }
4748 
4750 {
4751  m_impl->proto=p;
4752 }
4753 
4755 {
4756  m_impl->grpId=id;
4757 }
4758 
4760 {
4761  m_impl->implOnly=TRUE;
4762 }
4763 
4765 {
4766  m_impl->annScope=b;
4767 }
4768 
4770 {
4771  m_impl->annMemb=m;
4772 }
4773 
4775 {
4776  return m_impl->annMemb;
4777 }
4778 
4780 {
4781  m_impl->templateMaster=mt;
4782  m_isLinkableCached = 0;
4783 }
4784 
4786 {
4788 }
4789 
4791 {
4792  m_impl->groupAlias = md;
4793 }
4794 
4796 {
4797  m_impl->isTypedefValCached=FALSE;
4798 }
4799 
4801 {
4802  m_impl->memDef=md;
4803 }
4804 
4806 {
4807  m_impl->memDec=md;
4808 }
4809 
4811 {
4812  return m_impl->category;
4813 }
4814 
4816 {
4817  m_impl->category = def;
4818 }
4819 
4821 {
4822  return m_impl->categoryRelation;
4823 }
4824 
4826 {
4827  m_impl->categoryRelation = md;
4828 }
4829 
4830 void MemberDef::setEnumBaseType(const QCString &type)
4831 {
4832  m_impl->enumBaseType = type;
4833 }
4834 
4835 QCString MemberDef::enumBaseType() const
4836 {
4837  return m_impl->enumBaseType;
4838 }
4839 
4840 
4841 void MemberDef::cacheTypedefVal(ClassDef*val, const QCString & templSpec, const QCString &resolvedType)
4842 {
4843  m_impl->isTypedefValCached=TRUE;
4845  m_impl->cachedTypedefTemplSpec=templSpec;
4846  m_impl->cachedResolvedType=resolvedType;
4847  //printf("MemberDef::cacheTypedefVal=%s m_impl=%p\n",m_impl->cachedResolvedType.data(),m_impl);
4848 }
4849 
4851 {
4852  {
4853  ArgumentList *arguments = bmd->argumentList();
4854  if (m_impl->defArgList && arguments)
4855  {
4857  ArgumentListIterator aliSrc(*arguments);
4858  Argument *argDst, *argSrc;
4859  for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4860  {
4861  argDst->name = argSrc->name;
4862  }
4863  }
4864  }
4865  {
4866  ArgumentList *arguments = bmd->declArgumentList();
4867  if (m_impl->declArgList && arguments)
4868  {
4870  ArgumentListIterator aliSrc(*arguments);
4871  Argument *argDst, *argSrc;
4872  for (;(argDst=aliDst.current()) && (argSrc=aliSrc.current());++aliDst,++aliSrc)
4873  {
4874  argDst->name = argSrc->name;
4875  }
4876  }
4877  }
4878 }
4879 
4881 {
4882  if (al)
4883  {
4884  ArgumentListIterator ali(*al);
4885  Argument *a;
4886  for (ali.toFirst();(a=ali.current());++ali)
4887  {
4888  a->canType.resize(0);
4889  }
4890  }
4891 }
4892 
4894 {
4897 }
4898 
4899 //----------------
4900 
4901 QCString MemberDef::displayName(bool) const
4902 {
4903  return Definition::name();
4904 }
4905 
4907 {
4908  // write search index info
4910  {
4911  Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
4912  QCString ln=localName(),qn=qualifiedName();
4913  Doxygen::searchIndex->addWord(ln,TRUE);
4914  if (ln!=qn)
4915  {
4916  Doxygen::searchIndex->addWord(qn,TRUE);
4917  if (getClassDef())
4918  {
4920  }
4921  else if (getNamespaceDef())
4922  {
4924  }
4925  }
4926  }
4927 }
4928 
4929 
4930 
4931 //----------------
4932 
4934 {
4935  if (decAl && defAl)
4936  {
4937  ArgumentListIterator decAli(*decAl);
4938  ArgumentListIterator defAli(*defAl);
4939  Argument *decA,*defA;
4940  for (decAli.toFirst(),defAli.toFirst();
4941  (decA=decAli.current()) && (defA=defAli.current());
4942  ++decAli,++defAli)
4943  {
4944  //printf("Argument decA->name=%s (doc=%s) defA->name=%s (doc=%s)\n",
4945  // decA->name.data(),decA->docs.data(),
4946  // defA->name.data(),defA->docs.data()
4947  // );
4948  if (decA->docs.isEmpty() && !defA->docs.isEmpty())
4949  {
4950  decA->docs = defA->docs.copy();
4951  }
4952  else if (defA->docs.isEmpty() && !decA->docs.isEmpty())
4953  {
4954  defA->docs = decA->docs.copy();
4955  }
4956  }
4957  }
4958 }
4959 
4961 {
4962  //printf("mdec=%s isPrototype()=%d\n",mdec->name().data(),mdec->isPrototype());
4963  if (
4964  (mdef->isFunction() && !mdef->isStatic() && !mdef->isPrototype()) ||
4965  (mdef->isVariable() && !mdef->isExternal() && !mdef->isStatic())
4966  )
4967  {
4968  //printf("mdef=(%p,%s) mdec=(%p,%s)\n",
4969  // mdef, mdef ? mdef->name().data() : "",
4970  // mdec, mdec ? mdec->name().data() : "");
4971 
4972  ArgumentList *mdefAl = mdef->argumentList();
4973  ArgumentList *mdecAl = mdec->argumentList();
4974  if (matchArguments2(mdef->getOuterScope(),mdef->getFileDef(),mdefAl,
4975  mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
4976  TRUE
4977  )
4978  ) /* match found */
4979  {
4980  //printf("Found member %s: definition in %s (doc=`%s') and declaration in %s (doc=`%s')\n",
4981  // mn->memberName(),
4982  // mdef->getFileDef()->name().data(),mdef->documentation().data(),
4983  // mdec->getFileDef()->name().data(),mdec->documentation().data()
4984  // );
4985 
4986  // first merge argument documentation
4987  transferArgumentDocumentation(mdecAl,mdefAl);
4988 
4989  /* copy documentation between function definition and declaration */
4990  if (!mdec->briefDescription().isEmpty())
4991  {
4992  mdef->setBriefDescription(mdec->briefDescription(),mdec->briefFile(),mdec->briefLine());
4993  }
4994  else if (!mdef->briefDescription().isEmpty())
4995  {
4996  mdec->setBriefDescription(mdef->briefDescription(),mdef->briefFile(),mdef->briefLine());
4997  }
4998  if (!mdef->documentation().isEmpty())
4999  {
5000  //printf("transferring docs mdef->mdec (%s->%s)\n",mdef->argsString(),mdec->argsString());
5001  mdec->setDocumentation(mdef->documentation(),mdef->docFile(),mdef->docLine());
5003  if (mdefAl!=0)
5004  {
5005  ArgumentList *mdefAlComb = new ArgumentList;
5006  stringToArgumentList(mdef->argsString(),mdefAlComb);
5007  transferArgumentDocumentation(mdefAl,mdefAlComb);
5008  mdec->setArgumentList(mdefAlComb);
5009  }
5010  }
5011  else if (!mdec->documentation().isEmpty())
5012  {
5013  //printf("transferring docs mdec->mdef (%s->%s)\n",mdec->argsString(),mdef->argsString());
5014  mdef->setDocumentation(mdec->documentation(),mdec->docFile(),mdec->docLine());
5016  if (mdecAl!=0)
5017  {
5018  ArgumentList *mdecAlComb = new ArgumentList;
5019  stringToArgumentList(mdec->argsString(),mdecAlComb);
5020  transferArgumentDocumentation(mdecAl,mdecAlComb);
5021  mdef->setDeclArgumentList(mdecAlComb);
5022  }
5023  }
5024  if (!mdef->inbodyDocumentation().isEmpty())
5025  {
5026  mdec->setInbodyDocumentation(mdef->inbodyDocumentation(),mdef->inbodyFile(),mdef->inbodyLine());
5027  }
5028  else if (!mdec->inbodyDocumentation().isEmpty())
5029  {
5030  mdef->setInbodyDocumentation(mdec->inbodyDocumentation(),mdec->inbodyFile(),mdec->inbodyLine());
5031  }
5032  if (mdec->getStartBodyLine()!=-1 && mdef->getStartBodyLine()==-1)
5033  {
5034  //printf("body mdec->mdef %d-%d\n",mdec->getStartBodyLine(),mdef->getEndBodyLine());
5035  mdef->setBodySegment(mdec->getStartBodyLine(),mdec->getEndBodyLine());
5036  mdef->setBodyDef(mdec->getBodyDef());
5037  //mdef->setBodyMember(mdec);
5038  }
5039  else if (mdef->getStartBodyLine()!=-1 && mdec->getStartBodyLine()==-1)
5040  {
5041  //printf("body mdef->mdec %d-%d\n",mdef->getStartBodyLine(),mdec->getEndBodyLine());
5042  mdec->setBodySegment(mdef->getStartBodyLine(),mdef->getEndBodyLine());
5043  mdec->setBodyDef(mdef->getBodyDef());
5044  //mdec->setBodyMember(mdef);
5045  }
5048 
5049 
5050  // copy group info.
5051  if (mdec->getGroupDef()==0 && mdef->getGroupDef()!=0)
5052  {
5053  mdec->setGroupDef(mdef->getGroupDef(),
5054  mdef->getGroupPri(),
5055  mdef->docFile(),
5056  mdef->docLine(),
5057  mdef->hasDocumentation(),
5058  mdef
5059  );
5060  }
5061  else if (mdef->getGroupDef()==0 && mdec->getGroupDef()!=0)
5062  {
5063  mdef->setGroupDef(mdec->getGroupDef(),
5064  mdec->getGroupPri(),
5065  mdec->docFile(),
5066  mdec->docLine(),
5067  mdec->hasDocumentation(),
5068  mdec
5069  );
5070  }
5071 
5072 
5073  mdec->mergeRefItems(mdef);
5074  mdef->mergeRefItems(mdec);
5075 
5076  mdef->setMemberDeclaration(mdec);
5077  mdec->setMemberDefinition(mdef);
5078 
5079  mdef->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5080  mdef->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5081  mdec->enableCallGraph(mdec->hasCallGraph() || mdef->hasCallGraph());
5082  mdec->enableCallerGraph(mdec->hasCallerGraph() || mdef->hasCallerGraph());
5083  }
5084  }
5085 }
5086 
5087 QCString MemberDef::briefDescription(bool abbr) const
5088 {
5089  if (m_impl->templateMaster)
5090  {
5091  return m_impl->templateMaster->briefDescription(abbr);
5092  }
5093  else
5094  {
5095  return Definition::briefDescription(abbr);
5096  }
5097 }
5098 
5100 {
5101  if (m_impl->templateMaster)
5102  {
5103  return m_impl->templateMaster->documentation();
5104  }
5105  else
5106  {
5107  return Definition::documentation();
5108  }
5109 }
5110 
5112 {
5113  return m_impl->typeConstraints;
5114 }
5115 
5117 {
5118  static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
5119  bool isFriendToHide = hideFriendCompounds &&
5120  (m_impl->type=="friend class" ||
5121  m_impl->type=="friend struct" ||
5122  m_impl->type=="friend union");
5123  return isFriendToHide;
5124 }
5125 
5127 {
5128  return !(isFriend() && isFriendToHide());
5129 }
5130 
5132 {
5133  return isFunction() || isSlot() || isSignal();
5134 }
5135 
5137 {
5138  return isRelated() || isForeign() || (isFriend() && !isFriendToHide());
5139 }
5140 
5142 {
5143  return Definition::isReference() ||
5145 }
5146