Chameleon

Chameleon Svn Source Tree

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

Source at commit 1322 created 9 years 5 months ago.
By meklort, Add doxygen to utils folder
1/******************************************************************************
2 *
3 * $Id: classdef.cpp,v 1.54 2001/03/19 19:27:39 root Exp $
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 <qfile.h>
20#include <qregexp.h>
21#include "classdef.h"
22#include "classlist.h"
23#include "entry.h"
24#include "doxygen.h"
25#include "membername.h"
26#include "message.h"
27#include "config.h"
28#include "util.h"
29#include "diagram.h"
30#include "language.h"
31#include "htmlhelp.h"
32#include "example.h"
33#include "outputlist.h"
34#include "dot.h"
35#include "defargs.h"
36#include "debug.h"
37#include "docparser.h"
38#include "searchindex.h"
39#include "vhdldocgen.h"
40#include "layout.h"
41
42//-----------------------------------------------------------------------------
43
44//static inline MemberList *createNewMemberList(MemberList::ListType lt)
45//{
46// MemberList *result = new MemberList(lt);
47// return result;
48//}
49
50class ClassDefImpl
51{
52 public:
53 ClassDefImpl();
54 ~ClassDefImpl();
55 void init(const char *defFileName, const char *name,
56 const QCString &ctStr, const char *fName);
57
58 /*! file name that forms the base for the output file containing the
59 * class documentation. For compatibility with Qt (e.g. links via tag
60 * files) this name cannot be derived from the class name directly.
61 */
62 QCString fileName;
63
64 /*! Include information about the header file should be included
65 * in the documentation. 0 by default, set by setIncludeFile().
66 */
67 IncludeInfo *incInfo;
68
69 /*! List of base class (or super-classes) from which this class derives
70 * directly.
71 */
72 BaseClassList *inherits;
73
74 /*! List of sub-classes that directly derive from this class
75 */
76 BaseClassList *inheritedBy;
77
78 /*! Namespace this class is part of
79 * (this is the inner most namespace in case of nested namespaces)
80 */
81 NamespaceDef *nspace;
82
83 /*! File this class is defined in */
84 FileDef *fileDef;
85
86 /*! List of all members (including inherited members) */
87 MemberNameInfoSDict *allMemberNameInfoSDict;
88
89 /*! Template arguments of this class */
90 ArgumentList *tempArgs;
91
92 /*! Type constraints for template parameters */
93 ArgumentList *typeConstraints;
94
95 /*! Files that were used for generating the class documentation. */
96 QStrList files;
97
98 /*! Examples that use this class */
99 ExampleSDict *exampleSDict;
100
101 /*! Holds the kind of "class" this is. */
102 ClassDef::CompoundType compType;
103
104 /*! The protection level in which this class was found.
105 * Typically Public, but for nested classes this can also be Protected
106 * or Private.
107 */
108 Protection prot;
109
110 /*! The inner classes contained in this class. Will be 0 if there are
111 * no inner classes.
112 */
113 ClassSDict *innerClasses;
114
115 /* classes for the collaboration diagram */
116 UsesClassDict *usesImplClassDict;
117 UsesClassDict *usedByImplClassDict;
118 UsesClassDict *usesIntfClassDict;
119
120 /*! Template instances that exists of this class, the key in the
121 * dictionary is the template argument list.
122 */
123 QDict<ClassDef> *templateInstances;
124
125 /*! Template instances that exists of this class, as defined by variables.
126 * We do NOT want to document these individually. The key in the
127 * dictionary is the template argument list.
128 */
129 QDict<ClassDef> *variableInstances;
130
131 QDict<int> *templBaseClassNames;
132
133 /*! The class this class is an instance of. */
134 ClassDef *templateMaster;
135
136 /*! local class name which could be a typedef'ed alias name. */
137 QCString className;
138
139 /*! If this class is a Objective-C category, then this points to the
140 * class which is extended.
141 */
142 ClassDef *categoryOf;
143
144 QList<MemberList> memberLists;
145
146 /* user defined member groups */
147 MemberGroupSDict *memberGroupSDict;
148
149 /*! Is this an abstact class? */
150 bool isAbstract;
151
152 /*! Is the class part of an unnamed namespace? */
153 bool isStatic;
154
155 /*! Language used for this class */
156 SrcLangExt lang;
157
158 /*! TRUE if classes members are merged with those of the base classes. */
159 bool membersMerged;
160
161 /*! TRUE if the class is defined in a source file rather than a header file. */
162 bool isLocal;
163
164 bool isTemplArg;
165
166 /*! Does this class group its user-grouped members
167 * as a sub-section of the normal (public/protected/..)
168 * groups?
169 */
170 bool subGrouping;
171
172 /** Reason of existance is a "use" relation */
173 bool usedOnly;
174
175 /** List of titles to use for the summary */
176 SDict<QCString> vhdlSummaryTitles;
177};
178
179void ClassDefImpl::init(const char *defFileName, const char *name,
180 const QCString &ctStr, const char *fName)
181{
182 if (fName)
183 {
184 fileName=stripExtension(fName);
185 }
186 else
187 {
188 fileName=ctStr+name;
189 }
190 exampleSDict = 0;
191 inherits = 0;
192 inheritedBy = 0;
193 allMemberNameInfoSDict = 0;
194 incInfo=0;
195 tempArgs=0;
196 typeConstraints=0;
197 prot=Public;
198 nspace=0;
199 fileDef=0;
200 usesImplClassDict=0;
201 usedByImplClassDict=0;
202 usesIntfClassDict=0;
203 memberGroupSDict = 0;
204 innerClasses = 0;
205 subGrouping=Config_getBool("SUBGROUPING");
206 templateInstances = 0;
207 variableInstances = 0;
208 templateMaster =0;
209 templBaseClassNames = 0;
210 isAbstract = FALSE;
211 isStatic = FALSE;
212 isTemplArg = FALSE;
213 membersMerged = FALSE;
214 categoryOf = 0;
215 usedOnly = FALSE;
216 //QCString ns;
217 //extractNamespaceName(name,className,ns);
218 //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
219
220 if (getLanguageFromFileName(defFileName)!=SrcLangExt_Java &&
221 guessSection(defFileName)==Entry::SOURCE_SEC)
222 {
223 isLocal=TRUE;
224 }
225 else
226 {
227 isLocal=FALSE;
228 }
229}
230
231ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)
232{
233 vhdlSummaryTitles.setAutoDelete(TRUE);
234}
235
236ClassDefImpl::~ClassDefImpl()
237{
238 delete inherits;
239 delete inheritedBy;
240 delete allMemberNameInfoSDict;
241 delete exampleSDict;
242 delete usesImplClassDict;
243 delete usedByImplClassDict;
244 delete usesIntfClassDict;
245 delete incInfo;
246 delete memberGroupSDict;
247 delete innerClasses;
248 delete templateInstances;
249 delete variableInstances;
250 delete templBaseClassNames;
251 delete tempArgs;
252 delete typeConstraints;
253}
254
255// constructs a new class definition
256ClassDef::ClassDef(
257 const char *defFileName,int defLine,
258 const char *nm,CompoundType ct,
259 const char *lref,const char *fName,
260 bool isSymbol)
261 : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm),0,0,isSymbol)
262{
263 visited=FALSE;
264 setReference(lref);
265 m_impl = new ClassDefImpl;
266 m_impl->compType = ct;
267 m_impl->lang = SrcLangExt_Unknown;
268 m_impl->init(defFileName,name(),compoundTypeString(),fName);
269
270}
271
272// destroy the class definition
273ClassDef::~ClassDef()
274{
275 delete m_impl;
276}
277
278QCString ClassDef::getMemberListFileName() const
279{
280 return convertNameToFile(compoundTypeString()+name()+"-members");
281}
282
283QCString ClassDef::displayName() const
284{
285 static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
286 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
287 QCString n;
288 if (vhdlOpt)
289 {
290 n = VhdlDocGen::getClassName(this);
291 }
292 else
293 {
294 n=qualifiedNameWithTemplateParameters();
295 }
296 if (optimizeOutputForJava)
297 {
298 n=substitute(n,"::",".");
299 }
300 if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
301 {
302 n="<"+n.left(n.length()-2)+">";
303 }
304 //printf("ClassDef::displayName()=%s\n",n.data());
305 return n;
306}
307
308// inserts a base class in the inheritance list
309void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,
310 Specifier s,const char *t)
311{
312 //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
313 //inherits->inSort(new BaseClassDef(cd,p,s,t));
314 if (m_impl->inherits==0)
315 {
316 m_impl->inherits = new BaseClassList;
317 m_impl->inherits->setAutoDelete(TRUE);
318 }
319 m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
320}
321
322// inserts a sub class in the inherited list
323void ClassDef::insertSubClass(ClassDef *cd,Protection p,
324 Specifier s,const char *t)
325{
326 //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
327 if (m_impl->inheritedBy==0)
328 {
329 m_impl->inheritedBy = new BaseClassList;
330 m_impl->inheritedBy->setAutoDelete(TRUE);
331 }
332 m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
333}
334
335void ClassDef::addMembersToMemberGroup()
336{
337 QListIterator<MemberList> mli(m_impl->memberLists);
338 MemberList *ml;
339 for (mli.toFirst();(ml=mli.current());++mli)
340 {
341 if ((ml->listType()&MemberList::detailedLists)==0)
342 {
343 ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
344 }
345 }
346
347 // add members inside sections to their groups
348 if (m_impl->memberGroupSDict)
349 {
350 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
351 MemberGroup *mg;
352 for (;(mg=mgli.current());++mgli)
353 {
354 if (mg->allMembersInSameSection() && m_impl->subGrouping)
355 {
356 //printf("addToDeclarationSection(%s)\n",mg->header().data());
357 mg->addToDeclarationSection();
358 }
359 }
360 }
361}
362
363// adds new member definition to the class
364void ClassDef::internalInsertMember(MemberDef *md,
365 Protection prot,
366 bool addToAllList
367 )
368{
369 //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
370 if (md->isHidden()) return;
371
372 static bool optVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
373 if (optVhdl)
374 {
375 QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
376 if (!m_impl->vhdlSummaryTitles.find(title))
377 {
378 m_impl->vhdlSummaryTitles.append(title,new QCString(title));
379 }
380 }
381
382 if (!isReference())
383 {
384 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
385
386 /********************************************/
387 /* insert member in the declaration section */
388 /********************************************/
389 if (md->isRelated() && (extractPrivate || prot!=Private))
390 {
391 addMemberToList(MemberList::related,md,TRUE);
392 }
393 else if (md->isFriend())
394 {
395 addMemberToList(MemberList::friends,md,TRUE);
396 }
397 else
398 {
399 switch (md->memberType())
400 {
401 case MemberDef::Signal: // Qt specific
402 addMemberToList(MemberList::signals,md,TRUE);
403 break;
404 case MemberDef::DCOP: // KDE2 specific
405 addMemberToList(MemberList::dcopMethods,md,TRUE);
406 break;
407 case MemberDef::Property:
408 addMemberToList(MemberList::properties,md,TRUE);
409 break;
410 case MemberDef::Event:
411 addMemberToList(MemberList::events,md,TRUE);
412 break;
413 case MemberDef::Slot: // Qt specific
414 switch (prot)
415 {
416 case Protected:
417 case Package: // slots in packages are not possible!
418 addMemberToList(MemberList::proSlots,md,TRUE);
419 break;
420 case Public:
421 addMemberToList(MemberList::pubSlots,md,TRUE);
422 break;
423 case Private:
424 addMemberToList(MemberList::priSlots,md,TRUE);
425 break;
426 }
427 break;
428 default: // any of the other members
429 if (md->isStatic())
430 {
431 if (md->isVariable())
432 {
433 switch (prot)
434 {
435 case Protected:
436 addMemberToList(MemberList::proStaticAttribs,md,TRUE);
437 break;
438 case Package:
439 addMemberToList(MemberList::pacStaticAttribs,md,TRUE);
440 break;
441 case Public:
442 addMemberToList(MemberList::pubStaticAttribs,md,TRUE);
443 break;
444 case Private:
445 addMemberToList(MemberList::priStaticAttribs,md,TRUE);
446 break;
447 }
448 }
449 else // function
450 {
451 switch (prot)
452 {
453 case Protected:
454 addMemberToList(MemberList::proStaticMethods,md,TRUE);
455 break;
456 case Package:
457 addMemberToList(MemberList::pacStaticMethods,md,TRUE);
458 break;
459 case Public:
460 addMemberToList(MemberList::pubStaticMethods,md,TRUE);
461 break;
462 case Private:
463 addMemberToList(MemberList::priStaticMethods,md,TRUE);
464 break;
465 }
466 }
467 }
468 else // not static
469 {
470 if (md->isVariable())
471 {
472 switch (prot)
473 {
474 case Protected:
475 addMemberToList(MemberList::proAttribs,md,TRUE);
476 break;
477 case Package:
478 addMemberToList(MemberList::pacAttribs,md,TRUE);
479 break;
480 case Public:
481 addMemberToList(MemberList::pubAttribs,md,TRUE);
482 break;
483 case Private:
484 addMemberToList(MemberList::priAttribs,md,TRUE);
485 break;
486 }
487 }
488 else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
489 {
490 switch (prot)
491 {
492 case Protected:
493 addMemberToList(MemberList::proTypes,md,TRUE);
494 break;
495 case Package:
496 addMemberToList(MemberList::pacTypes,md,TRUE);
497 break;
498 case Public:
499 addMemberToList(MemberList::pubTypes,md,TRUE);
500 break;
501 case Private:
502 addMemberToList(MemberList::priTypes,md,TRUE);
503 break;
504 }
505 }
506 else // member function
507 {
508 switch (prot)
509 {
510 case Protected:
511 addMemberToList(MemberList::proMethods,md,TRUE);
512 break;
513 case Package:
514 addMemberToList(MemberList::pacMethods,md,TRUE);
515 break;
516 case Public:
517 addMemberToList(MemberList::pubMethods,md,TRUE);
518 break;
519 case Private:
520 addMemberToList(MemberList::priMethods,md,TRUE);
521 break;
522 }
523 }
524 }
525 break;
526 }
527 }
528
529 /*******************************************************/
530 /* insert member in the detailed documentation section */
531 /*******************************************************/
532 if ((md->isRelated() && (extractPrivate || prot!=Private)) || md->isFriend())
533 {
534 addMemberToList(MemberList::relatedMembers,md,FALSE);
535 }
536 else
537 {
538 switch (md->memberType())
539 {
540 case MemberDef::Property:
541 addMemberToList(MemberList::propertyMembers,md,FALSE);
542 break;
543 case MemberDef::Event:
544 addMemberToList(MemberList::eventMembers,md,FALSE);
545 break;
546 case MemberDef::Signal: // fall through
547 case MemberDef::DCOP:
548 addMemberToList(MemberList::functionMembers,md,FALSE);
549 break;
550 case MemberDef::Slot:
551 switch (prot)
552 {
553 case Protected:
554 case Package:
555 case Public:
556 addMemberToList(MemberList::functionMembers,md,FALSE);
557 break;
558 case Private:
559 if (extractPrivate)
560 {
561 addMemberToList(MemberList::functionMembers,md,FALSE);
562 }
563 break;
564 }
565 break;
566 default: // any of the other members
567 if (prot!=Private || extractPrivate)
568 {
569 switch (md->memberType())
570 {
571 case MemberDef::Typedef:
572 addMemberToList(MemberList::typedefMembers,md,FALSE);
573 break;
574 case MemberDef::Enumeration:
575 addMemberToList(MemberList::enumMembers,md,FALSE);
576 break;
577 case MemberDef::EnumValue:
578 addMemberToList(MemberList::enumValMembers,md,FALSE);
579 break;
580 case MemberDef::Function:
581 if (md->isConstructor() || md->isDestructor())
582 {
583 MemberList *ml = createMemberList(MemberList::constructors);
584 ml->append(md);
585 }
586 else
587 {
588 addMemberToList(MemberList::functionMembers,md,FALSE);
589 }
590 break;
591 case MemberDef::Variable:
592 addMemberToList(MemberList::variableMembers,md,FALSE);
593 break;
594 default:
595 err("Unexpected member type %d found!\n",md->memberType());
596 }
597 }
598 break;
599 }
600 }
601
602 /*************************************************/
603 /* insert member in the appropriate member group */
604 /*************************************************/
605 // Note: this must be done AFTER inserting the member in the
606 // regular groups
607 //addMemberToGroup(md,groupId);
608
609 }
610
611 if (md->virtualness()==Pure)
612 {
613 m_impl->isAbstract=TRUE;
614 }
615
616 //::addClassMemberNameToIndex(md);
617 if (addToAllList &&
618 !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
619 md->isFriend() &&
620 (QCString(md->typeString())=="friend class" ||
621 QCString(md->typeString())=="friend struct" ||
622 QCString(md->typeString())=="friend union")))
623 {
624 //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
625 MemberInfo *mi = new MemberInfo((MemberDef *)md,
626 prot,md->virtualness(),FALSE);
627 MemberNameInfo *mni=0;
628 if (m_impl->allMemberNameInfoSDict==0)
629 {
630 m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
631 m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
632 }
633 if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
634 {
635 mni->append(mi);
636 }
637 else
638 {
639 mni = new MemberNameInfo(md->name());
640 mni->append(mi);
641 m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
642 }
643 }
644}
645
646void ClassDef::insertMember(MemberDef *md)
647{
648 internalInsertMember(md,md->protection(),TRUE);
649}
650
651// compute the anchors for all members
652void ClassDef::computeAnchors()
653{
654 ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;
655 const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
656 QListIterator<MemberList> mli(m_impl->memberLists);
657 MemberList *ml;
658 int index = 0;
659 for (mli.toFirst();(ml=mli.current());++mli)
660 {
661 if ((ml->listType()&MemberList::detailedLists)==0)
662 {
663 setAnchors(context,letters[index++],ml);
664 }
665 }
666
667 if (m_impl->memberGroupSDict)
668 {
669 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
670 MemberGroup *mg;
671 for (;(mg=mgli.current());++mgli)
672 {
673 mg->setAnchors(context);
674 }
675 }
676}
677
678void ClassDef::distributeMemberGroupDocumentation()
679{
680 if (m_impl->memberGroupSDict)
681 {
682 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
683 MemberGroup *mg;
684 for (;(mg=mgli.current());++mgli)
685 {
686 mg->distributeMemberGroupDocumentation();
687 }
688 }
689}
690
691void ClassDef::findSectionsInDocumentation()
692{
693 docFindSections(documentation(),this,0,docFile());
694 if (m_impl->memberGroupSDict)
695 {
696 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
697 MemberGroup *mg;
698 for (;(mg=mgli.current());++mgli)
699 {
700 mg->findSectionsInDocumentation();
701 }
702 }
703 QListIterator<MemberList> mli(m_impl->memberLists);
704 MemberList *ml;
705 for (mli.toFirst();(ml=mli.current());++mli)
706 {
707 if ((ml->listType()&MemberList::detailedLists)==0)
708 {
709 ml->findSectionsInDocumentation();
710 }
711 }
712}
713
714
715// add a file name to the used files set
716void ClassDef::insertUsedFile(const char *f)
717{
718 if (m_impl->files.find(f)==-1) m_impl->files.append(f);
719 if (m_impl->templateInstances)
720 {
721 QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
722 ClassDef *cd;
723 for (qdi.toFirst();(cd=qdi.current());++qdi)
724 {
725 cd->insertUsedFile(f);
726 }
727 }
728}
729
730static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
731{
732 if (bcd->prot!=Public || bcd->virt!=Normal)
733 {
734 ol.startTypewriter();
735 ol.docify(" [");
736 QStrList sl;
737 if (bcd->prot==Protected) sl.append("protected");
738 else if (bcd->prot==Private) sl.append("private");
739 if (bcd->virt==Virtual) sl.append("virtual");
740 const char *s=sl.first();
741 while (s)
742 {
743 ol.docify(s);
744 s=sl.next();
745 if (s) ol.docify(", ");
746 }
747 ol.docify("]");
748 ol.endTypewriter();
749 }
750}
751
752void ClassDef::setIncludeFile(FileDef *fd,
753 const char *includeName,bool local, bool force)
754{
755 //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
756 if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
757 if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
758 (fd!=0 && m_impl->incInfo->fileDef==0)
759 )
760 {
761 //printf("Setting file info\n");
762 m_impl->incInfo->fileDef = fd;
763 m_impl->incInfo->includeName = includeName;
764 m_impl->incInfo->local = local;
765 }
766 if (force && includeName) m_impl->incInfo->includeName = includeName;
767}
768
769// TODO: fix this: a nested template class can have multiple outer templates
770//ArgumentList *ClassDef::outerTemplateArguments() const
771//{
772// int ti;
773// ClassDef *pcd=0;
774// int pi=0;
775// if (m_impl->tempArgs) return m_impl->tempArgs;
776// // find the outer most class scope
777// while ((ti=name().find("::",pi))!=-1 &&
778// (pcd=getClass(name().left(ti)))==0
779// ) pi=ti+2;
780// if (pcd)
781// {
782// return pcd->templateArguments();
783// }
784// return 0;
785//}
786
787static void searchTemplateSpecs(/*in*/ Definition *d,
788 /*out*/ QList<ArgumentList> &result,
789 /*out*/ QCString &name)
790{
791 if (d->definitionType()==Definition::TypeClass)
792 {
793 if (d->getOuterScope())
794 {
795 searchTemplateSpecs(d->getOuterScope(),result,name);
796 }
797 ClassDef *cd=(ClassDef *)d;
798 if (!name.isEmpty()) name+="::";
799 QCString clName = d->localName();
800 if (clName.right(2)=="-g" || clName.right(2)=="-p")
801 {
802 clName = clName.left(clName.length()-2);
803 }
804 name+=clName;
805 bool isSpecialization = d->localName().find('<')!=-1;
806 if (cd->templateArguments())
807 {
808 result.append(cd->templateArguments());
809 if (!isSpecialization)
810 {
811 name+=tempArgListToString(cd->templateArguments());
812 }
813 }
814 }
815 else
816 {
817 name+=d->qualifiedName();
818 }
819}
820
821static void writeTemplateSpec(OutputList &ol,Definition *d,
822 const QCString &type)
823{
824 QList<ArgumentList> specs;
825 QCString name;
826 searchTemplateSpecs(d,specs,name);
827 if (specs.count()>0) // class has template scope specifiers
828 {
829 ol.startSubsubsection();
830 QListIterator<ArgumentList> spi(specs);
831 ArgumentList *al;
832 for (spi.toFirst();(al=spi.current());++spi)
833 {
834 ol.docify("template<");
835 Argument *a=al->first();
836 while (a)
837 {
838 ol.docify(a->type);
839 if (!a->name.isEmpty())
840 {
841 ol.docify(" ");
842 ol.docify(a->name);
843 }
844 if (a->defval.length()!=0)
845 {
846 ol.docify(" = ");
847 ol.docify(a->defval);
848 }
849 a=al->next();
850 if (a) ol.docify(", ");
851 }
852 ol.docify(">");
853 ol.pushGeneratorState();
854 ol.disableAllBut(OutputGenerator::Html);
855 ol.lineBreak();
856 ol.popGeneratorState();
857 }
858 ol.docify(type.lower()+" "+name);
859 ol.endSubsubsection();
860 ol.writeString("\n");
861 }
862}
863
864void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
865{
866 if (!briefDescription().isEmpty())
867 {
868 ol.startParagraph();
869 ol.parseDoc(briefFile(),briefLine(),this,0,
870 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
871 ol.pushGeneratorState();
872 ol.disable(OutputGenerator::RTF);
873 ol.writeString(" \n");
874 ol.enable(OutputGenerator::RTF);
875 ol.popGeneratorState();
876
877 if (Config_getBool("REPEAT_BRIEF") ||
878 !documentation().isEmpty() ||
879 exampleFlag
880 )
881 {
882 writeMoreLink(ol,anchor());
883 }
884
885 //ol.pushGeneratorState();
886 //ol.disable(OutputGenerator::RTF);
887 //ol.newParagraph(); // FIXME:PARA
888 //ol.popGeneratorState();
889 ol.endParagraph();
890 }
891 ol.writeSynopsis();
892}
893
894void ClassDef::writeDetailedDocumentationBody(OutputList &ol)
895{
896 static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
897
898 ol.startTextBlock();
899
900 writeTemplateSpec(ol,this,compoundTypeString());
901
902 // repeat brief description
903 if (!briefDescription().isEmpty() && repeatBrief)
904 {
905 ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
906 }
907 if (!briefDescription().isEmpty() && repeatBrief &&
908 !documentation().isEmpty())
909 {
910 ol.pushGeneratorState();
911 ol.disable(OutputGenerator::Html);
912 ol.writeString("\n\n");
913 ol.popGeneratorState();
914 }
915 // write documentation
916 if (!documentation().isEmpty())
917 {
918 ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
919 }
920 // write type constraints
921 writeTypeConstraints(ol,this,m_impl->typeConstraints);
922
923 // write examples
924 if (hasExamples() && m_impl->exampleSDict)
925 {
926 ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
927 ol.startDescForItem();
928 ol.startParagraph();
929 writeExample(ol,m_impl->exampleSDict);
930 ol.endParagraph();
931 ol.endDescForItem();
932 ol.endSimpleSect();
933 }
934 //ol.newParagraph();
935 writeSourceDef(ol,name());
936 ol.endTextBlock();
937}
938
939// write the detailed description for this class
940void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &pageType, bool exampleFlag,
941 const QCString &title,const QCString &anchor)
942{
943 if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) ||
944 !documentation().isEmpty() ||
945 (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef()) ||
946 exampleFlag)
947 {
948 ol.writeRuler();
949
950 ol.pushGeneratorState();
951 ol.disableAllBut(OutputGenerator::Html);
952 ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
953 ol.popGeneratorState();
954
955 if (!anchor.isEmpty())
956 {
957 ol.pushGeneratorState();
958 ol.disable(OutputGenerator::Html);
959 ol.disable(OutputGenerator::Man);
960 ol.writeAnchor(getOutputFileBase(),anchor);
961 ol.popGeneratorState();
962 }
963
964 ol.startGroupHeader();
965 ol.parseText(title);
966 ol.endGroupHeader();
967
968 writeDetailedDocumentationBody(ol);
969
970 }
971 else
972 {
973 writeTemplateSpec(ol,this,pageType);
974 }
975}
976
977void ClassDef::showUsedFiles(OutputList &ol)
978{
979 ol.pushGeneratorState();
980 ol.disable(OutputGenerator::Man);
981 bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
982
983 ol.writeRuler();
984 if (fortranOpt)
985 {
986 ol.parseText(theTranslator->trGeneratedFromFilesFortran(
987 m_impl->lang==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
988 m_impl->files.count()==1));
989 }
990 else
991 {
992 ol.parseText(theTranslator->trGeneratedFromFiles(
993 m_impl->lang==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
994 m_impl->files.count()==1));
995 }
996
997
998 bool first=TRUE;
999 const char *file = m_impl->files.first();
1000 while (file)
1001 {
1002 bool ambig;
1003 FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
1004 if (fd)
1005 {
1006 if (first)
1007 {
1008 first=FALSE;
1009 ol.startItemList();
1010 }
1011
1012 ol.startItemListItem();
1013 QCString path=fd->getPath();
1014 if (Config_getBool("FULL_PATH_NAMES"))
1015 {
1016 ol.docify(stripFromPath(path));
1017 }
1018
1019 QCString fname = fd->name();
1020 if (!fd->getVersion().isEmpty()) // append version if available
1021 {
1022 fname += " (" + fd->getVersion() + ")";
1023 }
1024
1025 // for HTML
1026 ol.pushGeneratorState();
1027 ol.disableAllBut(OutputGenerator::Html);
1028 if (fd->generateSourceFile())
1029 {
1030 ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
1031 }
1032 else if (fd->isLinkable())
1033 {
1034 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
1035 fname);
1036 }
1037 else
1038 {
1039 ol.docify(fname);
1040 }
1041 ol.popGeneratorState();
1042
1043 // for other output formats
1044 ol.pushGeneratorState();
1045 ol.disable(OutputGenerator::Html);
1046 if (fd->isLinkable())
1047 {
1048 ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
1049 fname);
1050 }
1051 else
1052 {
1053 ol.docify(fname);
1054 }
1055 ol.popGeneratorState();
1056
1057 ol.endItemListItem();
1058 }
1059 file=m_impl->files.next();
1060 }
1061 if (!first) ol.endItemList();
1062
1063 ol.popGeneratorState();
1064}
1065
1066
1067void ClassDef::writeInheritanceGraph(OutputList &ol)
1068{
1069 // count direct inheritance relations
1070 int count=0;
1071 BaseClassDef *ibcd;
1072 if (m_impl->inheritedBy)
1073 {
1074 ibcd=m_impl->inheritedBy->first();
1075 while (ibcd)
1076 {
1077 ClassDef *icd=ibcd->classDef;
1078 if ( icd->isVisibleInHierarchy()) count++;
1079 ibcd=m_impl->inheritedBy->next();
1080 }
1081 }
1082 if (m_impl->inherits)
1083 {
1084 ibcd=m_impl->inherits->first();
1085 while (ibcd)
1086 {
1087 ClassDef *icd=ibcd->classDef;
1088 if ( icd->isVisibleInHierarchy()) count++;
1089 ibcd=m_impl->inherits->next();
1090 }
1091 }
1092
1093
1094 bool renderDiagram = FALSE;
1095 if (Config_getBool("HAVE_DOT") &&
1096 (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))
1097 // write class diagram using dot
1098 {
1099 DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
1100 if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
1101 {
1102 ol.pushGeneratorState();
1103 ol.disable(OutputGenerator::Man);
1104 ol.startDotGraph();
1105 ol.parseText(theTranslator->trClassDiagram(displayName()));
1106 ol.endDotGraph(inheritanceGraph);
1107 ol.popGeneratorState();
1108 renderDiagram = TRUE;
1109 }
1110 }
1111 else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
1112 // write class diagram using build-in generator
1113 {
1114 ClassDiagram diagram(this); // create a diagram of this class.
1115 ol.startClassDiagram();
1116 ol.disable(OutputGenerator::Man);
1117 ol.parseText(theTranslator->trClassDiagram(displayName()));
1118 ol.enable(OutputGenerator::Man);
1119 ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
1120 renderDiagram = TRUE;
1121 }
1122
1123 if (renderDiagram) // if we already show the inheritance relations graphically,
1124 // then hide the text version
1125 {
1126 ol.disableAllBut(OutputGenerator::Man);
1127 }
1128
1129 if (m_impl->inherits && (count=m_impl->inherits->count())>0)
1130 {
1131 ol.startParagraph();
1132 //parseText(ol,theTranslator->trInherits()+" ");
1133
1134 QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
1135 QRegExp marker("@[0-9]+");
1136 int index=0,newIndex,matchLen;
1137 // now replace all markers in inheritLine with links to the classes
1138 while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1139 {
1140 ol.parseText(inheritLine.mid(index,newIndex-index));
1141 bool ok;
1142 uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1143 BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
1144 if (ok && bcd)
1145 {
1146 ClassDef *cd=bcd->classDef;
1147
1148 // use the class name but with the template arguments as given
1149 // in the inheritance relation
1150 QCString displayName = insertTemplateSpecifierInScope(
1151 cd->displayName(),bcd->templSpecifiers);
1152
1153 if (cd->isLinkable())
1154 {
1155 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1156 {
1157 Doxygen::tagFile << " <base";
1158 if (bcd->prot==Protected)
1159 {
1160 Doxygen::tagFile << " protection=\"protected\"";
1161 }
1162 else if (bcd->prot==Private)
1163 {
1164 Doxygen::tagFile << " protection=\"private\"";
1165 }
1166 if (bcd->virt==Virtual)
1167 {
1168 Doxygen::tagFile << " virtualness=\"virtual\"";
1169 }
1170 Doxygen::tagFile << ">" << convertToXML(cd->name())
1171 << "</base>" << endl;
1172 }
1173 ol.writeObjectLink(cd->getReference(),
1174 cd->getOutputFileBase(),
1175 cd->anchor(),
1176 displayName);
1177 }
1178 else
1179 {
1180 ol.docify(displayName);
1181 }
1182 }
1183 else
1184 {
1185 err("error: invalid marker %d in inherits list!\n",entryIndex);
1186 }
1187 index=newIndex+matchLen;
1188 }
1189 ol.parseText(inheritLine.right(inheritLine.length()-index));
1190 ol.endParagraph();
1191 }
1192
1193 // write subclasses
1194 if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
1195 {
1196 ol.startParagraph();
1197 QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
1198 QRegExp marker("@[0-9]+");
1199 int index=0,newIndex,matchLen;
1200 // now replace all markers in inheritLine with links to the classes
1201 while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
1202 {
1203 ol.parseText(inheritLine.mid(index,newIndex-index));
1204 bool ok;
1205 uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
1206 BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
1207 if (ok && bcd)
1208 {
1209 ClassDef *cd=bcd->classDef;
1210 if (cd->isLinkable())
1211 {
1212 ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1213 }
1214 else
1215 {
1216 ol.docify(cd->displayName());
1217 }
1218 writeInheritanceSpecifier(ol,bcd);
1219 }
1220 index=newIndex+matchLen;
1221 }
1222 ol.parseText(inheritLine.right(inheritLine.length()-index));
1223 ol.endParagraph();
1224 }
1225
1226 if (renderDiagram)
1227 {
1228 ol.enableAll();
1229 }
1230}
1231
1232void ClassDef::writeCollaborationGraph(OutputList &ol)
1233{
1234 if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)
1235 {
1236 DotClassGraph usageImplGraph(this,DotNode::Collaboration);
1237 if (!usageImplGraph.isTrivial())
1238 {
1239 ol.pushGeneratorState();
1240 ol.disable(OutputGenerator::Man);
1241 ol.startDotGraph();
1242 ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
1243 ol.endDotGraph(usageImplGraph);
1244 ol.popGeneratorState();
1245 }
1246 }
1247}
1248
1249void ClassDef::writeIncludeFiles(OutputList &ol)
1250{
1251 if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
1252 {
1253 QCString nm=m_impl->incInfo->includeName.isEmpty() ?
1254 (m_impl->incInfo->fileDef ?
1255 m_impl->incInfo->fileDef->docName().data() : ""
1256 ) :
1257 m_impl->incInfo->includeName.data();
1258 if (!nm.isEmpty())
1259 {
1260 ol.startParagraph();
1261 ol.startTypewriter();
1262 SrcLangExt lang = getLanguageFromFileName(nm);
1263 bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
1264 if (isIDLorJava)
1265 {
1266 ol.docify("import ");
1267 }
1268 else if (isObjectiveC())
1269 {
1270 ol.docify("#import ");
1271 }
1272 else
1273 {
1274 ol.docify("#include ");
1275 }
1276 if (m_impl->incInfo->local || isIDLorJava)
1277 ol.docify("\"");
1278 else
1279 ol.docify("<");
1280 ol.pushGeneratorState();
1281 ol.disable(OutputGenerator::Html);
1282 ol.docify(nm);
1283 ol.disableAllBut(OutputGenerator::Html);
1284 ol.enable(OutputGenerator::Html);
1285 if (m_impl->incInfo->fileDef)
1286 {
1287 ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);
1288 }
1289 else
1290 {
1291 ol.docify(nm);
1292 }
1293 ol.popGeneratorState();
1294 if (m_impl->incInfo->local || isIDLorJava)
1295 ol.docify("\"");
1296 else
1297 ol.docify(">");
1298 if (isIDLorJava)
1299 ol.docify(";");
1300 ol.endTypewriter();
1301 ol.endParagraph();
1302 }
1303 }
1304}
1305
1306void ClassDef::writeAllMembersLink(OutputList &ol)
1307{
1308 // write link to list of all members (HTML only)
1309 if (m_impl->allMemberNameInfoSDict &&
1310 !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
1311 )
1312 {
1313 ol.pushGeneratorState();
1314 ol.disableAllBut(OutputGenerator::Html);
1315 ol.startParagraph();
1316 ol.startTextLink(getMemberListFileName(),0);
1317 ol.parseText(theTranslator->trListOfAllMembers());
1318 ol.endTextLink();
1319 ol.endParagraph();
1320 ol.enableAll();
1321 ol.popGeneratorState();
1322 }
1323}
1324
1325void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)
1326{
1327 // write user defined member groups
1328 if (m_impl->memberGroupSDict)
1329 {
1330 m_impl->memberGroupSDict->sort();
1331 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
1332 MemberGroup *mg;
1333 for (;(mg=mgli.current());++mgli)
1334 {
1335 if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
1336 {
1337 mg->writeDeclarations(ol,this,0,0,0,showInline);
1338 }
1339 else // add this group to the corresponding member section
1340 {
1341 //printf("addToDeclarationSection(%s)\n",mg->header().data());
1342 //mg->addToDeclarationSection();
1343 }
1344 }
1345 }
1346}
1347
1348void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
1349{
1350 // nested classes
1351 if (m_impl->innerClasses)
1352 {
1353 m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
1354 }
1355}
1356
1357void ClassDef::startMemberDocumentation(OutputList &ol)
1358{
1359 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
1360 {
1361 ol.disable(OutputGenerator::Html);
1362 Doxygen::suppressDocWarnings = TRUE;
1363 }
1364}
1365
1366void ClassDef::endMemberDocumentation(OutputList &ol)
1367{
1368 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
1369 {
1370 ol.enable(OutputGenerator::Html);
1371 Doxygen::suppressDocWarnings = FALSE;
1372 }
1373}
1374
1375void ClassDef::startMemberDeclarations(OutputList &ol)
1376{
1377 ol.startMemberSections();
1378}
1379
1380void ClassDef::endMemberDeclarations(OutputList &ol)
1381{
1382 ol.endMemberSections();
1383}
1384
1385void ClassDef::writeAuthorSection(OutputList &ol)
1386{
1387 ol.pushGeneratorState();
1388 ol.disableAllBut(OutputGenerator::Man);
1389 ol.writeString("\n");
1390 ol.startGroupHeader();
1391 ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
1392 ol.endGroupHeader();
1393 ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
1394 ol.popGeneratorState();
1395}
1396
1397
1398void ClassDef::writeSummaryLinks(OutputList &ol)
1399{
1400 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1401 ol.pushGeneratorState();
1402 ol.disableAllBut(OutputGenerator::Html);
1403 QListIterator<LayoutDocEntry> eli(
1404 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1405 LayoutDocEntry *lde;
1406 bool first=TRUE;
1407
1408 if (!vhdlOpt)
1409 {
1410 for (eli.toFirst();(lde=eli.current());++eli)
1411 {
1412 if (lde->kind()==LayoutDocEntry::ClassNestedClasses &&
1413 m_impl->innerClasses &&
1414 m_impl->innerClasses->declVisible()
1415 )
1416 {
1417 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1418 writeSummaryLink(ol,"nested-classes",ls->title,first);
1419 }
1420 else if (lde->kind()== LayoutDocEntry::MemberDecl)
1421 {
1422 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1423 MemberList * ml = getMemberList(lmd->type);
1424 if (ml && ml->declVisible())
1425 {
1426 writeSummaryLink(ol,ml->listTypeAsString(),lmd->title,first);
1427 }
1428 }
1429 }
1430 }
1431 else // VDHL only
1432 {
1433 SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);
1434 for (li.toFirst();li.current();++li)
1435 {
1436 writeSummaryLink(ol,li.current()->data(),li.current()->data(),first);
1437 }
1438 }
1439 if (!first)
1440 {
1441 ol.writeString(" </div>\n");
1442 }
1443 ol.popGeneratorState();
1444}
1445
1446void ClassDef::writeTagFileMarker(OutputList &ol)
1447{
1448 // write markers for tag file processing to the output
1449 ol.pushGeneratorState();
1450 ol.disableAllBut(OutputGenerator::Html);
1451 ol.writeString("<!-- doxytag: class=\"");
1452 ol.docify(name());
1453 ol.writeString("\" -->");
1454 if (m_impl->inherits && m_impl->inherits->count()>0)
1455 {
1456 BaseClassListIterator bli(*m_impl->inherits);
1457 ol.writeString("<!-- doxytag: inherits=\"");
1458 BaseClassDef *bcd=0;
1459 bool first=TRUE;
1460 for (bli.toFirst();(bcd=bli.current());++bli)
1461 {
1462 if (!first) ol.writeString(",");
1463 ol.docify(bcd->classDef->name());
1464 first=FALSE;
1465 }
1466 ol.writeString("\" -->");
1467 }
1468 ol.popGeneratorState();
1469
1470 // write section to the tag file
1471 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1472 {
1473 Doxygen::tagFile << " <compound kind=\"" << compoundTypeString();
1474 Doxygen::tagFile << "\"";
1475 if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }
1476 Doxygen::tagFile << ">" << endl;
1477 Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
1478 Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
1479 if (!anchor().isEmpty())
1480 {
1481 Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
1482 }
1483 if (m_impl->tempArgs)
1484 {
1485 ArgumentListIterator ali(*m_impl->tempArgs);
1486 Argument *a;
1487 for (;(a=ali.current());++ali)
1488 {
1489 Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
1490 }
1491 }
1492 }
1493}
1494
1495#if 0
1496void ClassDef::writeInlineDeclaration(OutputList &ol,bool first)
1497{
1498 //printf("ClassDef::writeInlineDeclaration for %s\n",name().data());
1499 bool exampleFlag=hasExamples();
1500 QListIterator<LayoutDocEntry> eli(
1501 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1502 LayoutDocEntry *lde;
1503 ol.startMemberHeader(first ? "nested-classes" : 0);
1504 //ol.parseText(name()+" "+theTranslator->trClassDocumentation());
1505 QCString s = compoundTypeString();
1506 if (s.length()>0 && isId(s.at(0))) s[0]=toupper(s[0]);
1507 s+=" "+name();
1508 ol.parseText(s);
1509 ol.endMemberHeader();
1510 ol.writeAnchor(getOutputFileBase(),anchor());
1511 ol.startInlineDescription();
1512 writeBriefDescription(ol,exampleFlag);
1513 ol.endInlineDescription();
1514 for (eli.toFirst();(lde=eli.current());++eli)
1515 {
1516 if (lde->kind()==LayoutDocEntry::MemberDecl)
1517 {
1518 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1519 writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript,TRUE);
1520 }
1521 else if (lde->kind()==LayoutDocEntry::MemberGroups)
1522 {
1523 writeMemberGroups(ol,TRUE);
1524 }
1525 }
1526}
1527#endif
1528
1529/** Write class documentation inside another container (i.e. a group) */
1530void ClassDef::writeInlineDocumentation(OutputList &ol)
1531{
1532 ol.addIndexItem(name(),0);
1533 //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());
1534 QListIterator<LayoutDocEntry> eli(
1535 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1536 LayoutDocEntry *lde;
1537
1538 // part 1: anchor and title
1539 QCString s = compoundTypeString()+" "+name();
1540
1541 // part 1a
1542 ol.pushGeneratorState();
1543 ol.disableAllBut(OutputGenerator::Html);
1544 { // only HTML only
1545 ol.writeAnchor(0,anchor());
1546 ol.startMemberDoc(0,0,0,0,FALSE);
1547 ol.startMemberDocName(FALSE);
1548 ol.parseText(s);
1549 ol.endMemberDocName();
1550 ol.endMemberDoc(FALSE);
1551 ol.startIndent();
1552 }
1553 ol.popGeneratorState();
1554
1555 // part 1b
1556 ol.pushGeneratorState();
1557 ol.disable(OutputGenerator::Html);
1558 ol.disable(OutputGenerator::Man);
1559 { // for LaTeX/RTF only
1560 ol.writeAnchor(getOutputFileBase(),anchor());
1561 }
1562 ol.popGeneratorState();
1563
1564 // part 1c
1565 ol.pushGeneratorState();
1566 ol.disable(OutputGenerator::Html);
1567 {
1568 // for LaTeX/RTF/Man
1569 ol.startGroupHeader(1);
1570 ol.parseText(s);
1571 ol.endGroupHeader(1);
1572 }
1573 ol.popGeneratorState();
1574
1575 // part 2: the header and detailed description
1576 for (eli.toFirst();(lde=eli.current());++eli)
1577 {
1578 switch (lde->kind())
1579 {
1580 case LayoutDocEntry::BriefDesc:
1581 {
1582 // since we already shown the brief description in the
1583 // declaration part of the container, so we use this to
1584 // show the details on top.
1585 writeDetailedDocumentationBody(ol);
1586 }
1587 break;
1588 case LayoutDocEntry::ClassInheritanceGraph:
1589 writeInheritanceGraph(ol);
1590 break;
1591 case LayoutDocEntry::ClassCollaborationGraph:
1592 writeCollaborationGraph(ol);
1593 break;
1594 case LayoutDocEntry::MemberDeclStart:
1595 startMemberDeclarations(ol);
1596 break;
1597 case LayoutDocEntry::MemberDecl:
1598 {
1599 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1600 writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript,TRUE);
1601 }
1602 break;
1603 case LayoutDocEntry::MemberGroups:
1604 {
1605 writeMemberGroups(ol,TRUE);
1606 }
1607 break;
1608 case LayoutDocEntry::MemberDeclEnd:
1609 endMemberDeclarations(ol);
1610 break;
1611 case LayoutDocEntry::MemberDefStart:
1612 startMemberDocumentation(ol);
1613 break;
1614 case LayoutDocEntry::MemberDef:
1615 {
1616 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
1617 writeMemberDocumentation(ol,lmd->type,lmd->title,TRUE);
1618 }
1619 break;
1620 case LayoutDocEntry::MemberDefEnd:
1621 endMemberDocumentation(ol);
1622 break;
1623 default:
1624 break;
1625 }
1626 }
1627
1628 // part 3: close the block
1629 ol.pushGeneratorState();
1630 ol.disableAllBut(OutputGenerator::Html);
1631 { // HTML only
1632 ol.endIndent();
1633 }
1634 ol.popGeneratorState();
1635
1636 // part 4: write tag file information
1637 writeTagFileMarker(ol);
1638}
1639
1640void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
1641{
1642 // TODO: clean up this mess by moving it to
1643 // the output generators...
1644 static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
1645 static bool rtfHyperlinks = Config_getBool("RTF_HYPERLINKS");
1646 static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
1647
1648 // HTML only
1649 ol.pushGeneratorState();
1650 ol.disableAllBut(OutputGenerator::Html);
1651 ol.docify(" ");
1652 ol.startTextLink(getOutputFileBase(),
1653 anchor.isEmpty() ? QCString("details") : anchor);
1654 ol.parseText(theTranslator->trMore());
1655 ol.endTextLink();
1656 ol.popGeneratorState();
1657
1658 if (!anchor.isEmpty())
1659 {
1660 ol.pushGeneratorState();
1661 // LaTeX + RTF
1662 ol.disable(OutputGenerator::Html);
1663 ol.disable(OutputGenerator::Man);
1664 if (!(usePDFLatex && pdfHyperlinks))
1665 {
1666 ol.disable(OutputGenerator::Latex);
1667 }
1668 if (!rtfHyperlinks)
1669 {
1670 ol.disable(OutputGenerator::RTF);
1671 }
1672 ol.docify(" ");
1673 ol.startTextLink(getOutputFileBase(), anchor);
1674 ol.parseText(theTranslator->trMore());
1675 ol.endTextLink();
1676 // RTF only
1677 ol.disable(OutputGenerator::Latex);
1678 ol.writeString("\\par");
1679 ol.popGeneratorState();
1680 }
1681}
1682
1683
1684void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)
1685{
1686 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
1687 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1688 static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
1689 static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
1690 bool isLink = isLinkable();
1691 if (isLink ||
1692 (!hideUndocClasses &&
1693 (!isLocal() || extractLocalClasses)
1694 )
1695 )
1696 {
1697 if (!found) // first class
1698 {
1699 ol.startMemberHeader("nested-classes");
1700 if (header)
1701 {
1702 ol.parseText(header);
1703 }
1704 else if (vhdlOpt)
1705 {
1706 ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
1707 }
1708 else
1709 {
1710 ol.parseText(fortranOpt ? theTranslator->trDataTypes() :
1711 theTranslator->trCompounds());
1712 }
1713 ol.endMemberHeader();
1714 ol.startMemberList();
1715 found=TRUE;
1716 }
1717 if (!Config_getString("GENERATE_TAGFILE").isEmpty() &&
1718 !isReference()) // skip classes found in tag files
1719 {
1720 Doxygen::tagFile << " <class kind=\"" << compoundTypeString()
1721 << "\">" << convertToXML(name()) << "</class>" << endl;
1722 }
1723 ol.startMemberItem(FALSE);
1724 QCString ctype = compoundTypeString();
1725 QCString cname;
1726 if (localNames)
1727 {
1728 cname = localName();
1729 if (cname.right(2)=="-p" || cname.right(2)=="-g")
1730 {
1731 cname = cname.left(cname.length()-2);
1732 }
1733 }
1734 else
1735 {
1736 cname = displayName();
1737 }
1738
1739 if (!vhdlOpt) // for VHDL we swap the name and the type
1740 {
1741 ol.writeString(ctype);
1742 ol.writeString(" ");
1743 ol.insertMemberAlign();
1744 }
1745 if (isLink)
1746 {
1747 ol.writeObjectLink(getReference(),
1748 getOutputFileBase(),
1749 anchor(),
1750 cname
1751 );
1752 }
1753 else
1754 {
1755 ol.startBold();
1756 ol.docify(cname);
1757 ol.endBold();
1758 }
1759 if (vhdlOpt) // now write the type
1760 {
1761 ol.writeString(" ");
1762 ol.insertMemberAlign();
1763 VhdlDocGen::writeClassType(this,ol,cname);
1764 }
1765 ol.endMemberItem();
1766
1767 // add the brief description if available
1768 if (!briefDescription().isEmpty())
1769 {
1770 ol.startMemberDescription();
1771 ol.parseDoc(briefFile(),briefLine(),this,0,
1772 briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
1773 if (isLinkableInProject())
1774 {
1775 writeMoreLink(ol,anchor());
1776 }
1777 ol.endMemberDescription();
1778 }
1779 }
1780}
1781
1782void ClassDef::writeDocumentationContents(OutputList &ol,const QCString &pageTitle)
1783{
1784 ol.startContents();
1785
1786 QCString pageType = " ";
1787 pageType += compoundTypeString();
1788 toupper(pageType.at(1));
1789
1790 writeTagFileMarker(ol);
1791
1792 Doxygen::indexList.addIndexItem(this,0);
1793
1794 if (Doxygen::searchIndex)
1795 {
1796 Doxygen::searchIndex->setCurrentDoc(pageTitle,getOutputFileBase(),anchor());
1797 Doxygen::searchIndex->addWord(localName(),TRUE);
1798 }
1799 bool exampleFlag=hasExamples();
1800
1801 //---------------------------------------- start flexible part -------------------------------
1802
1803 QListIterator<LayoutDocEntry> eli(
1804 LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
1805 LayoutDocEntry *lde;
1806 for (eli.toFirst();(lde=eli.current());++eli)
1807 {
1808 switch (lde->kind())
1809 {
1810 case LayoutDocEntry::BriefDesc:
1811 writeBriefDescription(ol,exampleFlag);
1812 break;
1813 case LayoutDocEntry::ClassIncludes:
1814 writeIncludeFiles(ol);
1815 break;
1816 case LayoutDocEntry::ClassInheritanceGraph:
1817 writeInheritanceGraph(ol);
1818 break;
1819 case LayoutDocEntry::ClassCollaborationGraph:
1820 writeCollaborationGraph(ol);
1821 break;
1822 case LayoutDocEntry::ClassAllMembersLink:
1823 writeAllMembersLink(ol);
1824 break;
1825 case LayoutDocEntry::MemberDeclStart:
1826 startMemberDeclarations(ol);
1827 break;
1828 case LayoutDocEntry::MemberGroups:
1829 writeMemberGroups(ol);
1830 break;
1831 case LayoutDocEntry::MemberDecl:
1832 {
1833 LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
1834 writeMemberDeclarations(ol,lmd->type,lmd->title,lmd->subscript);
1835 }
1836 break;
1837 case LayoutDocEntry::ClassNestedClasses:
1838 {
1839 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1840 writeNestedClasses(ol,ls->title);
1841 }
1842 break;
1843 case LayoutDocEntry::MemberDeclEnd:
1844 endMemberDeclarations(ol);
1845 break;
1846 case LayoutDocEntry::DetailedDesc:
1847 {
1848 LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
1849 writeDetailedDescription(ol,pageType,exampleFlag,ls->title);
1850 }
1851 break;
1852 case LayoutDocEntry::MemberDefStart:
1853 startMemberDocumentation(ol);
1854 break;
1855 case LayoutDocEntry::MemberDef:
1856 {
1857 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
1858 writeMemberDocumentation(ol,lmd->type,lmd->title);
1859 }
1860 break;
1861 case LayoutDocEntry::MemberDefEnd:
1862 endMemberDocumentation(ol);
1863 break;
1864 case LayoutDocEntry::ClassUsedFiles:
1865 showUsedFiles(ol);
1866 break;
1867 case LayoutDocEntry::AuthorSection:
1868 writeAuthorSection(ol);
1869 break;
1870 case LayoutDocEntry::NamespaceNestedNamespaces:
1871 case LayoutDocEntry::NamespaceClasses:
1872 case LayoutDocEntry::FileClasses:
1873 case LayoutDocEntry::FileNamespaces:
1874 case LayoutDocEntry::FileIncludes:
1875 case LayoutDocEntry::FileIncludeGraph:
1876 case LayoutDocEntry::FileIncludedByGraph:
1877 case LayoutDocEntry::FileSourceLink:
1878 case LayoutDocEntry::GroupClasses:
1879 case LayoutDocEntry::GroupInlineClasses:
1880 case LayoutDocEntry::GroupNamespaces:
1881 case LayoutDocEntry::GroupDirs:
1882 case LayoutDocEntry::GroupNestedGroups:
1883 case LayoutDocEntry::GroupFiles:
1884 case LayoutDocEntry::GroupGraph:
1885 case LayoutDocEntry::GroupPageDocs:
1886 case LayoutDocEntry::DirSubDirs:
1887 case LayoutDocEntry::DirFiles:
1888 case LayoutDocEntry::DirGraph:
1889 err("Internal inconsistency: member %d should not be part of "
1890 "LayoutDocManager::Class entry list\n",lde->kind());
1891 break;
1892 }
1893 }
1894
1895 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1896 {
1897 writeDocAnchorsToTagFile();
1898 Doxygen::tagFile << " </compound>" << endl;
1899 }
1900 ol.endContents();
1901}
1902
1903// write all documentation for this class
1904void ClassDef::writeDocumentation(OutputList &ol)
1905{
1906 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1907 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
1908 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1909 QCString pageTitle;
1910
1911 if (fortranOpt)
1912 {
1913 pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),
1914 m_impl->compType,
1915 m_impl->tempArgs != 0);
1916 }
1917 else if (vhdlOpt)
1918 {
1919 // TODO: translate
1920 pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
1921 }
1922 else
1923 {
1924 pageTitle = theTranslator->trCompoundReference(displayName(),
1925 m_impl->compType == Interface && m_impl->lang==SrcLangExt_ObjC ? Class : m_impl->compType,
1926 m_impl->tempArgs != 0);
1927 }
1928
1929 startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView);
1930 if (!generateTreeView)
1931 {
1932 if (getOuterScope()!=Doxygen::globalScope)
1933 {
1934 writeNavigationPath(ol);
1935 }
1936 ol.endQuickIndices();
1937 }
1938
1939 startTitle(ol,getOutputFileBase(),this);
1940 ol.parseText(pageTitle);
1941 addGroupListToTitle(ol,this);
1942 endTitle(ol,getOutputFileBase(),name());
1943 writeDocumentationContents(ol,pageTitle);
1944
1945 if (generateTreeView)
1946 {
1947 writeNavigationPath(ol);
1948 }
1949
1950 endFile(ol,TRUE);
1951
1952 if (Config_getBool("SEPARATE_MEMBER_PAGES"))
1953 {
1954 writeMemberPages(ol);
1955 }
1956}
1957
1958void ClassDef::writeMemberPages(OutputList &ol)
1959{
1960 ///////////////////////////////////////////////////////////////////////////
1961 //// Member definitions on separate pages
1962 ///////////////////////////////////////////////////////////////////////////
1963
1964 ol.pushGeneratorState();
1965 ol.disableAllBut(OutputGenerator::Html);
1966
1967 QListIterator<MemberList> mli(m_impl->memberLists);
1968 MemberList *ml;
1969 for (mli.toFirst();(ml=mli.current());++mli)
1970 {
1971 if (ml->listType()&MemberList::detailedLists)
1972 {
1973 ml->writeDocumentationPage(ol,name(),this);
1974 }
1975 }
1976
1977 ol.popGeneratorState();
1978}
1979
1980void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
1981{
1982 static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
1983
1984 ol.writeString(" <div class=\"navtab\">\n");
1985 ol.writeString(" <table>\n");
1986
1987 if (m_impl->allMemberNameInfoSDict)
1988 {
1989 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
1990 MemberNameInfo *mni;
1991 for (;(mni=mnili.current());++mnili)
1992 {
1993 MemberNameInfoIterator mnii(*mni);
1994 MemberInfo *mi;
1995 for (mnii.toFirst();(mi=mnii.current());++mnii)
1996 {
1997 MemberDef *md=mi->memberDef;
1998 if (md->getClassDef()==this && md->isLinkable())
1999 {
2000 ol.writeString(" <tr><td class=\"navtab\">");
2001 if (md->isLinkableInProject())
2002 {
2003 if (md==currentMd) // selected item => highlight
2004 {
2005 ol.writeString("<a class=\"qindexHL\" ");
2006 }
2007 else
2008 {
2009 ol.writeString("<a class=\"qindex\" ");
2010 }
2011 ol.writeString("href=\"");
2012 if (createSubDirs) ol.writeString("../../");
2013 ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
2014 ol.writeString("\">");
2015 ol.writeString(md->name());
2016 ol.writeString("</a>");
2017 }
2018 ol.writeString("</td></tr>\n");
2019 }
2020 }
2021 }
2022 }
2023
2024 ol.writeString(" </table>\n");
2025 ol.writeString(" </div>\n");
2026}
2027
2028
2029
2030void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)
2031{
2032 // write inner classes after the parent, so the tag files contain
2033 // the definition in proper order!
2034 if (m_impl->innerClasses)
2035 {
2036 ClassSDict::Iterator cli(*m_impl->innerClasses);
2037 ClassDef *innerCd;
2038 for (cli.toFirst();(innerCd=cli.current());++cli)
2039 {
2040 if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
2041 (innerCd->protection()!=Private || Config_getBool("EXTRACT_PRIVATE"))
2042 )
2043 {
2044 msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
2045 innerCd->writeDocumentation(ol);
2046 innerCd->writeMemberList(ol);
2047 }
2048 innerCd->writeDocumentationForInnerClasses(ol);
2049 }
2050 }
2051}
2052
2053// write the list of all (inherited) members for this class
2054void ClassDef::writeMemberList(OutputList &ol)
2055{
2056 static bool cOpt = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
2057 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2058 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2059 if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
2060 // only for HTML
2061 ol.pushGeneratorState();
2062 ol.disableAllBut(OutputGenerator::Html);
2063
2064 QCString memListFile = getMemberListFileName();
2065 startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),
2066 HLI_ClassVisible,!generateTreeView,getOutputFileBase());
2067 if (!generateTreeView)
2068 {
2069 if (getOuterScope()!=Doxygen::globalScope)
2070 {
2071 writeNavigationPath(ol);
2072 }
2073 ol.endQuickIndices();
2074 }
2075 startTitle(ol,0);
2076 ol.parseText(displayName()+" "+theTranslator->trMemberList());
2077 endTitle(ol,0,0);
2078 ol.startContents();
2079 ol.parseText(theTranslator->trThisIsTheListOfAllMembers());
2080 ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),displayName());
2081 ol.parseText(theTranslator->trIncludingInheritedMembers());
2082
2083 //ol.startItemList();
2084 ol.writeString("<table>\n");
2085
2086 //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
2087 MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict);
2088 MemberNameInfo *mni;
2089 for (mnii.toFirst();(mni=mnii.current());++mnii)
2090 {
2091 MemberInfo *mi=mni->first();
2092 while (mi)
2093 {
2094 MemberDef *md=mi->memberDef;
2095 ClassDef *cd=md->getClassDef();
2096 Protection prot = mi->prot;
2097 Specifier virt=md->virtualness();
2098
2099 //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
2100 // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
2101
2102
2103 if (cd && !md->name().isEmpty() && md->name()[0]!='@')
2104 {
2105 bool memberWritten=FALSE;
2106 if (cd->isLinkable() && md->isLinkable())
2107 // create a link to the documentation
2108 {
2109 QCString name=mi->ambiguityResolutionScope+md->name();
2110 //ol.writeListItem();
2111 ol.writeString(" <tr class=\"memlist\"><td>");
2112 if (cd->isObjectiveC())
2113 {
2114 if (md->isObjCMethod())
2115 {
2116 if (md->isStatic())
2117 ol.writeString("+&#160;</td><td>");
2118 else
2119 ol.writeString("-&#160;</td><td>");
2120 }
2121 else
2122 ol.writeString("</td><td>");
2123 }
2124 if (md->isObjCMethod())
2125 {
2126 ol.writeObjectLink(md->getReference(),
2127 md->getOutputFileBase(),
2128 md->anchor(),md->name());
2129 }
2130 else
2131 {
2132 //Definition *bd = md->getGroupDef();
2133 //if (bd==0) bd=cd;
2134 ol.writeObjectLink(md->getReference(),
2135 md->getOutputFileBase(),
2136 md->anchor(),name);
2137
2138 if ( md->isFunction() || md->isSignal() || md->isSlot() ||
2139 (md->isFriend() && md->argsString()))
2140 ol.docify(md->argsString());
2141 else if (md->isEnumerate())
2142 ol.parseText(" "+theTranslator->trEnumName());
2143 else if (md->isEnumValue())
2144 ol.parseText(" "+theTranslator->trEnumValue());
2145 else if (md->isTypedef())
2146 ol.docify(" typedef");
2147 else if (md->isFriend() && !strcmp(md->typeString(),"friend class"))
2148 ol.docify(" class");
2149 //ol.writeString("\n");
2150 }
2151 ol.writeString("</td>");
2152 memberWritten=TRUE;
2153 }
2154 else if (!Config_getBool("HIDE_UNDOC_MEMBERS") &&
2155 (md->protection()!=Private || Config_getBool("EXTRACT_PRIVATE") || md->isFriend())
2156 ) // no documentation,
2157 // generate link to the class instead.
2158 {
2159 //ol.writeListItem();
2160 ol.writeString(" <tr bgcolor=\"#f0f0f0\"><td>");
2161 if (cd->isObjectiveC())
2162 {
2163 if (md->isObjCMethod())
2164 {
2165 if (md->isStatic())
2166 ol.writeString("+&#160;</td><td>");
2167 else
2168 ol.writeString("-&#160;</td><td>");
2169 }
2170 else
2171 ol.writeString("</td><td>");
2172 }
2173 ol.startBold();
2174 ol.docify(md->name());
2175 ol.endBold();
2176 if (!md->isObjCMethod())
2177 {
2178 if ( md->isFunction() || md->isSignal() || md->isSlot() )
2179 ol.docify(md->argsString());
2180 else if (md->isEnumerate())
2181 ol.parseText(" "+theTranslator->trEnumName());
2182 else if (md->isEnumValue())
2183 ol.parseText(" "+theTranslator->trEnumValue());
2184 else if (md->isTypedef())
2185 ol.docify(" typedef");
2186 }
2187 ol.writeString(" (");
2188 ol.parseText(theTranslator->trDefinedIn()+" ");
2189 if (cd->isLinkable())
2190 {
2191 ol.writeObjectLink(
2192 cd->getReference(),
2193 cd->getOutputFileBase(),
2194 cd->anchor(),
2195 cd->displayName());
2196 }
2197 else
2198 {
2199 ol.startBold();
2200 ol.docify(cd->displayName());
2201 ol.endBold();
2202 }
2203 ol.writeString(")");
2204 ol.writeString("</td>");
2205 memberWritten=TRUE;
2206 }
2207 if (memberWritten)
2208 {
2209 ol.writeString("<td>");
2210 ol.writeObjectLink(cd->getReference(),
2211 cd->getOutputFileBase(),
2212 cd->anchor(),
2213 md->category() ?
2214 md->category()->displayName() :
2215 cd->displayName());
2216 ol.writeString("</td>");
2217 ol.writeString("<td>");
2218 }
2219 if (
2220 (prot!=Public || (virt!=Normal && m_impl->lang!=SrcLangExt_ObjC) ||
2221 md->isFriend() || md->isRelated() || md->isExplicit() ||
2222 md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
2223 md->isSignal() || md->isSlot() ||
2224 md->isStatic() || vhdlOpt
2225 )
2226 && memberWritten)
2227 {
2228 ol.startTypewriter();
2229 ol.docify(" [");
2230 QStrList sl;
2231 if (vhdlOpt) sl.append(VhdlDocGen::trVhdlType(
2232 md->getMemberSpecifiers())); //append vhdl type
2233 else if (md->isFriend()) sl.append("friend");
2234 else if (md->isRelated()) sl.append("related");
2235 else
2236 {
2237 if (Config_getBool("INLINE_INFO") && md->isInline())
2238 sl.append("inline");
2239 if (md->isExplicit()) sl.append("explicit");
2240 if (md->isMutable()) sl.append("mutable");
2241 if (prot==Protected) sl.append("protected");
2242 else if (prot==Private) sl.append("private");
2243 else if (prot==Package) sl.append("package");
2244 if (virt==Virtual &&
2245 m_impl->lang!=SrcLangExt_ObjC) sl.append("virtual");
2246 else if (virt==Pure) sl.append("pure virtual");
2247 if (md->isStatic()) sl.append("static");
2248 if (md->isSignal()) sl.append("signal");
2249 if (md->isSlot()) sl.append("slot");
2250 }
2251 const char *s=sl.first();
2252 while (s)
2253 {
2254 ol.docify(s);
2255 s=sl.next();
2256 if (s) ol.docify(", ");
2257 }
2258 ol.docify("]");
2259 ol.endTypewriter();
2260 }
2261 if (memberWritten)
2262 {
2263 ol.writeString("</td>");
2264 ol.writeString("</tr>\n");
2265 }
2266 }
2267 mi=mni->next();
2268 }
2269 }
2270 //ol.endItemList();
2271
2272 ol.writeString("</table>");
2273
2274 endFile(ol);
2275 ol.popGeneratorState();
2276}
2277
2278
2279// add a reference to an example
2280bool ClassDef::addExample(const char *anchor,const char *nameStr,
2281 const char *file)
2282{
2283 if (m_impl->exampleSDict==0)
2284 {
2285 m_impl->exampleSDict = new ExampleSDict;
2286 m_impl->exampleSDict->setAutoDelete(TRUE);
2287 }
2288 if (!m_impl->exampleSDict->find(nameStr))
2289 {
2290 Example *e=new Example;
2291 e->anchor=anchor;
2292 e->name=nameStr;
2293 e->file=file;
2294 m_impl->exampleSDict->inSort(nameStr,e);
2295 return TRUE;
2296 }
2297 return FALSE;
2298}
2299
2300// returns TRUE if this class is used in an example
2301bool ClassDef::hasExamples()
2302{
2303 if (m_impl->exampleSDict==0)
2304 return FALSE;
2305 else
2306 return m_impl->exampleSDict->count()>0;
2307}
2308
2309
2310void ClassDef::setTemplateArguments(ArgumentList *al)
2311{
2312 if (al==0) return;
2313 if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
2314 m_impl->tempArgs=new ArgumentList;
2315 ArgumentListIterator ali(*al);
2316 Argument *a;
2317 for (;(a=ali.current());++ali)
2318 {
2319 m_impl->tempArgs->append(new Argument(*a));
2320 }
2321}
2322
2323void ClassDef::setTypeConstraints(ArgumentList *al)
2324{
2325 if (al==0) return;
2326 if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
2327 m_impl->typeConstraints = new ArgumentList;
2328 ArgumentListIterator ali(*al);
2329 Argument *a;
2330 for (;(a=ali.current());++ali)
2331 {
2332 m_impl->typeConstraints->append(new Argument(*a));
2333 }
2334}
2335
2336/*! Returns \c TRUE iff this class or a class inheriting from this class
2337 * is \e not defined in an external tag file.
2338 */
2339bool ClassDef::hasNonReferenceSuperClass()
2340{
2341 bool found=!isReference() && isLinkableInProject() && !isHidden();
2342 if (found)
2343 {
2344 return TRUE; // we're done if this class is not a reference
2345 }
2346 if (m_impl->inheritedBy)
2347 {
2348 BaseClassListIterator bcli(*m_impl->inheritedBy);
2349 for ( ; bcli.current() && !found ; ++bcli ) // for each super class
2350 {
2351 ClassDef *bcd=bcli.current()->classDef;
2352 // recurse into the super class branch
2353 found = found || bcd->hasNonReferenceSuperClass();
2354 if (!found)
2355 {
2356 // look for template instances that might have non-reference super classes
2357 QDict<ClassDef> *cil = bcd->getTemplateInstances();
2358 if (cil)
2359 {
2360 QDictIterator<ClassDef> tidi(*cil);
2361 for ( ; tidi.current() && !found ; ++tidi) // for each template instance
2362 {
2363 // recurse into the template instance branch
2364 found = found || tidi.current()->hasNonReferenceSuperClass();
2365 }
2366 }
2367 }
2368 }
2369 }
2370 return found;
2371}
2372
2373/*! called from MemberDef::writeDeclaration() to (recusively) write the
2374 * definition of an anonymous struct, union or class.
2375 */
2376void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup)
2377{
2378 //ol.insertMemberAlign();
2379 //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
2380
2381 //if (inGroup && md && md->getClassDef()==this) return;
2382
2383 ol.docify(compoundTypeString());
2384 int ri=name().findRev("::");
2385 if (ri==-1) ri=name().length();
2386 QCString cn=name().right(name().length()-ri-2);
2387 if (!cn.isEmpty() && cn.at(0)!='@' && md)
2388 {
2389 if (cn.right(2)=="-p" || cn.right(2)=="-g")
2390 {
2391 cn = cn.left(cn.length()-2);
2392 }
2393 ol.docify(" ");
2394 if (isLinkable())
2395 {
2396 ol.writeObjectLink(0,0,md->anchor(),cn);
2397 }
2398 else
2399 {
2400 ol.startBold();
2401 ol.docify(cn);
2402 ol.endBold();
2403 }
2404 }
2405 ol.docify(" {");
2406 ol.endMemberItem();
2407
2408 // write user defined member groups
2409 if (m_impl->memberGroupSDict)
2410 {
2411 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
2412 MemberGroup *mg;
2413 for (;(mg=mgli.current());++mgli)
2414 {
2415 mg->setInGroup(inGroup);
2416 mg->writePlainDeclarations(ol,this,0,0,0);
2417 }
2418 }
2419
2420 writePlainMemberDeclaration(ol,MemberList::pubTypes,inGroup);
2421 writePlainMemberDeclaration(ol,MemberList::pubMethods,inGroup);
2422 writePlainMemberDeclaration(ol,MemberList::pubAttribs,inGroup);
2423 writePlainMemberDeclaration(ol,MemberList::pubSlots,inGroup);
2424 writePlainMemberDeclaration(ol,MemberList::signals,inGroup);
2425 writePlainMemberDeclaration(ol,MemberList::dcopMethods,inGroup);
2426 writePlainMemberDeclaration(ol,MemberList::properties,inGroup);
2427 writePlainMemberDeclaration(ol,MemberList::events,inGroup);
2428 writePlainMemberDeclaration(ol,MemberList::pubStaticMethods,inGroup);
2429 writePlainMemberDeclaration(ol,MemberList::pubStaticAttribs,inGroup);
2430 writePlainMemberDeclaration(ol,MemberList::proTypes,inGroup);
2431 writePlainMemberDeclaration(ol,MemberList::proMethods,inGroup);
2432 writePlainMemberDeclaration(ol,MemberList::proAttribs,inGroup);
2433 writePlainMemberDeclaration(ol,MemberList::proSlots,inGroup);
2434 writePlainMemberDeclaration(ol,MemberList::proStaticMethods,inGroup);
2435 writePlainMemberDeclaration(ol,MemberList::proStaticAttribs,inGroup);
2436 writePlainMemberDeclaration(ol,MemberList::pacTypes,inGroup);
2437 writePlainMemberDeclaration(ol,MemberList::pacMethods,inGroup);
2438 writePlainMemberDeclaration(ol,MemberList::pacAttribs,inGroup);
2439 writePlainMemberDeclaration(ol,MemberList::pacStaticMethods,inGroup);
2440 writePlainMemberDeclaration(ol,MemberList::pacStaticAttribs,inGroup);
2441 if (Config_getBool("EXTRACT_PRIVATE"))
2442 {
2443 writePlainMemberDeclaration(ol,MemberList::priTypes,inGroup);
2444 writePlainMemberDeclaration(ol,MemberList::priMethods,inGroup);
2445 writePlainMemberDeclaration(ol,MemberList::priAttribs,inGroup);
2446 writePlainMemberDeclaration(ol,MemberList::priSlots,inGroup);
2447 writePlainMemberDeclaration(ol,MemberList::priStaticMethods,inGroup);
2448 writePlainMemberDeclaration(ol,MemberList::priStaticAttribs,inGroup);
2449 }
2450 writePlainMemberDeclaration(ol,MemberList::friends,inGroup);
2451 writePlainMemberDeclaration(ol,MemberList::related,inGroup);
2452}
2453
2454/*! a link to this class is possible within this project */
2455bool ClassDef::isLinkableInProject() const
2456{
2457 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
2458 static bool extractLocal = Config_getBool("EXTRACT_LOCAL_CLASSES");
2459 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
2460 static bool hideUndoc = Config_getBool("HIDE_UNDOC_CLASSES");
2461 if (m_impl->templateMaster)
2462 {
2463 return m_impl->templateMaster->isLinkableInProject();
2464 }
2465 else
2466 {
2467 return !name().isEmpty() && /* has a name */
2468 !isArtificial() && !isHidden() && /* not hidden */
2469 name().find('@')==-1 && /* not anonymous */
2470 (m_impl->prot!=Private || extractPrivate) && /* private */
2471 (!m_impl->isLocal || extractLocal) && /* local */
2472 (hasDocumentation() || !hideUndoc) && /* documented */
2473 (!m_impl->isStatic || extractStatic) && /* static */
2474 !isReference(); /* not an external reference */
2475 }
2476}
2477
2478bool ClassDef::isLinkable() const
2479{
2480 if (m_impl->templateMaster)
2481 {
2482 return m_impl->templateMaster->isLinkable();
2483 }
2484 else
2485 {
2486 return isLinkableInProject() || isReference();
2487 }
2488}
2489
2490
2491/*! the class is visible in a class diagram, or class hierarchy */
2492bool ClassDef::isVisibleInHierarchy()
2493{
2494 static bool allExternals = Config_getBool("ALLEXTERNALS");
2495 static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
2496 static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
2497 static bool extractStatic = Config_getBool("EXTRACT_STATIC");
2498
2499 return // show all classes or a subclass is visible
2500 (allExternals || hasNonReferenceSuperClass()) &&
2501 // and not an anonymous compound
2502 name().find('@')==-1 &&
2503 // not an artificially introduced class
2504 !isArtificial() &&
2505 // and not privately inherited
2506 (m_impl->prot!=Private || extractPrivate) &&
2507 // documented or shown anyway or documentation is external
2508 (hasDocumentation() ||
2509 !hideUndocClasses ||
2510 (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) ||
2511 isReference()
2512 ) &&
2513 // is not part of an unnamed namespace or shown anyway
2514 (!m_impl->isStatic || extractStatic);
2515}
2516
2517bool ClassDef::hasDocumentation() const
2518{
2519 return Definition::hasDocumentation();
2520}
2521
2522//----------------------------------------------------------------------
2523// recursive function:
2524// returns TRUE iff class definition `bcd' represents an (in)direct base
2525// class of class definition `cd'.
2526
2527bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
2528{
2529 bool found=FALSE;
2530 //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
2531 if (level>256)
2532 {
2533 err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(name()),qPrint(bcd->name()));
2534 abort();
2535 return FALSE;
2536 }
2537 if (baseClasses())
2538 {
2539 // Beware: trying to optimise the iterator away using ->first() & ->next()
2540 // causes bug 625531
2541 BaseClassListIterator bcli(*baseClasses());
2542 for ( ; bcli.current() && !found ; ++bcli)
2543 {
2544 ClassDef *ccd=bcli.current()->classDef;
2545 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
2546 //printf("isBaseClass() baseclass %s\n",ccd->name().data());
2547 if (ccd==bcd)
2548 found=TRUE;
2549 else
2550 found=ccd->isBaseClass(bcd,followInstances,level+1);
2551 }
2552 }
2553 return found;
2554}
2555
2556//----------------------------------------------------------------------------
2557
2558static bool isStandardFunc(MemberDef *md)
2559{
2560 return md->name()=="operator=" || // assignment operator
2561 md->isConstructor() || // constructor
2562 md->isDestructor(); // destructor
2563}
2564
2565/*!
2566 * recusively merges the `all members' lists of a class base
2567 * with that of this class. Must only be called for classes without
2568 * subclasses!
2569 */
2570void ClassDef::mergeMembers()
2571{
2572 if (m_impl->membersMerged) return;
2573
2574 static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
2575 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2576 QCString sep="::";
2577 if (optimizeOutputForJava || vhdlOpt) sep=".";
2578 int sepLen = sep.length();
2579
2580 m_impl->membersMerged=TRUE;
2581 //printf(" mergeMembers for %s\n",name().data());
2582 bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );
2583 if (baseClasses())
2584 {
2585 //printf(" => has base classes!\n");
2586 BaseClassListIterator bcli(*baseClasses());
2587 BaseClassDef *bcd;
2588 for ( ; (bcd=bcli.current()) ; ++bcli )
2589 {
2590 ClassDef *bClass=bcd->classDef;
2591
2592 // merge the members in the base class of this inheritance branch first
2593 bClass->mergeMembers();
2594
2595 MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
2596 MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
2597
2598 if (srcMnd)
2599 {
2600 MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
2601 MemberNameInfo *srcMni;
2602 for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
2603 {
2604 //printf(" Base member name %s\n",srcMni->memberName());
2605 MemberNameInfo *dstMni;
2606 if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
2607 // a member with that name is already in the class.
2608 // the member may hide or reimplement the one in the sub class
2609 // or there may be another path to the base class that is already
2610 // visited via another branch in the class hierarchy.
2611 {
2612 MemberNameInfoIterator srcMnii(*srcMni);
2613 MemberInfo *srcMi;
2614 for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
2615 {
2616 MemberDef *srcMd = srcMi->memberDef;
2617 bool found=FALSE;
2618 bool ambigue=FALSE;
2619 bool hidden=FALSE;
2620 MemberNameInfoIterator dstMnii(*dstMni);
2621 MemberInfo *dstMi;
2622 ClassDef *srcCd = srcMd->getClassDef();
2623 for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
2624 {
2625 MemberDef *dstMd = dstMi->memberDef;
2626 if (srcMd!=dstMd) // different members
2627 {
2628 ClassDef *dstCd = dstMd->getClassDef();
2629 //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
2630 if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
2631 // member is in the same or a base class
2632 {
2633 LockingPtr<ArgumentList> srcAl = srcMd->argumentList();
2634 LockingPtr<ArgumentList> dstAl = dstMd->argumentList();
2635 found=matchArguments2(
2636 srcMd->getOuterScope(),srcMd->getFileDef(),srcAl.pointer(),
2637 dstMd->getOuterScope(),dstMd->getFileDef(),dstAl.pointer(),
2638 TRUE
2639 );
2640 //printf(" Yes, matching (%s<->%s): %d\n",
2641 // argListToString(srcMd->argumentList()).data(),
2642 // argListToString(dstMd->argumentList()).data(),
2643 // found);
2644 hidden = hidden || !found;
2645 }
2646 else // member is in a non base class => multiple inheritance
2647 // using the same base class.
2648 {
2649 //printf("$$ Existing member %s %s add scope %s\n",
2650 // dstMi->ambiguityResolutionScope.data(),
2651 // dstMd->name().data(),
2652 // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2653
2654 QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2655 if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2656 dstMi->ambiguityResolutionScope.prepend(scope);
2657 ambigue=TRUE;
2658 }
2659 }
2660 else // same members
2661 {
2662 // do not add if base class is virtual or
2663 // if scope paths are equal or
2664 // if base class is an interface (and thus implicitly virtual).
2665 //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
2666 if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
2667 bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
2668 dstMd->getClassDef()->compoundType()==Interface
2669 )
2670 {
2671 found=TRUE;
2672 }
2673 else // member can be reached via multiple paths in the
2674 // inheritance tree
2675 {
2676 //printf("$$ Existing member %s %s add scope %s\n",
2677 // dstMi->ambiguityResolutionScope.data(),
2678 // dstMd->name().data(),
2679 // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
2680
2681 QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
2682 if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
2683 {
2684 dstMi->ambiguityResolutionScope.prepend(scope);
2685 }
2686 ambigue=TRUE;
2687 }
2688 }
2689 }
2690 //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
2691 // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
2692
2693 // TODO: fix the case where a member is hidden by inheritance
2694 // of a member with the same name but with another prototype,
2695 // while there is more than one path to the member in the
2696 // base class due to multiple inheritance. In this case
2697 // it seems that the member is not reachable by prefixing a
2698 // scope name either (according to my compiler). Currently,
2699 // this case is shown anyway.
2700 if (!found && srcMd->protection()!=Private)
2701 {
2702 Protection prot=srcMd->protection();
2703 if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
2704 else if (bcd->prot==Private) prot=bcd->prot;
2705
2706 if (inlineInheritedMembers)
2707 {
2708 if (!isStandardFunc(srcMd))
2709 {
2710 //printf(" insertMember `%s'\n",srcMd->name().data());
2711 internalInsertMember(srcMd,prot,FALSE);
2712 }
2713 }
2714
2715 Specifier virt=srcMi->virt;
2716 if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
2717
2718 MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
2719 newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
2720 if (ambigue)
2721 {
2722 //printf("$$ New member %s %s add scope %s::\n",
2723 // srcMi->ambiguityResolutionScope.data(),
2724 // srcMd->name().data(),
2725 // bClass->name().data());
2726
2727 QCString scope=bClass->name()+sep;
2728 if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
2729 {
2730 newMi->ambiguityResolutionScope=
2731 scope+srcMi->ambiguityResolutionScope.copy();
2732 }
2733 }
2734 if (hidden)
2735 {
2736 if (srcMi->ambigClass==0)
2737 {
2738 newMi->ambigClass=bClass;
2739 newMi->ambiguityResolutionScope=bClass->name()+sep;
2740 }
2741 else
2742 {
2743 newMi->ambigClass=srcMi->ambigClass;
2744 newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
2745 }
2746 }
2747 dstMni->append(newMi);
2748 }
2749 }
2750 }
2751 else // base class has a member that is not in the sub class => copy
2752 {
2753 // create a deep copy of the list (only the MemberInfo's will be
2754 // copied, not the actual MemberDef's)
2755 MemberNameInfo *newMni = 0;
2756 newMni = new MemberNameInfo(srcMni->memberName());
2757
2758 // copy the member(s) from the base to the sub class
2759 MemberNameInfoIterator mnii(*srcMni);
2760 MemberInfo *mi;
2761 for (;(mi=mnii.current());++mnii)
2762 {
2763 Protection prot = mi->prot;
2764 if (bcd->prot==Protected)
2765 {
2766 if (prot==Public) prot=Protected;
2767 }
2768 else if (bcd->prot==Private)
2769 {
2770 prot=Private;
2771 }
2772 //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
2773 // name().data(),mi->memberDef->name().data(),mi->prot,
2774 // bcd->prot,prot);
2775
2776 if (mi->prot!=Private)
2777 {
2778 Specifier virt=mi->virt;
2779 if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
2780
2781 if (inlineInheritedMembers)
2782 {
2783 if (!isStandardFunc(mi->memberDef))
2784 {
2785 //printf(" insertMember `%s'\n",mi->memberDef->name().data());
2786 internalInsertMember(mi->memberDef,prot,FALSE);
2787 }
2788 }
2789 //printf("Adding!\n");
2790 MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
2791 newMi->scopePath=bClass->name()+sep+mi->scopePath;
2792 newMi->ambigClass=mi->ambigClass;
2793 newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
2794 newMni->append(newMi);
2795 }
2796 }
2797
2798 if (dstMnd==0)
2799 {
2800 m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
2801 m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
2802 dstMnd = m_impl->allMemberNameInfoSDict;
2803 }
2804 // add it to the dictionary
2805 dstMnd->append(newMni->memberName(),newMni);
2806 }
2807 }
2808 }
2809 }
2810 }
2811 //printf(" end mergeMembers\n");
2812}
2813
2814//----------------------------------------------------------------------------
2815
2816/*! Merges the members of a Objective-C category into this class.
2817 */
2818void ClassDef::mergeCategory(ClassDef *category)
2819{
2820 category->setCategoryOf(this);
2821 category->setArtificial(TRUE);
2822
2823 MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
2824 MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
2825
2826 if (srcMnd && dstMnd)
2827 {
2828 MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
2829 MemberNameInfo *srcMni;
2830 for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
2831 {
2832 MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
2833 if (dstMni) // method is already defined in the class
2834 {
2835 // TODO: we should remove the other member and insert this one.
2836 }
2837 else // new method name
2838 {
2839 // create a deep copy of the list
2840 MemberNameInfo *newMni = 0;
2841 newMni = new MemberNameInfo(srcMni->memberName());
2842
2843 // copy the member(s) from the category to this class
2844 MemberNameInfoIterator mnii(*srcMni);
2845 MemberInfo *mi;
2846 for (;(mi=mnii.current());++mnii)
2847 {
2848 //printf("Adding '%s'\n",mi->memberDef->name().data());
2849 MemberInfo *newMi=new MemberInfo(mi->memberDef,mi->prot,mi->virt,mi->inherited);
2850 newMi->scopePath=mi->scopePath;
2851 newMi->ambigClass=mi->ambigClass;
2852 newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;
2853 newMni->append(newMi);
2854 mi->memberDef->moveTo(this);
2855 mi->memberDef->setCategory(category);
2856 internalInsertMember(mi->memberDef,mi->prot,FALSE);
2857 }
2858
2859 // add it to the dictionary
2860 dstMnd->append(newMni->memberName(),newMni);
2861 }
2862 }
2863 }
2864}
2865
2866//----------------------------------------------------------------------------
2867
2868void ClassDef::addUsedClass(ClassDef *cd,const char *accessName)
2869{
2870 //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
2871 if (m_impl->usesImplClassDict==0)
2872 {
2873 m_impl->usesImplClassDict = new UsesClassDict(17);
2874 m_impl->usesImplClassDict->setAutoDelete(TRUE);
2875 }
2876 UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
2877 if (ucd==0)
2878 {
2879 ucd = new UsesClassDef(cd);
2880 m_impl->usesImplClassDict->insert(cd->name(),ucd);
2881 //printf("Adding used class %s to class %s via accessor %s\n",
2882 // cd->name().data(),name().data(),accessName);
2883 }
2884 ucd->addAccessor(accessName);
2885}
2886
2887void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName)
2888{
2889 //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
2890 if (m_impl->usedByImplClassDict==0)
2891 {
2892 m_impl->usedByImplClassDict = new UsesClassDict(17);
2893 m_impl->usedByImplClassDict->setAutoDelete(TRUE);
2894 }
2895 UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
2896 if (ucd==0)
2897 {
2898 ucd = new UsesClassDef(cd);
2899 m_impl->usedByImplClassDict->insert(cd->name(),ucd);
2900 //printf("Adding used by class %s to class %s\n",
2901 // cd->name().data(),name().data());
2902 }
2903 ucd->addAccessor(accessName);
2904}
2905
2906
2907#if 0
2908/*! Builds up a dictionary of all classes that are used by the state of this
2909 * class (the "implementation").
2910 * Must be called before mergeMembers() is called!
2911 */
2912
2913void ClassDef::determineImplUsageRelation()
2914{
2915 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
2916 MemberNameInfo *mni;
2917 for (;(mni=mnili.current());++mnili)
2918 {
2919 MemberNameInfoIterator mnii(*mni);
2920 MemberInfo *mi;
2921 for (mnii.toFirst();(mi=mnii.current());++mnii)
2922 {
2923 MemberDef *md=mi->memberDef;
2924 if (md->isVariable()) // for each member variable in this class
2925 {
2926 QCString type=removeRedundantWhiteSpace(md->typeString());
2927 //printf("in class %s found var type=`%s' name=`%s'\n",
2928 // name().data(),type.data(),md->name().data());
2929 int pos=0;
2930 QCString usedClassName;
2931 QCString templSpec;
2932 bool found=FALSE;
2933 while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
2934 {
2935 //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
2936 // check if usedClassName is a template argument of its class
2937 ClassDef *cd=md->getClassDef();
2938 if (cd && cd->templateArguments())
2939 {
2940 ArgumentListIterator ali(*cd->templateArguments());
2941 Argument *arg;
2942 int count=0;
2943 for (ali.toFirst();(arg=ali.current());++ali,++count)
2944 {
2945 if (arg->name==usedClassName) // type is a template argument
2946 {
2947 found=TRUE;
2948 if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257);
2949 cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
2950 usedClassName,ClassDef::Class);
2951 cd->setIsTemplateBaseClass(count);
2952 UsesClassDef *ucd = new UsesClassDef(cd);
2953 m_impl->usesImplClassDict->insert(cd->name(),ucd);
2954 ucd->templSpecifiers = templSpec;
2955 ucd->addAccessor(md->name());
2956 Doxygen::hiddenClasses.append(cd);
2957 //printf("Adding used template argument %s to class %s\n",
2958 // cd->name().data(),name().data());
2959 //printf("Adding accessor %s to class %s\n",
2960 // md->name().data(),ucd->classDef->name().data());
2961 }
2962 }
2963 }
2964
2965 if (!found)
2966 {
2967 cd=0;
2968 if (getNamespaceDef()!=0)
2969 {
2970 cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
2971 }
2972 if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
2973 if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try inbetween scopes!
2974 //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
2975 if (cd) // class exists
2976 {
2977 found=TRUE;
2978 if (m_impl->usesImplClassDict==0)
2979 {
2980 m_impl->usesImplClassDict = new UsesClassDict(257);
2981 m_impl->usesImplClassDict->setAutoDelete(TRUE);
2982 }
2983 UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
2984 if (ucd==0 || ucd->templSpecifiers!=templSpec)
2985 {
2986 ucd = new UsesClassDef(cd);
2987 m_impl->usesImplClassDict->insert(cd->name(),ucd);
2988 ucd->templSpecifiers = templSpec;
2989 //printf("Adding used class %s to class %s\n",
2990 // cd->name().data(),name().data());
2991 }
2992 ucd->addAccessor(md->name());
2993 //printf("Adding accessor %s to class %s\n",
2994 // md->name().data(),ucd->classDef->name().data());
2995 }
2996 }
2997 }
2998 }
2999 }
3000 }
3001#ifdef DUMP
3002 if (m_impl->usesClassDict)
3003 {
3004 msg("Class %s uses the following classes:\n",name().data());
3005 UsesClassDictIterator ucdi(*m_impl->usesClassDict);
3006 UsesClassDef *ucd;
3007 for (;(ucd=ucdi.current());++ucdi)
3008 {
3009 msg(" %s via ",ucd->classDef->name().data());
3010 QDictIterator<void> dvi(*ucd->accessors);
3011 const char *s;
3012 for (;(s=dvi.currentKey());++dvi)
3013 {
3014 msg("%s ",s);
3015 }
3016 msg("\n");
3017 }
3018 }
3019#endif
3020}
3021
3022//----------------------------------------------------------------------------
3023
3024// I have disabled this code because the graphs it renders quickly become
3025// too large to be of practical use.
3026
3027void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
3028{
3029 QCString type = typeStr;
3030 static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
3031 int p=0,i,l;
3032 while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
3033 {
3034 ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
3035 if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try inbetween scopes!
3036 if (cd && cd!=this && !isBaseClass(cd))
3037 {
3038 if (m_impl->usesIntfClassDict==0)
3039 {
3040 m_impl->usesIntfClassDict = new UsesClassDict(257);
3041 }
3042 UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
3043 if (ucd==0)
3044 {
3045 ucd = new UsesClassDef(cd);
3046 m_impl->usesIntfClassDict->insert(cd->name(),ucd);
3047 //printf("in class `%s' adding used intf class `%s'\n",
3048 // name().data(),cd->name().data());
3049 }
3050 ucd->addAccessor(md->name());
3051 //printf("in class `%s' adding accessor `%s' to class `%s'\n",
3052 // name().data(),md->name().data(),ucd->classDef->name().data());
3053 }
3054 p=i+l;
3055 }
3056}
3057
3058void ClassDef::determineIntfUsageRelation()
3059{
3060 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
3061 MemberNameInfo *mni;
3062 for (;(mni=mnili.current());++mnili)
3063 {
3064 MemberNameInfoIterator mnii(*mni);
3065 MemberInfo *mi;
3066 for (mnii.toFirst();(mi=mnii.current());++mnii)
3067 {
3068 MemberDef *md=mi->memberDef;
3069
3070 // compute the protection level for this member
3071 Protection protect=md->protection();
3072 if (mi->prot==Protected) // inherited protection
3073 {
3074 if (protect==Public) protect=Protected;
3075 else if (protect==Protected) protect=Private;
3076 }
3077
3078 if (!md->name().isEmpty() && md->name()[0]!='@' &&
3079 (mi->prot!=Private && protect!=Private)
3080 )
3081 {
3082 // add classes found in the return type
3083 addUsedInterfaceClasses(md,md->typeString());
3084 ArgumentList *al = md->argumentList();
3085 if (al) // member has arguments
3086 {
3087 // add classes found in the types of the argument list
3088 ArgumentListIterator ali(*al);
3089 Argument *a;
3090 for (;(a=ali.current());++ali)
3091 {
3092 if (!a->type.isEmpty() && a->type.at(0)!='@')
3093 {
3094 addUsedInterfaceClasses(md,a->type);
3095 }
3096 }
3097 }
3098 }
3099 }
3100 }
3101}
3102#endif
3103
3104QCString ClassDef::compoundTypeString() const
3105{
3106 if (m_impl->compType==Interface && m_impl->lang==SrcLangExt_ObjC) return "class";
3107 if (Config_getBool("OPTIMIZE_FOR_FORTRAN"))
3108 {
3109 switch (m_impl->compType)
3110 {
3111 case Class: return "module";
3112 case Struct: return "type";
3113 case Union: return "union";
3114 case Interface: return "interface";
3115 case Protocol: return "protocol";
3116 case Category: return "category";
3117 case Exception: return "exception";
3118 default: return "unknown";
3119 }
3120 }
3121 else
3122 {
3123 switch (m_impl->compType)
3124 {
3125 case Class: return "class";
3126 case Struct: return "struct";
3127 case Union: return "union";
3128 case Interface: return "interface";
3129 case Protocol: return "protocol";
3130 case Category: return "category";
3131 case Exception: return "exception";
3132 default: return "unknown";
3133 }
3134 }
3135}
3136
3137QCString ClassDef::getXmlOutputFileBase() const
3138{
3139 if (m_impl->templateMaster)
3140 {
3141 // point to the template of which this class is an instance
3142 return m_impl->templateMaster->getOutputFileBase();
3143 }
3144 else if (isReference())
3145 {
3146 // point to the external location
3147 return m_impl->fileName;
3148 }
3149 else
3150 {
3151 // normal locally defined class
3152 return convertNameToFile(m_impl->fileName);
3153 }
3154}
3155
3156QCString ClassDef::getOutputFileBase() const
3157{
3158 static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
3159 if (inlineGroupedClasses && partOfGroups()!=0)
3160 {
3161 // point to the group that embeds this class
3162 return partOfGroups()->at(0)->getOutputFileBase();
3163 }
3164 else
3165 {
3166 return getXmlOutputFileBase();
3167 }
3168}
3169
3170QCString ClassDef::getInstanceOutputFileBase() const
3171{
3172 if (isReference())
3173 {
3174 return m_impl->fileName;
3175 }
3176 else
3177 {
3178 return convertNameToFile(m_impl->fileName);
3179 }
3180}
3181
3182QCString ClassDef::getFileBase() const
3183{
3184 if (m_impl->templateMaster)
3185 {
3186 return m_impl->templateMaster->getFileBase();
3187 }
3188 else
3189 {
3190 return m_impl->fileName;
3191 }
3192}
3193
3194QCString ClassDef::getSourceFileBase() const
3195{
3196 if (m_impl->templateMaster)
3197 {
3198 return m_impl->templateMaster->getSourceFileBase();
3199 }
3200 else
3201 {
3202 return convertNameToFile(m_impl->fileName)+"_source";
3203 }
3204}
3205
3206void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
3207{
3208 gd->addClass(this);
3209 //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
3210 if (m_impl->allMemberNameInfoSDict==0) return;
3211 MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
3212 MemberNameInfo *mni;
3213 for (;(mni=mnili.current());++mnili)
3214 {
3215 MemberNameInfoIterator mnii(*mni);
3216 MemberInfo *mi;
3217 for (mnii.toFirst();(mi=mnii.current());++mnii)
3218 {
3219 MemberDef *md=mi->memberDef;
3220 md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
3221 gd->insertMember(md,TRUE);
3222 ClassDef *innerClass = md->getClassDefOfAnonymousType();
3223 if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
3224 }
3225 }
3226}
3227
3228void ClassDef::addInnerCompound(Definition *d)
3229{
3230 //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
3231 if (d->definitionType()==Definition::TypeClass) // only classes can be
3232 // nested in classes.
3233 {
3234 if (m_impl->innerClasses==0)
3235 {
3236 m_impl->innerClasses = new ClassSDict(17);
3237 }
3238 m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);
3239 }
3240}
3241
3242Definition *ClassDef::findInnerCompound(const char *name)
3243{
3244 Definition *result=0;
3245 if (name==0) return 0;
3246 if (m_impl->innerClasses)
3247 {
3248 result = m_impl->innerClasses->find(name);
3249 }
3250 return result;
3251}
3252
3253//void ClassDef::initTemplateMapping()
3254//{
3255// m_impl->templateMapping->clear();
3256// ArgumentList *al = templateArguments();
3257// if (al)
3258// {
3259// ArgumentListIterator ali(*al);
3260// Argument *arg;
3261// for (ali.toFirst();(arg=ali.current());++ali)
3262// {
3263// setTemplateArgumentMapping(arg->name,arg->defval);
3264// }
3265// }
3266//}
3267//void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
3268//{
3269// //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
3270// if (m_impl->templateMapping && formal)
3271// {
3272// if (m_impl->templateMapping->find(formal))
3273// {
3274// m_impl->templateMapping->remove(formal);
3275// }
3276// m_impl->templateMapping->insert(formal,new QCString(actual));
3277// }
3278//}
3279//
3280//QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
3281//{
3282// if (m_impl->templateMapping && formal)
3283// {
3284// QCString *s = m_impl->templateMapping->find(formal);
3285// if (s)
3286// {
3287// return *s;
3288// }
3289// }
3290// return "";
3291//}
3292
3293ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
3294 int startLine, const QCString &templSpec,bool &freshInstance)
3295{
3296 freshInstance = FALSE;
3297 if (m_impl->templateInstances==0)
3298 {
3299 m_impl->templateInstances = new QDict<ClassDef>(17);
3300 }
3301 ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
3302 if (templateClass==0)
3303 {
3304 Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data());
3305 templateClass = new ClassDef(
3306 fileName,startLine,localName()+templSpec,ClassDef::Class);
3307 templateClass->setTemplateMaster(this);
3308 templateClass->setOuterScope(getOuterScope());
3309 templateClass->setHidden(isHidden());
3310 m_impl->templateInstances->insert(templSpec,templateClass);
3311 freshInstance=TRUE;
3312 }
3313 return templateClass;
3314}
3315
3316ClassDef *ClassDef::getVariableInstance(const char *templSpec)
3317{
3318 if (m_impl->variableInstances==0)
3319 {
3320 m_impl->variableInstances = new QDict<ClassDef>(17);
3321 m_impl->variableInstances->setAutoDelete(TRUE);
3322 }
3323 ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
3324 if (templateClass==0)
3325 {
3326 Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
3327 templateClass = new ClassDef("<code>",1,name()+templSpec,
3328 ClassDef::Class,0,0,FALSE);
3329 templateClass->addMembersToTemplateInstance( this, templSpec );
3330 templateClass->setTemplateMaster(this);
3331 m_impl->variableInstances->insert(templSpec,templateClass);
3332 }
3333 return templateClass;
3334}
3335
3336void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
3337{
3338 if (templateNames==0) return;
3339 if (m_impl->templBaseClassNames==0)
3340 {
3341 m_impl->templBaseClassNames = new QDict<int>(17);
3342 m_impl->templBaseClassNames->setAutoDelete(TRUE);
3343 }
3344 // make a deep copy of the dictionary.
3345 QDictIterator<int> qdi(*templateNames);
3346 for (;qdi.current();++qdi)
3347 {
3348 if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
3349 {
3350 m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
3351 }
3352 }
3353}
3354
3355QDict<int> *ClassDef::getTemplateBaseClassNames() const
3356{
3357 return m_impl->templBaseClassNames;
3358}
3359
3360void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
3361{
3362 //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
3363 if (cd->memberNameInfoSDict()==0) return;
3364 MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());
3365 MemberNameInfo *mni;
3366 for (;(mni=mnili.current());++mnili)
3367 {
3368 MemberNameInfoIterator mnii(*mni);
3369 MemberInfo *mi;
3370 for (mnii.toFirst();(mi=mnii.current());++mnii)
3371 {
3372 ArgumentList *actualArguments = new ArgumentList;
3373 stringToArgumentList(templSpec,actualArguments);
3374 MemberDef *md = mi->memberDef;
3375 MemberDef *imd = md->createTemplateInstanceMember(
3376 cd->templateArguments(),actualArguments);
3377 delete actualArguments;
3378 //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
3379 imd->setMemberClass(this);
3380 imd->setTemplateMaster(md);
3381 imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
3382 imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
3383 imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
3384 imd->setMemberSpecifiers(md->getMemberSpecifiers());
3385 imd->setMemberGroupId(md->getMemberGroupId());
3386 insertMember(imd);
3387 //printf("Adding member=%s %s%s to class %s templSpec %s\n",
3388 // imd->typeString(),imd->name().data(),imd->argsString(),
3389 // imd->getClassDef()->name().data(),templSpec);
3390 // insert imd in the list of all members
3391 //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
3392 MemberName *mn = Doxygen::memberNameSDict->find(imd->name());
3393 if (mn==0)
3394 {
3395 mn = new MemberName(imd->name());
3396 Doxygen::memberNameSDict->append(imd->name(),mn);
3397 }
3398 mn->append(imd);
3399 }
3400 }
3401}
3402
3403QCString ClassDef::getReference() const
3404{
3405 if (m_impl->templateMaster)
3406 {
3407 return m_impl->templateMaster->getReference();
3408 }
3409 else
3410 {
3411 return Definition::getReference();
3412 }
3413}
3414
3415bool ClassDef::isReference() const
3416{
3417 if (m_impl->templateMaster)
3418 {
3419 return m_impl->templateMaster->isReference();
3420 }
3421 else
3422 {
3423 return Definition::isReference();
3424 }
3425}
3426
3427void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
3428{
3429 Definition *d=getOuterScope();
3430 if (d)
3431 {
3432 if (d->definitionType()==Definition::TypeClass)
3433 {
3434 ClassDef *cd=(ClassDef *)d;
3435 cd->getTemplateParameterLists(lists);
3436 }
3437 }
3438 if (templateArguments())
3439 {
3440 lists.append(templateArguments());
3441 }
3442}
3443
3444QCString ClassDef::qualifiedNameWithTemplateParameters(
3445 QList<ArgumentList> *actualParams) const
3446{
3447 static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
3448 static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
3449 //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
3450 QCString scName;
3451 Definition *d=getOuterScope();
3452 if (d)
3453 {
3454 if (d->definitionType()==Definition::TypeClass)
3455 {
3456 ClassDef *cd=(ClassDef *)d;
3457 scName = cd->qualifiedNameWithTemplateParameters(actualParams);
3458 }
3459 else if (!hideScopeNames)
3460 {
3461 scName = d->qualifiedName();
3462 }
3463 }
3464
3465 QCString scopeSeparator;
3466 if (optimizeOutputJava)
3467 scopeSeparator=".";
3468 else
3469 scopeSeparator="::";
3470
3471 if (!scName.isEmpty()) scName+=scopeSeparator;
3472
3473 bool isSpecialization = localName().find('<')!=-1;
3474 bool isGeneric = m_impl->lang==SrcLangExt_CSharp;
3475
3476 QCString clName = className();
3477 if (isGeneric && clName.right(2)=="-g")
3478 {
3479 clName = clName.left(clName.length()-2);
3480 }
3481 //printf("m_impl->lang=%d clName=%s\n",m_impl->lang,clName.data());
3482 scName+=clName;
3483 ArgumentList *al=0;
3484 if (templateArguments())
3485 {
3486 if (actualParams && (al=actualParams->current()))
3487 {
3488 if (!isSpecialization)
3489 {
3490 scName+=tempArgListToString(al);
3491 }
3492 actualParams->next();
3493 }
3494 else
3495 {
3496 if (!isSpecialization)
3497 {
3498 scName+=tempArgListToString(templateArguments());
3499 }
3500 }
3501 }
3502 //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
3503 return scName;
3504}
3505
3506QCString ClassDef::className() const
3507{
3508 if (m_impl->className.isEmpty())
3509 {
3510 return localName();
3511 }
3512 else
3513 {
3514 return m_impl->className;
3515 }
3516};
3517
3518void ClassDef::setClassName(const char *name)
3519{
3520 m_impl->className = name;
3521}
3522
3523void ClassDef::addListReferences()
3524{
3525 bool fortranOpt=Config_getBool("OPTIMIZE_FOR_FORTRAN");
3526 if (!isLinkableInProject()) return;
3527 //printf("ClassDef(%s)::addListReferences()\n",name().data());
3528 {
3529 LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
3530 addRefItem(xrefItems.pointer(),
3531 qualifiedName(),
3532 fortranOpt?theTranslator->trType(TRUE,TRUE):
3533 theTranslator->trClass(TRUE,TRUE),
3534 getOutputFileBase(),
3535 displayName(),
3536 0
3537 );
3538 }
3539 if (m_impl->memberGroupSDict)
3540 {
3541 MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
3542 MemberGroup *mg;
3543 for (;(mg=mgli.current());++mgli)
3544 {
3545 mg->addListReferences(this);
3546 }
3547 }
3548 QListIterator<MemberList> mli(m_impl->memberLists);
3549 MemberList *ml;
3550 for (mli.toFirst();(ml=mli.current());++mli)
3551 {
3552 if (ml->listType()&MemberList::detailedLists)
3553 {
3554 ml->addListReferences(this);
3555 }
3556 }
3557}
3558
3559MemberDef *ClassDef::getMemberByName(const QCString &name) const
3560{
3561 MemberDef *xmd = 0;
3562 if (m_impl->allMemberNameInfoSDict)
3563 {
3564 MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);
3565 if (mni)
3566 {
3567 const int maxInheritanceDepth = 100000;
3568 int mdist=maxInheritanceDepth;
3569 MemberNameInfoIterator mnii(*mni);
3570 MemberInfo *mi;
3571 for (mnii.toFirst();(mi=mnii.current());++mnii)
3572 {
3573 ClassDef *mcd=mi->memberDef->getClassDef();
3574 int m=minClassDistance(this,mcd);
3575 //printf("found member in %s linkable=%d m=%d\n",
3576 // mcd->name().data(),mcd->isLinkable(),m);
3577 if (m<mdist && mcd->isLinkable())
3578 {
3579 mdist=m;
3580 xmd=mi->memberDef;
3581 }
3582 }
3583 }
3584 }
3585 //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
3586 return xmd;
3587}
3588
3589bool ClassDef::isAccessibleMember(MemberDef *md)
3590{
3591 return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
3592}
3593
3594MemberList *ClassDef::createMemberList(MemberList::ListType lt)
3595{
3596 m_impl->memberLists.setAutoDelete(TRUE);
3597 QListIterator<MemberList> mli(m_impl->memberLists);
3598 MemberList *ml;
3599 for (mli.toFirst();(ml=mli.current());++mli)
3600 {
3601 if (ml->listType()==lt)
3602 {
3603 return ml;
3604 }
3605 }
3606 // not found, create a new member list
3607 ml = new MemberList(lt);
3608 m_impl->memberLists.append(ml);
3609 return ml;
3610}
3611
3612MemberList *ClassDef::getMemberList(MemberList::ListType lt)
3613{
3614 MemberList *ml = m_impl->memberLists.first();
3615 while (ml)
3616 {
3617 if (ml->listType()==lt)
3618 {
3619 return ml;
3620 }
3621 ml = m_impl->memberLists.next();
3622 }
3623 return 0;
3624}
3625
3626void ClassDef::addMemberToList(MemberList::ListType lt,MemberDef *md,bool isBrief)
3627{
3628 static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
3629 static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
3630 MemberList *ml = createMemberList(lt);
3631 ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
3632 ml->append(md);
3633
3634 // for members in the declaration lists we set the section, needed for member grouping
3635 if ((ml->listType()&MemberList::detailedLists)==0) md->setSectionList(this,ml);
3636}
3637
3638void ClassDef::sortMemberLists()
3639{
3640 MemberList *ml = m_impl->memberLists.first();
3641 while (ml)
3642 {
3643 if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
3644 ml = m_impl->memberLists.next();
3645 }
3646}
3647
3648void ClassDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title,
3649 const char *subTitle,bool showInline)
3650{
3651 static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
3652 MemberList * ml = getMemberList(lt);
3653 if (ml)
3654 {
3655 if (optimizeVhdl) // use specific declarations function
3656 {
3657 VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0);
3658 }
3659 else // use generic declaration function
3660 {
3661 ml->writeDeclarations(ol,this,0,0,0,title,subTitle,FALSE,showInline);
3662 }
3663 }
3664}
3665
3666void ClassDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title,bool showInline)
3667{
3668 MemberList * ml = getMemberList(lt);
3669 if (ml) ml->writeDocumentation(ol,name(),this,title,FALSE,showInline);
3670}
3671
3672void ClassDef::writePlainMemberDeclaration(OutputList &ol,MemberList::ListType lt,bool inGroup)
3673{
3674 MemberList * ml = getMemberList(lt);
3675 if (ml)
3676 {
3677 ml->setInGroup(inGroup);
3678 ml->writePlainDeclarations(ol,this,0,0,0);
3679 }
3680}
3681
3682bool ClassDef::isLocal() const
3683{
3684 return m_impl->isLocal;
3685}
3686
3687ClassSDict *ClassDef::getInnerClasses()
3688{
3689 return m_impl->innerClasses;
3690}
3691
3692ClassDef::CompoundType ClassDef::compoundType() const
3693{
3694 return m_impl->compType;
3695}
3696
3697BaseClassList *ClassDef::baseClasses() const
3698{
3699 return m_impl->inherits;
3700}
3701
3702BaseClassList *ClassDef::subClasses() const
3703{
3704 return m_impl->inheritedBy;
3705}
3706
3707MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const
3708{
3709 return m_impl->allMemberNameInfoSDict;
3710}
3711
3712Protection ClassDef::protection() const
3713{
3714 return m_impl->prot;
3715}
3716
3717ArgumentList *ClassDef::templateArguments() const
3718{
3719 return m_impl->tempArgs;
3720}
3721
3722NamespaceDef *ClassDef::getNamespaceDef() const
3723{
3724 return m_impl->nspace;
3725}
3726
3727FileDef *ClassDef::getFileDef() const
3728{
3729 return m_impl->fileDef;
3730}
3731
3732QDict<ClassDef> *ClassDef::getTemplateInstances() const
3733{
3734 return m_impl->templateInstances;
3735}
3736
3737ClassDef *ClassDef::templateMaster() const
3738{
3739 return m_impl->templateMaster;
3740}
3741
3742bool ClassDef::isTemplate() const
3743{
3744 return m_impl->tempArgs!=0;
3745}
3746
3747IncludeInfo *ClassDef::includeInfo() const
3748{
3749 return m_impl->incInfo;
3750}
3751
3752UsesClassDict *ClassDef::usedImplementationClasses() const
3753{
3754 return m_impl->usesImplClassDict;
3755}
3756
3757UsesClassDict *ClassDef::usedByImplementationClasses() const
3758{
3759 return m_impl->usedByImplClassDict;
3760}
3761
3762UsesClassDict *ClassDef::usedInterfaceClasses() const
3763{
3764 return m_impl->usesIntfClassDict;
3765}
3766
3767bool ClassDef::isTemplateArgument() const
3768{
3769 return m_impl->isTemplArg;
3770}
3771
3772bool ClassDef::isAbstract() const
3773{
3774 return m_impl->isAbstract;
3775}
3776
3777bool ClassDef::isObjectiveC() const
3778{
3779 return m_impl->lang==SrcLangExt_ObjC;
3780}
3781
3782bool ClassDef::isCSharp() const
3783{
3784 return m_impl->lang==SrcLangExt_CSharp;
3785}
3786
3787ClassDef *ClassDef::categoryOf() const
3788{
3789 return m_impl->categoryOf;
3790}
3791
3792const QList<MemberList> &ClassDef::getMemberLists() const
3793{
3794 return m_impl->memberLists;
3795}
3796
3797MemberGroupSDict *ClassDef::getMemberGroupSDict() const
3798{
3799 return m_impl->memberGroupSDict;
3800}
3801
3802void ClassDef::setNamespace(NamespaceDef *nd)
3803{
3804 m_impl->nspace = nd;
3805}
3806
3807void ClassDef::setFileDef(FileDef *fd)
3808{
3809 m_impl->fileDef=fd;
3810}
3811
3812void ClassDef::setSubGrouping(bool enabled)
3813{
3814 m_impl->subGrouping = enabled;
3815}
3816
3817void ClassDef::setProtection(Protection p)
3818{
3819 m_impl->prot=p;
3820}
3821
3822void ClassDef::setIsStatic(bool b)
3823{
3824 m_impl->isStatic=b;
3825}
3826
3827void ClassDef::setLanguage(SrcLangExt lang)
3828{
3829 m_impl->lang=lang;
3830}
3831
3832void ClassDef::setCompoundType(CompoundType t)
3833{
3834 m_impl->compType = t;
3835}
3836
3837void ClassDef::setTemplateMaster(ClassDef *tm)
3838{
3839 m_impl->templateMaster=tm;
3840}
3841
3842void ClassDef::makeTemplateArgument(bool b)
3843{
3844 m_impl->isTemplArg = b;
3845}
3846
3847void ClassDef::setCategoryOf(ClassDef *cd)
3848{
3849 m_impl->categoryOf = cd;
3850}
3851
3852void ClassDef::setUsedOnly(bool b)
3853{
3854 m_impl->usedOnly = b;
3855}
3856
3857bool ClassDef::isUsedOnly() const
3858{
3859 return m_impl->usedOnly;
3860}
3861
3862void ClassDef::reclassifyMember(MemberDef *md,MemberDef::MemberType t)
3863{
3864 md->setMemberType(t);
3865 MemberList *ml = m_impl->memberLists.first();
3866 while (ml)
3867 {
3868 ml->remove(md);
3869 ml = m_impl->memberLists.next();
3870 }
3871 insertMember(md);
3872}
3873
3874QCString ClassDef::anchor() const
3875{
3876 QCString anc;
3877 if (isEmbeddedInGroupDocs())
3878 {
3879 if (m_impl->templateMaster)
3880 {
3881 // point to the template of which this class is an instance
3882 anc = m_impl->templateMaster->getOutputFileBase();
3883 }
3884 else if (isReference())
3885 {
3886 // point to the external location
3887 anc = m_impl->fileName;
3888 }
3889 else
3890 {
3891 // normal locally defined class
3892 anc = convertNameToFile(m_impl->fileName);
3893 }
3894 }
3895 return anc;
3896}
3897
3898bool ClassDef::isEmbeddedInGroupDocs() const
3899{
3900 static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
3901 return (inlineGroupedClasses && partOfGroups()!=0);
3902}
3903
3904
3905

Archive Download this file

Revision: 1322