Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/src/memberdef.cpp

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

Archive Download this file

Revision: 1322