summaryrefslogtreecommitdiff
path: root/src/classdef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/classdef.cpp')
-rw-r--r--src/classdef.cpp4498
1 files changed, 4498 insertions, 0 deletions
diff --git a/src/classdef.cpp b/src/classdef.cpp
new file mode 100644
index 0000000..985c7b3
--- /dev/null
+++ b/src/classdef.cpp
@@ -0,0 +1,4498 @@
+/******************************************************************************
+ *
+ * $Id: classdef.cpp,v 1.54 2001/03/19 19:27:39 root Exp $
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdio.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include "classdef.h"
+#include "classlist.h"
+#include "entry.h"
+#include "doxygen.h"
+#include "membername.h"
+#include "message.h"
+#include "config.h"
+#include "util.h"
+#include "diagram.h"
+#include "language.h"
+#include "htmlhelp.h"
+#include "example.h"
+#include "outputlist.h"
+#include "dot.h"
+#include "defargs.h"
+#include "debug.h"
+#include "docparser.h"
+#include "searchindex.h"
+#include "vhdldocgen.h"
+#include "layout.h"
+#include "arguments.h"
+
+//-----------------------------------------------------------------------------
+
+/** Private data associated with a ClassDef object. */
+class ClassDefImpl
+{
+ public:
+ ClassDefImpl();
+ ~ClassDefImpl();
+ void init(const char *defFileName, const char *name,
+ const QCString &ctStr, const char *fName);
+
+ /*! file name that forms the base for the output file containing the
+ * class documentation. For compatibility with Qt (e.g. links via tag
+ * files) this name cannot be derived from the class name directly.
+ */
+ QCString fileName;
+
+ /*! Include information about the header file should be included
+ * in the documentation. 0 by default, set by setIncludeFile().
+ */
+ IncludeInfo *incInfo;
+
+ /*! List of base class (or super-classes) from which this class derives
+ * directly.
+ */
+ BaseClassList *inherits;
+
+ /*! List of sub-classes that directly derive from this class
+ */
+ BaseClassList *inheritedBy;
+
+ /*! Namespace this class is part of
+ * (this is the inner most namespace in case of nested namespaces)
+ */
+ NamespaceDef *nspace;
+
+ /*! File this class is defined in */
+ FileDef *fileDef;
+
+ /*! List of all members (including inherited members) */
+ MemberNameInfoSDict *allMemberNameInfoSDict;
+
+ /*! Template arguments of this class */
+ ArgumentList *tempArgs;
+
+ /*! Type constraints for template parameters */
+ ArgumentList *typeConstraints;
+
+ /*! Files that were used for generating the class documentation. */
+ QStrList files;
+
+ /*! Examples that use this class */
+ ExampleSDict *exampleSDict;
+
+ /*! Holds the kind of "class" this is. */
+ ClassDef::CompoundType compType;
+
+ /*! The protection level in which this class was found.
+ * Typically Public, but for nested classes this can also be Protected
+ * or Private.
+ */
+ Protection prot;
+
+ /*! The inner classes contained in this class. Will be 0 if there are
+ * no inner classes.
+ */
+ ClassSDict *innerClasses;
+
+ /* classes for the collaboration diagram */
+ UsesClassDict *usesImplClassDict;
+ UsesClassDict *usedByImplClassDict;
+ UsesClassDict *usesIntfClassDict;
+
+ /*! Template instances that exists of this class, the key in the
+ * dictionary is the template argument list.
+ */
+ QDict<ClassDef> *templateInstances;
+
+ /*! Template instances that exists of this class, as defined by variables.
+ * We do NOT want to document these individually. The key in the
+ * dictionary is the template argument list.
+ */
+ QDict<ClassDef> *variableInstances;
+
+ QDict<int> *templBaseClassNames;
+
+ /*! The class this class is an instance of. */
+ ClassDef *templateMaster;
+
+ /*! local class name which could be a typedef'ed alias name. */
+ QCString className;
+
+ /*! If this class is a Objective-C category, then this points to the
+ * class which is extended.
+ */
+ ClassDef *categoryOf;
+
+ QList<MemberList> memberLists;
+
+ /* user defined member groups */
+ MemberGroupSDict *memberGroupSDict;
+
+ /*! Is this an abstact class? */
+ bool isAbstract;
+
+ /*! Is the class part of an unnamed namespace? */
+ bool isStatic;
+
+ /*! TRUE if classes members are merged with those of the base classes. */
+ bool membersMerged;
+
+ /*! TRUE if the class is defined in a source file rather than a header file. */
+ bool isLocal;
+
+ bool isTemplArg;
+
+ /*! Does this class group its user-grouped members
+ * as a sub-section of the normal (public/protected/..)
+ * groups?
+ */
+ bool subGrouping;
+
+ /** Reason of existence is a "use" relation */
+ bool usedOnly;
+
+ /** List of titles to use for the summary */
+ SDict<QCString> vhdlSummaryTitles;
+
+ /** Is this a simple (non-nested) C structure? */
+ bool isSimple;
+
+ /** Does this class overloaded the -> operator? */
+ MemberDef *arrowOperator;
+
+ ClassList *taggedInnerClasses;
+ ClassDef *tagLessRef;
+
+ /** Does this class represent a Java style enum? */
+ bool isJavaEnum;
+
+ bool isGeneric;
+
+ int spec;
+};
+
+void ClassDefImpl::init(const char *defFileName, const char *name,
+ const QCString &ctStr, const char *fName)
+{
+ if (fName)
+ {
+ fileName=stripExtension(fName);
+ }
+ else
+ {
+ fileName=ctStr+name;
+ }
+ exampleSDict = 0;
+ inherits = 0;
+ inheritedBy = 0;
+ allMemberNameInfoSDict = 0;
+ incInfo=0;
+ tempArgs=0;
+ typeConstraints=0;
+ prot=Public;
+ nspace=0;
+ fileDef=0;
+ usesImplClassDict=0;
+ usedByImplClassDict=0;
+ usesIntfClassDict=0;
+ memberGroupSDict = 0;
+ innerClasses = 0;
+ subGrouping=Config_getBool("SUBGROUPING");
+ templateInstances = 0;
+ variableInstances = 0;
+ templateMaster =0;
+ templBaseClassNames = 0;
+ isAbstract = FALSE;
+ isStatic = FALSE;
+ isTemplArg = FALSE;
+ membersMerged = FALSE;
+ categoryOf = 0;
+ usedOnly = FALSE;
+ isSimple = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ arrowOperator = 0;
+ taggedInnerClasses = 0;
+ tagLessRef = 0;
+ spec=0;
+ //QCString ns;
+ //extractNamespaceName(name,className,ns);
+ //printf("m_name=%s m_className=%s ns=%s\n",m_name.data(),m_className.data(),ns.data());
+
+ // we cannot use getLanguage at this point, as setLanguage has not been called.
+ SrcLangExt lang = getLanguageFromFileName(defFileName);
+ if ((lang==SrcLangExt_Cpp || lang==SrcLangExt_ObjC) &&
+ guessSection(defFileName)==Entry::SOURCE_SEC)
+ {
+ isLocal=TRUE;
+ }
+ else
+ {
+ isLocal=FALSE;
+ }
+ isGeneric = lang==SrcLangExt_CSharp && QCString(name).find('<')!=-1;
+}
+
+ClassDefImpl::ClassDefImpl() : vhdlSummaryTitles(17)
+{
+ vhdlSummaryTitles.setAutoDelete(TRUE);
+}
+
+ClassDefImpl::~ClassDefImpl()
+{
+ delete inherits;
+ delete inheritedBy;
+ delete allMemberNameInfoSDict;
+ delete exampleSDict;
+ delete usesImplClassDict;
+ delete usedByImplClassDict;
+ delete usesIntfClassDict;
+ delete incInfo;
+ delete memberGroupSDict;
+ delete innerClasses;
+ delete templateInstances;
+ delete variableInstances;
+ delete templBaseClassNames;
+ delete tempArgs;
+ delete typeConstraints;
+ delete taggedInnerClasses;
+}
+
+// constructs a new class definition
+ClassDef::ClassDef(
+ const char *defFileName,int defLine,
+ const char *nm,CompoundType ct,
+ const char *lref,const char *fName,
+ bool isSymbol,bool isJavaEnum)
+ : Definition(defFileName,defLine,removeRedundantWhiteSpace(nm),0,0,isSymbol)
+{
+ visited=FALSE;
+ setReference(lref);
+ m_impl = new ClassDefImpl;
+ m_impl->compType = ct;
+ m_impl->isJavaEnum = isJavaEnum;
+ m_impl->init(defFileName,name(),compoundTypeString(),fName);
+}
+
+// destroy the class definition
+ClassDef::~ClassDef()
+{
+ delete m_impl;
+}
+
+QCString ClassDef::getMemberListFileName() const
+{
+ return convertNameToFile(compoundTypeString()+name()+"-members");
+}
+
+QCString ClassDef::displayName(bool includeScope) const
+{
+ //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ SrcLangExt lang = getLanguage();
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString n;
+ if (lang==SrcLangExt_VHDL)
+ {
+ n = VhdlDocGen::getClassName(this);
+ }
+ else
+ {
+ if (includeScope)
+ {
+ n=qualifiedNameWithTemplateParameters();
+ }
+ else
+ {
+ n=className();
+ }
+ }
+ QCString sep=getLanguageSpecificSeparator(lang);
+ if (sep!="::")
+ {
+ n=substitute(n,"::",sep);
+ }
+ if (m_impl->compType==ClassDef::Protocol && n.right(2)=="-p")
+ {
+ n="<"+n.left(n.length()-2)+">";
+ }
+ //else if (n.right(2)=="-g")
+ //{
+ // n = n.left(n.length()-2);
+ //}
+ //printf("ClassDef::displayName()=%s\n",n.data());
+ return n;
+}
+
+// inserts a base/super class in the inheritance list
+void ClassDef::insertBaseClass(ClassDef *cd,const char *n,Protection p,
+ Specifier s,const char *t)
+{
+ //printf("*** insert base class %s into %s\n",cd->name().data(),name().data());
+ //inherits->inSort(new BaseClassDef(cd,p,s,t));
+ if (m_impl->inherits==0)
+ {
+ m_impl->inherits = new BaseClassList;
+ m_impl->inherits->setAutoDelete(TRUE);
+ }
+ m_impl->inherits->append(new BaseClassDef(cd,n,p,s,t));
+ m_impl->isSimple = FALSE;
+}
+
+// inserts a derived/sub class in the inherited-by list
+void ClassDef::insertSubClass(ClassDef *cd,Protection p,
+ Specifier s,const char *t)
+{
+ //printf("*** insert sub class %s into %s\n",cd->name().data(),name().data());
+ if (m_impl->inheritedBy==0)
+ {
+ m_impl->inheritedBy = new BaseClassList;
+ m_impl->inheritedBy->setAutoDelete(TRUE);
+ }
+ m_impl->inheritedBy->inSort(new BaseClassDef(cd,0,p,s,t));
+ m_impl->isSimple = FALSE;
+}
+
+void ClassDef::addMembersToMemberGroup()
+{
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberList::detailedLists)==0)
+ {
+ ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
+ }
+ }
+
+ // add members inside sections to their groups
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (mg->allMembersInSameSection() && m_impl->subGrouping)
+ {
+ //printf("addToDeclarationSection(%s)\n",mg->header().data());
+ mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+// adds new member definition to the class
+void ClassDef::internalInsertMember(MemberDef *md,
+ Protection prot,
+ bool addToAllList
+ )
+{
+ //printf("insertInternalMember(%s) isHidden()=%d\n",md->name().data(),md->isHidden());
+ if (md->isHidden()) return;
+
+ if (getLanguage()==SrcLangExt_VHDL)
+ {
+ QCString title=VhdlDocGen::trVhdlType(md->getMemberSpecifiers(),FALSE);
+ if (!m_impl->vhdlSummaryTitles.find(title))
+ {
+ m_impl->vhdlSummaryTitles.append(title,new QCString(title));
+ }
+ }
+
+ if (1 /*!isReference()*/) // changed to 1 for showing members of external
+ // classes when HAVE_DOT and UML_LOOK are enabled.
+ {
+ bool isSimple=FALSE;
+
+ /********************************************/
+ /* insert member in the declaration section */
+ /********************************************/
+ if (md->isRelated() && protectionLevelVisible(prot))
+ {
+ addMemberToList(MemberList::related,md,TRUE);
+ }
+ else if (md->isFriend())
+ {
+ addMemberToList(MemberList::friends,md,TRUE);
+ }
+ else
+ {
+ switch (md->memberType())
+ {
+ case MemberDef::Signal: // Qt specific
+ addMemberToList(MemberList::signals,md,TRUE);
+ break;
+ case MemberDef::DCOP: // KDE2 specific
+ addMemberToList(MemberList::dcopMethods,md,TRUE);
+ break;
+ case MemberDef::Property:
+ addMemberToList(MemberList::properties,md,TRUE);
+ break;
+ case MemberDef::Event:
+ addMemberToList(MemberList::events,md,TRUE);
+ break;
+ case MemberDef::Slot: // Qt specific
+ switch (prot)
+ {
+ case Protected:
+ case Package: // slots in packages are not possible!
+ addMemberToList(MemberList::proSlots,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubSlots,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberList::priSlots,md,TRUE);
+ break;
+ }
+ break;
+ default: // any of the other members
+ if (md->isStatic())
+ {
+ if (md->isVariable())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberList::proStaticAttribs,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberList::pacStaticAttribs,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubStaticAttribs,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberList::priStaticAttribs,md,TRUE);
+ break;
+ }
+ }
+ else // function
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberList::proStaticMethods,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberList::pacStaticMethods,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubStaticMethods,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberList::priStaticMethods,md,TRUE);
+ break;
+ }
+ }
+ }
+ else // not static
+ {
+ if (md->isVariable())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberList::proAttribs,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberList::pacAttribs,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubAttribs,md,TRUE);
+ isSimple=!md->isFunctionPtr();
+ break;
+ case Private:
+ addMemberToList(MemberList::priAttribs,md,TRUE);
+ break;
+ }
+ }
+ else if (md->isTypedef() || md->isEnumerate() || md->isEnumValue())
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberList::proTypes,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberList::pacTypes,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubTypes,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberList::priTypes,md,TRUE);
+ break;
+ }
+ }
+ else // member function
+ {
+ switch (prot)
+ {
+ case Protected:
+ addMemberToList(MemberList::proMethods,md,TRUE);
+ break;
+ case Package:
+ addMemberToList(MemberList::pacMethods,md,TRUE);
+ break;
+ case Public:
+ addMemberToList(MemberList::pubMethods,md,TRUE);
+ break;
+ case Private:
+ addMemberToList(MemberList::priMethods,md,TRUE);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ if (!isSimple) // not a simple field -> not a simple struct
+ {
+ m_impl->isSimple = FALSE;
+ }
+ //printf("adding %s simple=%d total_simple=%d\n",name().data(),isSimple,m_impl->isSimple);
+
+ /*******************************************************/
+ /* insert member in the detailed documentation section */
+ /*******************************************************/
+ if ((md->isRelated() && protectionLevelVisible(prot)) || md->isFriend())
+ {
+ addMemberToList(MemberList::relatedMembers,md,FALSE);
+ }
+ else
+ {
+ switch (md->memberType())
+ {
+ case MemberDef::Property:
+ addMemberToList(MemberList::propertyMembers,md,FALSE);
+ break;
+ case MemberDef::Event:
+ addMemberToList(MemberList::eventMembers,md,FALSE);
+ break;
+ case MemberDef::Signal: // fall through
+ case MemberDef::DCOP:
+ addMemberToList(MemberList::functionMembers,md,FALSE);
+ break;
+ case MemberDef::Slot:
+ if (protectionLevelVisible(prot))
+ {
+ addMemberToList(MemberList::functionMembers,md,FALSE);
+ }
+ break;
+ default: // any of the other members
+ if (protectionLevelVisible(prot))
+ {
+ switch (md->memberType())
+ {
+ case MemberDef::Typedef:
+ addMemberToList(MemberList::typedefMembers,md,FALSE);
+ break;
+ case MemberDef::Enumeration:
+ addMemberToList(MemberList::enumMembers,md,FALSE);
+ break;
+ case MemberDef::EnumValue:
+ addMemberToList(MemberList::enumValMembers,md,FALSE);
+ break;
+ case MemberDef::Function:
+ if (md->isConstructor() || md->isDestructor())
+ {
+ MemberList *ml = createMemberList(MemberList::constructors);
+ ml->append(md);
+ }
+ else
+ {
+ addMemberToList(MemberList::functionMembers,md,FALSE);
+ }
+ break;
+ case MemberDef::Variable:
+ addMemberToList(MemberList::variableMembers,md,FALSE);
+ break;
+ default:
+ err("Unexpected member type %d found!\n",md->memberType());
+ }
+ }
+ break;
+ }
+ }
+
+ /*************************************************/
+ /* insert member in the appropriate member group */
+ /*************************************************/
+ // Note: this must be done AFTER inserting the member in the
+ // regular groups
+ //addMemberToGroup(md,groupId);
+
+ }
+
+ if (md->virtualness()==Pure)
+ {
+ m_impl->isAbstract=TRUE;
+ }
+
+ if (md->name()=="operator->")
+ {
+ m_impl->arrowOperator=md;
+ }
+
+ //::addClassMemberNameToIndex(md);
+ if (addToAllList &&
+ !(Config_getBool("HIDE_FRIEND_COMPOUNDS") &&
+ md->isFriend() &&
+ (QCString(md->typeString())=="friend class" ||
+ QCString(md->typeString())=="friend struct" ||
+ QCString(md->typeString())=="friend union")))
+ {
+ //printf("=======> adding member %s to class %s\n",md->name().data(),name().data());
+ MemberInfo *mi = new MemberInfo((MemberDef *)md,
+ prot,md->virtualness(),FALSE);
+ MemberNameInfo *mni=0;
+ if (m_impl->allMemberNameInfoSDict==0)
+ {
+ m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
+ m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
+ }
+ if ((mni=m_impl->allMemberNameInfoSDict->find(md->name())))
+ {
+ mni->append(mi);
+ }
+ else
+ {
+ mni = new MemberNameInfo(md->name());
+ mni->append(mi);
+ m_impl->allMemberNameInfoSDict->append(mni->memberName(),mni);
+ }
+ }
+}
+
+void ClassDef::insertMember(MemberDef *md)
+{
+ internalInsertMember(md,md->protection(),TRUE);
+}
+
+// compute the anchors for all members
+void ClassDef::computeAnchors()
+{
+ ClassDef *context = Config_getBool("INLINE_INHERITED_MEMB") ? this : 0;
+ const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ int index = 0;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberList::detailedLists)==0)
+ {
+ setAnchors(context,letters[index++],ml);
+ }
+ }
+
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->setAnchors(context);
+ }
+ }
+}
+
+void ClassDef::distributeMemberGroupDocumentation()
+{
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->distributeMemberGroupDocumentation();
+ }
+ }
+}
+
+void ClassDef::findSectionsInDocumentation()
+{
+ docFindSections(documentation(),this,0,docFile());
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->findSectionsInDocumentation();
+ }
+ }
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberList::detailedLists)==0)
+ {
+ ml->findSectionsInDocumentation();
+ }
+ }
+}
+
+
+// add a file name to the used files set
+void ClassDef::insertUsedFile(const char *f)
+{
+ if (m_impl->files.find(f)==-1) m_impl->files.append(f);
+ if (m_impl->templateInstances)
+ {
+ QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
+ ClassDef *cd;
+ for (qdi.toFirst();(cd=qdi.current());++qdi)
+ {
+ cd->insertUsedFile(f);
+ }
+ }
+}
+
+static void writeInheritanceSpecifier(OutputList &ol,BaseClassDef *bcd)
+{
+ if (bcd->prot!=Public || bcd->virt!=Normal)
+ {
+ ol.startTypewriter();
+ ol.docify(" [");
+ QStrList sl;
+ if (bcd->prot==Protected) sl.append("protected");
+ else if (bcd->prot==Private) sl.append("private");
+ if (bcd->virt==Virtual) sl.append("virtual");
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.docify(", ");
+ }
+ ol.docify("]");
+ ol.endTypewriter();
+ }
+}
+
+void ClassDef::setIncludeFile(FileDef *fd,
+ const char *includeName,bool local, bool force)
+{
+ //printf("ClassDef::setIncludeFile(%p,%s,%d,%d)\n",fd,includeName,local,force);
+ if (!m_impl->incInfo) m_impl->incInfo=new IncludeInfo;
+ if ((includeName && m_impl->incInfo->includeName.isEmpty()) ||
+ (fd!=0 && m_impl->incInfo->fileDef==0)
+ )
+ {
+ //printf("Setting file info\n");
+ m_impl->incInfo->fileDef = fd;
+ m_impl->incInfo->includeName = includeName;
+ m_impl->incInfo->local = local;
+ }
+ if (force && includeName)
+ {
+ m_impl->incInfo->includeName = includeName;
+ m_impl->incInfo->local = local;
+ }
+}
+
+// TODO: fix this: a nested template class can have multiple outer templates
+//ArgumentList *ClassDef::outerTemplateArguments() const
+//{
+// int ti;
+// ClassDef *pcd=0;
+// int pi=0;
+// if (m_impl->tempArgs) return m_impl->tempArgs;
+// // find the outer most class scope
+// while ((ti=name().find("::",pi))!=-1 &&
+// (pcd=getClass(name().left(ti)))==0
+// ) pi=ti+2;
+// if (pcd)
+// {
+// return pcd->templateArguments();
+// }
+// return 0;
+//}
+
+static void searchTemplateSpecs(/*in*/ Definition *d,
+ /*out*/ QList<ArgumentList> &result,
+ /*out*/ QCString &name)
+{
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ if (d->getOuterScope())
+ {
+ searchTemplateSpecs(d->getOuterScope(),result,name);
+ }
+ ClassDef *cd=(ClassDef *)d;
+ if (!name.isEmpty()) name+="::";
+ QCString clName = d->localName();
+ if (/*clName.right(2)=="-g" ||*/ clName.right(2)=="-p")
+ {
+ clName = clName.left(clName.length()-2);
+ }
+ name+=clName;
+ bool isSpecialization = d->localName().find('<')!=-1;
+ if (cd->templateArguments())
+ {
+ result.append(cd->templateArguments());
+ if (!isSpecialization)
+ {
+ name+=tempArgListToString(cd->templateArguments());
+ }
+ }
+ }
+ else
+ {
+ name+=d->qualifiedName();
+ }
+}
+
+static void writeTemplateSpec(OutputList &ol,Definition *d,
+ const QCString &type)
+{
+ QList<ArgumentList> specs;
+ QCString name;
+ searchTemplateSpecs(d,specs,name);
+ if (specs.count()>0) // class has template scope specifiers
+ {
+ ol.startSubsubsection();
+ QListIterator<ArgumentList> spi(specs);
+ ArgumentList *al;
+ for (spi.toFirst();(al=spi.current());++spi)
+ {
+ ol.docify("template<");
+ Argument *a=al->first();
+ while (a)
+ {
+ ol.docify(a->type);
+ if (!a->name.isEmpty())
+ {
+ ol.docify(" ");
+ ol.docify(a->name);
+ }
+ if (a->defval.length()!=0)
+ {
+ ol.docify(" = ");
+ ol.docify(a->defval);
+ }
+ a=al->next();
+ if (a) ol.docify(", ");
+ }
+ ol.docify(">");
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.lineBreak();
+ ol.popGeneratorState();
+ }
+ ol.docify(type.lower()+" "+name);
+ ol.endSubsubsection();
+ ol.writeString("\n");
+ }
+}
+
+void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
+{
+ if (!briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
+ {
+ ol.startParagraph();
+ ol.parseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::RTF);
+ ol.writeString(" \n");
+ ol.enable(OutputGenerator::RTF);
+ ol.popGeneratorState();
+
+ if (Config_getBool("REPEAT_BRIEF") ||
+ !documentation().isEmpty() ||
+ exampleFlag
+ )
+ {
+ writeMoreLink(ol,anchor());
+ }
+
+ ol.endParagraph();
+ }
+ ol.writeSynopsis();
+}
+
+void ClassDef::writeDetailedDocumentationBody(OutputList &ol)
+{
+ static bool repeatBrief = Config_getBool("REPEAT_BRIEF");
+
+ ol.startTextBlock();
+
+ if (getLanguage()==SrcLangExt_Cpp)
+ {
+ writeTemplateSpec(ol,this,compoundTypeString());
+ }
+
+ // repeat brief description
+ if (!briefDescription().isEmpty() && repeatBrief)
+ {
+ ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ }
+ if (!briefDescription().isEmpty() && repeatBrief &&
+ !documentation().isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeString("\n\n");
+ ol.popGeneratorState();
+ }
+ // write documentation
+ if (!documentation().isEmpty())
+ {
+ ol.parseDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
+ }
+ // write type constraints
+ writeTypeConstraints(ol,this,m_impl->typeConstraints);
+
+ // write examples
+ if (hasExamples() && m_impl->exampleSDict)
+ {
+ ol.startSimpleSect(BaseOutputDocInterface::Examples,0,0,theTranslator->trExamples()+": ");
+ ol.startDescForItem();
+ //ol.startParagraph();
+ writeExample(ol,m_impl->exampleSDict);
+ //ol.endParagraph();
+ ol.endDescForItem();
+ ol.endSimpleSect();
+ }
+ //ol.newParagraph();
+ writeSourceDef(ol,name());
+ ol.endTextBlock();
+}
+
+// write the detailed description for this class
+void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageType*/, bool exampleFlag,
+ const QCString &title,const QCString &anchor)
+{
+ if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) ||
+ !documentation().isEmpty() ||
+ (Config_getBool("SOURCE_BROWSER") && getStartBodyLine()!=-1 && getBodyDef()) ||
+ exampleFlag)
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.writeRuler();
+ ol.popGeneratorState();
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.writeAnchor(0,anchor.isEmpty() ? QCString("details") : anchor);
+ ol.popGeneratorState();
+
+ if (!anchor.isEmpty())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ ol.writeAnchor(getOutputFileBase(),anchor);
+ ol.popGeneratorState();
+ }
+
+ ol.startGroupHeader();
+ ol.parseText(title);
+ ol.endGroupHeader();
+
+ writeDetailedDocumentationBody(ol);
+ }
+ else
+ {
+ //writeTemplateSpec(ol,this,pageType);
+ }
+}
+
+void ClassDef::showUsedFiles(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+
+ SrcLangExt lang = getLanguage();
+ ol.writeRuler();
+ if (lang==SrcLangExt_Fortran)
+ {
+ ol.parseText(theTranslator->trGeneratedFromFilesFortran(
+ getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
+ m_impl->files.count()==1));
+ }
+ else if (isJavaEnum())
+ {
+ ol.parseText(theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1));
+ }
+ else
+ {
+ ol.parseText(theTranslator->trGeneratedFromFiles(
+ getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
+ m_impl->files.count()==1));
+ }
+
+ bool first=TRUE;
+ const char *file = m_impl->files.first();
+ while (file)
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
+ if (fd)
+ {
+ if (first)
+ {
+ first=FALSE;
+ ol.startItemList();
+ }
+
+ ol.startItemListItem();
+ QCString path=fd->getPath();
+ if (Config_getBool("FULL_PATH_NAMES"))
+ {
+ ol.docify(stripFromPath(path));
+ }
+
+ QCString fname = fd->name();
+ if (!fd->getVersion().isEmpty()) // append version if available
+ {
+ fname += " (" + fd->getVersion() + ")";
+ }
+
+ // for HTML
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ if (fd->generateSourceFile())
+ {
+ ol.writeObjectLink(0,fd->getSourceFileBase(),0,fname);
+ }
+ else if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
+ fname);
+ }
+ else
+ {
+ ol.docify(fname);
+ }
+ ol.popGeneratorState();
+
+ // for other output formats
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ if (fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,
+ fname);
+ }
+ else
+ {
+ ol.docify(fname);
+ }
+ ol.popGeneratorState();
+
+ ol.endItemListItem();
+ }
+ file=m_impl->files.next();
+ }
+ if (!first) ol.endItemList();
+
+ ol.popGeneratorState();
+}
+
+
+void ClassDef::writeInheritanceGraph(OutputList &ol)
+{
+ // count direct inheritance relations
+ int count=0;
+ BaseClassDef *ibcd;
+ if (m_impl->inheritedBy)
+ {
+ ibcd=m_impl->inheritedBy->first();
+ while (ibcd)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ ibcd=m_impl->inheritedBy->next();
+ }
+ }
+ if (m_impl->inherits)
+ {
+ ibcd=m_impl->inherits->first();
+ while (ibcd)
+ {
+ ClassDef *icd=ibcd->classDef;
+ if ( icd->isVisibleInHierarchy()) count++;
+ ibcd=m_impl->inherits->next();
+ }
+ }
+
+
+ bool renderDiagram = FALSE;
+ if (Config_getBool("HAVE_DOT") &&
+ (Config_getBool("CLASS_DIAGRAMS") || Config_getBool("CLASS_GRAPH")))
+ // write class diagram using dot
+ {
+ DotClassGraph inheritanceGraph(this,DotNode::Inheritance);
+ if (!inheritanceGraph.isTrivial() && !inheritanceGraph.isTooBig())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.endDotGraph(inheritanceGraph);
+ ol.popGeneratorState();
+ renderDiagram = TRUE;
+ }
+ }
+ else if (Config_getBool("CLASS_DIAGRAMS") && count>0)
+ // write class diagram using build-in generator
+ {
+ ClassDiagram diagram(this); // create a diagram of this class.
+ ol.startClassDiagram();
+ ol.disable(OutputGenerator::Man);
+ ol.parseText(theTranslator->trClassDiagram(displayName()));
+ ol.enable(OutputGenerator::Man);
+ ol.endClassDiagram(diagram,getOutputFileBase(),displayName());
+ renderDiagram = TRUE;
+ }
+
+ if (renderDiagram) // if we already show the inheritance relations graphically,
+ // then hide the text version
+ {
+ ol.disableAllBut(OutputGenerator::Man);
+ }
+
+ if (m_impl->inherits && (count=m_impl->inherits->count())>0)
+ {
+ ol.startParagraph();
+ //parseText(ol,theTranslator->trInherits()+" ");
+
+ QCString inheritLine = theTranslator->trInheritsList(m_impl->inherits->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inherits->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+
+ // use the class name but with the template arguments as given
+ // in the inheritance relation
+ QCString displayName = insertTemplateSpecifierInScope(
+ cd->displayName(),bcd->templSpecifiers);
+
+ if (cd->isLinkable())
+ {
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <base";
+ if (bcd->prot==Protected)
+ {
+ Doxygen::tagFile << " protection=\"protected\"";
+ }
+ else if (bcd->prot==Private)
+ {
+ Doxygen::tagFile << " protection=\"private\"";
+ }
+ if (bcd->virt==Virtual)
+ {
+ Doxygen::tagFile << " virtualness=\"virtual\"";
+ }
+ Doxygen::tagFile << ">" << convertToXML(cd->name())
+ << "</base>" << endl;
+ }
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ displayName);
+ }
+ else
+ {
+ ol.docify(displayName);
+ }
+ }
+ else
+ {
+ err("error: invalid marker %d in inherits list!\n",entryIndex);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.endParagraph();
+ }
+
+ // write subclasses
+ if (m_impl->inheritedBy && (count=m_impl->inheritedBy->count())>0)
+ {
+ ol.startParagraph();
+ QCString inheritLine = theTranslator->trInheritedByList(m_impl->inheritedBy->count());
+ QRegExp marker("@[0-9]+");
+ int index=0,newIndex,matchLen;
+ // now replace all markers in inheritLine with links to the classes
+ while ((newIndex=marker.match(inheritLine,index,&matchLen))!=-1)
+ {
+ ol.parseText(inheritLine.mid(index,newIndex-index));
+ bool ok;
+ uint entryIndex = inheritLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
+ BaseClassDef *bcd=m_impl->inheritedBy->at(entryIndex);
+ if (ok && bcd)
+ {
+ ClassDef *cd=bcd->classDef;
+ if (cd->isLinkable())
+ {
+ ol.writeObjectLink(cd->getReference(),cd->getOutputFileBase(),cd->anchor(),cd->displayName());
+ }
+ else
+ {
+ ol.docify(cd->displayName());
+ }
+ writeInheritanceSpecifier(ol,bcd);
+ }
+ index=newIndex+matchLen;
+ }
+ ol.parseText(inheritLine.right(inheritLine.length()-index));
+ ol.endParagraph();
+ }
+
+ if (renderDiagram)
+ {
+ ol.enableAll();
+ }
+}
+
+void ClassDef::writeCollaborationGraph(OutputList &ol)
+{
+ if (Config_getBool("HAVE_DOT") /*&& Config_getBool("COLLABORATION_GRAPH")*/)
+ {
+ DotClassGraph usageImplGraph(this,DotNode::Collaboration);
+ if (!usageImplGraph.isTrivial())
+ {
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Man);
+ ol.startDotGraph();
+ ol.parseText(theTranslator->trCollaborationDiagram(displayName()));
+ ol.endDotGraph(usageImplGraph);
+ ol.popGeneratorState();
+ }
+ }
+}
+
+void ClassDef::writeIncludeFiles(OutputList &ol)
+{
+ if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
+ {
+ QCString nm=m_impl->incInfo->includeName.isEmpty() ?
+ (m_impl->incInfo->fileDef ?
+ m_impl->incInfo->fileDef->docName().data() : ""
+ ) :
+ m_impl->incInfo->includeName.data();
+ if (!nm.isEmpty())
+ {
+ ol.startParagraph();
+ ol.startTypewriter();
+ SrcLangExt lang = getLanguage();
+ bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ if (isIDLorJava)
+ {
+ ol.docify("import ");
+ }
+ else if (isObjectiveC())
+ {
+ ol.docify("#import ");
+ }
+ else
+ {
+ ol.docify("#include ");
+ }
+ if (m_impl->incInfo->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify("<");
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.docify(nm);
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.enable(OutputGenerator::Html);
+ if (m_impl->incInfo->fileDef)
+ {
+ ol.writeObjectLink(0,m_impl->incInfo->fileDef->includeName(),0,nm);
+ }
+ else
+ {
+ ol.docify(nm);
+ }
+ ol.popGeneratorState();
+ if (m_impl->incInfo->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify(">");
+ if (isIDLorJava)
+ ol.docify(";");
+ ol.endTypewriter();
+ ol.endParagraph();
+ }
+ }
+}
+
+#if 0
+void ClassDef::writeAllMembersLink(OutputList &ol)
+{
+ // write link to list of all members (HTML only)
+ if (m_impl->allMemberNameInfoSDict &&
+ !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
+ )
+ {
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.startParagraph();
+ ol.startTextLink(getMemberListFileName(),0);
+ ol.parseText(theTranslator->trListOfAllMembers());
+ ol.endTextLink();
+ ol.endParagraph();
+ ol.enableAll();
+ ol.popGeneratorState();
+ }
+}
+#endif
+
+void ClassDef::writeMemberGroups(OutputList &ol,bool showInline)
+{
+ // write user defined member groups
+ if (m_impl->memberGroupSDict)
+ {
+ m_impl->memberGroupSDict->sort();
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
+ {
+ mg->writeDeclarations(ol,this,0,0,0,showInline);
+ }
+ else // add this group to the corresponding member section
+ {
+ //printf("addToDeclarationSection(%s)\n",mg->header().data());
+ //mg->addToDeclarationSection();
+ }
+ }
+ }
+}
+
+void ClassDef::writeNestedClasses(OutputList &ol,const QCString &title)
+{
+ // nested classes
+ if (m_impl->innerClasses)
+ {
+ m_impl->innerClasses->writeDeclaration(ol,0,title,TRUE);
+ }
+}
+
+void ClassDef::writeInlineClasses(OutputList &ol)
+{
+ if (m_impl->innerClasses)
+ {
+ m_impl->innerClasses->writeDocumentation(ol,this);
+ }
+}
+
+void ClassDef::startMemberDocumentation(OutputList &ol)
+{
+ //printf("%s: ClassDef::startMemberDocumentation()\n",name().data());
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.disable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = TRUE;
+ }
+}
+
+void ClassDef::endMemberDocumentation(OutputList &ol)
+{
+ //printf("%s: ClassDef::endMemberDocumentation()\n",name().data());
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ ol.enable(OutputGenerator::Html);
+ Doxygen::suppressDocWarnings = FALSE;
+ }
+}
+
+void ClassDef::startMemberDeclarations(OutputList &ol)
+{
+ //printf("%s: ClassDef::startMemberDeclarations()\n",name().data());
+ ol.startMemberSections();
+}
+
+void ClassDef::endMemberDeclarations(OutputList &ol)
+{
+ //printf("%s: ClassDef::endMemberDeclarations()\n",name().data());
+ static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
+ if (!inlineInheritedMembers && countAdditionalInheritedMembers()>0)
+ {
+ ol.startMemberHeader("inherited");
+ ol.parseText(theTranslator->trAdditionalInheritedMembers());
+ ol.endMemberHeader();
+ writeAdditionalInheritedMembers(ol);
+ }
+ ol.endMemberSections();
+}
+
+void ClassDef::writeAuthorSection(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Man);
+ ol.writeString("\n");
+ ol.startGroupHeader();
+ ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
+ ol.endGroupHeader();
+ ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
+ ol.popGeneratorState();
+}
+
+
+void ClassDef::writeSummaryLinks(OutputList &ol)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ bool first=TRUE;
+ SrcLangExt lang = getLanguage();
+
+ if (lang!=SrcLangExt_VHDL)
+ {
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::ClassNestedClasses &&
+ m_impl->innerClasses &&
+ m_impl->innerClasses->declVisible()
+ )
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ ol.writeSummaryLink(0,"nested-classes",ls->title(lang),first);
+ first=FALSE;
+ }
+ else if (lde->kind()==LayoutDocEntry::ClassAllMembersLink &&
+ m_impl->allMemberNameInfoSDict &&
+ !Config_getBool("OPTIMIZE_OUTPUT_FOR_C")
+ )
+ {
+ ol.writeSummaryLink(getMemberListFileName(),"all-members-list",theTranslator->trListOfAllMembers(),first);
+ first=FALSE;
+ }
+ else if (lde->kind()== LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList * ml = getMemberList(lmd->type);
+ if (ml && ml->declVisible())
+ {
+ ol.writeSummaryLink(0,ml->listTypeAsString(),lmd->title(lang),first);
+ first=FALSE;
+ }
+ }
+ }
+ }
+ else // VDHL only
+ {
+ SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);
+ for (li.toFirst();li.current();++li)
+ {
+ ol.writeSummaryLink(0,li.current()->data(),li.current()->data(),first);
+ }
+ }
+ if (!first)
+ {
+ ol.writeString(" </div>\n");
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeTagFileMarker()
+{
+ // write section to the tag file
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ Doxygen::tagFile << " <compound kind=\"" << compoundTypeString();
+ Doxygen::tagFile << "\"";
+ if (isObjectiveC()) { Doxygen::tagFile << " objc=\"yes\""; }
+ Doxygen::tagFile << ">" << endl;
+ Doxygen::tagFile << " <name>" << convertToXML(name()) << "</name>" << endl;
+ Doxygen::tagFile << " <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
+ if (!anchor().isEmpty())
+ {
+ Doxygen::tagFile << " <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
+ }
+ if (m_impl->tempArgs)
+ {
+ ArgumentListIterator ali(*m_impl->tempArgs);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ Doxygen::tagFile << " <templarg>" << convertToXML(a->name) << "</templarg>" << endl;
+ }
+ }
+ }
+}
+
+/** Write class documentation inside another container (i.e. a group) */
+void ClassDef::writeInlineDocumentation(OutputList &ol)
+{
+ bool isSimple = m_impl->isSimple;
+
+ ol.addIndexItem(name(),0);
+ //printf("ClassDef::writeInlineDocumentation(%s)\n",name().data());
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+
+ // part 1: anchor and title
+ QCString s = compoundTypeString()+" "+name();
+
+ // part 1a
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ { // only HTML only
+ ol.writeAnchor(0,anchor());
+ ol.startMemberDoc(0,0,0,0,FALSE);
+ ol.startMemberDocName(FALSE);
+ ol.parseText(s);
+ ol.endMemberDocName();
+ ol.endMemberDoc(FALSE);
+ ol.writeString("</div>");
+ ol.startIndent();
+ }
+ ol.popGeneratorState();
+
+ // part 1b
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ { // for LaTeX/RTF only
+ ol.writeAnchor(getOutputFileBase(),anchor());
+ }
+ ol.popGeneratorState();
+
+ // part 1c
+ ol.pushGeneratorState();
+ ol.disable(OutputGenerator::Html);
+ {
+ // for LaTeX/RTF/Man
+ ol.startGroupHeader(1);
+ ol.parseText(s);
+ ol.endGroupHeader(1);
+ }
+ ol.popGeneratorState();
+
+ SrcLangExt lang=getLanguage();
+
+ // part 2: the header and detailed description
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ {
+ // since we already shown the brief description in the
+ // declaration part of the container, so we use this to
+ // show the details on top.
+ writeDetailedDocumentationBody(ol);
+ }
+ break;
+ case LayoutDocEntry::ClassInheritanceGraph:
+ writeInheritanceGraph(ol);
+ break;
+ case LayoutDocEntry::ClassCollaborationGraph:
+ writeCollaborationGraph(ol);
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ if (!isSimple) startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (!isSimple) writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang),TRUE);
+ }
+ break;
+ case LayoutDocEntry::MemberGroups:
+ if (!isSimple) writeMemberGroups(ol,TRUE);
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ if (!isSimple) endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ if (!isSimple) startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ if (isSimple)
+ {
+ writeSimpleMemberDocumentation(ol,lmd->type);
+ }
+ else
+ {
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang),TRUE);
+ }
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ if (!isSimple) endMemberDocumentation(ol);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // part 3: close the block
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ { // HTML only
+ ol.endIndent();
+ }
+ ol.popGeneratorState();
+
+ // part 4: write tag file information
+ writeTagFileMarker();
+}
+
+void ClassDef::writeMoreLink(OutputList &ol,const QCString &anchor)
+{
+ // TODO: clean up this mess by moving it to
+ // the output generators...
+ static bool pdfHyperlinks = Config_getBool("PDF_HYPERLINKS");
+ static bool rtfHyperlinks = Config_getBool("RTF_HYPERLINKS");
+ static bool usePDFLatex = Config_getBool("USE_PDFLATEX");
+
+ // HTML only
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ ol.docify(" ");
+ ol.startTextLink(getOutputFileBase(),
+ anchor.isEmpty() ? QCString("details") : anchor);
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ ol.popGeneratorState();
+
+ if (!anchor.isEmpty())
+ {
+ ol.pushGeneratorState();
+ // LaTeX + RTF
+ ol.disable(OutputGenerator::Html);
+ ol.disable(OutputGenerator::Man);
+ if (!(usePDFLatex && pdfHyperlinks))
+ {
+ ol.disable(OutputGenerator::Latex);
+ }
+ if (!rtfHyperlinks)
+ {
+ ol.disable(OutputGenerator::RTF);
+ }
+ ol.docify(" ");
+ ol.startTextLink(getOutputFileBase(), anchor);
+ ol.parseText(theTranslator->trMore());
+ ol.endTextLink();
+ // RTF only
+ ol.disable(OutputGenerator::Latex);
+ ol.writeString("\\par");
+ ol.popGeneratorState();
+ }
+}
+
+
+void ClassDef::writeDeclarationLink(OutputList &ol,bool &found,const char *header,bool localNames)
+{
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
+ static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
+ bool isLink = isLinkable();
+ SrcLangExt lang = getLanguage();
+ if (isLink ||
+ (!hideUndocClasses &&
+ (!isLocal() || extractLocalClasses)
+ )
+ )
+ {
+ if (!found) // first class
+ {
+ ol.startMemberHeader("nested-classes");
+ if (header)
+ {
+ ol.parseText(header);
+ }
+ else if (lang==SrcLangExt_VHDL)
+ {
+ ol.parseText(VhdlDocGen::trVhdlType(VhdlDocGen::ARCHITECTURE,FALSE));
+ }
+ else
+ {
+ ol.parseText(lang==SrcLangExt_Fortran ?
+ theTranslator->trDataTypes() :
+ theTranslator->trCompounds());
+ }
+ ol.endMemberHeader();
+ ol.startMemberList();
+ found=TRUE;
+ }
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty() &&
+ !isReference()) // skip classes found in tag files
+ {
+ Doxygen::tagFile << " <class kind=\"" << compoundTypeString()
+ << "\">" << convertToXML(name()) << "</class>" << endl;
+ }
+ ol.startMemberDeclaration();
+ ol.startMemberItem(anchor(),FALSE);
+ QCString ctype = compoundTypeString();
+ QCString cname = displayName(!localNames);
+
+ if (lang!=SrcLangExt_VHDL) // for VHDL we swap the name and the type
+ {
+ ol.writeString(ctype);
+ ol.writeString(" ");
+ ol.insertMemberAlign();
+ }
+ if (isLink)
+ {
+ ol.writeObjectLink(getReference(),
+ getOutputFileBase(),
+ anchor(),
+ cname
+ );
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cname);
+ ol.endBold();
+ }
+ if (lang==SrcLangExt_VHDL) // now write the type
+ {
+ ol.writeString(" ");
+ ol.insertMemberAlign();
+ ol.writeString(VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)protection()));
+ }
+ ol.endMemberItem();
+
+ // add the brief description if available
+ if (!briefDescription().isEmpty())
+ {
+ ol.startMemberDescription(anchor());
+ ol.parseDoc(briefFile(),briefLine(),this,0,
+ briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ if (isLinkableInProject())
+ {
+ writeMoreLink(ol,anchor());
+ }
+ ol.endMemberDescription();
+ }
+ ol.endMemberDeclaration(anchor(),0);
+ }
+}
+
+void ClassDef::addClassAttributes(OutputList &ol)
+{
+ QStrList sl;
+ if (isFinal()) sl.append("final");
+ if (isSealed()) sl.append("sealed");
+ if (isAbstract()) sl.append("abstract");
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ if (sl.count()>0)
+ {
+ ol.startLabels();
+ const char *s=sl.first();
+ while (s)
+ {
+ const char *ns = sl.next();
+ ol.writeLabel(s,ns==0);
+ s=ns;
+ }
+ ol.endLabels();
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeDocumentationContents(OutputList &ol,const QCString & /*pageTitle*/)
+{
+ ol.startContents();
+
+ QCString pageType = " ";
+ pageType += compoundTypeString();
+ toupper(pageType.at(1));
+
+ writeTagFileMarker();
+
+ Doxygen::indexList.addIndexItem(this,0);
+
+ if (Doxygen::searchIndex)
+ {
+ Doxygen::searchIndex->setCurrentDoc(this,anchor(),FALSE);
+ Doxygen::searchIndex->addWord(localName(),TRUE);
+ }
+ bool exampleFlag=hasExamples();
+
+ //---------------------------------------- start flexible part -------------------------------
+
+ SrcLangExt lang = getLanguage();
+
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ switch (lde->kind())
+ {
+ case LayoutDocEntry::BriefDesc:
+ writeBriefDescription(ol,exampleFlag);
+ break;
+ case LayoutDocEntry::ClassIncludes:
+ writeIncludeFiles(ol);
+ break;
+ case LayoutDocEntry::ClassInheritanceGraph:
+ writeInheritanceGraph(ol);
+ break;
+ case LayoutDocEntry::ClassCollaborationGraph:
+ writeCollaborationGraph(ol);
+ break;
+ case LayoutDocEntry::ClassAllMembersLink:
+ //writeAllMembersLink(ol); // this is now part of the summary links
+ break;
+ case LayoutDocEntry::MemberDeclStart:
+ startMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::MemberGroups:
+ writeMemberGroups(ol);
+ break;
+ case LayoutDocEntry::MemberDecl:
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writeMemberDeclarations(ol,lmd->type,lmd->title(lang),lmd->subtitle(lang));
+ }
+ break;
+ case LayoutDocEntry::ClassNestedClasses:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeNestedClasses(ol,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDeclEnd:
+ endMemberDeclarations(ol);
+ break;
+ case LayoutDocEntry::DetailedDesc:
+ {
+ LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
+ writeDetailedDescription(ol,pageType,exampleFlag,ls->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefStart:
+ startMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::ClassInlineClasses:
+ writeInlineClasses(ol);
+ break;
+ case LayoutDocEntry::MemberDef:
+ {
+ LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
+ writeMemberDocumentation(ol,lmd->type,lmd->title(lang));
+ }
+ break;
+ case LayoutDocEntry::MemberDefEnd:
+ endMemberDocumentation(ol);
+ break;
+ case LayoutDocEntry::ClassUsedFiles:
+ showUsedFiles(ol);
+ break;
+ case LayoutDocEntry::AuthorSection:
+ writeAuthorSection(ol);
+ break;
+ case LayoutDocEntry::NamespaceNestedNamespaces:
+ case LayoutDocEntry::NamespaceClasses:
+ case LayoutDocEntry::NamespaceInlineClasses:
+ case LayoutDocEntry::FileClasses:
+ case LayoutDocEntry::FileNamespaces:
+ case LayoutDocEntry::FileIncludes:
+ case LayoutDocEntry::FileIncludeGraph:
+ case LayoutDocEntry::FileIncludedByGraph:
+ case LayoutDocEntry::FileSourceLink:
+ case LayoutDocEntry::FileInlineClasses:
+ case LayoutDocEntry::GroupClasses:
+ case LayoutDocEntry::GroupInlineClasses:
+ case LayoutDocEntry::GroupNamespaces:
+ case LayoutDocEntry::GroupDirs:
+ case LayoutDocEntry::GroupNestedGroups:
+ case LayoutDocEntry::GroupFiles:
+ case LayoutDocEntry::GroupGraph:
+ case LayoutDocEntry::GroupPageDocs:
+ case LayoutDocEntry::DirSubDirs:
+ case LayoutDocEntry::DirFiles:
+ case LayoutDocEntry::DirGraph:
+ err("Internal inconsistency: member %d should not be part of "
+ "LayoutDocManager::Class entry list\n",lde->kind());
+ break;
+ }
+ }
+
+ if (!Config_getString("GENERATE_TAGFILE").isEmpty())
+ {
+ writeDocAnchorsToTagFile();
+ Doxygen::tagFile << " </compound>" << endl;
+ }
+ ol.endContents();
+}
+
+// write all documentation for this class
+void ClassDef::writeDocumentation(OutputList &ol)
+{
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ QCString pageTitle;
+ SrcLangExt lang = getLanguage();
+
+ if (lang==SrcLangExt_Fortran)
+ {
+ pageTitle = theTranslator->trCompoundReferenceFortran(displayName(),
+ m_impl->compType,
+ m_impl->tempArgs != 0);
+ }
+ else if (lang==SrcLangExt_VHDL)
+ {
+ pageTitle = VhdlDocGen::getClassTitle(this)+" Reference";
+ }
+ else if (isJavaEnum())
+ {
+ pageTitle = theTranslator->trEnumReference(displayName());
+ }
+ else
+ {
+ pageTitle = theTranslator->trCompoundReference(displayName(),
+ m_impl->compType == Interface && getLanguage()==SrcLangExt_ObjC ? Class : m_impl->compType,
+ m_impl->tempArgs != 0);
+ }
+
+ startFile(ol,getOutputFileBase(),name(),pageTitle,HLI_ClassVisible,!generateTreeView);
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+
+ startTitle(ol,getOutputFileBase(),this);
+ ol.parseText(pageTitle);
+ addClassAttributes(ol);
+ addGroupListToTitle(ol,this);
+ endTitle(ol,getOutputFileBase(),displayName());
+ writeDocumentationContents(ol,pageTitle);
+
+ endFileWithNavPath(this,ol);
+
+ if (Config_getBool("SEPARATE_MEMBER_PAGES"))
+ {
+ writeMemberPages(ol);
+ }
+}
+
+void ClassDef::writeMemberPages(OutputList &ol)
+{
+ ///////////////////////////////////////////////////////////////////////////
+ //// Member definitions on separate pages
+ ///////////////////////////////////////////////////////////////////////////
+
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberList::detailedLists)
+ {
+ ml->writeDocumentationPage(ol,displayName(),this);
+ }
+ }
+
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
+{
+ static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
+
+ ol.writeString(" <div class=\"navtab\">\n");
+ ol.writeString(" <table>\n");
+
+ if (m_impl->allMemberNameInfoSDict)
+ {
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->getClassDef()==this && md->isLinkable())
+ {
+ ol.writeString(" <tr><td class=\"navtab\">");
+ if (md->isLinkableInProject())
+ {
+ if (md==currentMd) // selected item => highlight
+ {
+ ol.writeString("<a class=\"qindexHL\" ");
+ }
+ else
+ {
+ ol.writeString("<a class=\"qindex\" ");
+ }
+ ol.writeString("href=\"");
+ if (createSubDirs) ol.writeString("../../");
+ ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
+ ol.writeString("\">");
+ ol.writeString(convertToHtml(md->name()));
+ ol.writeString("</a>");
+ }
+ ol.writeString("</td></tr>\n");
+ }
+ }
+ }
+ }
+
+ ol.writeString(" </table>\n");
+ ol.writeString(" </div>\n");
+}
+
+
+
+void ClassDef::writeDocumentationForInnerClasses(OutputList &ol)
+{
+ // write inner classes after the parent, so the tag files contain
+ // the definition in proper order!
+ if (m_impl->innerClasses)
+ {
+ ClassSDict::Iterator cli(*m_impl->innerClasses);
+ ClassDef *innerCd;
+ for (cli.toFirst();(innerCd=cli.current());++cli)
+ {
+ if (innerCd->isLinkableInProject() && innerCd->templateMaster()==0 &&
+ protectionLevelVisible(innerCd->protection()) &&
+ !innerCd->isEmbeddedInOuterScope()
+ )
+ {
+ msg("Generating docs for nested compound %s...\n",qPrint(innerCd->name()));
+ innerCd->writeDocumentation(ol);
+ innerCd->writeMemberList(ol);
+ }
+ innerCd->writeDocumentationForInnerClasses(ol);
+ }
+ }
+}
+
+// write the list of all (inherited) members for this class
+void ClassDef::writeMemberList(OutputList &ol)
+{
+ static bool cOpt = Config_getBool("OPTIMIZE_OUTPUT_FOR_C");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
+ if (m_impl->allMemberNameInfoSDict==0 || cOpt) return;
+ // only for HTML
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+
+ QCString memListFile = getMemberListFileName();
+ startFile(ol,memListFile,memListFile,theTranslator->trMemberList(),
+ HLI_ClassVisible,!generateTreeView,getOutputFileBase());
+ if (!generateTreeView)
+ {
+ if (getOuterScope()!=Doxygen::globalScope)
+ {
+ writeNavigationPath(ol);
+ }
+ ol.endQuickIndices();
+ }
+ startTitle(ol,0);
+ ol.parseText(displayName()+" "+theTranslator->trMemberList());
+ endTitle(ol,0,0);
+ ol.startContents();
+ ol.startParagraph();
+ ol.parseText(theTranslator->trThisIsTheListOfAllMembers());
+ ol.writeObjectLink(getReference(),getOutputFileBase(),anchor(),displayName());
+ ol.parseText(theTranslator->trIncludingInheritedMembers());
+ ol.endParagraph();
+
+ //ol.startItemList();
+ ol.writeString("<table class=\"directory\">\n");
+
+ int idx=0;
+ //MemberNameInfo *mni=m_impl->allMemberNameInfoList->first();
+ MemberNameInfoSDict::Iterator mnii(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
+ {
+ MemberInfo *mi=mni->first();
+ while (mi)
+ {
+ MemberDef *md=mi->memberDef;
+ ClassDef *cd=md->getClassDef();
+ Protection prot = mi->prot;
+ Specifier virt=md->virtualness();
+
+ //printf("%s: Member %s of class %s md->protection()=%d mi->prot=%d prot=%d inherited=%d\n",
+ // name().data(),md->name().data(),cd->name().data(),md->protection(),mi->prot,prot,mi->inherited);
+
+ if (cd && !md->name().isEmpty() && md->name()[0]!='@')
+ {
+ bool memberWritten=FALSE;
+ if (cd->isLinkable() && md->isLinkable())
+ // create a link to the documentation
+ {
+ QCString name=mi->ambiguityResolutionScope+md->name();
+ //ol.writeListItem();
+ ol.writeString(" <tr");
+ if ((idx&1)==0) ol.writeString(" class=\"even\"");
+ idx++;
+ ol.writeString("><td class=\"entry\">");
+ if (cd->isObjectiveC())
+ {
+ if (md->isObjCMethod())
+ {
+ if (md->isStatic())
+ ol.writeString("+&#160;</td><td>");
+ else
+ ol.writeString("-&#160;</td><td>");
+ }
+ else
+ ol.writeString("</td><td class=\"entry\">");
+ }
+ if (md->isObjCMethod())
+ {
+ ol.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),md->name());
+ }
+ else
+ {
+ //Definition *bd = md->getGroupDef();
+ //if (bd==0) bd=cd;
+ ol.writeObjectLink(md->getReference(),
+ md->getOutputFileBase(),
+ md->anchor(),name);
+
+ if ( md->isFunction() || md->isSignal() || md->isSlot() ||
+ (md->isFriend() && md->argsString()))
+ ol.docify(md->argsString());
+ else if (md->isEnumerate())
+ ol.parseText(" "+theTranslator->trEnumName());
+ else if (md->isEnumValue())
+ ol.parseText(" "+theTranslator->trEnumValue());
+ else if (md->isTypedef())
+ ol.docify(" typedef");
+ else if (md->isFriend() && !strcmp(md->typeString(),"friend class"))
+ ol.docify(" class");
+ //ol.writeString("\n");
+ }
+ ol.writeString("</td>");
+ memberWritten=TRUE;
+ }
+ else if (!Config_getBool("HIDE_UNDOC_MEMBERS") &&
+ (protectionLevelVisible(md->protection()) || md->isFriend())
+ ) // no documentation,
+ // generate link to the class instead.
+ {
+ //ol.writeListItem();
+ ol.writeString(" <tr bgcolor=\"#f0f0f0\"");
+ if ((idx&1)==0) ol.writeString("class=\"even\"");
+ idx++;
+ ol.writeString("><td class=\"entry\">");
+ if (cd->isObjectiveC())
+ {
+ if (md->isObjCMethod())
+ {
+ if (md->isStatic())
+ ol.writeString("+&#160;</td><td class=\"entry\">");
+ else
+ ol.writeString("-&#160;</td><td class=\"entry\">");
+ }
+ else
+ ol.writeString("</td><td class=\"entry\">");
+ }
+ ol.startBold();
+ ol.docify(md->name());
+ ol.endBold();
+ if (!md->isObjCMethod())
+ {
+ if ( md->isFunction() || md->isSignal() || md->isSlot() )
+ ol.docify(md->argsString());
+ else if (md->isEnumerate())
+ ol.parseText(" "+theTranslator->trEnumName());
+ else if (md->isEnumValue())
+ ol.parseText(" "+theTranslator->trEnumValue());
+ else if (md->isTypedef())
+ ol.docify(" typedef");
+ }
+ ol.writeString(" (");
+ ol.parseText(theTranslator->trDefinedIn()+" ");
+ if (cd->isLinkable())
+ {
+ ol.writeObjectLink(
+ cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ cd->displayName());
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cd->displayName());
+ ol.endBold();
+ }
+ ol.writeString(")");
+ ol.writeString("</td>");
+ memberWritten=TRUE;
+ }
+ if (memberWritten)
+ {
+ ol.writeString("<td class=\"entry\">");
+ ol.writeObjectLink(cd->getReference(),
+ cd->getOutputFileBase(),
+ cd->anchor(),
+ md->category() ?
+ md->category()->displayName() :
+ cd->displayName());
+ ol.writeString("</td>");
+ ol.writeString("<td class=\"entry\">");
+ }
+ SrcLangExt lang = md->getLanguage();
+ if (
+ (prot!=Public || (virt!=Normal && getLanguage()!=SrcLangExt_ObjC) ||
+ md->isFriend() || md->isRelated() || md->isExplicit() ||
+ md->isMutable() || (md->isInline() && Config_getBool("INLINE_INFO")) ||
+ md->isSignal() || md->isSlot() ||
+ md->isStatic() || lang==SrcLangExt_VHDL
+ )
+ && memberWritten)
+ {
+ ol.writeString("<span class=\"mlabel\">");
+ QStrList sl;
+ if (lang==SrcLangExt_VHDL)
+ {
+ sl.append(VhdlDocGen::trVhdlType(md->getMemberSpecifiers())); //append vhdl type
+ }
+ else if (md->isFriend()) sl.append("friend");
+ else if (md->isRelated()) sl.append("related");
+ else
+ {
+ if (Config_getBool("INLINE_INFO") && md->isInline())
+ sl.append("inline");
+ if (md->isExplicit()) sl.append("explicit");
+ if (md->isMutable()) sl.append("mutable");
+ if (prot==Protected) sl.append("protected");
+ else if (prot==Private) sl.append("private");
+ else if (prot==Package) sl.append("package");
+ if (virt==Virtual && getLanguage()!=SrcLangExt_ObjC)
+ sl.append("virtual");
+ else if (virt==Pure) sl.append("pure virtual");
+ if (md->isStatic()) sl.append("static");
+ if (md->isSignal()) sl.append("signal");
+ if (md->isSlot()) sl.append("slot");
+ }
+ const char *s=sl.first();
+ while (s)
+ {
+ ol.docify(s);
+ s=sl.next();
+ if (s) ol.writeString("</span><span class=\"mlabel\">");
+ }
+ ol.writeString("</span>");
+ }
+ if (memberWritten)
+ {
+ ol.writeString("</td>");
+ ol.writeString("</tr>\n");
+ }
+ }
+ mi=mni->next();
+ }
+ }
+ //ol.endItemList();
+
+ ol.writeString("</table>");
+
+ endFile(ol);
+ ol.popGeneratorState();
+}
+
+
+// add a reference to an example
+bool ClassDef::addExample(const char *anchor,const char *nameStr,
+ const char *file)
+{
+ if (m_impl->exampleSDict==0)
+ {
+ m_impl->exampleSDict = new ExampleSDict;
+ m_impl->exampleSDict->setAutoDelete(TRUE);
+ }
+ if (!m_impl->exampleSDict->find(nameStr))
+ {
+ Example *e=new Example;
+ e->anchor=anchor;
+ e->name=nameStr;
+ e->file=file;
+ m_impl->exampleSDict->inSort(nameStr,e);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// returns TRUE if this class is used in an example
+bool ClassDef::hasExamples()
+{
+ if (m_impl->exampleSDict==0)
+ return FALSE;
+ else
+ return m_impl->exampleSDict->count()>0;
+}
+
+
+void ClassDef::setTemplateArguments(ArgumentList *al)
+{
+ if (al==0) return;
+ if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
+ m_impl->tempArgs=new ArgumentList;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->tempArgs->append(new Argument(*a));
+ }
+}
+
+void ClassDef::setTypeConstraints(ArgumentList *al)
+{
+ if (al==0) return;
+ if (!m_impl->typeConstraints) delete m_impl->typeConstraints;
+ m_impl->typeConstraints = new ArgumentList;
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ m_impl->typeConstraints->append(new Argument(*a));
+ }
+}
+
+/*! Returns \c TRUE iff this class or a class inheriting from this class
+ * is \e not defined in an external tag file.
+ */
+bool ClassDef::hasNonReferenceSuperClass()
+{
+ bool found=!isReference() && isLinkableInProject() && !isHidden();
+ if (found)
+ {
+ return TRUE; // we're done if this class is not a reference
+ }
+ if (m_impl->inheritedBy)
+ {
+ BaseClassListIterator bcli(*m_impl->inheritedBy);
+ for ( ; bcli.current() && !found ; ++bcli ) // for each super class
+ {
+ ClassDef *bcd=bcli.current()->classDef;
+ // recurse into the super class branch
+ found = found || bcd->hasNonReferenceSuperClass();
+ if (!found)
+ {
+ // look for template instances that might have non-reference super classes
+ QDict<ClassDef> *cil = bcd->getTemplateInstances();
+ if (cil)
+ {
+ QDictIterator<ClassDef> tidi(*cil);
+ for ( ; tidi.current() && !found ; ++tidi) // for each template instance
+ {
+ // recurse into the template instance branch
+ found = found || tidi.current()->hasNonReferenceSuperClass();
+ }
+ }
+ }
+ }
+ }
+ return found;
+}
+
+/*! called from MemberDef::writeDeclaration() to (recusively) write the
+ * definition of an anonymous struct, union or class.
+ */
+void ClassDef::writeDeclaration(OutputList &ol,MemberDef *md,bool inGroup,
+ ClassDef *inheritedFrom,const char *inheritId)
+{
+ //ol.insertMemberAlign();
+ //printf("ClassName=`%s' inGroup=%d\n",name().data(),inGroup);
+
+ //if (inGroup && md && md->getClassDef()==this) return;
+
+ ol.docify(compoundTypeString());
+ int ri=name().findRev("::");
+ if (ri==-1) ri=name().length();
+ QCString cn=name().right(name().length()-ri-2);
+ if (!cn.isEmpty() && cn.at(0)!='@' && md)
+ {
+ if (cn.right(2)=="-p" /*|| cn.right(2)=="-g"*/)
+ {
+ cn = cn.left(cn.length()-2);
+ }
+ ol.docify(" ");
+ if (isLinkable())
+ {
+ ol.writeObjectLink(0,0,md->anchor(),cn);
+ }
+ else
+ {
+ ol.startBold();
+ ol.docify(cn);
+ ol.endBold();
+ }
+ }
+ ol.docify(" {");
+ ol.endMemberItem();
+
+ // write user defined member groups
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->setInGroup(inGroup);
+ mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
+ }
+ }
+
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ writePlainMemberDeclaration(ol,lmd->type,inGroup,inheritedFrom,inheritId);
+ }
+ }
+}
+
+/*! a link to this class is possible within this project */
+bool ClassDef::isLinkableInProject() const
+{
+ static bool extractLocal = Config_getBool("EXTRACT_LOCAL_CLASSES");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+ static bool hideUndoc = Config_getBool("HIDE_UNDOC_CLASSES");
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkableInProject();
+ }
+ else
+ {
+ return !name().isEmpty() && /* has a name */
+ !isArtificial() && !isHidden() && /* not hidden */
+ name().find('@')==-1 && /* not anonymous */
+ protectionLevelVisible(m_impl->prot) && /* private/internal */
+ (!m_impl->isLocal || extractLocal) && /* local */
+ (hasDocumentation() || !hideUndoc) && /* documented */
+ (!m_impl->isStatic || extractStatic) && /* static */
+ !isReference(); /* not an external reference */
+ }
+}
+
+bool ClassDef::isLinkable() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isLinkable();
+ }
+ else
+ {
+ return isLinkableInProject() || isReference();
+ }
+}
+
+
+/*! the class is visible in a class diagram, or class hierarchy */
+bool ClassDef::isVisibleInHierarchy()
+{
+ static bool allExternals = Config_getBool("ALLEXTERNALS");
+ static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
+ static bool extractStatic = Config_getBool("EXTRACT_STATIC");
+
+ return // show all classes or a subclass is visible
+ (allExternals || hasNonReferenceSuperClass()) &&
+ // and not an anonymous compound
+ name().find('@')==-1 &&
+ // not an artificially introduced class
+ /*!isArtificial() &&*/ // 1.8.2: allowed these to appear
+ // and not privately inherited
+ protectionLevelVisible(m_impl->prot) &&
+ // documented or shown anyway or documentation is external
+ (hasDocumentation() ||
+ !hideUndocClasses ||
+ (m_impl->templateMaster && m_impl->templateMaster->hasDocumentation()) ||
+ isReference()
+ ) &&
+ // is not part of an unnamed namespace or shown anyway
+ (!m_impl->isStatic || extractStatic);
+}
+
+bool ClassDef::hasDocumentation() const
+{
+ return Definition::hasDocumentation();
+}
+
+//----------------------------------------------------------------------
+// recursive function:
+// returns TRUE iff class definition `bcd' represents an (in)direct base
+// class of class definition `cd'.
+
+bool ClassDef::isBaseClass(ClassDef *bcd, bool followInstances,int level)
+{
+ bool found=FALSE;
+ //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
+ if (level>256)
+ {
+ err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(name()),qPrint(bcd->name()));
+ abort();
+ return FALSE;
+ }
+ if (baseClasses())
+ {
+ // Beware: trying to optimise the iterator away using ->first() & ->next()
+ // causes bug 625531
+ BaseClassListIterator bcli(*baseClasses());
+ for ( ; bcli.current() && !found ; ++bcli)
+ {
+ ClassDef *ccd=bcli.current()->classDef;
+ if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
+ //printf("isBaseClass() baseclass %s\n",ccd->name().data());
+ if (ccd==bcd)
+ found=TRUE;
+ else
+ found=ccd->isBaseClass(bcd,followInstances,level+1);
+ }
+ }
+ return found;
+}
+
+//----------------------------------------------------------------------------
+
+static bool isStandardFunc(MemberDef *md)
+{
+ return md->name()=="operator=" || // assignment operator
+ md->isConstructor() || // constructor
+ md->isDestructor(); // destructor
+}
+
+/*!
+ * recusively merges the `all members' lists of a class base
+ * with that of this class. Must only be called for classes without
+ * subclasses!
+ */
+void ClassDef::mergeMembers()
+{
+ if (m_impl->membersMerged) return;
+
+ //static bool optimizeOutputForJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ //static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ SrcLangExt lang = getLanguage();
+ QCString sep=getLanguageSpecificSeparator(lang,TRUE);
+ int sepLen = sep.length();
+
+ m_impl->membersMerged=TRUE;
+ //printf(" mergeMembers for %s\n",name().data());
+ bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB" );
+ if (baseClasses())
+ {
+ //printf(" => has base classes!\n");
+ BaseClassListIterator bcli(*baseClasses());
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ ClassDef *bClass=bcd->classDef;
+
+ // merge the members in the base class of this inheritance branch first
+ bClass->mergeMembers();
+
+ MemberNameInfoSDict *srcMnd = bClass->memberNameInfoSDict();
+ MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
+
+ if (srcMnd)
+ {
+ MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
+ MemberNameInfo *srcMni;
+ for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
+ {
+ //printf(" Base member name %s\n",srcMni->memberName());
+ MemberNameInfo *dstMni;
+ if (dstMnd!=0 && (dstMni=dstMnd->find(srcMni->memberName())))
+ // a member with that name is already in the class.
+ // the member may hide or reimplement the one in the sub class
+ // or there may be another path to the base class that is already
+ // visited via another branch in the class hierarchy.
+ {
+ MemberNameInfoIterator srcMnii(*srcMni);
+ MemberInfo *srcMi;
+ for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
+ {
+ MemberDef *srcMd = srcMi->memberDef;
+ bool found=FALSE;
+ bool ambigue=FALSE;
+ bool hidden=FALSE;
+ MemberNameInfoIterator dstMnii(*dstMni);
+ MemberInfo *dstMi;
+ ClassDef *srcCd = srcMd->getClassDef();
+ for ( ; (dstMi=dstMnii.current()) && !found; ++dstMnii )
+ {
+ MemberDef *dstMd = dstMi->memberDef;
+ if (srcMd!=dstMd) // different members
+ {
+ ClassDef *dstCd = dstMd->getClassDef();
+ //printf(" Is %s a base class of %s?\n",srcCd->name().data(),dstCd->name().data());
+ if (srcCd==dstCd || dstCd->isBaseClass(srcCd,TRUE))
+ // member is in the same or a base class
+ {
+ LockingPtr<ArgumentList> srcAl = srcMd->argumentList();
+ LockingPtr<ArgumentList> dstAl = dstMd->argumentList();
+ found=matchArguments2(
+ srcMd->getOuterScope(),srcMd->getFileDef(),srcAl.pointer(),
+ dstMd->getOuterScope(),dstMd->getFileDef(),dstAl.pointer(),
+ TRUE
+ );
+ //printf(" Yes, matching (%s<->%s): %d\n",
+ // argListToString(srcMd->argumentList()).data(),
+ // argListToString(dstMd->argumentList()).data(),
+ // found);
+ hidden = hidden || !found;
+ }
+ else // member is in a non base class => multiple inheritance
+ // using the same base class.
+ {
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
+
+ QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
+ dstMi->ambiguityResolutionScope.prepend(scope);
+ ambigue=TRUE;
+ }
+ }
+ else // same members
+ {
+ // do not add if base class is virtual or
+ // if scope paths are equal or
+ // if base class is an interface (and thus implicitly virtual).
+ //printf("same member found srcMi->virt=%d dstMi->virt=%d\n",srcMi->virt,dstMi->virt);
+ if ((srcMi->virt!=Normal && dstMi->virt!=Normal) ||
+ bClass->name()+sep+srcMi->scopePath == dstMi->scopePath ||
+ dstMd->getClassDef()->compoundType()==Interface
+ )
+ {
+ found=TRUE;
+ }
+ else // member can be reached via multiple paths in the
+ // inheritance tree
+ {
+ //printf("$$ Existing member %s %s add scope %s\n",
+ // dstMi->ambiguityResolutionScope.data(),
+ // dstMd->name().data(),
+ // dstMi->scopePath.left(dstMi->scopePath.find("::")+2).data());
+
+ QCString scope=dstMi->scopePath.left(dstMi->scopePath.find(sep)+sepLen);
+ if (scope!=dstMi->ambiguityResolutionScope.left(scope.length()))
+ {
+ dstMi->ambiguityResolutionScope.prepend(scope);
+ }
+ ambigue=TRUE;
+ }
+ }
+ }
+ //printf("member %s::%s hidden %d ambigue %d srcMi->ambigClass=%p\n",
+ // srcCd->name().data(),srcMd->name().data(),hidden,ambigue,srcMi->ambigClass);
+
+ // TODO: fix the case where a member is hidden by inheritance
+ // of a member with the same name but with another prototype,
+ // while there is more than one path to the member in the
+ // base class due to multiple inheritance. In this case
+ // it seems that the member is not reachable by prefixing a
+ // scope name either (according to my compiler). Currently,
+ // this case is shown anyway.
+ if (!found && srcMd->protection()!=Private && !srcMd->isFriend())
+ {
+ Protection prot=srcMd->protection();
+ if (bcd->prot==Protected && prot==Public) prot=bcd->prot;
+ else if (bcd->prot==Private) prot=bcd->prot;
+
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(srcMd))
+ {
+ //printf(" insertMember `%s'\n",srcMd->name().data());
+ internalInsertMember(srcMd,prot,FALSE);
+ }
+ }
+
+ Specifier virt=srcMi->virt;
+ if (srcMi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+
+ MemberInfo *newMi = new MemberInfo(srcMd,prot,virt,TRUE);
+ newMi->scopePath=bClass->name()+sep+srcMi->scopePath;
+ if (ambigue)
+ {
+ //printf("$$ New member %s %s add scope %s::\n",
+ // srcMi->ambiguityResolutionScope.data(),
+ // srcMd->name().data(),
+ // bClass->name().data());
+
+ QCString scope=bClass->name()+sep;
+ if (scope!=srcMi->ambiguityResolutionScope.left(scope.length()))
+ {
+ newMi->ambiguityResolutionScope=
+ scope+srcMi->ambiguityResolutionScope.copy();
+ }
+ }
+ if (hidden)
+ {
+ if (srcMi->ambigClass==0)
+ {
+ newMi->ambigClass=bClass;
+ newMi->ambiguityResolutionScope=bClass->name()+sep;
+ }
+ else
+ {
+ newMi->ambigClass=srcMi->ambigClass;
+ newMi->ambiguityResolutionScope=srcMi->ambigClass->name()+sep;
+ }
+ }
+ dstMni->append(newMi);
+ }
+ }
+ }
+ else // base class has a member that is not in the sub class => copy
+ {
+ // create a deep copy of the list (only the MemberInfo's will be
+ // copied, not the actual MemberDef's)
+ MemberNameInfo *newMni = 0;
+ newMni = new MemberNameInfo(srcMni->memberName());
+
+ // copy the member(s) from the base to the sub class
+ MemberNameInfoIterator mnii(*srcMni);
+ MemberInfo *mi;
+ for (;(mi=mnii.current());++mnii)
+ {
+ if (!mi->memberDef->isFriend()) // don't inherit friends
+ {
+ Protection prot = mi->prot;
+ if (bcd->prot==Protected)
+ {
+ if (prot==Public) prot=Protected;
+ }
+ else if (bcd->prot==Private)
+ {
+ prot=Private;
+ }
+ //printf("%s::%s: prot=%d bcd->prot=%d result=%d\n",
+ // name().data(),mi->memberDef->name().data(),mi->prot,
+ // bcd->prot,prot);
+
+ if (mi->prot!=Private)
+ {
+ Specifier virt=mi->virt;
+ if (mi->virt==Normal && bcd->virt!=Normal) virt=bcd->virt;
+
+ if (inlineInheritedMembers)
+ {
+ if (!isStandardFunc(mi->memberDef))
+ {
+ //printf(" insertMember `%s'\n",mi->memberDef->name().data());
+ internalInsertMember(mi->memberDef,prot,FALSE);
+ }
+ }
+ //printf("Adding!\n");
+ MemberInfo *newMi=new MemberInfo(mi->memberDef,prot,virt,TRUE);
+ newMi->scopePath=bClass->name()+sep+mi->scopePath;
+ newMi->ambigClass=mi->ambigClass;
+ newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope.copy();
+ newMni->append(newMi);
+ }
+ }
+ }
+
+ if (dstMnd==0)
+ {
+ m_impl->allMemberNameInfoSDict = new MemberNameInfoSDict(17);
+ m_impl->allMemberNameInfoSDict->setAutoDelete(TRUE);
+ dstMnd = m_impl->allMemberNameInfoSDict;
+ }
+ // add it to the dictionary
+ dstMnd->append(newMni->memberName(),newMni);
+ }
+ }
+ }
+ }
+ }
+ //printf(" end mergeMembers\n");
+}
+
+//----------------------------------------------------------------------------
+
+/*! Merges the members of a Objective-C category into this class.
+ */
+void ClassDef::mergeCategory(ClassDef *category)
+{
+ static bool extractLocalMethods = Config_getBool("EXTRACT_LOCAL_METHODS");
+ bool makePrivate = category->isLocal();
+ // in case extract local methods is not enabled we don't add the methods
+ // of the category in case it is defined in the .m file.
+ if (makePrivate && !extractLocalMethods) return;
+ bool isExtension = category->isExtension();
+
+ category->setCategoryOf(this);
+ if (isExtension)
+ {
+ category->setArtificial(TRUE);
+
+ // copy base classes/protocols from extension
+ if (category->baseClasses())
+ {
+ BaseClassListIterator bcli(*category->baseClasses());
+ BaseClassDef *bcd;
+ for ( ; (bcd=bcli.current()) ; ++bcli )
+ {
+ insertBaseClass(bcd->classDef,bcd->usedName,bcd->prot,bcd->virt,bcd->templSpecifiers);
+ // correct bcd->classDef so that they do no longer derive from
+ // category, but from this class!
+ if (bcd->classDef->subClasses())
+ {
+ BaseClassListIterator scli(*bcd->classDef->subClasses());
+ BaseClassDef *scd;
+ for ( ; (scd=scli.current()) ; ++scli )
+ {
+ if (scd->classDef==category)
+ {
+ scd->classDef=this;
+ }
+ }
+ }
+ }
+ }
+
+ }
+ // make methods private for categories defined in the .m file
+ //printf("%s::mergeCategory makePrivate=%d\n",name().data(),makePrivate);
+
+ MemberNameInfoSDict *srcMnd = category->memberNameInfoSDict();
+ MemberNameInfoSDict *dstMnd = m_impl->allMemberNameInfoSDict;
+
+ if (srcMnd && dstMnd)
+ {
+ MemberNameInfoSDict::Iterator srcMnili(*srcMnd);
+ MemberNameInfo *srcMni;
+ for ( ; (srcMni=srcMnili.current()) ; ++srcMnili)
+ {
+ MemberNameInfo *dstMni=dstMnd->find(srcMni->memberName());
+ if (dstMni) // method is already defined in the class
+ {
+ //printf("Existing member %s\n",srcMni->memberName());
+ MemberInfo *dstMi = dstMni->getFirst();
+ MemberInfo *srcMi = srcMni->getFirst();
+ //if (dstMi)
+ //{
+ // Protection prot = dstMi->prot;
+ // if (makePrivate || isExtension)
+ // {
+ // prot = Private;
+ // removeMemberFromLists(dstMi->memberDef);
+ // internalInsertMember(dstMi->memberDef,prot,FALSE);
+ // }
+ //}
+ if (srcMi && dstMi)
+ {
+ combineDeclarationAndDefinition(srcMi->memberDef,dstMi->memberDef);
+ dstMi->memberDef->setCategory(category);
+ dstMi->memberDef->setCategoryRelation(srcMi->memberDef);
+ srcMi->memberDef->setCategoryRelation(dstMi->memberDef);
+ }
+ }
+ else // new method name
+ {
+ //printf("New member %s\n",srcMni->memberName());
+ // create a deep copy of the list
+ MemberNameInfo *newMni = 0;
+ newMni = new MemberNameInfo(srcMni->memberName());
+
+ // copy the member(s) from the category to this class
+ MemberNameInfoIterator mnii(*srcMni);
+ MemberInfo *mi;
+ for (;(mi=mnii.current());++mnii)
+ {
+ //printf("Adding '%s'\n",mi->memberDef->name().data());
+ Protection prot = mi->prot;
+ //if (makePrivate) prot = Private;
+ MemberDef *newMd = mi->memberDef->deepCopy();
+ //printf("Copying member %s\n",mi->memberDef->name().data());
+ newMd->moveTo(this);
+
+ MemberInfo *newMi=new MemberInfo(newMd,prot,mi->virt,mi->inherited);
+ newMi->scopePath=mi->scopePath;
+ newMi->ambigClass=mi->ambigClass;
+ newMi->ambiguityResolutionScope=mi->ambiguityResolutionScope;
+ newMni->append(newMi);
+
+ // also add the newly created member to the global members list
+ if (newMd)
+ {
+ MemberName *mn;
+ QCString name = newMd->name();
+ if ((mn=Doxygen::memberNameSDict->find(name)))
+ {
+ mn->append(newMd);
+ }
+ else
+ {
+ mn = new MemberName(newMd->name());
+ mn->append(newMd);
+ Doxygen::memberNameSDict->append(name,mn);
+ }
+ }
+
+ newMd->setCategory(category);
+ newMd->setCategoryRelation(mi->memberDef);
+ mi->memberDef->setCategoryRelation(newMd);
+ if (makePrivate || isExtension)
+ {
+ newMd->makeImplementationDetail();
+ }
+ internalInsertMember(newMd,prot,FALSE);
+ }
+
+ // add it to the dictionary
+ dstMnd->append(newMni->memberName(),newMni);
+ }
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+
+void ClassDef::addUsedClass(ClassDef *cd,const char *accessName,
+ Protection prot)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ if (prot==Private && !extractPrivate) return;
+ //printf("%s::addUsedClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
+ if (m_impl->usesImplClassDict==0)
+ {
+ m_impl->usesImplClassDict = new UsesClassDict(17);
+ m_impl->usesImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ //printf("Adding used class %s to class %s via accessor %s\n",
+ // cd->name().data(),name().data(),accessName);
+ }
+ ucd->addAccessor(accessName);
+}
+
+void ClassDef::addUsedByClass(ClassDef *cd,const char *accessName,
+ Protection prot)
+{
+ static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
+ if (prot==Private && !extractPrivate) return;
+ //printf("%s::addUsedByClass(%s,%s)\n",name().data(),cd->name().data(),accessName);
+ if (m_impl->usedByImplClassDict==0)
+ {
+ m_impl->usedByImplClassDict = new UsesClassDict(17);
+ m_impl->usedByImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usedByImplClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usedByImplClassDict->insert(cd->name(),ucd);
+ //printf("Adding used by class %s to class %s\n",
+ // cd->name().data(),name().data());
+ }
+ ucd->addAccessor(accessName);
+}
+
+
+#if 0
+/*! Builds up a dictionary of all classes that are used by the state of this
+ * class (the "implementation").
+ * Must be called before mergeMembers() is called!
+ */
+
+void ClassDef::determineImplUsageRelation()
+{
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ if (md->isVariable()) // for each member variable in this class
+ {
+ QCString type=removeRedundantWhiteSpace(md->typeString());
+ //printf("in class %s found var type=`%s' name=`%s'\n",
+ // name().data(),type.data(),md->name().data());
+ int pos=0;
+ QCString usedClassName;
+ QCString templSpec;
+ bool found=FALSE;
+ while (extractClassNameFromType(type,pos,usedClassName,templSpec)!=-1 && !found)
+ {
+ //printf("usedClassName=`%s' templSpec=%s\n",usedClassName.data(),templSpec.data());
+ // check if usedClassName is a template argument of its class
+ ClassDef *cd=md->getClassDef();
+ if (cd && cd->templateArguments())
+ {
+ ArgumentListIterator ali(*cd->templateArguments());
+ Argument *arg;
+ int count=0;
+ for (ali.toFirst();(arg=ali.current());++ali,++count)
+ {
+ if (arg->name==usedClassName) // type is a template argument
+ {
+ found=TRUE;
+ if (m_impl->usesImplClassDict==0) m_impl->usesImplClassDict = new UsesClassDict(257);
+ cd = new ClassDef(cd->getDefFileName(),cd->getDefLine(),
+ usedClassName,ClassDef::Class);
+ cd->setIsTemplateBaseClass(count);
+ UsesClassDef *ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ ucd->templSpecifiers = templSpec;
+ ucd->addAccessor(md->name());
+ Doxygen::hiddenClasses.append(cd);
+ //printf("Adding used template argument %s to class %s\n",
+ // cd->name().data(),name().data());
+ //printf("Adding accessor %s to class %s\n",
+ // md->name().data(),ucd->classDef->name().data());
+ }
+ }
+ }
+
+ if (!found)
+ {
+ cd=0;
+ if (getNamespaceDef()!=0)
+ {
+ cd=getResolvedClass(getNamespaceDef()->name()+"::"+usedClassName,0,&templSpec);
+ }
+ if (cd==0) cd=getResolvedClass(name()+"::"+usedClassName,0,&templSpec);
+ if (cd==0) cd=getResolvedClass(usedClassName,0,&templSpec); // TODO: also try inbetween scopes!
+ //printf("Search for class %s result=%p\n",usedClassName.data(),cd);
+ if (cd) // class exists
+ {
+ found=TRUE;
+ if (m_impl->usesImplClassDict==0)
+ {
+ m_impl->usesImplClassDict = new UsesClassDict(257);
+ m_impl->usesImplClassDict->setAutoDelete(TRUE);
+ }
+ UsesClassDef *ucd=m_impl->usesImplClassDict->find(cd->name());
+ if (ucd==0 || ucd->templSpecifiers!=templSpec)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesImplClassDict->insert(cd->name(),ucd);
+ ucd->templSpecifiers = templSpec;
+ //printf("Adding used class %s to class %s\n",
+ // cd->name().data(),name().data());
+ }
+ ucd->addAccessor(md->name());
+ //printf("Adding accessor %s to class %s\n",
+ // md->name().data(),ucd->classDef->name().data());
+ }
+ }
+ }
+ }
+ }
+ }
+#ifdef DUMP
+ if (m_impl->usesClassDict)
+ {
+ msg("Class %s uses the following classes:\n",name().data());
+ UsesClassDictIterator ucdi(*m_impl->usesClassDict);
+ UsesClassDef *ucd;
+ for (;(ucd=ucdi.current());++ucdi)
+ {
+ msg(" %s via ",ucd->classDef->name().data());
+ QDictIterator<void> dvi(*ucd->accessors);
+ const char *s;
+ for (;(s=dvi.currentKey());++dvi)
+ {
+ msg("%s ",s);
+ }
+ msg("\n");
+ }
+ }
+#endif
+}
+
+//----------------------------------------------------------------------------
+
+// I have disabled this code because the graphs it renders quickly become
+// too large to be of practical use.
+
+void ClassDef::addUsedInterfaceClasses(MemberDef *md,const char *typeStr)
+{
+ QCString type = typeStr;
+ static const QRegExp re("[a-z_A-Z][a-z_A-Z0-9:]*");
+ int p=0,i,l;
+ while ((i=re.match(type,p,&l))!=-1) // for each class name in the type
+ {
+ ClassDef *cd=getClass(name()+"::"+type.mid(i,l));
+ if (cd==0) cd=getClass(type.mid(i,l)); // TODO: also try inbetween scopes!
+ if (cd && cd!=this && !isBaseClass(cd))
+ {
+ if (m_impl->usesIntfClassDict==0)
+ {
+ m_impl->usesIntfClassDict = new UsesClassDict(257);
+ }
+ UsesClassDef *ucd=m_impl->usesIntfClassDict->find(cd->name());
+ if (ucd==0)
+ {
+ ucd = new UsesClassDef(cd);
+ m_impl->usesIntfClassDict->insert(cd->name(),ucd);
+ //printf("in class `%s' adding used intf class `%s'\n",
+ // name().data(),cd->name().data());
+ }
+ ucd->addAccessor(md->name());
+ //printf("in class `%s' adding accessor `%s' to class `%s'\n",
+ // name().data(),md->name().data(),ucd->classDef->name().data());
+ }
+ p=i+l;
+ }
+}
+
+void ClassDef::determineIntfUsageRelation()
+{
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoList);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+
+ // compute the protection level for this member
+ Protection protect=md->protection();
+ if (mi->prot==Protected) // inherited protection
+ {
+ if (protect==Public) protect=Protected;
+ else if (protect==Protected) protect=Private;
+ }
+
+ if (!md->name().isEmpty() && md->name()[0]!='@' &&
+ (mi->prot!=Private && protect!=Private)
+ )
+ {
+ // add classes found in the return type
+ addUsedInterfaceClasses(md,md->typeString());
+ ArgumentList *al = md->argumentList();
+ if (al) // member has arguments
+ {
+ // add classes found in the types of the argument list
+ ArgumentListIterator ali(*al);
+ Argument *a;
+ for (;(a=ali.current());++ali)
+ {
+ if (!a->type.isEmpty() && a->type.at(0)!='@')
+ {
+ addUsedInterfaceClasses(md,a->type);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+QCString ClassDef::compoundTypeString() const
+{
+ if (getLanguage()==SrcLangExt_Fortran)
+ {
+ switch (m_impl->compType)
+ {
+ case Class: return "module";
+ case Struct: return "type";
+ case Union: return "union";
+ case Interface: return "interface";
+ case Protocol: return "protocol";
+ case Category: return "category";
+ case Exception: return "exception";
+ default: return "unknown";
+ }
+ }
+ else
+ {
+ switch (m_impl->compType)
+ {
+ case Class: return isJavaEnum() ? "enum" : "class";
+ case Struct: return "struct";
+ case Union: return "union";
+ case Interface: return getLanguage()==SrcLangExt_ObjC ? "class" : "interface";
+ case Protocol: return "protocol";
+ case Category: return "category";
+ case Exception: return "exception";
+ default: return "unknown";
+ }
+ }
+}
+
+QCString ClassDef::getOutputFileBase() const
+{
+ if (!Doxygen::generatingXmlOutput)
+ {
+ static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+ Definition *scope=0;
+ if (inlineGroupedClasses && partOfGroups()!=0)
+ {
+ // point to the group that embeds this class
+ return partOfGroups()->at(0)->getOutputFileBase();
+ }
+ else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
+ {
+ // point to simple struct inside a group
+ return partOfGroups()->at(0)->getOutputFileBase();
+ }
+ else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
+ {
+ if (scope==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) // simple struct embedded in file
+ {
+ return getFileDef()->getOutputFileBase();
+ }
+ else if (scope->isLinkableInProject()) // simple struct embedded in other container (namespace/group/class)
+ {
+ return getOuterScope()->getOutputFileBase();
+ }
+ }
+ }
+ if (m_impl->templateMaster)
+ {
+ // point to the template of which this class is an instance
+ return m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (isReference())
+ {
+ // point to the external location
+ return m_impl->fileName;
+ }
+ else
+ {
+ // normal locally defined class
+ return convertNameToFile(m_impl->fileName);
+ }
+}
+
+QCString ClassDef::getInstanceOutputFileBase() const
+{
+ if (isReference())
+ {
+ return m_impl->fileName;
+ }
+ else
+ {
+ return convertNameToFile(m_impl->fileName);
+ }
+}
+
+QCString ClassDef::getFileBase() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getFileBase();
+ }
+ else
+ {
+ return m_impl->fileName;
+ }
+}
+
+QCString ClassDef::getSourceFileBase() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getSourceFileBase();
+ }
+ else
+ {
+ return convertNameToFile(m_impl->fileName)+"_source";
+ }
+}
+
+void ClassDef::setGroupDefForAllMembers(GroupDef *gd,Grouping::GroupPri_t pri,const QCString &fileName,int startLine,bool hasDocs)
+{
+ gd->addClass(this);
+ //printf("ClassDef::setGroupDefForAllMembers(%s)\n",gd->name().data());
+ if (m_impl->allMemberNameInfoSDict==0) return;
+ MemberNameInfoSDict::Iterator mnili(*m_impl->allMemberNameInfoSDict);
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ MemberDef *md=mi->memberDef;
+ md->setGroupDef(gd,pri,fileName,startLine,hasDocs);
+ gd->insertMember(md,TRUE);
+ ClassDef *innerClass = md->getClassDefOfAnonymousType();
+ if (innerClass) innerClass->setGroupDefForAllMembers(gd,pri,fileName,startLine,hasDocs);
+ }
+ }
+}
+
+void ClassDef::addInnerCompound(Definition *d)
+{
+ //printf("**** %s::addInnerCompound(%s)\n",name().data(),d->name().data());
+ if (d->definitionType()==Definition::TypeClass) // only classes can be
+ // nested in classes.
+ {
+ if (m_impl->innerClasses==0)
+ {
+ m_impl->innerClasses = new ClassSDict(17);
+ }
+ m_impl->innerClasses->inSort(d->localName(),(ClassDef *)d);
+ }
+}
+
+Definition *ClassDef::findInnerCompound(const char *name)
+{
+ Definition *result=0;
+ if (name==0) return 0;
+ if (m_impl->innerClasses)
+ {
+ result = m_impl->innerClasses->find(name);
+ }
+ return result;
+}
+
+//void ClassDef::initTemplateMapping()
+//{
+// m_impl->templateMapping->clear();
+// ArgumentList *al = templateArguments();
+// if (al)
+// {
+// ArgumentListIterator ali(*al);
+// Argument *arg;
+// for (ali.toFirst();(arg=ali.current());++ali)
+// {
+// setTemplateArgumentMapping(arg->name,arg->defval);
+// }
+// }
+//}
+//void ClassDef::setTemplateArgumentMapping(const char *formal,const char *actual)
+//{
+// //printf("ClassDef::setTemplateArgumentMapping(%s,%s)\n",formal,actual);
+// if (m_impl->templateMapping && formal)
+// {
+// if (m_impl->templateMapping->find(formal))
+// {
+// m_impl->templateMapping->remove(formal);
+// }
+// m_impl->templateMapping->insert(formal,new QCString(actual));
+// }
+//}
+//
+//QCString ClassDef::getTemplateArgumentMapping(const char *formal) const
+//{
+// if (m_impl->templateMapping && formal)
+// {
+// QCString *s = m_impl->templateMapping->find(formal);
+// if (s)
+// {
+// return *s;
+// }
+// }
+// return "";
+//}
+
+ClassDef *ClassDef::insertTemplateInstance(const QCString &fileName,
+ int startLine, const QCString &templSpec,bool &freshInstance)
+{
+ freshInstance = FALSE;
+ if (m_impl->templateInstances==0)
+ {
+ m_impl->templateInstances = new QDict<ClassDef>(17);
+ }
+ ClassDef *templateClass=m_impl->templateInstances->find(templSpec);
+ if (templateClass==0)
+ {
+ Debug::print(Debug::Classes,0," New template instance class `%s'`%s'\n",name().data(),templSpec.data());
+ templateClass = new ClassDef(
+ fileName,startLine,localName()+templSpec,ClassDef::Class);
+ templateClass->setTemplateMaster(this);
+ templateClass->setOuterScope(getOuterScope());
+ templateClass->setHidden(isHidden());
+ m_impl->templateInstances->insert(templSpec,templateClass);
+ freshInstance=TRUE;
+ }
+ return templateClass;
+}
+
+ClassDef *ClassDef::getVariableInstance(const char *templSpec)
+{
+ if (m_impl->variableInstances==0)
+ {
+ m_impl->variableInstances = new QDict<ClassDef>(17);
+ m_impl->variableInstances->setAutoDelete(TRUE);
+ }
+ ClassDef *templateClass=m_impl->variableInstances->find(templSpec);
+ if (templateClass==0)
+ {
+ Debug::print(Debug::Classes,0," New template variable instance class `%s'`%s'\n",qPrint(name()),qPrint(templSpec));
+ templateClass = new ClassDef("<code>",1,name()+templSpec,
+ ClassDef::Class,0,0,FALSE);
+ templateClass->addMembersToTemplateInstance( this, templSpec );
+ templateClass->setTemplateMaster(this);
+ m_impl->variableInstances->insert(templSpec,templateClass);
+ }
+ return templateClass;
+}
+
+void ClassDef::setTemplateBaseClassNames(QDict<int> *templateNames)
+{
+ if (templateNames==0) return;
+ if (m_impl->templBaseClassNames==0)
+ {
+ m_impl->templBaseClassNames = new QDict<int>(17);
+ m_impl->templBaseClassNames->setAutoDelete(TRUE);
+ }
+ // make a deep copy of the dictionary.
+ QDictIterator<int> qdi(*templateNames);
+ for (;qdi.current();++qdi)
+ {
+ if (m_impl->templBaseClassNames->find(qdi.currentKey())==0)
+ {
+ m_impl->templBaseClassNames->insert(qdi.currentKey(),new int(*qdi.current()));
+ }
+ }
+}
+
+QDict<int> *ClassDef::getTemplateBaseClassNames() const
+{
+ return m_impl->templBaseClassNames;
+}
+
+void ClassDef::addMembersToTemplateInstance(ClassDef *cd,const char *templSpec)
+{
+ //printf("%s::addMembersToTemplateInstance(%s,%s)\n",name().data(),cd->name().data(),templSpec);
+ if (cd->memberNameInfoSDict()==0) return;
+ MemberNameInfoSDict::Iterator mnili(*cd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (;(mni=mnili.current());++mnili)
+ {
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ ArgumentList *actualArguments = new ArgumentList;
+ stringToArgumentList(templSpec,actualArguments);
+ MemberDef *md = mi->memberDef;
+ MemberDef *imd = md->createTemplateInstanceMember(
+ cd->templateArguments(),actualArguments);
+ delete actualArguments;
+ //printf("%s->setMemberClass(%p)\n",imd->name().data(),this);
+ imd->setMemberClass(this);
+ imd->setTemplateMaster(md);
+ imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+ imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+ imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+ imd->setMemberSpecifiers(md->getMemberSpecifiers());
+ imd->setMemberGroupId(md->getMemberGroupId());
+ insertMember(imd);
+ //printf("Adding member=%s %s%s to class %s templSpec %s\n",
+ // imd->typeString(),imd->name().data(),imd->argsString(),
+ // imd->getClassDef()->name().data(),templSpec);
+ // insert imd in the list of all members
+ //printf("Adding member=%s class=%s\n",imd->name().data(),name().data());
+ MemberName *mn = Doxygen::memberNameSDict->find(imd->name());
+ if (mn==0)
+ {
+ mn = new MemberName(imd->name());
+ Doxygen::memberNameSDict->append(imd->name(),mn);
+ }
+ mn->append(imd);
+ }
+ }
+}
+
+QCString ClassDef::getReference() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->getReference();
+ }
+ else
+ {
+ return Definition::getReference();
+ }
+}
+
+bool ClassDef::isReference() const
+{
+ if (m_impl->templateMaster)
+ {
+ return m_impl->templateMaster->isReference();
+ }
+ else
+ {
+ return Definition::isReference();
+ }
+}
+
+void ClassDef::getTemplateParameterLists(QList<ArgumentList> &lists) const
+{
+ Definition *d=getOuterScope();
+ if (d)
+ {
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd=(ClassDef *)d;
+ cd->getTemplateParameterLists(lists);
+ }
+ }
+ if (templateArguments())
+ {
+ lists.append(templateArguments());
+ }
+}
+
+QCString ClassDef::qualifiedNameWithTemplateParameters(
+ QList<ArgumentList> *actualParams) const
+{
+ //static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
+ static bool hideScopeNames = Config_getBool("HIDE_SCOPE_NAMES");
+ //printf("qualifiedNameWithTemplateParameters() localName=%s\n",localName().data());
+ QCString scName;
+ Definition *d=getOuterScope();
+ if (d)
+ {
+ if (d->definitionType()==Definition::TypeClass)
+ {
+ ClassDef *cd=(ClassDef *)d;
+ scName = cd->qualifiedNameWithTemplateParameters(actualParams);
+ }
+ else if (!hideScopeNames)
+ {
+ scName = d->qualifiedName();
+ }
+ }
+
+ SrcLangExt lang = getLanguage();
+ QCString scopeSeparator = getLanguageSpecificSeparator(lang);
+ if (!scName.isEmpty()) scName+=scopeSeparator;
+
+ bool isSpecialization = localName().find('<')!=-1;
+
+ QCString clName = className();
+ //bool isGeneric = getLanguage()==SrcLangExt_CSharp;
+ //if (isGeneric && clName.right(2)=="-g")
+ //{
+ // clName = clName.left(clName.length()-2);
+ //}
+ //printf("m_impl->lang=%d clName=%s\n",m_impl->lang,clName.data());
+ scName+=clName;
+ ArgumentList *al=0;
+ if (templateArguments())
+ {
+ if (actualParams && (al=actualParams->current()))
+ {
+ if (!isSpecialization)
+ {
+ scName+=tempArgListToString(al);
+ }
+ actualParams->next();
+ }
+ else
+ {
+ if (!isSpecialization)
+ {
+ scName+=tempArgListToString(templateArguments());
+ }
+ }
+ }
+ //printf("qualifiedNameWithTemplateParameters: scope=%s qualifiedName=%s\n",name().data(),scName.data());
+ return scName;
+}
+
+QCString ClassDef::className() const
+{
+ if (m_impl->className.isEmpty())
+ {
+ return localName();
+ }
+ else
+ {
+ return m_impl->className;
+ }
+};
+
+void ClassDef::setClassName(const char *name)
+{
+ m_impl->className = name;
+}
+
+void ClassDef::addListReferences()
+{
+ SrcLangExt lang = getLanguage();
+ if (!isLinkableInProject()) return;
+ //printf("ClassDef(%s)::addListReferences()\n",name().data());
+ {
+ LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
+ addRefItem(xrefItems.pointer(),
+ qualifiedName(),
+ lang==SrcLangExt_Fortran ? theTranslator->trType(TRUE,TRUE)
+ : theTranslator->trClass(TRUE,TRUE),
+ getOutputFileBase(),
+ displayName(),
+ 0
+ );
+ }
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ mg->addListReferences(this);
+ }
+ }
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()&MemberList::detailedLists)
+ {
+ ml->addListReferences(this);
+ }
+ }
+}
+
+MemberDef *ClassDef::getMemberByName(const QCString &name) const
+{
+ MemberDef *xmd = 0;
+ if (m_impl->allMemberNameInfoSDict)
+ {
+ MemberNameInfo *mni = m_impl->allMemberNameInfoSDict->find(name);
+ if (mni)
+ {
+ const int maxInheritanceDepth = 100000;
+ int mdist=maxInheritanceDepth;
+ MemberNameInfoIterator mnii(*mni);
+ MemberInfo *mi;
+ for (mnii.toFirst();(mi=mnii.current());++mnii)
+ {
+ ClassDef *mcd=mi->memberDef->getClassDef();
+ int m=minClassDistance(this,mcd);
+ //printf("found member in %s linkable=%d m=%d\n",
+ // mcd->name().data(),mcd->isLinkable(),m);
+ if (m<mdist && mcd->isLinkable())
+ {
+ mdist=m;
+ xmd=mi->memberDef;
+ }
+ }
+ }
+ }
+ //printf("getMemberByName(%s)=%p\n",name.data(),xmd);
+ return xmd;
+}
+
+bool ClassDef::isAccessibleMember(MemberDef *md)
+{
+ return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
+}
+
+MemberList *ClassDef::createMemberList(MemberList::ListType lt)
+{
+ m_impl->memberLists.setAutoDelete(TRUE);
+ QListIterator<MemberList> mli(m_impl->memberLists);
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ }
+ // not found, create a new member list
+ ml = new MemberList(lt);
+ m_impl->memberLists.append(ml);
+ return ml;
+}
+
+MemberList *ClassDef::getMemberList(MemberList::ListType lt)
+{
+ MemberList *ml = m_impl->memberLists.first();
+ while (ml)
+ {
+ if (ml->listType()==lt)
+ {
+ return ml;
+ }
+ ml = m_impl->memberLists.next();
+ }
+ return 0;
+}
+
+void ClassDef::addMemberToList(MemberList::ListType lt,MemberDef *md,bool isBrief)
+{
+ static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
+ static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
+ MemberList *ml = createMemberList(lt);
+ ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
+ ml->append(md);
+
+ // for members in the declaration lists we set the section, needed for member grouping
+ if ((ml->listType()&MemberList::detailedLists)==0) md->setSectionList(this,ml);
+}
+
+void ClassDef::sortMemberLists()
+{
+ MemberList *ml = m_impl->memberLists.first();
+ while (ml)
+ {
+ if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
+ ml = m_impl->memberLists.next();
+ }
+}
+
+static void convertProtectionLevel(
+ MemberList::ListType inListType,
+ Protection inProt,
+ int *outListType1,
+ int *outListType2
+ )
+{
+ // default representing Public inheritance
+ *outListType1=inListType;
+ *outListType2=-1;
+ if (inProt==Public)
+ {
+ switch (inListType) // in the private section of the derived class,
+ // the private section of the base class should not
+ // be visible
+ {
+ case MemberList::priMethods:
+ case MemberList::priStaticMethods:
+ case MemberList::priSlots:
+ case MemberList::priAttribs:
+ case MemberList::priStaticAttribs:
+ case MemberList::priTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (inProt==Protected) // Protected inheritance
+ {
+ switch (inListType) // in the protected section of the derived class,
+ // both the public and protected members are shown
+ // as protected
+ {
+ case MemberList::pubMethods:
+ case MemberList::pubStaticMethods:
+ case MemberList::pubSlots:
+ case MemberList::pubAttribs:
+ case MemberList::pubStaticAttribs:
+ case MemberList::pubTypes:
+ case MemberList::priMethods:
+ case MemberList::priStaticMethods:
+ case MemberList::priSlots:
+ case MemberList::priAttribs:
+ case MemberList::priStaticAttribs:
+ case MemberList::priTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+
+ case MemberList::proMethods:
+ *outListType1=MemberList::pubMethods;
+ *outListType2=MemberList::proMethods;
+ break;
+ case MemberList::proStaticMethods:
+ *outListType1=MemberList::pubStaticMethods;
+ *outListType2=MemberList::proStaticMethods;
+ break;
+ case MemberList::proSlots:
+ *outListType1=MemberList::pubSlots;
+ *outListType1=MemberList::proSlots;
+ break;
+ case MemberList::proAttribs:
+ *outListType1=MemberList::pubAttribs;
+ *outListType2=MemberList::proAttribs;
+ break;
+ case MemberList::proStaticAttribs:
+ *outListType1=MemberList::pubStaticAttribs;
+ *outListType2=MemberList::proStaticAttribs;
+ break;
+ case MemberList::proTypes:
+ *outListType1=MemberList::pubTypes;
+ *outListType2=MemberList::proTypes;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (inProt==Private)
+ {
+ switch (inListType) // in the private section of the derived class,
+ // both the public and protected members are shown
+ // as private
+ {
+ case MemberList::pubMethods:
+ case MemberList::pubStaticMethods:
+ case MemberList::pubSlots:
+ case MemberList::pubAttribs:
+ case MemberList::pubStaticAttribs:
+ case MemberList::pubTypes:
+ case MemberList::proMethods:
+ case MemberList::proStaticMethods:
+ case MemberList::proSlots:
+ case MemberList::proAttribs:
+ case MemberList::proStaticAttribs:
+ case MemberList::proTypes:
+ *outListType1=-1;
+ *outListType2=-1;
+ break;
+
+ case MemberList::priMethods:
+ *outListType1=MemberList::pubMethods;
+ *outListType2=MemberList::proMethods;
+ break;
+ case MemberList::priStaticMethods:
+ *outListType1=MemberList::pubStaticMethods;
+ *outListType2=MemberList::proStaticMethods;
+ break;
+ case MemberList::priSlots:
+ *outListType1=MemberList::pubSlots;
+ *outListType1=MemberList::proSlots;
+ break;
+ case MemberList::priAttribs:
+ *outListType1=MemberList::pubAttribs;
+ *outListType2=MemberList::proAttribs;
+ break;
+ case MemberList::priStaticAttribs:
+ *outListType1=MemberList::pubStaticAttribs;
+ *outListType2=MemberList::proStaticAttribs;
+ break;
+ case MemberList::priTypes:
+ *outListType1=MemberList::pubTypes;
+ *outListType2=MemberList::proTypes;
+ break;
+ default:
+ break;
+ }
+ }
+ //printf("convertProtectionLevel(type=%d prot=%d): %d,%d\n",
+ // inListType,inProt,*outListType1,*outListType2);
+}
+
+int ClassDef::countInheritedDecMembersRec(MemberList::ListType lt,
+ ClassDef *inheritedFrom)
+{
+ //printf("> %s::countedInheritedDecMembersRec(%d)\n",name().data(),lt);
+ int count=0;
+ if (m_impl->inherits)
+ {
+ BaseClassListIterator it(*m_impl->inherits);
+ BaseClassDef *ibcd;
+ for (it.toFirst();(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ int lt1,lt2;
+ // an inherited member with protection level lt
+ // could have come from a section with protection levels lt1 or lt2
+ // in the bass class (e.g. for protected inheritance, the protected
+ // member comes from protected and public methods in the base class)
+ convertProtectionLevel(lt,ibcd->prot,&lt1,&lt2);
+ MemberList *ml1 = icd->getMemberList((MemberList::ListType)lt1);
+ MemberList *ml2 = icd->getMemberList((MemberList::ListType)lt2);
+ if (ml1)
+ {
+ count+=icd->countMembersIncludingGrouped((MemberList::ListType)lt1,inheritedFrom,TRUE);
+ }
+ if (ml2)
+ {
+ count+=icd->countMembersIncludingGrouped((MemberList::ListType)lt2,inheritedFrom,TRUE);
+ }
+ if (lt1!=-1)
+ {
+ count+=icd->countInheritedDecMembersRec((MemberList::ListType)lt1,inheritedFrom);
+ }
+ if (lt2!=-1)
+ {
+ count+=icd->countInheritedDecMembersRec((MemberList::ListType)lt2,inheritedFrom);
+ }
+ }
+ }
+ //printf("< %s::countedInheritedDecMembersRec(%d) count=%d\n",name().data(),lt,count);
+ return count;
+}
+
+int ClassDef::countInheritedDecMembers(MemberList::ListType lt)
+{
+ int count=0;
+ MemberList *ml = getMemberList(lt);
+ if (ml)
+ {
+ count = ml->countInheritableMembers(this);
+ }
+ if (count==0) // for this class the (non-private) member list is empty
+ // see if we need to create a section for it under
+ // Additional Inherited Members
+ {
+ count = countInheritedDecMembersRec(lt,this);
+ }
+ else // member list is not empty, so we will add the inherited members there
+ {
+ count = 0;
+ }
+ return count;
+}
+
+int ClassDef::countAdditionalInheritedMembers()
+{
+ int totalCount=0;
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ if (lmd->type!=MemberList::friends) // friendship is not inherited
+ {
+ totalCount+=countInheritedDecMembers(lmd->type);
+ }
+ }
+ }
+ //printf("countAdditonalInheritedMembers()=%d\n",totalCount);
+ return totalCount;
+}
+
+void ClassDef::writeAdditionalInheritedMembers(OutputList &ol)
+{
+ //printf("**** writeAdditionalInheritedMembers()\n");
+ QListIterator<LayoutDocEntry> eli(
+ LayoutDocManager::instance().docEntries(LayoutDocManager::Class));
+ LayoutDocEntry *lde;
+ for (eli.toFirst();(lde=eli.current());++eli)
+ {
+ if (lde->kind()==LayoutDocEntry::MemberDecl)
+ {
+ LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
+ MemberList *ml = getMemberList(lmd->type);
+ if (ml==0 || ml->numDecMembers()==0)
+ {
+ QPtrDict<void> visited(17);
+ writeInheritedMemberDeclarations(ol,lmd->type,lmd->title(getLanguage()),this,TRUE,&visited);
+ }
+ }
+ }
+}
+
+int ClassDef::countMembersIncludingGrouped(MemberList::ListType lt,
+ ClassDef *inheritedFrom,bool additional)
+{
+ int count=0;
+ MemberList *ml = getMemberList(lt);
+ if (ml)
+ {
+ count=ml->countInheritableMembers(inheritedFrom);
+ }
+ //printf("%s:countMembersIncludingGrouped: count=%d\n",name().data(),count);
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ bool hasOwnSection = !mg->allMembersInSameSection() ||
+ !m_impl->subGrouping; // group is in its own section
+ if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
+ {
+ count+=mg->countGroupedInheritedMembers(lt);
+ }
+ }
+ }
+ //printf("%s:countMembersIncludingGrouped(lt=%d,%s)=%d\n",
+ // name().data(),lt,ml?ml->listTypeAsString().data():"<none>",count);
+ return count;
+}
+
+void ClassDef::writeInheritedMemberDeclarations(OutputList &ol,
+ MemberList::ListType lt,const QCString &title,
+ ClassDef *inheritedFrom,bool invert,
+ QPtrDict<void> *visitedClasses)
+{
+ ol.pushGeneratorState();
+ ol.disableAllBut(OutputGenerator::Html);
+ bool process = countMembersIncludingGrouped(lt,inheritedFrom,FALSE)>0;
+ //printf("%s: writeInheritedMemberDec: lt=%d process=%d invert=%d\n",
+ // name().data(),lt,process,invert);
+ if (process^invert)
+ {
+ if (m_impl->inherits)
+ {
+ BaseClassListIterator it(*m_impl->inherits);
+ BaseClassDef *ibcd;
+ for (it.toFirst();(ibcd=it.current());++it)
+ {
+ ClassDef *icd=ibcd->classDef;
+ int lt1,lt2;
+ convertProtectionLevel(lt,ibcd->prot,&lt1,&lt2);
+ //printf("%s:convert %d->(%d,%d)\n",icd->name().data(),lt,lt1,lt2);
+ if (visitedClasses->find(icd)!=0)
+ {
+ return; // already processed before (in case of multiple inheritance)
+ }
+ visitedClasses->insert(icd,icd);
+ if (lt1!=-1)
+ {
+ icd->writeMemberDeclarations(ol,(MemberList::ListType)lt1,
+ title,QCString(),FALSE,inheritedFrom,lt2,invert,visitedClasses);
+ }
+ }
+ }
+ }
+ ol.popGeneratorState();
+}
+
+void ClassDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title,
+ const char *subTitle,bool showInline,ClassDef *inheritedFrom,int lt2,bool invert,QPtrDict<void> *visitedClasses)
+{
+ //printf("%s: ClassDef::writeMemberDeclarations for %s\n",name().data(),ml->listTypeAsString().data());
+ MemberList * ml = getMemberList(lt);
+ if (getLanguage()==SrcLangExt_VHDL) // use specific declarations function
+ {
+ if (ml)
+ {
+ VhdlDocGen::writeVhdlDeclarations(ml,ol,0,this,0,0);
+ }
+ }
+ else
+ {
+ //printf("%s::writeMemberDeclarations(%s)\n",name().data(),title.data());
+ //static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
+ if (ml)
+ {
+ ml->writeDeclarations(ol,this,0,0,0,title,subTitle,FALSE,showInline,inheritedFrom);
+ if (lt2!=-1)
+ {
+ MemberList * ml2 = getMemberList((MemberList::ListType)lt2);
+ if (ml2)
+ {
+ ml2->writeDeclarations(ol,this,0,0,0,0,0,FALSE,showInline,inheritedFrom);
+ }
+ }
+ }
+ static bool inlineInheritedMembers = Config_getBool("INLINE_INHERITED_MEMB");
+ if (!inlineInheritedMembers) // show inherited members as separate lists
+ {
+ QPtrDict<void> visited(17);
+ writeInheritedMemberDeclarations(ol,lt,title,
+ inheritedFrom ? inheritedFrom : this,
+ invert,visitedClasses==0 ? &visited: visitedClasses);
+ }
+ }
+}
+
+void ClassDef::addGroupedInheritedMembers(OutputList &ol,MemberList::ListType lt,
+ ClassDef *inheritedFrom,const QCString &inheritId)
+{
+ //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data());
+ if (m_impl->memberGroupSDict)
+ {
+ MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
+ {
+ mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
+ }
+ }
+ }
+}
+
+void ClassDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title,bool showInline)
+{
+ //printf("%s: ClassDef::writeMemberDocumentation()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeDocumentation(ol,displayName(),this,title,FALSE,showInline);
+}
+
+void ClassDef::writeSimpleMemberDocumentation(OutputList &ol,MemberList::ListType lt)
+{
+ //printf("%s: ClassDef::writeSimpleMemberDocumentation()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml) ml->writeSimpleDocumentation(ol,this);
+}
+
+void ClassDef::writePlainMemberDeclaration(OutputList &ol,
+ MemberList::ListType lt,bool inGroup,
+ ClassDef *inheritedFrom,const char *inheritId)
+{
+ //printf("%s: ClassDef::writePlainMemberDeclaration()\n",name().data());
+ MemberList * ml = getMemberList(lt);
+ if (ml)
+ {
+ ml->setInGroup(inGroup);
+ ml->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
+ }
+}
+
+bool ClassDef::isLocal() const
+{
+ return m_impl->isLocal;
+}
+
+ClassSDict *ClassDef::getClassSDict()
+{
+ return m_impl->innerClasses;
+}
+
+ClassDef::CompoundType ClassDef::compoundType() const
+{
+ return m_impl->compType;
+}
+
+BaseClassList *ClassDef::baseClasses() const
+{
+ return m_impl->inherits;
+}
+
+BaseClassList *ClassDef::subClasses() const
+{
+ return m_impl->inheritedBy;
+}
+
+MemberNameInfoSDict *ClassDef::memberNameInfoSDict() const
+{
+ return m_impl->allMemberNameInfoSDict;
+}
+
+Protection ClassDef::protection() const
+{
+ return m_impl->prot;
+}
+
+ArgumentList *ClassDef::templateArguments() const
+{
+ return m_impl->tempArgs;
+}
+
+NamespaceDef *ClassDef::getNamespaceDef() const
+{
+ return m_impl->nspace;
+}
+
+FileDef *ClassDef::getFileDef() const
+{
+ return m_impl->fileDef;
+}
+
+QDict<ClassDef> *ClassDef::getTemplateInstances() const
+{
+ return m_impl->templateInstances;
+}
+
+ClassDef *ClassDef::templateMaster() const
+{
+ return m_impl->templateMaster;
+}
+
+bool ClassDef::isTemplate() const
+{
+ return m_impl->tempArgs!=0;
+}
+
+IncludeInfo *ClassDef::includeInfo() const
+{
+ return m_impl->incInfo;
+}
+
+UsesClassDict *ClassDef::usedImplementationClasses() const
+{
+ return m_impl->usesImplClassDict;
+}
+
+UsesClassDict *ClassDef::usedByImplementationClasses() const
+{
+ return m_impl->usedByImplClassDict;
+}
+
+UsesClassDict *ClassDef::usedInterfaceClasses() const
+{
+ return m_impl->usesIntfClassDict;
+}
+
+bool ClassDef::isTemplateArgument() const
+{
+ return m_impl->isTemplArg;
+}
+
+bool ClassDef::isAbstract() const
+{
+ return m_impl->isAbstract || (m_impl->spec&Entry::Abstract);
+}
+
+bool ClassDef::isFinal() const
+{
+ return m_impl->spec&Entry::Final;
+}
+
+bool ClassDef::isSealed() const
+{
+ return m_impl->spec&Entry::Sealed;
+}
+
+bool ClassDef::isObjectiveC() const
+{
+ return getLanguage()==SrcLangExt_ObjC;
+}
+
+bool ClassDef::isCSharp() const
+{
+ return getLanguage()==SrcLangExt_CSharp;
+}
+
+ClassDef *ClassDef::categoryOf() const
+{
+ return m_impl->categoryOf;
+}
+
+const QList<MemberList> &ClassDef::getMemberLists() const
+{
+ return m_impl->memberLists;
+}
+
+MemberGroupSDict *ClassDef::getMemberGroupSDict() const
+{
+ return m_impl->memberGroupSDict;
+}
+
+void ClassDef::setNamespace(NamespaceDef *nd)
+{
+ m_impl->nspace = nd;
+}
+
+void ClassDef::setFileDef(FileDef *fd)
+{
+ m_impl->fileDef=fd;
+}
+
+void ClassDef::setSubGrouping(bool enabled)
+{
+ m_impl->subGrouping = enabled;
+}
+
+void ClassDef::setProtection(Protection p)
+{
+ m_impl->prot=p;
+}
+
+void ClassDef::setIsStatic(bool b)
+{
+ m_impl->isStatic=b;
+}
+
+void ClassDef::setCompoundType(CompoundType t)
+{
+ m_impl->compType = t;
+}
+
+void ClassDef::setTemplateMaster(ClassDef *tm)
+{
+ m_impl->templateMaster=tm;
+}
+
+void ClassDef::makeTemplateArgument(bool b)
+{
+ m_impl->isTemplArg = b;
+}
+
+void ClassDef::setCategoryOf(ClassDef *cd)
+{
+ m_impl->categoryOf = cd;
+}
+
+void ClassDef::setUsedOnly(bool b)
+{
+ m_impl->usedOnly = b;
+}
+
+bool ClassDef::isUsedOnly() const
+{
+ return m_impl->usedOnly;
+}
+
+bool ClassDef::isSimple() const
+{
+ return m_impl->isSimple;
+}
+
+MemberDef *ClassDef::isSmartPointer() const
+{
+ return m_impl->arrowOperator;
+}
+
+void ClassDef::reclassifyMember(MemberDef *md,MemberDef::MemberType t)
+{
+ md->setMemberType(t);
+ MemberList *ml = m_impl->memberLists.first();
+ while (ml)
+ {
+ ml->remove(md);
+ ml = m_impl->memberLists.next();
+ }
+ insertMember(md);
+}
+
+QCString ClassDef::anchor() const
+{
+ QCString anc;
+ if (isEmbeddedInOuterScope() && !Doxygen::generatingXmlOutput)
+ {
+ if (m_impl->templateMaster)
+ {
+ // point to the template of which this class is an instance
+ anc = m_impl->templateMaster->getOutputFileBase();
+ }
+ else if (isReference())
+ {
+ // point to the external location
+ anc = m_impl->fileName;
+ }
+ else
+ {
+ // normal locally defined class
+ anc = convertNameToFile(m_impl->fileName);
+ }
+ }
+ return anc;
+}
+
+bool ClassDef::isEmbeddedInOuterScope() const
+{
+ static bool inlineGroupedClasses = Config_getBool("INLINE_GROUPED_CLASSES");
+ static bool inlineSimpleClasses = Config_getBool("INLINE_SIMPLE_STRUCTS");
+
+ Definition *container = getOuterScope();
+
+ bool containerLinkable =
+ container &&
+ (
+ (container==Doxygen::globalScope && getFileDef() && getFileDef()->isLinkableInProject()) || // global class in documented file
+ container->isLinkableInProject() // class in documented scope
+ );
+
+ // inline because of INLINE_GROUPED_CLASSES=YES ?
+ bool b1 = (inlineGroupedClasses && partOfGroups()!=0); // a grouped class
+ // inline because of INLINE_SIMPLE_STRUCTS=YES ?
+ bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
+ (containerLinkable || // in a documented container
+ partOfGroups()!=0 // or part of a group
+ )
+ );
+ //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
+ // "inlineSimpleClasses=%d partOfGroups()=%p m_impl->isSimple=%d "
+ // "getOuterScope()=%s b1=%d b2=%d\n",
+ // name().data(),inlineGroupedClasses,inlineSimpleClasses,
+ // partOfGroups().pointer(),m_impl->isSimple,getOuterScope()?getOuterScope()->name().data():"<none>",b1,b2);
+ return b1 || b2; // either reason will do
+}
+
+const ClassList *ClassDef::taggedInnerClasses() const
+{
+ return m_impl->taggedInnerClasses;
+}
+
+void ClassDef::addTaggedInnerClass(ClassDef *cd)
+{
+ if (m_impl->taggedInnerClasses==0)
+ {
+ m_impl->taggedInnerClasses = new ClassList;
+ }
+ m_impl->taggedInnerClasses->append(cd);
+}
+
+ClassDef *ClassDef::tagLessReference() const
+{
+ return m_impl->tagLessRef;
+}
+
+void ClassDef::setTagLessReference(ClassDef *cd)
+{
+ m_impl->tagLessRef = cd;
+}
+
+void ClassDef::removeMemberFromLists(MemberDef *md)
+{
+ MemberList *ml = m_impl->memberLists.first();
+ while (ml)
+ {
+ ml->remove(md);
+ ml = m_impl->memberLists.next();
+ }
+}
+
+bool ClassDef::isJavaEnum() const
+{
+ return m_impl->isJavaEnum;
+}
+
+bool ClassDef::isGeneric() const
+{
+ return m_impl->isGeneric;
+}
+
+void ClassDef::setClassSpecifier(int spec)
+{
+ m_impl->spec = spec;
+}
+
+bool ClassDef::isExtension() const
+{
+ QCString n = name();
+ int si = n.find('(');
+ int ei = n.find(')');
+ bool b = ei>si && n.mid(si+1,ei-si-1).stripWhiteSpace().isEmpty();
+ return b;
+}
+
+